JT808Prot.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. local JT808Prot = {}
  2. local paraCtrl = require "paraCtrl"
  3. --终端消息ID
  4. JT808Prot.T_COMMON_RSP = 0x0001
  5. JT808Prot.T_LOC_RPT = 0x0200
  6. JT808Prot.T_HEART_RPT = 0x0002
  7. JT808Prot.PARA_HEART_FREQ = 0x0001
  8. JT808Prot.PARA_TCP_RSP_TIMEOUT = 0x0002
  9. JT808Prot.PARA_TCP_RESEND_CNT = 0x0003
  10. JT808Prot.PARA_LOC_RPT_STRATEGY = 0x0020
  11. JT808Prot.PARA_LOC_RPT_MODE = 0x0021
  12. JT808Prot.PARA_SLEEP_LOC_RPT_FREQ = 0x0027
  13. JT808Prot.PARA_ALARM_LOC_RPT_FREQ = 0x0028
  14. JT808Prot.PARA_WAKE_LOC_RPT_FREQ = 0x0029
  15. JT808Prot.PARA_WAKE_LOC_RPT_DISTANCE = 0x002C
  16. JT808Prot.PARA_SLEEP_LOC_RPT_DISTANCE = 0x002E
  17. JT808Prot.PARA_ALARM_LOC_RPT_DISTANCE = 0x002F
  18. JT808Prot.PARA_FENCE_RADIS = 0x0031
  19. JT808Prot.PARA_ALARM_FILTER = 0x0050
  20. JT808Prot.PARA_KEY_FLAG = 0x0054
  21. JT808Prot.PARA_SPEED_LIMIT = 0x0055
  22. JT808Prot.PARA_SPEED_EXCEED_TIME = 0x0056
  23. JT808Prot.CONTROL_RESET = 4
  24. --平台消息ID
  25. JT808Prot.S_COMMON_RSP = 0x8001
  26. JT808Prot.S_REGISTER_RSP = 0x8100
  27. JT808Prot.S_SET_PARA = 0x8103
  28. JT808Prot.S_CONTROL = 0x8105
  29. local tSendSeq = 0
  30. local function encodeBcdNum(d,n)
  31. if d:len()<n then
  32. return (string.rep("0",n-d:len())..d):fromHex()
  33. else
  34. return (d:sub(1,n)):fromHex()
  35. end
  36. end
  37. local function calCrc(d)
  38. local sum = 0
  39. for i=1,d:len() do
  40. sum = sum~d:byte(i)
  41. end
  42. return sum
  43. end
  44. --终端消息封包
  45. --返回值1:打包后的字符串
  46. --返回值2:流水号
  47. function JT808Prot.encode(msgId,...)
  48. local function cmnRsp(svrSeq,svrId,result)
  49. return pack.pack(">HHb",svrSeq,svrId,result)
  50. end
  51. local function locRpt(alarm,status,lat,lng,alt,spd,course,tm,extInfo)
  52. -- return pack.pack(">ddddHHHAA",alarm,status,lat,lng,alt,spd,course,tm,extInfo)
  53. return pack.pack(">ddddHHHAA",alarm,status,lat,lng,math.modf(alt),math.modf(spd),math.modf(course),tm,extInfo)
  54. end
  55. local procer =
  56. {
  57. [JT808Prot.T_COMMON_RSP] = cmnRsp,
  58. [JT808Prot.T_LOC_RPT] = locRpt,
  59. [JT808Prot.T_HEART_RPT] = function() return "" end,
  60. }
  61. local msgBody = procer[msgId](...) --消息体
  62. local msgHead = pack.pack(">HHAH", --消息头
  63. msgId, --消息ID
  64. msgBody:len(), --消息体属性,暂未实现分包和数据加密
  65. encodeBcdNum(paraCtrl.getTerminalNum(),12), --终端手机号
  66. tSendSeq --消息流水号
  67. )
  68. local curSeq = tSendSeq
  69. tSendSeq = (tSendSeq==0xFFFF) and 0 or (tSendSeq+1)
  70. --校验码
  71. local crc = calCrc(msgHead..msgBody)
  72. --转义
  73. local s = msgHead..msgBody..string.char(crc)
  74. s = s:gsub("\125","\125\1") -- 7D -> 7D 01
  75. s = s:gsub("\126","\125\2") -- 7E -> 7D 02
  76. return string.char(0x7E)..s..string.char(0x7E),curSeq
  77. end
  78. --返回值1:未处理的数据
  79. --返回值2:解析后的packet,解析失败为nil,解释成功为table类型,table中有一个boolean类型的result变量进一步表示结果
  80. function JT808Prot.decode(s)
  81. local _,tail,msg = s:find("\126(.-)\126")
  82. local decPacket,msgAttr = {}
  83. if not msg then
  84. log.warn("prot.decode","wait packet complete")
  85. return s,nil
  86. end
  87. --反转义
  88. msg = msg:gsub("\125\2","\126") -- 7D 02 -> 7E
  89. msg = msg:gsub("\125\1","\125") -- 7D 01 -> 7D
  90. if msg:len()<13 then
  91. log.error("prot.decode","packet len is too short")
  92. return s:sub(tail+1,-1),nil
  93. end
  94. --验证校验码
  95. if calCrc(msg:sub(1,-2))~=msg:byte(-1) then
  96. log.error("prot.decode","packet len is too short")
  97. return s:sub(tail+1,-1),nil
  98. end
  99. --消息头和消息体
  100. msg = msg:sub(1,-2)
  101. --消息ID
  102. _,decPacket.msgId = pack.unpack(msg,">H")
  103. --消息流水号
  104. decPacket.msgSeq = pack.unpack(msg,">H")
  105. --消息体属性
  106. _,msgAttr = pack.unpack(msg:sub(3,4),">H")
  107. --分包标志
  108. local msgMultiPacket = bit.isset(msgAttr,13)
  109. --数据加密标志
  110. local msgEncrypt = bit.band(bit.rshift(msgAttr,10),0x07)
  111. --消息体长度
  112. local msgLen = bit.band(msgAttr,0x03FF)
  113. local msgBodyHead = msgMultiPacket and 17 or 13
  114. local msgBody = msg:sub(msgBodyHead,-1)
  115. decPacket.result = msgBody:len()==msgLen
  116. if not decPacket.result then
  117. log.error("prot.decode","body len no match")
  118. return s:sub(tail+1,-1),decPacket
  119. end
  120. local function cmnRsp(body)
  121. if body:len()~=5 then
  122. log.error("prot.decode.cmnRsp","len~=5 error",body:len())
  123. return false
  124. end
  125. _,decPacket.tmnlSeq,decPacket.tmnlId,decPacket.rspResult = pack.unpack(body,">HHb")
  126. end
  127. local function setPara(body)
  128. if body:len()<5 then
  129. log.error("prot.decode.setPara","len<5 error",body:len())
  130. return false
  131. end
  132. local cnt,i = body.byte(1)
  133. local tmp,id = body:sub(2,-1)
  134. while tmp:len() > 0 do
  135. _,id = pack.unpack(tmp,">i")
  136. if not list[id] then
  137. log.error("prot.decode.setPara","unsupport para",id)
  138. return false
  139. end
  140. local paraLen = tmp:byte(5)
  141. if tmp:len() < paraLen+5 then
  142. log.error("prot.decode.setPara","para data incomplete",id)
  143. return false
  144. end
  145. if not paraCtrl.setPara(id,paraLen,tmp:sub(6,5+paraLen)) then
  146. log.error("prot.decode.setPara","para proc error",id)
  147. return false
  148. end
  149. tmp = tmp:sub(6+tmpLen,-1)
  150. end
  151. return true
  152. end
  153. local function control(body)
  154. if body:len()<1 then
  155. log.error("prot.decode.control","len<1 error",body:len())
  156. return false
  157. end
  158. decPacket.controlCmd = body:byte(1)
  159. return true
  160. end
  161. local procer =
  162. {
  163. [JT808Prot.S_COMMON_RSP] = cmnRsp,
  164. [JT808Prot.S_SET_PARA] = setPara,
  165. [JT808Prot.S_CONTROL] = control,
  166. }
  167. if not procer[decPacket.msgId] then
  168. log.error("prot.decode","invalid id",decPacket.msgId)
  169. decPacket.result = false
  170. return s:sub(tail+1,-1),decPacket
  171. end
  172. if procer[decPacket.msgId](msgBody)==false then
  173. log.error("prot.decode","procer fail")
  174. decPacket.result = false
  175. end
  176. return s:sub(tail+1,-1),decPacket
  177. end
  178. return JT808Prot