8 Star 26 Fork 14

wibim / luat-jt808

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
protoair808.lua 13.39 KB
一键复制 编辑 原始数据 按行查看 历史
wibim 提交于 2020-08-13 14:52 . 少上了一个文件
--[[
模块名称:prot808
模块功能�?808协议实现
模块最后修改时间:2019.04.18
]]
local lpack = require"pack"
module(...,package.seeall)
local slen,sbyte,ssub,sgsub,schar,srep,smatch,sgmatch = string.len,string.byte,string.sub,string.gsub,string.char,string.rep,string.match,string.gmatch
local sformat = string.format
local bpack = lpack.pack
local bunpack = lpack.unpack
--up
MSG_REGISTER = 0x0100
MSG_HEART = 0x0002
MSG_UNREGISTER = 0x0003
MSG_AUTH = 0x0102
MSG_POSITION = 0x0200
MSG_BATCH_POSITION = 0x0704
MSG_GENERAL_RESPONSE = 0x0001
--down
MSG_SERVER_RESPONSE = 0x8001
MSG_SERVER_REGIST_RESPONSE = 0x8100
MSG_SERVER_CONTROL_DEV = 0x8105
MSG_SERVER_CONTROL_CAR = 0x8500
local imei -- 命令头包含IMEI,在第一次获取以后做缓存
local get
local sendFunc,sucFunc
local function print(...)
_G.print("protoair808",...)
end
function bcd(d,n)
local l = slen(d or "")
local num
local t = {}
s = d
if l < 2*n then
s = srep("0",2*n-l) .. s
elseif l > 2*n then
s = ssub(s,l-2*n+1,-1)
end
for i=1,2*n,2 do
num = tonumber(ssub(s,i,i+1),16)
table.insert(t,num)
end
local s = schar(_G.unpack(t))
return s
end
local function stringProc(s,el)
local ss = s
l = slen(s)
if l < el then
ss = s .. srep("\0",el-l)
elseif l > el then
ss = ssub(s,1,el)
end
return ss
end
function print_r ( t )
local print_r_cache={}
local function sub_print_r(t,indent)
if (print_r_cache[tostring(t)]) then
print(indent.."*"..tostring(t))
else
print_r_cache[tostring(t)]=true
if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
print(indent.."["..pos.."] => "..tostring(t).." {")
sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
print(indent..string.rep(" ",string.len(pos)+6).."}")
elseif (type(val)=="string") then
print(indent.."["..pos..'] => "'..val..'"')
else
print(indent.."["..pos.."] => "..tostring(val))
end
end
else
print(indent..tostring(t))
end
end
end
if (type(t)=="table") then
print(tostring(t).." {")
sub_print_r(t," ")
print("}")
else
sub_print_r(t," ")
end
print()
end
table.print = print_r
-----------------------------------------------------------------------------------------------------------------------
local function cmdName(cmd)
if cmd == MSG_REGISTER then
return "MSG_REGISTER"
elseif cmd == MSG_HEART then
return "MSG_HEART"
elseif cmd == MSG_UNREGISTER then
return "MSG_UNREGISTER"
elseif cmd == MSG_AUTH then
return "MSG_AUTH"
elseif cmd == MSG_POSITION then
return "MSG_POSITION"
elseif cmd == MSG_BATCH_POSITION then
return "MSG_BATCH_POSITION"
elseif cmd == MSG_GENERAL_RESPONSE then
return "MSG_GENERAL_RESPONSE"
--down
elseif cmd == MSG_SERVER_RESPONSE then
return "MSG_SERVER_RESPONSE"
elseif cmd == MSG_SERVER_REGIST_RESPONSE then
return "MSG_SERVER_REGIST_RESPONSE"
elseif cmd == MSG_SERVER_CONTROL_DEV then
return "MSG_SERVER_CONTROL_DEV"
elseif cmd == MSG_SERVER_CONTROL_CAR then
return "MSG_SERVER_CONTROL_CAR"
end
return "UNKOWN_CMD"
end
local function computeCrc(indata)
local r = 0
for i = 1, slen(indata) do
local charcode = sbyte(indata, i, i)
r = bit.bxor(r, charcode)
end
return r
end
local MSG_INDEX = 0xffff
local function genMsgIndex()
MSG_INDEX = MSG_INDEX + 1
MSG_INDEX = bit.band(MSG_INDEX,0xffff)
return MSG_INDEX
end
local function genMsgParam(len, encT, totalMsgSplit)
len = bit.band(len,0x3ff)
encT = bit.band(encT,0x07)
encT = bit.lshift(encT, 10)
splitP = 0
if (totalMsgSplit > 1) then
splitP = 1
end
splitP = bit.lshift(splitP, 13)
return len + encT + splitP
end
local function encLatLng(gps)
-- print("xxxxx", gps)
-- print("xxxxx", tonumber(gps))
if gps == nil then
gps = "0.0"
end
local integer,fraction = smatch(gps,"(%d+)%.(%d+)")
if (fraction == nil) then
return 0
end
strL = string.len(fraction)
str = ssub(fraction,1,-1-(strL-6))
-- print("xxxxx", tonumber(integer))
-- print("xxxxx", tonumber(fraction))
local ret = tonumber(sformat("%s%s", integer, str))
-- print("xxxxx", ret)
return ret
end
function getPhoneEx()
imei = _G.TEST_IMEI
if imei == nil or imei == "" then
ii = get("IMEI") --"869300038441535"
log.info("--zbb--imei:", ii)
if ii ~= nil then
-- imei = "13"..ssub(ii,slen(ii)-9+1,-1)
imei = "13"..ssub(ii,slen(ii)-10+1,-2)
end
end
log.error("--zbb--phone:", imei)
return imei
end
-----------------------------------------------------------------------------
local function packMsg(msgtype, msg)
local total = 1
local cur = 0
local msglen = slen(msg)
-- if (total > 1) then
-- msglen = msglen + 4
-- end
-- msglen = msglen + 2
local msgparam = genMsgParam(msglen, 0, total)
local msgs = 0
-- local imei111 = get("IMEI")
-- log.error("--zbb--imei111:", imei111)
-- imei2222 = bcd(get("IMEI"),6)
-- log.error("--zbb--imei2222:", string.toHex(imei2222))
if not imei or imei == "" then
imei = bcd(getPhoneEx(),6)
end
log.error("--zbb--imei:", string.toHex(imei))
local a = bpack(">H2AH", msgtype, msgparam, imei, genMsgIndex())
local tbl = {}
table.insert(tbl, a)
if (total > 1) then
b = bpack(">H2", total, cur)
table.insert(tbl, b)
end
if (msg ~= nil) then
table.insert(tbl, msg)
end
return table.concat(tbl)
end
function packAll(t,indata)
h1 = packMsg(t, indata)
local r = computeCrc(h1)
--print("rr:" .. r)
indatacrc = h1 .. string.format("%c", r);
--print(hex2str(indatacrc))
local str = sformat("%c", 0x7e)
for i = 1, slen(indatacrc) do
local charcode = string.byte(indatacrc, i, i);
if (charcode == 0x7d) then
str = str .. string.format("%c%c", 0x7d, 0x01);
elseif (charcode == 0x7e) then
str = str .. string.format("%c%c", 0x7d, 0x02);
elseif (charcode == 0x00) then
str = str .. string.format("\0");
else
str = str .. string.format("%c", charcode);
end
end
str = str .. sformat("%c", 0x7e);
return str
end
function pack(t,...)
local function empty(d)
return true
end
local function regist()
local provID = 0
local cityID = 0
local manufacturerId = "ccwcc" --5
local terminalType = "ccw-z01s-201805"
local terminalId = "1234567"
local color = 0
local licensePlate = "2029487246592"
-- ss=stringProc(terminalType,20)
-- log.error("--zbb--ss:", string.toHex(ss))
-- start = bpack(">H2", provID, cityID)..stringProc(manufacturerId,5)
-- log.error("--zbb--ss:", start)
-- start = start .. stringProc(terminalType,20)..stringProc(terminalId,20)
-- log.error("--zbb--ss:", start)
-- return start..bpack(">b",color)..licensePlate
return bpack(">H2AAAbA", provID, cityID, stringProc(manufacturerId,5), stringProc(terminalType,20), stringProc(terminalId,20), color, licensePlate)
end
local function auth(a)
return a
end
local function heart()
return ""
end
local function genRes(msgIndexFromServer, msgType, result)
--log.info("--zwb--protocal.genResponseMsg:", msgIndexFromServer, msgType, result)
return bpack(">H2b", msgIndexFromServer, msgType, result)
end
local function loc(gpsStat,devStat,adcr)
-- local v = misc.getVbatt()
-- log.info("---getVbatt mv:", v)
local status = devStat.acc -- acc 0)
+ (gpsStat.fix and 1 or 0) * 0x2 -- gps valid
+ (gpsStat.lngType == "S" and 1 or 0) * 0x4
+ (gpsStat.latType == "W" and 1 or 0) * 0x8
+ (devStat.block) * 0x400 --10
local alarm = 0
+ devStat.dismantle * 0x100 --8
log.error("--zbb--protoair808.loc status alarm:", status, alarm)
-- a = nil
-- string.toHex(a)
local tbl = {}
a = bpack(">I2",alarm,status)
table.insert(tbl, a)
if (gpsStat.lat ~= "" and gpsStat.lng ~= "") then
b = bpack(">I2", encLatLng(gpsStat.lat), encLatLng(gpsStat.lng))
table.insert(tbl, b)
end
d = bpack(">H3", gpsStat.alt, gpsStat.spd * 10, gpsStat.cog)
table.insert(tbl, d)
utcTime = gpsStat.time
-- log.info("---updateGps utcTime:", #utcTime)
table.print( utcTime )
if (utcTime ~= nil) then
year = utcTime["year"]
year = ssub(year,3,-1)
-- log.info("---updateGps utcTime year:", year)
time = sformat("%02d%02d%02d%02d%02d%02d", year, utcTime["month"], utcTime["day"], utcTime["hour"], utcTime["min"], utcTime["sec"])
local tttt = bcd(time,6)
log.info("---updateGps utcTime2:", string.toHex(tttt))
table.insert(tbl, tttt)
end
-- ret = table.concat(tbl)
-- log.info("---updateGps ret:", string.toHex(ret))
return table.concat(tbl)
end
local function locbatch(msgs)
local count = #msgs
local tbl = {}
a = bpack(">Hb",count,1) --位置数据类型 0:正常位置批量汇报,1:盲区补�?
table.insert(tbl, a)
for i=1,count do
local msg = msgs[i]
log.info("--zbb--protoair808.locbatch:",i,string.toHex(msg))
local len = slen(msg)
b = bpack(">H",len)
table.insert(tbl, b)
table.insert(tbl, msg)
end
return table.concat(tbl)
end
local procer = {
[MSG_REGISTER] = regist,
[MSG_AUTH] = auth,
[MSG_GENERAL_RESPONSE] = genRes,
[MSG_POSITION] = loc,
[MSG_BATCH_POSITION] = locbatch,
[MSG_HEART] = heart,
}
local s = procer[t](...)
print("--zbb--pack",cmdName(t),string.toHex(s))
return s
end
function setInitFunc(sfunc,sucfunc)
sendFunc = sfunc
sucFunc = sucfunc
end
function init()
d = pack(MSG_REGISTER)
sendFunc(MSG_REGISTER,d)
return 0
end
function heart()
-- log.info("--zbb--32960.heart")
d = pack(MSG_HEART)
sendFunc(MSG_HEART,d)
end
local function authReq(a)
d = pack(MSG_AUTH,a)
sendFunc(MSG_AUTH,d)
end
local function genResponseMsg(msgIndexFromServer, msgType, result)
d = pack(MSG_GENERAL_RESPONSE,msgIndexFromServer, msgType, result)
sendFunc(MSG_GENERAL_RESPONSE,d)
end
function loc(t,stat,adcr)
d = pack(MSG_POSITION,t,stat,adcr)
if sendFunc ~= nil then sendFunc(MSG_POSITION,d) end
end
function locbatch(msgs)
d = pack(MSG_BATCH_POSITION,msgs)
if sendFunc ~= nil then sendFunc(MSG_BATCH_POSITION,d) end
end
---------------------------------------------------------------------------------------
local function pa(b)
return sformat("%d%d",b/16,b%16)
end
--[[
函数名:unpack
功能 :根据ptotobuffer协议进行封包
参数 �?
s:需要解析字符串
返回值:解包字符�?
]]
function unpack(s)
local packet = {}
local function registRes(data,msgIndexFromServer)
if slen(data) > 0 then
extpox1,msgIndexFromDevice,result=bunpack(data,">Hb")
log.info("--zbb--protacal808.registRes:",sformat("result:%d, msgIndexFromDevice:%d",result,msgIndexFromDevice))
auth = ssub(data, 4, -1)
log.info("--zbb--protacal808.registRes auth:",auth)
authReq(auth)
end
end
local function generalRes(data,msgIndexFromServer)
if slen(data) > 0 then
extpox1,msgIndexFromDevice,msgTypeFromDevice,result=bunpack(data,">HHb")
log.info("--zbb--protacal808.generalRes:",
sformat("result:%d, msgIndexFromDevice:%d, msgTypeOrgCmd:%s(0x%04X)",result,msgIndexFromDevice,cmdName(msgTypeFromDevice),msgTypeFromDevice))
if msgTypeFromDevice == MSG_AUTH then
sucFunc()
end
end
end
local function control(data,msgIndexFromServer)
if slen(data) > 0 then
extpoz,controlId=bunpack(data,">b")
param = ssub(data, extpoz, -1)
log.info("--zbb--protoair808.control:",controlId,param)
if controlId == 0 or controlId == 0x65 then
pincontrol.setBlockWithNvm(false)
genResponseMsg(msgIndexFromServer, MSG_SERVER_CONTROL_DEV, 0)
sys.publish("MY_DEV_EVENT")
elseif controlId == 1 or controlId == 0x64 then
pincontrol.setBlockWithNvm(true)
genResponseMsg(msgIndexFromServer, MSG_SERVER_CONTROL_DEV, 0)
sys.publish("MY_DEV_EVENT")
end
end
end
local procer = {
[MSG_SERVER_REGIST_RESPONSE] = registRes,
[MSG_SERVER_RESPONSE] = generalRes,
[MSG_SERVER_CONTROL_CAR] = control,
[MSG_SERVER_CONTROL_DEV] = control,
}
local hexStr = string.toHex(s)
-- hexStr = "7E80010005575021921749007D010217020000047E"
-- log.error("--zbb--protoair808.unpack hexStr1=",hexStr)
hexStr = sgsub(hexStr, "(7D02)", "7E")
hexStr = sgsub(hexStr, "(7D01)", "7D")
-- log.error("--zbb--protoair808.unpack hexStr2=",hexStr)
local data1 = string.fromHex(hexStr)
local data2 = ssub(data1, 2, -2)
local r = computeCrc(data2)
if r ~= 0 then
log.error("--zbb--protoair808.unpack error crc=",r)
return nil
end
-- extpoz,msgType,msgLen,b1,b2,b3,b4,b5,b6,msgIndexFromServer,ptotal,pindex=bunpack(data2,">HHb6HHH")
extpoz,msgType,msgLen,b1,b2,b3,b4,b5,b6,msgIndexFromServer=bunpack(data2,">HHb6H")
local imeiTT = sformat("%s%s%s%s%s%s", pa(b1), pa(b2), pa(b3), pa(b4), pa(b5), pa(b6))
-- log.info("--zwb--protacal.parseMsg imei:",imei)
local imeiLocal = string.toHex(imei)
if imeiTT ~= imeiLocal then
log.error("--zbb--protoair808.parseMsg imei error:", imeiTT, imeiLocal)
return nil
end
local data3 = ssub(data2,extpoz,extpoz + msgLen - 1)
log.info("--zbb--protoair808.parseMsg:",sformat("%s(0x%04X), serverIndex:%d",cmdName(msgType),msgType,msgIndexFromServer),string.toHex(data3))
packet.id = msgType
if procer[msgType] ~= nil then procer[msgType](data3,msgIndexFromServer) end
return packet or nil
end
function reget(id)
get = id
end
Lua
1
https://gitee.com/wibim/luat-jt808.git
git@gitee.com:wibim/luat-jt808.git
wibim
luat-jt808
luat-jt808
master

搜索帮助