air_log_serer.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. air_jt808 = require("air_gt808")
  2. local moduleName = "建栋服务器"
  3. local taskName = "auxTask"
  4. local libfota = require "libfota"
  5. local auxServer = {}
  6. local simID = nil
  7. local connectOk = false
  8. local isWaitMsg, isResponseOK, isResponseNeedCheck, connectOKFlag, waitAck
  9. local lastTxMsgID, lastTxMsgSn, lastRxMsgID, lastRxData, localMsgID
  10. local responseQueue, dataQueue
  11. local logSwitch = true
  12. local libnet = require("libnet")
  13. local function logF(...)
  14. if logSwitch then
  15. log.info(moduleName, ...)
  16. end
  17. end
  18. -- 处理未识别的网络消息
  19. local function netCB(msg)
  20. logF("unprocessed message", msg[1], msg[2], msg[3], msg[4])
  21. end
  22. -- 客户端定位数据发送
  23. function auxServer.dataSend(data)
  24. local tTime = os.date("!*t", os.time())
  25. if tTime.year < 2024 then
  26. logF("时间未校准,放弃本次数据上传")
  27. return false, 0
  28. end
  29. if #dataQueue > 200 then
  30. local item = table.remove(dataQueue, 1)
  31. item:free()
  32. end
  33. if not data then
  34. local item = zbuff.create(200)
  35. item:copy(nil, common.monitorRecord())
  36. table.insert(dataQueue, item)
  37. else
  38. table.insert(dataQueue, data)
  39. end
  40. if isWaitMsg and connectOKFlag then
  41. sys_send(taskName, socket.EVENT, 0)
  42. end
  43. return true, 0
  44. end
  45. -- 客户端连接状态
  46. function auxServer.isConnected()
  47. return connectOKFlag
  48. end
  49. -- 客户端注册应答解析
  50. local function monitorRxReg(inData)
  51. logF("客户端注册应答解析", inData:toHex())
  52. local lastMsgSn, procResult, authCode = air_jt808.analyzeRegResopnse(inData)
  53. logF("rx reg response", lastTxMsgSn, lastMsgSn, procResult, authCode:toHex())
  54. if (lastMsgSn == lastTxMsgSn) and (procResult == 0) and (authCode ~= nil) then
  55. log.info("设置鉴权码", fskv.set("authCode2", authCode))
  56. -- logF("当前鉴权码",fskv.get("authCode2"),fskv.get("authCode2"):toHex())
  57. isResponseOK = true
  58. else
  59. isResponseOK = false
  60. end
  61. logF("isresponseok", isResponseOK)
  62. end
  63. -- 客户端通用应答解析
  64. local function monitorRxResponse(inData)
  65. local lastMsgSn, lastMsgID, procResult = air_jt808.analyzeMonitorResopnse(inData)
  66. if isResponseNeedCheck then
  67. logF("rx normal response", string.format("%04x", lastTxMsgID), string.format("%04x", lastMsgID), lastTxMsgSn,
  68. lastMsgSn, procResult)
  69. if (lastTxMsgID == lastMsgID) and (lastMsgSn == lastTxMsgSn) and ((procResult == 0) or (procResult == 4)) then
  70. logF("rx response ok")
  71. isResponseNeedCheck = false
  72. isResponseOK = true
  73. else
  74. isResponseOK = false
  75. end
  76. end
  77. end
  78. local function monitorTrackIngResponse(inData, msgSn)
  79. logF("track data", inData:toHex(), msgSn)
  80. if #inData ~= 6 then
  81. return
  82. end
  83. -- local interval, timeout = tonumber(inData:sub(1, 2), 2), tonumber(inData:sub(3), 2)
  84. local _, interval, timeout = pack.unpack(inData, ">hI")
  85. logF("interval", interval, timeout)
  86. if not interval or not timeout or interval <= 0 and timeout < 0 then
  87. return
  88. end
  89. local pTxBuf = ""
  90. localMsgID = (localMsgID + 1) % 65536
  91. pTxBuf = air_jt808.air_jt808Head(0x0001, localMsgID, simID, pTxBuf)
  92. table.insert(responseQueue, pTxBuf)
  93. common.setfastUpload(interval, timeout)
  94. end
  95. local function monitorDlTrans(inData, msgSn)
  96. local result, ret, data = true, nil, nil
  97. if #inData > 0 then
  98. -- 解析indata从第2个位置开始的json数据
  99. local flag = string.sub(inData, 1, 1)
  100. if string.byte(flag) == 0xF1 then
  101. local data, ret = json.decode(inData:sub(2))
  102. log.info("data", result)
  103. if ret == 1 then
  104. fskv.set("phoneList", data)
  105. for k, v in pairs(data) do
  106. if v and v.name and v.num then
  107. logF("联系人列表", v, string.fromHex(v.name), v.num)
  108. end
  109. end
  110. else
  111. result = false
  112. end
  113. else
  114. result = false
  115. end
  116. else
  117. result = false
  118. end
  119. localMsgID = (localMsgID + 1) % 65536
  120. local pTxBuf = air_jt808.makeTransResponseBody(result and "OK#" or "ERROR#")
  121. pTxBuf = air_jt808.air_jt808Head(0x0900, localMsgID, simID, pTxBuf)
  122. table.insert(responseQueue, pTxBuf)
  123. end
  124. -- 注册命令解析函数
  125. local monitorRxFun = {
  126. [0x8001] = monitorRxResponse,
  127. [0x8100] = monitorRxReg,
  128. [0x8202] = monitorTrackIngResponse,
  129. [0x8900] = monitorDlTrans
  130. }
  131. -- 命令消息分发
  132. local function msgDispatch(param)
  133. logF("dispatch", param)
  134. for index, msg in pairs(param) do
  135. logF("msg", msg.msgID, msg.body:toHex())
  136. if monitorRxFun[msg.msgID] then
  137. monitorRxFun[msg.msgID](msg.body, msg.msgSn)
  138. end
  139. end
  140. end
  141. -- 重启设备
  142. local function reBootDevice(ret)
  143. if ret == 0 then
  144. pm.reboot()
  145. end
  146. end
  147. local function auxServerTask(d1Name)
  148. log.info("auxServer in")
  149. local result, data, queue, rxBuff, param, param2, ip, port, succ, netc, authCode, pTxBuf
  150. local firstWaitNetReady = true
  151. local nowStatus = "WAIT_NET_READY"
  152. local retryTimes = 0
  153. local recvTimeout = 0
  154. local ipv6Valid = false
  155. localMsgID = 0
  156. dataQueue = {}
  157. rxBuff = zbuff.create(1024)
  158. netc = socket.create(nil, d1Name)
  159. socket.debug(netc, true)
  160. while true do
  161. ::CONTINUE::
  162. if nowStatus == "WAIT_NET_READY" then
  163. responseQueue = {}
  164. lastRxData = ""
  165. sysplus.cleanMsg(d1Name)
  166. connectOKFlag = false
  167. if not firstWaitNetReady then
  168. retryTimes = retryTimes + 1
  169. libnet.close(d1Name, 5000, netc)
  170. socket.release(netc)
  171. if retryTimes > 3 then -- 重试3次,进入FLY_MODE
  172. nowStatus = "FLY_MODE"
  173. goto CONTINUE
  174. end
  175. math.randomseed(os.time()) -- 设置随机数种子
  176. sys.wait(math.random(10, 20) * 1000)
  177. end
  178. while not netWork.isReady() do -- 等待网络就绪
  179. sys.wait(1000)
  180. end
  181. if firstWaitNetReady then -- 第一次或者进出飞行模式后等待网络就绪, 触发下远程升级
  182. socket.sntp()
  183. firstWaitNetReady = false
  184. libfota.request(reBootDevice)
  185. sys.timerLoopStart(libfota.request, 3600000, reBootDevice)
  186. end
  187. nowStatus = "REQ_SERVER"
  188. goto CONTINUE
  189. end
  190. if nowStatus == "REQ_SERVER" then
  191. sys.wait(3000)
  192. local _0, _1, _2, ipv6 = socket.localIP()
  193. if ipv6 and #ipv6 > 0 and ipv6:sub(1, 2) ~= "FE" then
  194. ipv6Valid = true
  195. else
  196. ipv6Valid = false
  197. end
  198. netc = socket.create(nil, d1Name)
  199. if _G.IPV6_UDP_VER and ipv6Valid then
  200. socket.config(netc, 12398, true)
  201. else
  202. socket.config(netc, nil, false)
  203. end
  204. local code, headers, body = http.request("GET", string.format(
  205. "https://gps.openluat.com/iot/getip?clientid=%s&p=%s", mobile.imei():sub(3, 14), _G.PRODUCT_VER)).wait()
  206. log.info("连接ip 请求结果", code, headers, body)
  207. if (code == 200 or code == 206) and body then
  208. local data, result = json.decode(body)
  209. if result == 1 and type(data) == "table" and data.msg == "ok" then
  210. if _G.IPV6_UDP_VER then
  211. if ipv6Valid and data.ipv6 and data.udp then
  212. log.info(
  213. "获取到IPV6地址,且服务器返回了IPV6地址,使用IPV6 UDP方式连接服务器")
  214. ip = data.ipv6
  215. port = data.udp
  216. else
  217. if not ipv6Valid then
  218. log.info("设备没有分配到IPV6地址,使用IPV4 TCP方式连接服务器")
  219. end
  220. if not data.ipv6 or not data.udp then
  221. log.info(
  222. "服务器没有返回IPV6地址或UDP端口,使用IPV4 TCP方式连接服务器")
  223. end
  224. if data.ipv4 and data.tcp then
  225. log.info("使用IPV4 TCP方式连接服务器")
  226. ip = data.ipv4
  227. port = data.tcp
  228. else
  229. nowStatus = "WAIT_NET_READY"
  230. goto CONTINUE
  231. end
  232. end
  233. else
  234. if data.ipv4 and data.tcp then
  235. log.info("使用IPV4 TCP方式连接服务器")
  236. ip = data.ipv4
  237. port = data.tcp
  238. else
  239. log.info("服务器没有返回IPV4地址,使用IPV4 TCP方式连接服务器")
  240. nowStatus = "WAIT_NET_READY"
  241. goto CONTINUE
  242. end
  243. end
  244. else
  245. nowStatus = "WAIT_NET_READY"
  246. goto CONTINUE
  247. end
  248. else
  249. nowStatus = "WAIT_NET_READY"
  250. goto CONTINUE
  251. end
  252. simID = mobile.imei():sub(3, 14)
  253. simID = api.StrToBin(simID)
  254. result = libnet.connect(d1Name, 30000, netc, ip, port)
  255. if not result then
  256. nowStatus = "WAIT_NET_READY"
  257. else
  258. nowStatus = "REG_DEVICE"
  259. end
  260. goto CONTINUE
  261. end
  262. if nowStatus == "REG_DEVICE" then
  263. authCode = fskv.get("authCode2")
  264. if authCode and #authCode > 0 then
  265. nowStatus = "AUTH_DEVICE"
  266. goto CONTINUE
  267. end
  268. localMsgID = (localMsgID + 1) % 65536
  269. lastTxMsgSn = localMsgID
  270. -- pTxBuf = air_jt808.makeRegMsg(0, 0, "Airm2m", string.fromHex(string.rep("0", 36) .. _G.PRODUCT_VER), api.StrToBin(mobile.imei():sub(1, 14)), 0, string.char(0x00))
  271. pTxBuf = air_jt808.makeRegMsg(0, 0, "Airm2m", "Air8000", api.StrToBin(mobile.imei():sub(1, 14)), 0,
  272. string.char(0x00))
  273. pTxBuf = air_jt808.air_jt808Head(0x0100, localMsgID, simID, pTxBuf)
  274. result, param = libnet.tx(d1Name, 15000, netc, pTxBuf)
  275. if not result then
  276. logF("注册发送异常")
  277. nowStatus = "WAIT_NET_READY"
  278. goto CONTINUE
  279. end
  280. logF("注册发送成功", pTxBuf:toHex())
  281. result, param = libnet.wait(d1Name, 30000, netc)
  282. if not result then
  283. logF("注册数据等待异常", result, param)
  284. nowStatus = "WAIT_NET_READY"
  285. goto CONTINUE
  286. end
  287. if not ipv6Valid and IPV6_UDP_VER then
  288. if not param then
  289. logF("注册数据等待超时", result, param)
  290. nowStatus = "WAIT_NET_READY"
  291. goto CONTINUE
  292. end
  293. end
  294. succ, param = socket.rx(netc, rxBuff)
  295. if not succ then
  296. logF("服务器断开了")
  297. nowStatus = "WAIT_NET_READY"
  298. goto CONTINUE
  299. end
  300. -- 如果服务器有下发数据, used()就必然大于0, 进行处理
  301. if rxBuff:used() > 0 then
  302. data = rxBuff:query()
  303. rxBuff:del()
  304. isResponseOK = false
  305. lastRxData, queue = air_jt808.rxAnalyze(lastRxData .. data)
  306. msgDispatch(queue)
  307. if not isResponseOK then
  308. nowStatus = "WAIT_NET_READY"
  309. goto CONTINUE
  310. end
  311. nowStatus = "AUTH_DEVICE"
  312. logF("注册成功")
  313. end
  314. goto CONTINUE
  315. end
  316. if nowStatus == "AUTH_DEVICE" then
  317. if mreport then
  318. mreport.send()
  319. end
  320. localMsgID = (localMsgID + 1) % 65536
  321. lastTxMsgSn = localMsgID
  322. pTxBuf = air_jt808.authPackage(lastTxMsgSn, simID, fskv.get("authCode2"))
  323. lastTxMsgID = 0x0102
  324. result, param = libnet.tx(d1Name, 15000, netc, pTxBuf)
  325. if not result then
  326. logF("鉴权发送失败")
  327. nowStatus = "WAIT_NET_READY"
  328. goto CONTINUE
  329. end
  330. logF("鉴权发送成功")
  331. result, param = libnet.wait(d1Name, 30000, netc)
  332. if not result then
  333. logF("鉴权数据等待异常", result, param)
  334. nowStatus = "WAIT_NET_READY"
  335. goto CONTINUE
  336. end
  337. if not ipv6Valid and IPV6_UDP_VER then
  338. if not param then
  339. logF("鉴权 超时未收到响应报文")
  340. nowStatus = "WAIT_NET_READY"
  341. goto CONTINUE
  342. end
  343. end
  344. succ, param = socket.rx(netc, rxBuff)
  345. if not succ then
  346. logF("数据读取出现异常 4", succ, param, ip, port)
  347. nowStatus = "WAIT_NET_READY"
  348. goto CONTINUE
  349. end
  350. if rxBuff:used() > 0 then
  351. data = rxBuff:query() -- 获取数据
  352. rxBuff:del()
  353. logF("鉴权data", data:toHex())
  354. isResponseOK = false
  355. isResponseNeedCheck = true
  356. lastRxData, queue = air_jt808.rxAnalyze(lastRxData .. data)
  357. msgDispatch(queue)
  358. if not isResponseOK then
  359. logF("鉴权失败")
  360. logF("lastRxData = ", lastRxData)
  361. nowStatus = "WAIT_NET_READY"
  362. goto CONTINUE
  363. end
  364. logF("鉴权成功")
  365. nowStatus = "MSG_LISTEN"
  366. retryTimes = 0
  367. end
  368. goto CONTINUE
  369. end
  370. if nowStatus == "MSG_LISTEN" then
  371. connectOKFlag = true
  372. logF("开始监听")
  373. while true do
  374. waitAck = false
  375. while #responseQueue > 0 do
  376. -- 应答区有数据
  377. pTxBuf = responseQueue[1]
  378. result, param = libnet.tx(d1Name, 15000, netc, pTxBuf)
  379. if not result then
  380. nowStatus = "WAIT_NET_READY"
  381. goto CONTINUE
  382. end
  383. table.remove(responseQueue, 1)
  384. logF("response packet", api.BinToHex(pTxBuf, " "))
  385. end
  386. if #dataQueue > 0 then
  387. if mreport then
  388. mreport.send()
  389. end
  390. local item = dataQueue[1]
  391. localMsgID = (localMsgID + 1) % 65536
  392. lastTxMsgSn = localMsgID
  393. pTxBuf = air_jt808.positionPackage(lastTxMsgSn, simID, item:query())
  394. lastTxMsgID = 0x0200
  395. logF("data packet", #pTxBuf, api.BinToHex(pTxBuf, " "))
  396. result, param = libnet.tx(d1Name, 15000, netc, pTxBuf)
  397. if not result then
  398. nowStatus = "WAIT_NET_READY"
  399. goto CONTINUE
  400. end
  401. item:free()
  402. table.remove(dataQueue, 1)
  403. waitAck = true
  404. end
  405. isWaitMsg = true
  406. if waitAck then
  407. result, param = libnet.wait(d1Name, 60000, netc)
  408. else
  409. result, param = libnet.wait(d1Name, 300000, netc)
  410. end
  411. isWaitMsg = false
  412. logF("wait", result, param, param2)
  413. if not result then
  414. logF("服务器断开了 5", result, param)
  415. nowStatus = "WAIT_NET_READY"
  416. goto CONTINUE
  417. end
  418. succ, param = socket.rx(netc, rxBuff)
  419. if not succ then
  420. logF("服务器断开了 6", succ, param, ip, port)
  421. nowStatus = "WAIT_NET_READY"
  422. goto CONTINUE
  423. end
  424. -- 如果服务器有下发数据, used()就必然大于0, 进行处理
  425. if rxBuff:used() > 0 then
  426. logF("socket", "收到服务器数据,长度", rxBuff:used())
  427. data = rxBuff:query()
  428. rxBuff:del()
  429. logF("rxData", data:toHex())
  430. lastRxData, queue = air_jt808.rxAnalyze(lastRxData .. data)
  431. msgDispatch(queue)
  432. end
  433. -- 其他task给服务器发消息
  434. local _, msg = sys.waitUntil("OTHER_FILE_SENDMSG")
  435. log.info("其他task或者文件发过来的要发给日志服务器的消息", msg)
  436. local d1Name = taskName
  437. local pTxBuf = string.char(0xF0)..msg
  438. localMsgID = 0xF0 --透传
  439. pTxBuf = air_jt808.air_jt808Head(0x0900, localMsgID, simID, pTxBuf)
  440. logF("实际其他task发送给服务器的数据是", pTxBuf:toHex())
  441. -- local result, param = libnet.tx(d1Name, 15000, netCB, pTxBuf)
  442. local result, full,result = socket.tx(netc, pTxBuf)
  443. -- if not result then
  444. -- logF("没发出去") --我也不知道为啥显示是没发送出去,但是建栋那边收到了,先屏蔽这玩意
  445. -- nowStatus = "WAIT_NET_READY"
  446. -- -- goto CONTINUE
  447. -- else
  448. -- logF("发送成功")
  449. -- table.insert(responseQueue, pTxBuf)
  450. -- end
  451. -- 循环尾部, 继续下一轮循环
  452. end
  453. goto CONTINUE
  454. end
  455. if nowStatus == "FLY_MODE" then
  456. firstWaitNetReady = true
  457. netWork.setFlyMode(true)
  458. sys.waitUntil("EXIT_FLYMODE", 10 * 60 * 1000)
  459. netWork.setFlyMode(false)
  460. nowStatus = "WAIT_NET_READY"
  461. goto CONTINUE
  462. end
  463. end
  464. end
  465. sysplus.taskInitEx(auxServerTask, taskName, netCB, taskName)
  466. sys.timerLoopStart(function()
  467. local data = {
  468. type= "http_test",
  469. test_mode = "GET方法,无请求头、body以及额外的附加数据",
  470. test_end= "失败",
  471. fail_res = "download time out",
  472. imei= mobile.imei(),
  473. }
  474. local data = json.encode(data)
  475. sys.publish("OTHER_FILE_SENDMSG", data)
  476. end, 60 * 1000)