module(...,package.seeall) require"socket" require"nvm" require"utils" --调度中心服务器信息 local ddzxIpDahua,ddzxTcpPortDahua = nvm.get("ddzxIpDahua"),nvm.get("ddzxTcpPortDahua") local rfidBufferMaxCountDahua = nvm.get("rfidBufferMaxCountDahua") or 50 local rfidReportIntervalDahua = nvm.get("rfidReportIntervalDahua") or 60 local ddzxWaitRecvMsgMaxTime = 10 local qzjWaitRecvMsgMaxTime = 10 --读写器ID local devId = nvm.get("devId") or "0000000000" --读写器版本号 local devSn = nvm.get("devSn") --ntp同步时间结果 local timerSyncResult = false --长连接socket连接状态 local longLinkSocketConnState = false --前置机服务器信息 local qzjIp,qzjTcpPort local qzjFrameSn = 0x0000 --协议参数 --帧头 local prefix = 0xAAAA --协议类型及协议版本 local protoVer = 0x10 --十六进制字符串反转 local function hexStrReverse(hexstr) local str = "" for i = 1, string.len(hexstr) - 1, 2 do local tmpStr = string.sub(hexstr, -(i+1), -i) str = str .. tmpStr end return str end --openMulByteReverse:开启多字节反转 local function hex2bin( hexstr, openMulByteReverse ) --检查字符串长度 if(hexstr:len()%2~=0) then return false,"hex2str invalid input lenth" end if openMulByteReverse then hexstr = hexStrReverse(hexstr) end local str = "" for i = 1, string.len(hexstr) - 1, 2 do local doublebytestr = string.sub(hexstr, i, i+1); local n = tonumber(doublebytestr, 16); if 0 == n then str = str .. '\00' else str = str .. string.format("%c", n) end end return str end local function hex2str(str) --判断输入类型 if (type(str)~="string") then return nil,"hex2str invalid input type" end --滤掉分隔符 str=str:gsub("[%s%p]",""):upper() --检查内容是否合法 if(str:find("[^0-9A-Fa-f]")~=nil) then return nil,"hex2str invalid input content" end --检查字符串长度 if(str:len()%2~=0) then return nil,"hex2str invalid input lenth" end --拼接字符串 local index=1 local ret="" for index=1,str:len(),2 do ret=ret..string.char(tonumber(str:sub(index,index+1),16)) end --log.info("socketHeartbeatTask.hex2str", ret) return ret end local function getFormatTimeBin(time) local tClock = time and os.date("*t",time) or os.date("*t") local formatTimeBin = string.char(tonumber((""..tClock.year):sub(3,4))) ..string.char(tClock.month) ..string.char(tClock.day) ..string.char(tClock.hour) ..string.char(tClock.min) ..string.char(tClock.sec) return formatTimeBin end local crc16Table = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 } --计算尾部校验码 local function getCrc16(packet) if not packet then log.error("longLinkSocketDahua.getCrc16", "packet empty!!") return false end local CRC = 0XFFFF local tableNo = 1 for i=1,#packet do tableNo = bit.band(bit.bxor( bit.rshift(CRC,8), string.byte(packet,i)), 0xFF) --log.info("longLinkSocketDahua.getCrc16",bit.lshift(CRC,8)) CRC = bit.band(bit.bxor(bit.band(bit.lshift(CRC,8), 0xFFFF), crc16Table[tableNo+1]), 0xFFFF) --log.info("longLinkSocketDahua.getCrc16",tableNo,crc16Table[tableNo+1],CRC) end local crc16Bin = hex2bin(string.format("%04x",CRC)) return true, crc16Bin end --生成报文 local function createPacket(frameSn,commandId,content) if not prefix then log.error("longLinkSocketDahua.createPacket", "prefix empty!!") return false end if not protoVer then log.error("longLinkSocketDahua.createPacket", "protoVer empty!!") return false end if not devId then log.error("longLinkSocketDahua.createPacket", "devId empty!!") return false end if not frameSn then log.error("longLinkSocketDahua.createPacket", "frameSn empty!!") return false end if not commandId then log.error("longLinkSocketDahua.createPacket", "commandId empty!!") return false end if not content then content = "" end local packetBin = "" local length = #content + 10 local prefixHexStr = string.format("%04x",prefix) local lengthHexStr = string.format("%04x",length) packetBin = hex2bin(prefixHexStr)..hex2bin(lengthHexStr)..string.char(protoVer) ..hex2bin(devId)..string.char(frameSn) ..string.char(commandId)..content local res, crc16Bin = getCrc16(packetBin:sub(3,-1)) log.info("longLinkSocketDahua.createPacket", "packetBin hex:",packetBin:toHex(), "crc16Bin hex:",crc16Bin:toHex()) if not res then log.error("longLinkSocketDahua.createPacket", "getCrc16 failed!!") return false end packetBin = packetBin..crc16Bin --log.info("longLinkSocketDahua.createPacket", "packetBin hex:",packetBin:toHex()) return true, packetBin end --解析响应报文 local function parseRespPacket(packet) if not packet then log.error("longLinkSocketDahua.parseRespPacket", "packet empty!!") return false end if #packet < 14 then log.error("longLinkSocketDahua.parseRespPacket", "packet length < 14!! packet:", packet:toHex()) return false end local prefixP = packet:sub(1,2):toHex() if tonumber(prefixP,16) ~= prefix then log.error("longLinkSocketDahua.parseRespPacket", "prefix invalid!! prefixP:", prefixP) return false end local length = tonumber(packet:sub(3,4):toHex(), 16) if #packet < length + 4 then log.error("longLinkSocketDahua.parseRespPacket", "packet length error!!", packet:toHex()) return false end --crc校验 local crc_packet = packet:sub(3,length + 2) local res, crc16Bin = getCrc16(crc_packet) if not res then log.error("longLinkSocketDahua.parseRespPacket", "getCrc16 failed!! crc_packet:",crc_packet:toHex()) return false end local crc16P = packet:sub(length + 3,length + 4):toHex() local crc16 = crc16Bin:toHex() if crc16P ~= crc16 then log.error("longLinkSocketDahua.parseRespPacket", "crc verify failed!! crc16P:",crc16P,", crc16:",crc16) return false end -- AAAA 0012 10 FFC10001EC 00 52 0100202BDD0A2179 EBD7 local contentLenP = length - 10 local contentP = "" if contentLenP > 0 then contentP = packet:sub(13,contentLenP + 12) end if #contentP ~= contentLenP then log.error("longLinkSocketDahua.parseRespPacket", "contentLenP error!! contentLenP:",contentLenP,", contenLen:", #contentP) return false end local parseRes = {} local devIdP = packet:sub(6,10):toHex() local commandIdP = string.byte(packet,12) parseRes["devId"] = devIdP parseRes["commandId"] = commandIdP parseRes["frameSn"] = string.byte(packet,11) parseRes["length"] = length log.info("longLinkSocketDahua.parseRespPacket","commandIdP:",commandIdP,"contentLenP:",contentLenP) if commandIdP == 0x52 then --配置主控参数 if contentLenP == 0 then log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!") return false end local contentTypeP = string.byte(contentP,1) parseRes["contentType"] = contentTypeP --bit7: 1--读, 0--写 local cmdTypeP = bit.rshift(contentTypeP,7) parseRes["cmdType"] = cmdTypeP --bit6~0: 1--通讯服务器参数区, 0--统一调度服务器参数区 local areaTypeP = bit.band(contentTypeP,0x7F) parseRes["areaType"] = areaTypeP --读取主控配置参数 if cmdTypeP == 1 then return true, parseRes end local addrTypeP = string.byte(contentP,2) local qzjIpP = "" local qzjPortP = tonumber(contentP:sub(3,4):toHex(),16) if addrTypeP == 0x1 then qzjIpP = contentP:sub(5,-1) elseif addrTypeP == 0x0 then qzjIpP = string.byte(contentP,5).."."..string.byte(contentP,6) .."."..string.byte(contentP,7).."."..string.byte(contentP,8) else log.error("longLinkSocketDahua.parseRespPacket", "addrTypeP invalid!! addrTypeP:", addrTypeP) return false end parseRes["qzjIp"] = qzjIpP parseRes["qzjPort"] = qzjPortP parseRes["addrType"] = addrTypeP qzjIp = qzjIpP qzjTcpPort = qzjPortP log.info("longLinkSocketDahua.parseRespPacket","parseRes qzjIpP:", qzjIpP, "qzjPortP:", qzjPortP) return true, parseRes elseif commandIdP == 0x01 then --校时包 if contentLenP ~= 0x05 then log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!") return false end local cacheCtlP = string.byte(contentP,1) local serverTimeP = tonumber(contentP:sub(2,5):toHex(),16) parseRes["serverTime"] = serverTimeP return true, parseRes elseif commandIdP == 0x02 then --服务器确认包 if contentLenP ~= 0x01 then log.error("longLinkSocketDahua.parseRespPacket", "contentLen invalid!!") return false end local cacheCtlP = string.byte(contentP,1) parseRes["cacheCtl"] = cacheCtlP return true, parseRes elseif commandIdP == 0x0A then --获取设备版本包 return true, parseRes elseif commandIdP == 0x06 then --设备重启包 return true, parseRes elseif commandIdP == 0x70 then --设备恢复出厂设置包 return true, parseRes else log.error("longLinkSocketDahua.parseRespPacket","commandIdP invalid!!") return false end end --连接前置机主任务 sys.taskInit( function() while true do log.info("longLinkSocketDahua.qzjTask","wait ON_MESSAGE_DDZX_AUTH_SUCCESS message ...") local res,data = sys.waitUntil("ON_MESSAGE_DDZX_AUTH_SUCCESS", 3600*1000) if res then log.info("longLinkSocketDahua.qzjTask","receive ON_MESSAGE_DDZX_AUTH_SUCCESS message") break else log.info("longLinkSocketDahua.qzjTask","wait ON_MESSAGE_DDZX_AUTH_SUCCESS timeout") end end local retryConnectCnt = 0 --失败次数统计 while true do --是否获取到了分配的ip(是否连上网) if socket.isReady() then --新建一个socket对象,如果是udp只需要把tcp改成udp即可 local socketClient = socket.tcp() log.info("longLinkSocketDahua.qzjTask","connect to qzjIp:", qzjIp, "qzjTcpPort:", qzjTcpPort) --尝试连接指定服务器 if socketClient:connect(qzjIp,qzjTcpPort) then --连接成功 log.info("longLinkSocketDahua.qzjTask","connect success") retryConnectCnt = 0 --失败次数清零 longLinkSocketConnState = true --发送注册包 local result,packet_data = createPacket(0,0x80,string.char(0x0)..devSn..string.char(0x0)) if not result then log.error("longLinkSocketDahua.qzjTask", "createPacket failed!!") else if socketClient:send(packet_data, 10) then log.info("longLinkSocketDahua.qzjTask","send regist success:", packet_data:toHex()) --等待服务端校时包(出厂前必须收到校时包才开启射频功能,出厂后可能收不到校时包) local res,msg_data = socketClient:recv(qzjWaitRecvMsgMaxTime*1000) if not res then log.warn("longLinkSocketDahua.qzjTask","wait receive serverTime timeout!") else log.info("longLinkSocketDahua.qzjTask","receive serverTime msg:", msg_data:toHex()) local res, parseRes = parseRespPacket(msg_data) if not res then log.error("longLinkSocketDahua.qzjTask","parseRespPacket failed!!", msg_data:toHex()) else if parseRes.serverTime > 0 then --需要ntp切换时区 local diffTime = parseRes.serverTime - os.time() log.info("longLinkSocketDahua.qzjTask","serverTime:", parseRes.serverTime,"diffTime:", diffTime) if diffTime >= 1 or diffTime <= -1 then sys.publish("RESET_CLOCK_TIME", diffTime) end end end end --发送注册响应包 local result,packet_data = createPacket(0,0x82) if not result then log.error("longLinkSocketDahua.qzjTask", "createPacket failed!!") else if socketClient:send(packet_data, 10) then log.info("longLinkSocketDahua.qzjTask","send regist resp success:", packet_data:toHex()) --通知发送标签数据任务开始工作 sys.publish("start_rfid_upload_task") qzjFrameSn = 1 local r,s,p while true do r, s, p = socketClient:recv(120000, "send_msg_to_server") if r then local res, parseRes = parseRespPacket(s) if not res then log.error("longLinkSocketDahua.qzjTask","parseRespPacket failed!!", s:toHex()) else log.info("longLinkSocketDahua.qzjTask","receive msg from server:", s:toHex(),", commandId:",parseRes.commandId,", frameSn:",parseRes.frameSn) if parseRes.commandId == 0xa then --响应查询版本信息 local res, resp_data = createPacket(parseRes.frameSn,0x8a,devSn..string.char(0x0)) if res then log.info("longLinkSocketDahua.qzjTask","send device version info to server:", resp_data:toHex()) if not socketClient:send(resp_data) then log.error("longLinkSocketDahua.qzjTask","send device version info to server failed!!", resp_data:toHex()) break end else log.error("longLinkSocketDahua.qzjTask","createPacket device version info failed!!") end elseif parseRes.commandId == 0x2 then sys.publish("recv_resp_msg_"..parseRes.frameSn) end end elseif s == "send_msg_to_server" then log.info("longLinkSocketDahua.qzjTask","send msg to server(30):", p:sub(1, 30):toHex()) if not socketClient:send(p) then log.error("longLinkSocketDahua.qzjTask","send msg to server failed!! data:", p:toHex()) break end elseif s == "timeout" then qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1 local res, qzjHeartbeatPacket = createPacket(qzjFrameSn,0x83,string.char(0x0)) if res then log.info("longLinkSocketDahua.qzjTask","send heartbeat to server:", qzjHeartbeatPacket:toHex()) if not socketClient:send(qzjHeartbeatPacket) then log.error("longLinkSocketDahua.qzjTask","send heartbeat to server failed!!", qzjHeartbeatPacket:toHex()) break end else log.error("longLinkSocketDahua.qzjTask","createPacket qzjHeartbeatPacket failed!!") end else log.error("longLinkSocketDahua.qzjTask","socket connect error!!") break end end else log.error("longLinkSocketDahua.qzjTask","send regist resp timeout!") end end else log.error("longLinkSocketDahua.qzjTask","send regist timeout!") end end else log.error("longLinkSocketDahua.qzjTask","connect fail") --连接失败 retryConnectCnt = retryConnectCnt+1 --失败次数加一 end socketClient:close() --断开socket连接 if retryConnectCnt>=5 then --失败次数大于五次了 link.shut() --强制断开TCP/UDP连接 retryConnectCnt=0 --失败次数清零 longLinkSocketConnState = false else sys.wait(5000) end else retryConnectCnt = 0 --没连上网,失败次数清零 longLinkSocketConnState = false --没连上网 --等待网络环境准备就绪,超时时间是5分钟 sys.waitUntil("IP_READY_IND",300000) --等完了还没连上? if not socket.isReady() then --进入飞行模式,20秒之后,退出飞行模式 net.switchFly(true) sys.wait(20000) net.switchFly(false) end end end end) --等待时间同步成功消息通知 sys.subscribe("TIMER_SYNC_SUCCESS", function ( ... ) log.info("longLinkSocketDahua.subscribe","TIMER_SYNC_SUCCESS") timerSyncResult = true end) --连接调度中心(获取前置机连接信息) sys.taskInit( function() while not timerSyncResult do log.info("longLinkSocketDahua.ddzxSocketClient","wait TIMER_SYNC_SUCCESS message ...") sys.wait(1000) end while not devId do log.info("longLinkSocketDahua.ddzxSocketClient","devId empty! time:", os.time()) devId = nvm.get("devId") sys.wait(1000) end while not ddzxIpDahua do log.info("longLinkSocketDahua.ddzxSocketClient","ddzxIpDahua empty! time:", os.time()) ddzxIpDahua = nvm.get("ddzxIpDahua") sys.wait(1000) end while not ddzxTcpPortDahua do log.info("longLinkSocketDahua.ddzxSocketClient","ddzxTcpPortDahua empty! time:", os.time()) ddzxTcpPortDahua = nvm.get("ddzxTcpPortDahua") sys.wait(1000) end if not ddzxWaitRecvMsgMaxTime then ddzxWaitRecvMsgMaxTime = 10 end sys.wait(10000) local retryConnectCnt = 0 --失败次数统计 while true do --是否获取到了分配的ip(是否连上网) if socket.isReady() then --新建一个socket对象,如果是udp只需要把tcp改成udp即可 local ddzxSocketClient = socket.tcp() --尝试连接指定服务器 if ddzxSocketClient:connect(ddzxIpDahua,ddzxTcpPortDahua) then local result,packet_data = createPacket(0,0x88) if not result then log.error("longLinkSocketDahua.ddzxSocketClient", "createDdzxAuthPacket failed!!") else --连接成功 log.info("longLinkSocketDahua.ddzxSocketClient", "ddzxIpDahua", ddzxIpDahua, "ddzxTcpPortDahua", ddzxTcpPortDahua, "packet_data", packet_data:toHex()) if ddzxSocketClient:send(packet_data, 10) then retryConnectCnt = 0 log.info("longLinkSocketDahua.ddzxSocketClient", "wait recv server message ... time:", os.time()) local res,ddzx_data = ddzxSocketClient:recv(ddzxWaitRecvMsgMaxTime*1000) if not res then log.error("longLinkSocketDahua.ddzxSocketClient", "ddzxSocketClient:recv(10000) wait timeout, time:", os.time()) else --TODO:处理收到的数据data log.info("longLinkSocketDahua.ddzxSocketClient", "receive server message, time: ", os.time(), ", message:", ddzx_data:toHex()) --解析数据并响应结果 local res,parseData = parseRespPacket(ddzx_data) if not res then log.error("longLinkSocketDahua.ddzxSocketClient","parseRespPacket failed!!") else --回复响应包 local result,packet_data = createPacket(0,0xD2,hex2bin("0000")) if not result then log.error("longLinkSocketDahua.ddzxSocketClient", "createPacket failed!!") else if ddzxSocketClient:send(packet_data, 10) then log.info("longLinkSocketDahua.ddzxSocketClient","publish ON_MESSAGE_DDZX_AUTH_SUCCESS,task finish,wait ON_MESSAGE_DO_DDZX_TASK ...") sys.publish("ON_MESSAGE_DDZX_AUTH_SUCCESS") ddzxSocketClient:close() --断开socket连接 --进入阻塞状态,等待下一次连接调度中心的任务 while true do local result,msg = sys.waitUntil("ON_MESSAGE_DO_DDZX_TASK", 3600*1000) if result then log.info("longLinkSocketDahua.ddzxSocketClient","receive ON_MESSAGE_DO_DDZX_TASK message, msg:", msg) break else log.info("longLinkSocketDahua.ddzxSocketClient","wait ON_MESSAGE_DO_DDZX_TASK timeout") end end else log.error("longLinkSocketDahua.ddzxSocketClient",">>>>>>> socket.send resp timeout!") end end end end else retryConnectCnt = retryConnectCnt+1 log.error("longLinkSocketDahua.ddzxSocketClient",">>>>>>> socket.send failed") --sys.wait(5000) end end else log.error("longLinkSocketDahua.ddzxSocketClient","connect fail") --连接失败 retryConnectCnt = retryConnectCnt+1 --失败次数加一 end ddzxSocketClient:close() --断开socket连接 if retryConnectCnt>=5 then --失败次数大于五次了 link.shut() --强制断开TCP/UDP连接 retryConnectCnt=0 --失败次数清零 end sys.wait(5000) else retryConnectCnt = 0 --没连上网,失败次数清零 --没连上网 --等待网络环境准备就绪,超时时间是5分钟 sys.waitUntil("IP_READY_IND",300000) --等完了还没连上? if not socket.isReady() then --进入飞行模式,20秒之后,退出飞行模式 net.switchFly(true) sys.wait(20000) net.switchFly(false) end end end end) -- 监听并上报rfid数据任务 sys.taskInit(function() --等心跳开启时,再开始上报rfid数据 while true do log.info("longLinkSocketDahua.upload_dahua_rfid_info","wait start_rfid_upload_task message ...") local res,data = sys.waitUntil("start_rfid_upload_task", 3600*1000) if res then log.info("longLinkSocketDahua.upload_dahua_rfid_info","receive start_rfid_upload_task message") break else log.info("longLinkSocketDahua.upload_dahua_rfid_info","wait start_rfid_upload_task timeout") end end while not rfidReportIntervalDahua do log.info("longLinkSocketDahua.upload_dahua_rfid_info","rfidReportIntervalDahua empty! time:", os.time()) rfidReportIntervalDahua = nvm.get("rfidReportIntervalDahua") sys.wait(1000) end --起始流水号 local packetSn = 0 --标签个数 local rfidBufferCount = 0 --数据包 local content = "" while true do --阻塞监听监听rfid接收数据 local cur_time = os.time() local result, rfid = sys.waitUntil("pub_packet_data_dahua_rfid_info",rfidReportIntervalDahua*1000) if result then --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)) if type(rfid) == "table" then if not rfid.time then log.error("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid.time empty! ") elseif not rfid.id then log.error("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid.id empty! ") else rfidBufferCount = (rfidBufferCount + 1 < rfidBufferMaxCountDahua) and (rfidBufferCount + 1) or 1 --分类信息内容 local categoryContent = string.char(0xe)..hex2bin(string.format("%08x",rfid.time))..string.char(0x0) ..hex2bin(rfid.id)..string.char(rfid.type)..string.char(rfid.status) ..string.char(rfid.sn)..string.char(rfid.location) log.info("longLinkSocketDahua.upload_dahua_rfid_info","rfid.id:",rfid.id,",rfid.time:",rfid.time,",rfidBufferCount:",rfidBufferCount) --标签个数达到最大值时,组装数据包并上报 if rfidBufferCount >= rfidBufferMaxCountDahua then packetSn = (packetSn + 1 < 0xffffff) and (packetSn + 1) or 0 content = string.char(rfidBufferCount)..hex2bin(string.format("%06x",packetSn))..categoryContent qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1 local res,packetData = createPacket(qzjFrameSn,0x84,content) if not res then log.error("longLinkSocketDahua.upload_dahua_rfid_info", "createPacket failed!!") else sys.publish("send_msg_to_server", packetData) local frameSn = qzjFrameSn --等待服务端响应消息 if not sys.waitUntil("recv_resp_msg_"..frameSn, 5000) then log.error("longLinkSocketDahua.upload_dahua_rfid_info", "wait recv_resp_msg_"..frameSn.." timeout!!") else log.info("longLinkSocketDahua.upload_dahua_rfid_info", "recv recv_resp_msg_"..frameSn) end end --初始化 content = "" rfidBufferCount = 0 else content = content..categoryContent end end else log.info("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> rfid error! key = ", key) end else --等待超时,就发送已接收的标签数据 if rfidBufferCount > 0 and #content > 0 then packetSn = (packetSn + 1 < 0xffffff) and (packetSn + 1) or 0 content = string.char(rfidBufferCount)..hex2bin(string.format("%06x",packetSn))..content qzjFrameSn = (qzjFrameSn + 1 < 255) and (qzjFrameSn + 1) or 1 local res,packetData = createPacket(qzjFrameSn,0x84,content) if not res then log.error("longLinkSocketDahua.upload_dahua_rfid_info", "createPacket failed!!") else log.info("longLinkSocketDahua.upload_dahua_rfid_info","upload rfid data(30):",packetData:sub(1,30):toHex(),", qzjFrameSn:",qzjFrameSn) sys.publish("send_msg_to_server", packetData) local frameSn = qzjFrameSn --等待服务端响应消息 if not sys.waitUntil("recv_resp_msg_"..frameSn, 5000) then log.error("longLinkSocketDahua.upload_dahua_rfid_info", "wait recv_resp_msg_"..frameSn.." timeout!!") else log.info("longLinkSocketDahua.upload_dahua_rfid_info", "recv recv_resp_msg_"..frameSn) end end --初始化 content = "" rfidBufferCount = 0 else log.info("longLinkSocketDahua.upload_dahua_rfid_info",">>>>>>>>> wait upload_dahua_rfid_info timeout") end end end end)