longLinkSocketDahua.lua 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. module(...,package.seeall)
  2. require"socket"
  3. require"nvm"
  4. require"utils"
  5. --调度中心服务器信息
  6. local ddzxIpDahua,ddzxTcpPortDahua = nvm.get("ddzxIpDahua"),nvm.get("ddzxTcpPortDahua")
  7. local rfidBufferMaxCountDahua = nvm.get("rfidBufferMaxCountDahua") or 50
  8. local rfidReportIntervalDahua = nvm.get("rfidReportIntervalDahua") or 60
  9. local ddzxWaitRecvMsgMaxTime = 10
  10. local qzjWaitRecvMsgMaxTime = 10
  11. --读写器ID
  12. local devId = nvm.get("devId") or "0000000000"
  13. --读写器版本号
  14. local devSn = nvm.get("devSn")
  15. --ntp同步时间结果
  16. local timerSyncResult = false
  17. --长连接socket连接状态
  18. local longLinkSocketConnState = false
  19. --前置机服务器信息
  20. local qzjIp,qzjTcpPort
  21. local qzjFrameSn = 0x0000
  22. --协议参数
  23. --帧头
  24. local prefix = 0xAAAA
  25. --协议类型及协议版本
  26. local protoVer = 0x10
  27. --十六进制字符串反转
  28. local function hexStrReverse(hexstr)
  29. local str = ""
  30. for i = 1, string.len(hexstr) - 1, 2 do
  31. local tmpStr = string.sub(hexstr, -(i+1), -i)
  32. str = str .. tmpStr
  33. end
  34. return str
  35. end
  36. --openMulByteReverse:开启多字节反转
  37. local function hex2bin( hexstr, openMulByteReverse )
  38. --检查字符串长度
  39. if(hexstr:len()%2~=0) then
  40. return false,"hex2str invalid input lenth"
  41. end
  42. if openMulByteReverse then
  43. hexstr = hexStrReverse(hexstr)
  44. end
  45. local str = ""
  46. for i = 1, string.len(hexstr) - 1, 2 do
  47. local doublebytestr = string.sub(hexstr, i, i+1);
  48. local n = tonumber(doublebytestr, 16);
  49. if 0 == n then
  50. str = str .. '\00'
  51. else
  52. str = str .. string.format("%c", n)
  53. end
  54. end
  55. return str
  56. end
  57. local function hex2str(str)
  58. --判断输入类型
  59. if (type(str)~="string") then
  60. return nil,"hex2str invalid input type"
  61. end
  62. --滤掉分隔符
  63. str=str:gsub("[%s%p]",""):upper()
  64. --检查内容是否合法
  65. if(str:find("[^0-9A-Fa-f]")~=nil) then
  66. return nil,"hex2str invalid input content"
  67. end
  68. --检查字符串长度
  69. if(str:len()%2~=0) then
  70. return nil,"hex2str invalid input lenth"
  71. end
  72. --拼接字符串
  73. local index=1
  74. local ret=""
  75. for index=1,str:len(),2 do
  76. ret=ret..string.char(tonumber(str:sub(index,index+1),16))
  77. end
  78. --log.info("socketHeartbeatTask.hex2str", ret)
  79. return ret
  80. end
  81. local function getFormatTimeBin(time)
  82. local tClock = time and os.date("*t",time) or os.date("*t")
  83. local formatTimeBin = string.char(tonumber((""..tClock.year):sub(3,4)))
  84. ..string.char(tClock.month)
  85. ..string.char(tClock.day)
  86. ..string.char(tClock.hour)
  87. ..string.char(tClock.min)
  88. ..string.char(tClock.sec)
  89. return formatTimeBin
  90. end
  91. local crc16Table = {
  92. 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
  93. 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
  94. 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
  95. 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
  96. 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
  97. 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
  98. 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
  99. 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
  100. 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
  101. 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
  102. 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
  103. 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
  104. 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
  105. 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
  106. 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
  107. 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
  108. 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
  109. 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
  110. 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
  111. 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
  112. 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
  113. 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  114. 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
  115. 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
  116. 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
  117. 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
  118. 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
  119. 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
  120. 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
  121. 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
  122. 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
  123. 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
  124. }
  125. --计算尾部校验码
  126. local function getCrc16(packet)
  127. if not packet then
  128. log.error("longLinkSocketDahua.getCrc16", "packet empty!!")
  129. return false
  130. end
  131. local CRC = 0XFFFF
  132. local tableNo = 1
  133. for i=1,#packet do
  134. tableNo = bit.band(bit.bxor( bit.rshift(CRC,8), string.byte(packet,i)), 0xFF)
  135. --log.info("longLinkSocketDahua.getCrc16",bit.lshift(CRC,8))
  136. CRC = bit.band(bit.bxor(bit.band(bit.lshift(CRC,8), 0xFFFF), crc16Table[tableNo+1]), 0xFFFF)
  137. --log.info("longLinkSocketDahua.getCrc16",tableNo,crc16Table[tableNo+1],CRC)
  138. end
  139. local crc16Bin = hex2bin(string.format("%04x",CRC))
  140. return true, crc16Bin
  141. end
  142. --生成报文
  143. local function createPacket(frameSn,commandId,content)
  144. if not prefix then
  145. log.error("longLinkSocketDahua.createPacket", "prefix empty!!")
  146. return false
  147. end
  148. if not protoVer then
  149. log.error("longLinkSocketDahua.createPacket", "protoVer empty!!")
  150. return false
  151. end
  152. if not devId then
  153. log.error("longLinkSocketDahua.createPacket", "devId empty!!")
  154. return false
  155. end
  156. if not frameSn then
  157. log.error("longLinkSocketDahua.createPacket", "frameSn empty!!")
  158. return false
  159. end
  160. if not commandId then
  161. log.error("longLinkSocketDahua.createPacket", "commandId empty!!")
  162. return false
  163. end
  164. if not content then
  165. content = ""
  166. end
  167. local packetBin = ""
  168. local length = #content + 10
  169. local prefixHexStr = string.format("%04x",prefix)
  170. local lengthHexStr = string.format("%04x",length)
  171. packetBin = hex2bin(prefixHexStr)..hex2bin(lengthHexStr)..string.char(protoVer)
  172. ..hex2bin(devId)..string.char(frameSn)
  173. ..string.char(commandId)..content
  174. local res, crc16Bin = getCrc16(packetBin:sub(3,-1))
  175. log.info("longLinkSocketDahua.createPacket", "packetBin hex:",packetBin:toHex(), "crc16Bin hex:",crc16Bin:toHex())
  176. if not res then
  177. log.error("longLinkSocketDahua.createPacket", "getCrc16 failed!!")
  178. return false
  179. end
  180. packetBin = packetBin..crc16Bin
  181. --log.info("longLinkSocketDahua.createPacket", "packetBin hex:",packetBin:toHex())
  182. return true, packetBin
  183. end
  184. --解析响应报文
  185. local function parseRespPacket(packet)
  186. if not packet then
  187. log.error("longLinkSocketDahua.parseRespPacket", "packet empty!!")
  188. return false
  189. end
  190. if #packet < 14 then
  191. log.error("longLinkSocketDahua.parseRespPacket", "packet length < 14!! packet:", packet:toHex())
  192. return false
  193. end
  194. local prefixP = packet:sub(1,2):toHex()
  195. if tonumber(prefixP,16) ~= prefix then
  196. log.error("longLinkSocketDahua.parseRespPacket", "prefix invalid!! prefixP:", prefixP)
  197. return false
  198. end
  199. local length = tonumber(packet:sub(3,4):toHex(), 16)
  200. if #packet < length + 4 then
  201. log.error("longLinkSocketDahua.parseRespPacket", "packet length error!!", packet:toHex())
  202. return false
  203. end
  204. --crc校验
  205. local crc_packet = packet:sub(3,length + 2)
  206. local res, crc16Bin = getCrc16(crc_packet)
  207. if not res then
  208. log.error("longLinkSocketDahua.parseRespPacket", "getCrc16 failed!! crc_packet:",crc_packet:toHex())
  209. return false
  210. end
  211. local crc16P = packet:sub(length + 3,length + 4):toHex()
  212. local crc16 = crc16Bin:toHex()
  213. if crc16P ~= crc16 then
  214. log.error("longLinkSocketDahua.parseRespPacket", "crc verify failed!! crc16P:",crc16P,", crc16:",crc16)
  215. return false
  216. end
  217. -- AAAA 0012 10 FFC10001EC 00 52 0100202BDD0A2179 EBD7
  218. local contentLenP = length - 10
  219. local contentP = ""
  220. if contentLenP > 0 then
  221. contentP = packet:sub(13,contentLenP + 12)
  222. end
  223. if #contentP ~= contentLenP then
  224. log.error("longLinkSocketDahua.parseRespPacket", "contentLenP error!! contentLenP:",contentLenP,", contenLen:", #contentP)
  225. return false
  226. end
  227. local parseRes = {}
  228. local devIdP = packet:sub(6,10):toHex()
  229. local commandIdP = string.byte(packet,12)
  230. parseRes["devId"] = devIdP
  231. parseRes["commandId"] = commandIdP
  232. parseRes["frameSn"] = string.byte(packet,11)
  233. parseRes["length"] = length
  234. log.info("longLinkSocketDahua.parseRespPacket","commandIdP:",commandIdP,"contentLenP:",contentLenP)
  235. if commandIdP == 0x52 then --配置主控参数
  236. if contentLenP == 0 then
  237. log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!")
  238. return false
  239. end
  240. local contentTypeP = string.byte(contentP,1)
  241. parseRes["contentType"] = contentTypeP
  242. --bit7: 1--读, 0--写
  243. local cmdTypeP = bit.rshift(contentTypeP,7)
  244. parseRes["cmdType"] = cmdTypeP
  245. --bit6~0: 1--通讯服务器参数区, 0--统一调度服务器参数区
  246. local areaTypeP = bit.band(contentTypeP,0x7F)
  247. parseRes["areaType"] = areaTypeP
  248. --读取主控配置参数
  249. if cmdTypeP == 1 then
  250. return true, parseRes
  251. end
  252. local addrTypeP = string.byte(contentP,2)
  253. local qzjIpP = ""
  254. local qzjPortP = tonumber(contentP:sub(3,4):toHex(),16)
  255. if addrTypeP == 0x1 then
  256. qzjIpP = contentP:sub(5,-1)
  257. elseif addrTypeP == 0x0 then
  258. qzjIpP = string.byte(contentP,5).."."..string.byte(contentP,6)
  259. .."."..string.byte(contentP,7).."."..string.byte(contentP,8)
  260. else
  261. log.error("longLinkSocketDahua.parseRespPacket", "addrTypeP invalid!! addrTypeP:", addrTypeP)
  262. return false
  263. end
  264. parseRes["qzjIp"] = qzjIpP
  265. parseRes["qzjPort"] = qzjPortP
  266. parseRes["addrType"] = addrTypeP
  267. qzjIp = qzjIpP
  268. qzjTcpPort = qzjPortP
  269. log.info("longLinkSocketDahua.parseRespPacket","parseRes qzjIpP:", qzjIpP, "qzjPortP:", qzjPortP)
  270. return true, parseRes
  271. elseif commandIdP == 0x01 then --校时包
  272. if contentLenP ~= 0x05 then
  273. log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!")
  274. return false
  275. end
  276. local cacheCtlP = string.byte(contentP,1)
  277. local serverTimeP = tonumber(contentP:sub(2,5):toHex(),16)
  278. parseRes["serverTime"] = serverTimeP
  279. return true, parseRes
  280. elseif commandIdP == 0x02 then --服务器确认包
  281. if contentLenP ~= 0x01 then
  282. log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!")
  283. return false
  284. end
  285. local cacheCtlP = string.byte(contentP,1)
  286. parseRes["cacheCtl"] = cacheCtlP
  287. return true, parseRes
  288. elseif commandIdP == 0x0A then --获取设备版本包
  289. return true, parseRes
  290. elseif commandIdP == 0x06 then --设备重启包
  291. return true, parseRes
  292. elseif commandIdP == 0x70 then --设备恢复出厂设置包
  293. return true, parseRes
  294. else
  295. log.error("longLinkSocketDahua.parseRespPacket","commandIdP invalid!!")
  296. return false
  297. end
  298. end
  299. --连接前置机主任务
  300. sys.taskInit(
  301. function()
  302. while true do
  303. log.info("longLinkSocketDahua.qzjTask","wait ON_MESSAGE_DDZX_AUTH_SUCCESS message ...")
  304. local res,data = sys.waitUntil("ON_MESSAGE_DDZX_AUTH_SUCCESS", 3600*1000)
  305. if res then
  306. log.info("longLinkSocketDahua.qzjTask","receive ON_MESSAGE_DDZX_AUTH_SUCCESS message")
  307. break
  308. else
  309. log.info("longLinkSocketDahua.qzjTask","wait ON_MESSAGE_DDZX_AUTH_SUCCESS timeout")
  310. end
  311. end
  312. local retryConnectCnt = 0 --失败次数统计
  313. while true do
  314. --是否获取到了分配的ip(是否连上网)
  315. if socket.isReady() then
  316. --新建一个socket对象,如果是udp只需要把tcp改成udp即可
  317. local socketClient = socket.tcp()
  318. log.info("longLinkSocketDahua.qzjTask","connect to qzjIp:", qzjIp, "qzjTcpPort:", qzjTcpPort)
  319. --尝试连接指定服务器
  320. if socketClient:connect(qzjIp,qzjTcpPort) then
  321. --连接成功
  322. log.info("longLinkSocketDahua.qzjTask","connect success")
  323. retryConnectCnt = 0 --失败次数清零
  324. longLinkSocketConnState = true
  325. --发送注册包
  326. local result,packet_data = createPacket(0,0x80,string.char(0x0)..devSn..string.char(0x0))
  327. if not result then
  328. log.error("longLinkSocketDahua.qzjTask", "createPacket failed!!")
  329. else
  330. if socketClient:send(packet_data, 10) then
  331. log.info("longLinkSocketDahua.qzjTask","send regist success:", packet_data:toHex())
  332. --等待服务端校时包(出厂前必须收到校时包才开启射频功能,出厂后可能收不到校时包)
  333. local res,msg_data = socketClient:recv(qzjWaitRecvMsgMaxTime*1000)
  334. if not res then
  335. log.warn("longLinkSocketDahua.qzjTask","wait receive serverTime timeout!")
  336. else
  337. log.info("longLinkSocketDahua.qzjTask","receive serverTime msg:", msg_data:toHex())
  338. local res, parseRes = parseRespPacket(msg_data)
  339. if not res then
  340. log.error("longLinkSocketDahua.qzjTask","parseRespPacket failed!!", msg_data:toHex())
  341. else
  342. if parseRes.serverTime > 0 then
  343. --需要ntp切换时区
  344. local diffTime = parseRes.serverTime - os.time()
  345. log.info("longLinkSocketDahua.qzjTask","serverTime:", parseRes.serverTime,"diffTime:", diffTime)
  346. if diffTime >= 1 or diffTime <= -1 then
  347. sys.publish("RESET_CLOCK_TIME", diffTime)
  348. end
  349. end
  350. end
  351. end
  352. --发送注册响应包
  353. local result,packet_data = createPacket(0,0x82)
  354. if not result then
  355. log.error("longLinkSocketDahua.qzjTask", "createPacket failed!!")
  356. else
  357. if socketClient:send(packet_data, 10) then
  358. log.info("longLinkSocketDahua.qzjTask","send regist resp success:", packet_data:toHex())
  359. --通知发送标签数据任务开始工作
  360. sys.publish("start_rfid_upload_task")
  361. qzjFrameSn = 1
  362. local r,s,p
  363. while true do
  364. r, s, p = socketClient:recv(120000, "send_msg_to_server")
  365. if r then
  366. local res, parseRes = parseRespPacket(s)
  367. if not res then
  368. log.error("longLinkSocketDahua.qzjTask","parseRespPacket failed!!", s:toHex())
  369. else
  370. log.info("longLinkSocketDahua.qzjTask","receive msg from server:", s:toHex(),", commandId:",parseRes.commandId,", frameSn:",parseRes.frameSn)
  371. if parseRes.commandId == 0xa then --响应查询版本信息
  372. local res, resp_data = createPacket(parseRes.frameSn,0x8a,devSn..string.char(0x0))
  373. if res then
  374. log.info("longLinkSocketDahua.qzjTask","send device version info to server:", resp_data:toHex())
  375. if not socketClient:send(resp_data) then
  376. log.error("longLinkSocketDahua.qzjTask","send device version info to server failed!!", resp_data:toHex())
  377. break
  378. end
  379. else
  380. log.error("longLinkSocketDahua.qzjTask","createPacket device version info failed!!")
  381. end
  382. elseif parseRes.commandId == 0x2 then
  383. sys.publish("recv_resp_msg_"..parseRes.frameSn)
  384. end
  385. end
  386. elseif s == "send_msg_to_server" then
  387. log.info("longLinkSocketDahua.qzjTask","send msg to server(30):", p:sub(1, 30):toHex())
  388. if not socketClient:send(p) then
  389. log.error("longLinkSocketDahua.qzjTask","send msg to server failed!! data:", p:toHex())
  390. break
  391. end
  392. elseif s == "timeout" then
  393. qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1
  394. local res, qzjHeartbeatPacket = createPacket(qzjFrameSn,0x83,string.char(0x0))
  395. if res then
  396. log.info("longLinkSocketDahua.qzjTask","send heartbeat to server:", qzjHeartbeatPacket:toHex())
  397. if not socketClient:send(qzjHeartbeatPacket) then
  398. log.error("longLinkSocketDahua.qzjTask","send heartbeat to server failed!!", qzjHeartbeatPacket:toHex())
  399. break
  400. end
  401. else
  402. log.error("longLinkSocketDahua.qzjTask","createPacket qzjHeartbeatPacket failed!!")
  403. end
  404. else
  405. log.error("longLinkSocketDahua.qzjTask","socket connect error!!")
  406. break
  407. end
  408. end
  409. else
  410. log.error("longLinkSocketDahua.qzjTask","send regist resp timeout!")
  411. end
  412. end
  413. else
  414. log.error("longLinkSocketDahua.qzjTask","send regist timeout!")
  415. end
  416. end
  417. else
  418. log.error("longLinkSocketDahua.qzjTask","connect fail")
  419. --连接失败
  420. retryConnectCnt = retryConnectCnt+1 --失败次数加一
  421. end
  422. socketClient:close() --断开socket连接
  423. if retryConnectCnt>=5 then --失败次数大于五次了
  424. link.shut() --强制断开TCP/UDP连接
  425. retryConnectCnt=0 --失败次数清零
  426. longLinkSocketConnState = false
  427. else
  428. sys.wait(5000)
  429. end
  430. else
  431. retryConnectCnt = 0 --没连上网,失败次数清零
  432. longLinkSocketConnState = false
  433. --没连上网
  434. --等待网络环境准备就绪,超时时间是5分钟
  435. sys.waitUntil("IP_READY_IND",300000)
  436. --等完了还没连上?
  437. if not socket.isReady() then
  438. --进入飞行模式,20秒之后,退出飞行模式
  439. net.switchFly(true)
  440. sys.wait(20000)
  441. net.switchFly(false)
  442. end
  443. end
  444. end
  445. end)
  446. --等待时间同步成功消息通知
  447. sys.subscribe("TIMER_SYNC_SUCCESS", function ( ... )
  448. log.info("longLinkSocketDahua.subscribe","TIMER_SYNC_SUCCESS")
  449. timerSyncResult = true
  450. end)
  451. --连接调度中心(获取前置机连接信息)
  452. sys.taskInit(
  453. function()
  454. while not timerSyncResult do
  455. log.info("longLinkSocketDahua.ddzxSocketClient","wait TIMER_SYNC_SUCCESS message ...")
  456. sys.wait(1000)
  457. end
  458. while not devId do
  459. log.info("longLinkSocketDahua.ddzxSocketClient","devId empty! time:", os.time())
  460. devId = nvm.get("devId")
  461. sys.wait(1000)
  462. end
  463. while not ddzxIpDahua do
  464. log.info("longLinkSocketDahua.ddzxSocketClient","ddzxIpDahua empty! time:", os.time())
  465. ddzxIpDahua = nvm.get("ddzxIpDahua")
  466. sys.wait(1000)
  467. end
  468. while not ddzxTcpPortDahua do
  469. log.info("longLinkSocketDahua.ddzxSocketClient","ddzxTcpPortDahua empty! time:", os.time())
  470. ddzxTcpPortDahua = nvm.get("ddzxTcpPortDahua")
  471. sys.wait(1000)
  472. end
  473. if not ddzxWaitRecvMsgMaxTime then
  474. ddzxWaitRecvMsgMaxTime = 10
  475. end
  476. sys.wait(10000)
  477. local retryConnectCnt = 0 --失败次数统计
  478. while true do
  479. --是否获取到了分配的ip(是否连上网)
  480. if socket.isReady() then
  481. --新建一个socket对象,如果是udp只需要把tcp改成udp即可
  482. local ddzxSocketClient = socket.tcp()
  483. --尝试连接指定服务器
  484. if ddzxSocketClient:connect(ddzxIpDahua,ddzxTcpPortDahua) then
  485. local result,packet_data = createPacket(0,0x88)
  486. if not result then
  487. log.error("longLinkSocketDahua.ddzxSocketClient", "createDdzxAuthPacket failed!!")
  488. else
  489. --连接成功
  490. log.info("longLinkSocketDahua.ddzxSocketClient", "ddzxIpDahua", ddzxIpDahua, "ddzxTcpPortDahua", ddzxTcpPortDahua, "packet_data", packet_data:toHex())
  491. if ddzxSocketClient:send(packet_data, 10) then
  492. retryConnectCnt = 0
  493. log.info("longLinkSocketDahua.ddzxSocketClient", "wait recv server message ... time:", os.time())
  494. local res,ddzx_data = ddzxSocketClient:recv(ddzxWaitRecvMsgMaxTime*1000)
  495. if not res then
  496. log.error("longLinkSocketDahua.ddzxSocketClient", "ddzxSocketClient:recv(10000) wait timeout, time:", os.time())
  497. else
  498. --TODO:处理收到的数据data
  499. log.info("longLinkSocketDahua.ddzxSocketClient", "receive server message, time: ", os.time(), ", message:", ddzx_data:toHex())
  500. --解析数据并响应结果
  501. local res,parseData = parseRespPacket(ddzx_data)
  502. if not res then
  503. log.error("longLinkSocketDahua.ddzxSocketClient","parseRespPacket failed!!")
  504. else
  505. --回复响应包
  506. local result,packet_data = createPacket(0,0xD2,hex2bin("0000"))
  507. if not result then
  508. log.error("longLinkSocketDahua.ddzxSocketClient", "createPacket failed!!")
  509. else
  510. if ddzxSocketClient:send(packet_data, 10) then
  511. log.info("longLinkSocketDahua.ddzxSocketClient","publish ON_MESSAGE_DDZX_AUTH_SUCCESS,task finish,wait ON_MESSAGE_DO_DDZX_TASK ...")
  512. sys.publish("ON_MESSAGE_DDZX_AUTH_SUCCESS")
  513. ddzxSocketClient:close() --断开socket连接
  514. --进入阻塞状态,等待下一次连接调度中心的任务
  515. while true do
  516. local result,msg = sys.waitUntil("ON_MESSAGE_DO_DDZX_TASK", 3600*1000)
  517. if result then
  518. log.info("longLinkSocketDahua.ddzxSocketClient","receive ON_MESSAGE_DO_DDZX_TASK message, msg:", msg)
  519. break
  520. else
  521. log.info("longLinkSocketDahua.ddzxSocketClient","wait ON_MESSAGE_DO_DDZX_TASK timeout")
  522. end
  523. end
  524. else
  525. log.error("longLinkSocketDahua.ddzxSocketClient",">>>>>>> socket.send resp timeout!")
  526. end
  527. end
  528. end
  529. end
  530. else
  531. retryConnectCnt = retryConnectCnt+1
  532. log.error("longLinkSocketDahua.ddzxSocketClient",">>>>>>> socket.send failed")
  533. --sys.wait(5000)
  534. end
  535. end
  536. else
  537. log.error("longLinkSocketDahua.ddzxSocketClient","connect fail")
  538. --连接失败
  539. retryConnectCnt = retryConnectCnt+1 --失败次数加一
  540. end
  541. ddzxSocketClient:close() --断开socket连接
  542. if retryConnectCnt>=5 then --失败次数大于五次了
  543. link.shut() --强制断开TCP/UDP连接
  544. retryConnectCnt=0 --失败次数清零
  545. end
  546. sys.wait(5000)
  547. else
  548. retryConnectCnt = 0 --没连上网,失败次数清零
  549. --没连上网
  550. --等待网络环境准备就绪,超时时间是5分钟
  551. sys.waitUntil("IP_READY_IND",300000)
  552. --等完了还没连上?
  553. if not socket.isReady() then
  554. --进入飞行模式,20秒之后,退出飞行模式
  555. net.switchFly(true)
  556. sys.wait(20000)
  557. net.switchFly(false)
  558. end
  559. end
  560. end
  561. end)
  562. -- 监听并上报rfid数据任务
  563. sys.taskInit(function()
  564. --等心跳开启时,再开始上报rfid数据
  565. while true do
  566. log.info("longLinkSocketDahua.upload_dahua_rfid_info","wait start_rfid_upload_task message ...")
  567. local res,data = sys.waitUntil("start_rfid_upload_task", 3600*1000)
  568. if res then
  569. log.info("longLinkSocketDahua.upload_dahua_rfid_info","receive start_rfid_upload_task message")
  570. break
  571. else
  572. log.info("longLinkSocketDahua.upload_dahua_rfid_info","wait start_rfid_upload_task timeout")
  573. end
  574. end
  575. while not rfidReportIntervalDahua do
  576. log.info("longLinkSocketDahua.upload_dahua_rfid_info","rfidReportIntervalDahua empty! time:", os.time())
  577. rfidReportIntervalDahua = nvm.get("rfidReportIntervalDahua")
  578. sys.wait(1000)
  579. end
  580. --起始流水号
  581. local packetSn = 0
  582. --标签个数
  583. local rfidBufferCount = 0
  584. --数据包
  585. local content = ""
  586. while true do
  587. --阻塞监听监听rfid接收数据
  588. local cur_time = os.time()
  589. local result, rfid = sys.waitUntil("pub_packet_data_dahua_rfid_info",rfidReportIntervalDahua*1000)
  590. if result then
  591. --log.info("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> recv pub_packet_data_dahua_rfid_info, wait msg time(s):", os.time()-cur_time, json.encode(rfid))
  592. if type(rfid) == "table" then
  593. if not rfid.time then
  594. log.error("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid.time empty! ")
  595. elseif not rfid.id then
  596. log.error("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid.id empty! ")
  597. else
  598. rfidBufferCount = (rfidBufferCount + 1 < rfidBufferMaxCountDahua) and (rfidBufferCount + 1) or 1
  599. --分类信息内容
  600. local categoryContent = string.char(0xe)..hex2bin(string.format("%08x",rfid.time))..string.char(0x0)
  601. ..hex2bin(rfid.id)..string.char(rfid.type)..string.char(rfid.status)
  602. ..string.char(rfid.sn)..string.char(rfid.location)
  603. log.info("longLinkSocketDahua.upload_dahua_rfid_info","rfid.id:",rfid.id,",rfid.time:",rfid.time,",rfidBufferCount:",rfidBufferCount)
  604. --标签个数达到最大值时,组装数据包并上报
  605. if rfidBufferCount >= rfidBufferMaxCountDahua then
  606. packetSn = (packetSn + 1 < 0xffffff) and (packetSn + 1) or 0
  607. content = string.char(rfidBufferCount)..hex2bin(string.format("%06x",packetSn))..categoryContent
  608. qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1
  609. local res,packetData = createPacket(qzjFrameSn,0x84,content)
  610. if not res then
  611. log.error("longLinkSocketDahua.upload_dahua_rfid_info", "createPacket failed!!")
  612. else
  613. sys.publish("send_msg_to_server", packetData)
  614. local frameSn = qzjFrameSn
  615. --等待服务端响应消息
  616. if not sys.waitUntil("recv_resp_msg_"..frameSn, 5000) then
  617. log.error("longLinkSocketDahua.upload_dahua_rfid_info", "wait recv_resp_msg_"..frameSn.." timeout!!")
  618. else
  619. log.info("longLinkSocketDahua.upload_dahua_rfid_info", "recv recv_resp_msg_"..frameSn)
  620. end
  621. end
  622. --初始化
  623. content = ""
  624. rfidBufferCount = 0
  625. else
  626. content = content..categoryContent
  627. end
  628. end
  629. else
  630. log.info("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid error! key = ", key)
  631. end
  632. else
  633. --等待超时,就发送已接收的标签数据
  634. if rfidBufferCount > 0 and #content > 0 then
  635. packetSn = (packetSn + 1 < 0xffffff) and (packetSn + 1) or 0
  636. content = string.char(rfidBufferCount)..hex2bin(string.format("%06x",packetSn))..content
  637. qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1
  638. local res,packetData = createPacket(qzjFrameSn,0x84,content)
  639. if not res then
  640. log.error("longLinkSocketDahua.upload_dahua_rfid_info", "createPacket failed!!")
  641. else
  642. log.info("longLinkSocketDahua.upload_dahua_rfid_info","upload rfid data(30):",packetData:sub(1,30):toHex(),", qzjFrameSn:",qzjFrameSn)
  643. sys.publish("send_msg_to_server", packetData)
  644. local frameSn = qzjFrameSn
  645. --等待服务端响应消息
  646. if not sys.waitUntil("recv_resp_msg_"..frameSn, 5000) then
  647. log.error("longLinkSocketDahua.upload_dahua_rfid_info", "wait recv_resp_msg_"..frameSn.." timeout!!")
  648. else
  649. log.info("longLinkSocketDahua.upload_dahua_rfid_info", "recv recv_resp_msg_"..frameSn)
  650. end
  651. end
  652. --初始化
  653. content = ""
  654. rfidBufferCount = 0
  655. else
  656. log.info("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> wait upload_dahua_rfid_info timeout")
  657. end
  658. end
  659. end
  660. end)