--[[
ģƣʱ
ģ鹦ܣֻÿοʱNTPϵͳʱ
-- Ҫѣ
-- ģöѹNTPͬʱ
-- ܱ֤κʱκεص㶼ܰٷְͬȷʱ
-- ԣûĿеҵ߼ϸʱͬ
-- Ҫʹʹñģ飬ʹԼӦ÷ͬʱ
аٶѧϰNTPЭ
ȻĶģ
ģ޸ʱ䣺2017.03.22
]]

--ģ,
local base = _G
local string = require"string"
local os = require"os"
local sys  = require"sys"
local link = require"link"
local misc = require"misc"
local common = require"common"
local pack = require"pack"
module(...)

--سõȫֺ
local print = base.print
local send = link.send
local dispatch = sys.dispatch
local sbyte,ssub = string.byte,string.sub


--õNTPϣ˳ȥӷͬʱ䣬ͬɹ󣬾˳ټ
local tserver =
{	
	"cn.pool.ntp.org",
	"ntp1.aliyun.com",
	"cn.ntp.org.cn",    
	"s2c.time.edu.cn",
	"tw.pool.ntp.org",    
	"0.cn.pool.ntp.org",
	"0.tw.pool.ntp.org",	
	"1.cn.pool.ntp.org",
	"1.tw.pool.ntp.org",
	"ntp2.aliyun.com",
	"2.cn.pool.ntp.org",
	"2.tw.pool.ntp.org",
	"ntp3.aliyun.com",
	"3.cn.pool.ntp.org",
	"3.tw.pool.ntp.org",
	"edu.ntp.org.cn", 
}
--ǰӵķtserverе
local tserveridx = 1

--REQUESTȴʱ
local REQUEST_TIMEOUT = 8000
--ÿREQUESTԴ
local REQUEST_RETRY_TIMES = 1
--socket id
local lid
--뵱ǰNTPʱͬѾԵĴ
local retries = 0


--[[
retry
  ʱͬеԶ
  
ֵ
]]
local function retry()
	sys.timer_stop(retry)
	--Դ1
	retries = retries + 1
	--δԴ,ͬ
	if retries < REQUEST_RETRY_TIMES then
		request()
	else
		--Դ,뵱ǰͬʧ
		upend(false)
	end
end


--[[
upend
  뵱ǰNTPʱͬ
  
		sucʱͬtrueΪɹΪʧ
ֵ
]]
function upend(suc)
	print("ntp.upend",tserver[tserveridx],suc)
	--ֹͣԶʱ
	sys.timer_stop(retry)
	retries = 0
	--Ͽ
	link.close(lid)
	--ͬʱɹ  NTPѾ
	if suc or tserveridx>=#tserver then
		--һڲϢNTP_END_INDĿǰģʽʹ
		dispatch("NTP_END_IND",suc)
		--һⲿϢNTP_INDӦýűʹãsucʾͬʱĽ
		dispatch("NTP_IND",suc)
	else
		tserveridx = tserveridx+1
		connect()
	end	
end

--[[
request
  ͬ͡ʱ䡱ݵ
  
ֵ
]]
function request()
	send(lid,common.hexstobins("E30006EC0000000000000000314E31340000000000000000000000000000000000000000000000000000000000000000"))
	sys.timer_start(retry,REQUEST_TIMEOUT)
end

--[[
nofity
  socket״̬Ĵ
  
        idsocket idԺԲ
        evtϢ¼
		val Ϣ¼
ֵ
]]
local function nofity(id,evt,val)
	--ӽ
	if evt == "CONNECT" then
		--һڲϢNTP_BEGIN_INDĿǰģʽʹ
		dispatch("NTP_BEGIN_IND")
		--ӳɹ
		if val == "CONNECT OK" then
			request()
		--ʧ
		else
			upend(false)
		end
	--ӱϿ
	elseif evt == "STATE" and val == "CLOSED" then		 
		upend(false)
	end
end

--[[
setclkcb
  misc.setclockӿʱĻص
  
        cmd ԺԲ
        sucóɹʧܣtrueɹʧ
ֵ
]]
local function setclkcb(cmd,suc)
	upend(suc)
end

--[[
recv
  socketݵĴ
  
        id socket idԺԲ
        dataյ
ֵ
]]
local function recv(id,data)
	--ֹͣԶʱ
	sys.timer_stop(retry)
	--ݸʽ
	if string.len(data)~=48 then
		upend(false)
		return
	end
	print("ntp recv:",common.binstohexs(ssub(data,41,44)))
	misc.setclock(os.date("*t",(sbyte(ssub(data,41,41))-0x83)*2^24+(sbyte(ssub(data,42,42))-0xAA)*2^16+(sbyte(ssub(data,43,43))-0x7E)*2^8+(sbyte(ssub(data,44,44))-0x80)+1),setclkcb)
end

--[[
connect
  socketӵtserveridxNTP
  
ֵ
]]
function connect()
	lid = link.open(nofity,recv,"ntp")
	link.connect(lid,"UDP",tserver[tserveridx],123)
end

connect()
