8 Star 27 Fork 16

wibim/luat-jt808

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
protoair.lua 16.92 KB
一键复制 编辑 原始数据 按行查看 历史
wibim 提交于 2020-02-15 14:44 . 第一次上代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
--[[
模块名称:protoair
模块功能:根据mqtt协议进行封包
模块最后修改时间:2017.08.25
]]
local lpack = require"pack"
local protobuf = require"protobuf"
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
GPS,LBS1,LBS2,HEART,LBS3,GPSLBS,GPSLBS1,GPSLBSWIFIEXT,GPSLBSWIFI,RPTPARA,SETPARARSP,DEVEVENTRSP,GPSLBSWIFI1,INFO = 1,2,3,4,5,6,7,8,9,10,11,12,13,14
RPTFREQ,ALMFREQ,GUARDON,GUARDOFF,HORNOFF,HORNON,RELNUM,CALLVOL,CALLRINGVOL,CALLRINGMUTEON,CALLRINGMUTEOFF,AUTOGUARDON,AUTOGUARDOFF,AUTOSLEEPON,AUTOSLEEPOFF,LOCRPON,LOCRPOFF = 3,4,5,6,13,14,15,16,17,18,19,48,49,50,51,52,53
SILTIME,FIXTM,WHITENUM,FIXMOD,SMSFORBIDON,SMSFORBIDOFF,CALLRINGID,SOSIND,ENTERTAIN,ALARM = 20,21,22,23,24,25,26,27,28,29
SETPARA,SENDSMS,DIAL,QRYLOC,RESET,MONIT,POWEROFF,RESTORE,PROMPT,BTCTL,SMPSET,QRYPARA = 10,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x3A,0x3C,0x50
VER = 0
FIXTIMEPOS,QRYPOS = 0,1
BTCLS,BTOPN,BTOTA,BTUPD = 0,1,2,3
DATETIME,poweron = 0,true
local histsnd,timed = {},0
local PROTOVERSION = 0
local serial = 0
local imei -- 命令头包含IMEI,在第一次获取以后做缓存
local get
local function print(...)
_G.print("protoair",...)
end
function bcd(d,n)
local l = slen(d or "")
local num
local t = {}
for i=1,l,2 do
num = tonumber(ssub(d,i,i+1),16)
if i == l then
num = 0xf0+num
else
num = (num%0x10)*0x10 + num/0x10
end
table.insert(t,num)
end
local s = schar(_G.unpack(t))
l = slen(s)
if l < n then
s = s .. srep("\255",n-l)
elseif l > n then
s = ssub(s,1,n)
end
return s
end
local function unbcd(d)
local byte,v1,v2
local t = {}
for i=1,slen(d) do
byte = sbyte(d,i)
v1,v2 = bit.band(byte,0x0f),bit.band(bit.rshift(byte,4),0x0f)
if v1 == 0x0f then break end
table.insert(t,v1)
if v2 == 0x0f then break end
table.insert(t,v2)
end
return table.concat(t)
end
local function enlnla(v,s)
if not v then return string.toHex("FFFFFFFFFF") end
local v1,v2 = smatch(s,"(%d+)%.(%d+)")
if not v1 or not v2 then return string.toHex("FFFFFFFFFF") end
if slen(v1) < 3 then v1 = srep("0",3-slen(v1)) .. v1 end
return bcd(v1..v2,5)
end
-- 基本状态信息封包处理
local function enstat()
local stat = get("STATUS")
local rssi = get("RSSI")
local gpstat = get("GPSTAT")
local satenum = gpstat.satenum
local chgstat = chg.getcharger()
local pwoffcause = 0 --linkair.getpwoffcause()
local _,adc = adcv.read()
-- 状态字节1
local n1 = stat.shake + stat.charger*2 + stat.acc*4 + stat.gps*8 + stat.sleep*16+stat.fly*32+stat.poweroff*64+stat.rest*128
-- 状态字节2
rssi = rssi > 31 and 31 or rssi
satenum = satenum > 7 and 7 or satenum
local n2 = rssi + satenum*32
local base = lpack.pack(">bbH",n1,n2,stat.volt)
local extend
extend = lpack.pack(">bHI",0x04,4,os.time())
if get("GPSLEEP") then
extend = extend..lpack.pack(">bHb",5,1,0)
else
extend = extend..lpack.pack(">bHb",5,1,1)
end
if chgstat == false then
extend = extend..lpack.pack(">bHb",6,1,0)
elseif chgstat == true then
extend = extend..lpack.pack(">bHb",6,1,1)
end
if pwoffcause == 0 then
extend = extend..lpack.pack(">bHb",7,1,0)
elseif pwoffcause == 1 then
extend = extend..lpack.pack(">bHb",7,1,1)
end
if timed == 0 then
extend = extend..lpack.pack(">bHH",0x0B,2,0)
else
extend = extend..lpack.pack(">bHH",0x0B,2,timed)
end
if adc then extend = extend..lpack.pack(">bHH",0x0C,2,adc) end
return base..extend
end
local function encellinfo()
local info,ret,t,lac,ci,rssi,k,v,m,n,cntrssi = get("CELLINFO"),"",{}
print("encellinfo",info)
for lac,ci,rssi in sgmatch(info,"(%d+)%.(%d+)%.(%d+);") do
lac,ci,rssi = tonumber(lac),tonumber(ci),(tonumber(rssi) > 31) and 31 or tonumber(rssi)
local handle = nil
for k,v in pairs(t) do
if v.lac == lac then
if #v.rssici < 8 then
table.insert(v.rssici,{rssi=rssi,ci=ci})
end
handle = true
break
end
end
if not handle then
table.insert(t,{lac=lac,rssici={{rssi=rssi,ci=ci}}})
end
end
for k,v in pairs(t) do
ret = ret .. lpack.pack(">H",v.lac)
for m,n in pairs(v.rssici) do
cntrssi = bit.bor(bit.lshift(((m == 1) and (#v.rssici-1) or 0),5),n.rssi)
ret = ret .. lpack.pack(">bH",cntrssi,n.ci)
end
end
return schar(#t)..ret
end
local function cellinfoext()
local info,ret,t,mcc,mnc,lac,ci,rssi,k,v,m,n,cntrssi = get("CELLINFOEXT"),"",{}
print("cellinfoext",info)
for mcc,mnc,lac,ci,rssi in sgmatch(info,"(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+);") do
mcc,mnc,lac,ci,rssi = tonumber(mcc),tonumber(mnc),tonumber(lac),tonumber(ci),(tonumber(rssi) > 31) and 31 or tonumber(rssi)
local handle = nil
for k,v in pairs(t) do
if v.lac_id == lac then
if #v.cells < 8 then
table.insert(v.cells,{mcc=mcc,mnc=mnc,cell_id=ci,cell_rssi=rssi})
end
handle = true
break
end
end
if not handle then
table.insert(t,{lac_id=lac,cells={{mcc=mcc,mnc=mnc,cell_id=ci,cell_rssi=rssi}}})
end
end
--[[for k,v in pairs(t) do
print("cells k,v",k,v.lac_id,#v.cells)
for k,v in pairs(v.cells) do
print("cells.cells",v.mcc,v.mnc,v.cell_id,v.cell_rssi)
end
end]]
return t
end
local function encellinfoext()
local info,ret,t,mcc,mnc,lac,ci,rssi,k,v,m,n,cntrssi = get("CELLINFOEXT"),"",{}
print("encellinfoext",info)
for mcc,mnc,lac,ci,rssi in sgmatch(info,"(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+);") do
mcc,mnc,lac,ci,rssi = tonumber(mcc),tonumber(mnc),tonumber(lac),tonumber(ci),(tonumber(rssi) > 31) and 31 or tonumber(rssi)
local handle = nil
for k,v in pairs(t) do
if v.lac == lac and v.mcc == mcc and v.mnc == mnc then
if #v.rssici < 8 then
table.insert(v.rssici,{rssi=rssi,ci=ci})
end
handle = true
break
end
end
if not handle then
table.insert(t,{mcc=mcc,mnc=mnc,lac=lac,rssici={{rssi=rssi,ci=ci}}})
end
end
for k,v in pairs(t) do
ret = ret .. lpack.pack(">HHb",v.lac,v.mcc,v.mnc)
for m,n in pairs(v.rssici) do
cntrssi = bit.bor(bit.lshift(((m == 1) and (#v.rssici-1) or 0),5),n.rssi)
ret = ret .. lpack.pack(">bH",cntrssi,n.ci)
end
end
return schar(#t)..ret
end
--注册proto描述文件
local pbFile = io.open("/ldata/tracker.pb","rb")
local pbBuf = pbFile:read("*a")
pbFile:close()
protobuf.register(pbBuf)
local function decodeAndPrint(encodeStream)
--使用protobuf.decode反序列化
--如果成功,反序列化后的数据以table类型赋值给decodeTable
--如果失败,返回false
local decodeTable = protobuf.decode("tracker.Client",encodeStream)
print("decodeTable",decodeTable)
if decodeTable then
print("decode message_id",decodeTable.message_id,type(decodeTable.message_id))
if decodeTable.message_id=="DEV_LOGIN" then
print("decode project_id",decodeTable.log_in.project_id)
print("decode project_name",decodeTable.log_in.project_name)
print("decode script_version",decodeTable.log_in.script_version)
print("decode iccid",decodeTable.log_in.iccid)
print("decode imsi",decodeTable.log_in.imsi)
print("decode heart_interval",decodeTable.log_in.heart_interval)
print("decode power_on",decodeTable.log_in.power_on)
elseif decodeTable.message_id=="DEV_HEART" then
print("decode shake",decodeTable.heart.status.shake)
print("decode charger",decodeTable.heart.status.charger)
print("decode acc",decodeTable.heart.status.acc)
print("decode gps",decodeTable.heart.status.gps)
print("decode rssi",decodeTable.heart.status.rssi)
print("decode vbat",decodeTable.heart.status.vbat)
print("decode charge_status",decodeTable.heart.status.charge_status)
print("decode adc",decodeTable.heart.status.adc)
elseif decodeTable.message_id=="DEV_PARA_REPORT" then
print("decode pararpt type",decodeTable.para_report.type)
print("decode para guard",decodeTable.para_report.guard)
elseif decodeTable.message_id=="DEV_SVRSETPARA_RSP" then
print("decode set_para_rsp type",decodeTable.set_para_rsp.type)
print("decode set_para_rsp result",decodeTable.set_para_rsp.result)
elseif decodeTable.message_id=="DEV_SVREVENT_RSP" then
print("decode event_rsp type",decodeTable.event_rsp.type)
print("decode event_rsp result",decodeTable.event_rsp.result)
elseif decodeTable.message_id=="DEV_LOCATION" then
print("decode type",decodeTable.location.type)
if decodeTable.location.gps_exist then
print("decode gps_info longitude",decodeTable.location.gps_info.longitude)
print("decode gps_info latitude",decodeTable.location.gps_info.latitude)
print("decode gps_info degree",decodeTable.location.gps_info.degree)
print("decode gps_info speed",decodeTable.location.gps_info.speed)
print("decode gps_info viewed_sates",decodeTable.location.gps_info.viewed_sates)
end
if decodeTable.location.cell_exist then
for k,v in ipairs(decodeTable.location.cell_info.cells) do
if type(v)=="table" then
print("decode cell_info",k,"lac_id",v.lac_id)
if type(v.cells)=="table" then
for m,n in ipairs(v.cells) do
print("decode cell_info",k,"cells",m,n.mcc,n.mnc,n.cell_id,n.cell_rssi)
end
end
end
end
print("decode ta",decodeTable.location.cell_info.ta)
end
if type(decodeTable.location.status)=="table" then
print("decode status shake",decodeTable.location.status.shake)
print("decode status charger",decodeTable.location.status.charger)
print("decode status acc",decodeTable.location.status.acc)
print("decode status gps",decodeTable.location.status.gps)
print("decode status rssi",decodeTable.location.status.rssi)
print("decode status vbat",decodeTable.location.status.vbat)
print("decode status charge_status",decodeTable.location.status.charge_status)
end
end
end
end
--[[
函数名:pack
功能 :根据ptotobuffer协议进行封包
参数 :
id:协议对应指令ID
返回值:封包字符串
]]
function pack(id,...)
if not imei then imei = bcd(get("IMEI"),8) end
local head = schar(id)
local function gpslbs1(w,typ)
local t = get("GPS")
lng = enlnla(t.fix,t.lng)
lat = enlnla(t.fix,t.lat)
local stat = get("STATUS")
local shk,chgstat,chg,gpstat = false,chg.getcharger(),"NOT_CHARGE",false
if stat.shake == 1 then shk = true end
if chgstat then chg = "CHARGING" end
if stat.gps == 1 then gpstat = true end
local _,adcr = adcv.read()
local typstr = "DEV_TIMER_REPORT"
if typ == QRYPOS then typstr = "SVR_QUERY_RSP" end
local locationGPS =
{
message_id = "DEV_LOCATION",
location =
{
type = typstr,
gps_exist = true,
cell_exist = true,
gps_info =
{
longitude = t.lng,
latitude = t.lat,
degree = t.cog,
speed = t.spd,
viewed_sates = get("GPSTAT").satenum,
},
cell_info =
{
cells = cellinfoext(),
ta = get("TA"),
},
status =
{
shake = shk,
charger = chgstat,
acc = acc.getflag(),
gps = gpstat,
rssi = get("RSSI"),
vbat = stat.volt,
charge_status = chg,
adc = adcr
},
}
}
encodeStr = protobuf.encode("tracker.Client",locationGPS)
--print("locationGPSStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr
end
local function heart()
local stat = get("STATUS")
local shk,chgstat,chg,gpstat = false,chg.getcharger(),"NOT_CHARGE",false
if stat.shake == 1 then shk = true end
if chgstat then chg = "CHARGING" end
if stat.gps == 1 then gpstat = true end
local _,adcr = adcv.read()
local devheart =
{
message_id = "DEV_HEART",
heart =
{
status =
{
shake = shk,
charger = chgstat,
acc = acc.getflag(),
gps = gpstat,
rssi = get("RSSI"),
vbat = stat.volt,
charge_status = chg,
adc = adcr,
},
}
}
local encodeStr = protobuf.encode("tracker.Client",devheart)
print("logInStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr
end
local function rptpara(dat)
local pararpt =
{
message_id = "DEV_PARA_REPORT",
para_report =
{
type = "GUARD",
guard = nvm.get("guard"),
}
}
local encodeStr = protobuf.encode("tracker.Client",pararpt)
print("pararptStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr or ""
end
local function rsp(typ,result)
local rlt = false
if result == 1 then rlt = true end
local pararsp =
{
message_id = "DEV_SVRSETPARA_RSP",
set_para_rsp =
{
type = "GUARD",
result = rlt,
}
}
local encodeStr = protobuf.encode("tracker.Client",pararsp)
print("pararspStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr
end
local function eventrsp(typ,result)
print("eventrsp",typ,result,schar(1))
local rlt = false
local ty
if typ == QRYLOC then
ty = "SVR_QUERY_LOCATION"
elseif typ == RESET then
ty = "SVR_RESET"
elseif typ == POWEROFF then
ty = "SVR_POWEROFF"
elseif typ == RESTORE then
ty = "SVR_RESTORE"
elseif typ == QRYPARA then
ty = "SVR_SET_PARA"
end
if result == schar(1) then rlt = true end
local pararsp =
{
message_id = "DEV_SVREVENT_RSP",
event_rsp =
{
type = ty,
result = rlt,
}
}
local encodeStr = protobuf.encode("tracker.Client",pararsp)
print("pararspStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr
end
local function info()
--登录报文的封包和解包
local logIn =
{
message_id = "DEV_LOGIN",
log_in =
{
project_id = get("PROJECTID"),
project_name = get("PROJECT").."_"..rtos.get_version(),
script_version = get("VERSION"),
iccid = get("ICCID"),
imsi = get("IMSI"),
heart_interval = get("HEART"),
power_on = poweron
}
}
local encodeStr = protobuf.encode("tracker.Client",logIn)
print("logInStr",string.toHex(encodeStr))
decodeAndPrint(encodeStr)
return encodeStr
end
local procer = {
[GPSLBS1] = gpslbs1,
[HEART] = heart,
[RPTPARA] = rptpara,
[SETPARARSP] = rsp,
[DEVEVENTRSP] = eventrsp,
[INFO] = info,
}
local s = procer[id](...)
if id == INFO then poweron = false end
print("pack",id,string.toHex(s),poweron)
return s
end
--[[
函数名:unpack
功能 :根据ptotobuffer协议进行封包
参数 :
s:需要解析字符串
返回值:解包字符串
]]
function unpack(s)
local packet = {}
local function setpara(d,p)
if slen(d) > 0 then
local function unsignshort(m)
if slen(m) ~= 2 then return end
_,packet.val = m
return true
end
local function empty(m)
return m==""
end
local proc =
{
[RPTFREQ] = unsignshort,
[GUARDON] = empty,
[GUARDOFF] = empty,
}
if d == "GUARD" and p then
packet.cmd = GUARDON
elseif d == "GUARD" and not p then
packet.cmd = GUARDOFF
elseif d == "GUARD" and p then
packet.cmd = RPTFREQ
end
return proc[packet.cmd](p) and packet or nil
end
end
local function empty(d)
return true
end
local function prompt(d)
if d == "" then return end
packet.data = d
return true
end
local function smpset(d,p)
if slen(d) > 0 then
local function datetime(m)
--print("Server datetime m",m)
packet.year = ssub(m,1,4)
packet.month = ssub(m,5,6)
packet.day = ssub(m,7,8)
packet.hour = ssub(m,9,10)
packet.min = ssub(m,11,12)
packet.sec = ssub(m,13,14)
return true
end
local proc =
{
[DATETIME] = datetime,
}
if d == "DATE" then packet.cmd = DATETIME end
if not proc[packet.cmd] then print("protoair.unpack:unknwon smpset",sbyte(d)) return end
return proc[packet.cmd](p) and packet or nil
end
end
local procer = {
[SETPARA] = setpara,
[QRYLOC] = empty,
[RESET] = empty,
[POWEROFF] = empty,
[RESTORE] = empty,
[SMPSET] = smpset,
}
local decodeTable = protobuf.decode("tracker.Server",s)
print("Server decodeTable")
local decodestr,typ,id
if decodeTable then
print("Server decode message_id",decodeTable.message_id,type(decodeTable.message_id))
if decodeTable.message_id=="SVR_SET_PARA" then
id = SETPARA
typ = decodeTable.svr_set_para.type
print("decode type",typ)
if typ == "GUARD" then
decodestr = decodeTable.svr_set_para.guard
print("decode decodestr",decodestr)
elseif typ == "LOCATION_INTERVAL" then
decodestr = decodeTable.svr_set_para.location_interval
print("decode decodestr",decodeTable.svr_set_para.location_interval)
end
elseif decodeTable.message_id=="SVR_QUERY_LOCATION" then
id = QRYLOC
elseif decodeTable.message_id=="SVR_RESET" then
id = RESET
elseif decodeTable.message_id=="SVR_POWEROFF" then
id = POWEROFF
elseif decodeTable.message_id=="SVR_RESTORE" then
id = RESTORE
elseif decodeTable.message_id=="SVR_SET_DATE" then
id = SMPSET
typ = decodeTable.svr_set_para.type
print("Server decode type",typ)
if decodeTable.svr_set_para.type == "DATE" then
decodestr = decodeTable.svr_set_para.date
print("Server decode decodestr",decodestr)
end
end
end
print("Server decode id",id,typ,decodestr)
packet.id = id
return procer[id](typ,decodestr) and packet or nil
end
function reget(id)
get = id
end
--此文件沒用
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Lua
1
https://gitee.com/wibim/luat-jt808.git
[email protected]:wibim/luat-jt808.git
wibim
luat-jt808
luat-jt808
master

搜索帮助