| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- --[[
- @module airlbs
- @summary airlbs 定位服务(收费服务,需自行联系销售申请)
- @version 1.1
- @date 2024.12.30
- @author Dozingfiretruck
- @usage
- -- lbsloc 是异步回调接口,
- -- lbsloc2 是是同步接口。
- -- lbsloc比lbsloc2多了一个请求地址文本的功能。
- -- lbsloc 和 lbsloc2 都是免费LBS定位的实现方式;
- -- airlbs 扩展库是收费 LBS 的实现方式。
- ]]
- sys = require("sys")
- sysplus = require("sysplus")
- libnet = require "libnet"
- local airlbs_host = "airlbs.openluat.com"
- local airlbs_port = 12413
- local lib_name = "airlbs"
- local lib_topic = lib_name .. "topic"
- local location_data = 0
- local disconnect = -1
- local airlbs_timeout = 15000
- local airlbs = {}
- local function airlbs_task(task_name, buff, timeout, adapter)
- local netc = socket.create(nil, lib_name)
- socket.config(netc, nil, true) -- udp
- sysplus.cleanMsg(lib_name)
- local result = libnet.connect(lib_name, 15000, netc, airlbs_host, airlbs_port)
- if result then
- log.info(lib_name, "服务器连上了")
- libnet.tx(lib_name, 0, netc, buff)
- else
- log.info(lib_name, "服务器没连上了!!!")
- sys.publish(lib_topic, disconnect)
- libnet.close(lib_name, 5000, netc)
- return
- end
- buff:del()
- while result do
- local succ, param = socket.rx(netc, buff)
- if not succ then
- log.error(lib_name, "服务器断开了", succ, param)
- sys.publish(lib_topic, disconnect)
- break
- end
- if buff:used() > 0 then
- local location = nil
- local data = buff:query(0, 1) -- 获取数据
- if data:toHex() == '00' then
- location = json.decode(buff:query(1))
- else
- log.error(lib_name, "not json data")
- end
- sys.publish(lib_topic, location_data, location)
- buff:del()
- break
- end
- result, param, param2 = libnet.wait(lib_name, timeout, netc)
- log.info(lib_name, "wait", result, param, param2)
- if param == false then
- log.error(lib_name, "服务器断开了", succ, param)
- sys.publish(lib_topic, disconnect)
- break
- end
- end
- libnet.close(lib_name, 5000, netc)
- end
- -- 处理未识别的网络消息
- local function netCB(msg)
- log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
- end
- --[[
- 获取定位数据
- @api airlbs.request(param)
- @param table 参数(联系销售获取id与key) project_id:项目ID project_key:项目密钥 timeout:超时时间,单位毫秒 默认15000 adapter: 网络适配器id,可选,默认是平台自带的网络协议栈
- @return bool 成功返回true,失败会返回false
- @return table 定位成功生效,成功返回定位数据
- @usage
- --注意:函数内因使用了sys.waitUntil阻塞接口,所以api需要在协程中使用
- --注意:使用前需同步时间
- local airlbs = require "airlbs"
- sys.taskInit(function()
- -- 等待网络就绪
- sys.waitUntil("IP_READY")
- -- 执行时间同步
- socket.sntp()
- sys.waitUntil("NTP_UPDATE", 10000)
- while 1 do
- -- airlbs请求定位
- local result ,data = airlbs.request({
- project_id = airlbs_project_id,
- project_key = airlbs_project_key,
- timeout = 10000,
- adapter = socket.LWIP_STA
- })
- if result then
- log.info("airlbs", json.encode(data))
- end
- sys.wait(20000)
- end
- end)
- ]]
- function airlbs.request(param)
- if not param or param.project_id == nil or param.project_key == nil then
- log.error(lib_name, "param error")
- return false
- end
- if not mobile and not param.wifi_info then
- log.error(lib_name, "no mobile and no wifi_info")
- return false
- end
- local udp_buff = zbuff.create(1500)
- local auth_type = 0x01
- local lbs_data_type = 0x00
- local project_id = param.project_id
- if project_id:len() ~= 6 then
- log.error("airlbs", "project_id len not 6")
- end
- local mac1 = netdrv.mac(socket.LWIP_STA)
- local mac = "MAC" .. mac1
- log.info("mac", mac)
- local timestamp = os.time()
- local project_key = param.project_key
- local nonce = crypto.trng(6)
- local hmac_data
- local bsp = rtos.bsp()
- log.info("硬件型号", rtos.bsp())
- if bsp == "Air8101" then
- -- 此处由于目前属于测试阶段,先将muid写死,后续会进行修改
- -- local muid = mcu.muid() or ""
- local muid = "12345678901234567890123456789012"
- log.info("muid", muid)
- hmac_data = crypto.hmac_sha1(project_id .. mac .. muid .. timestamp .. nonce, project_key)
- else
- local imei = mobile and mobile.imei() or ""
- local muid = mobile and mobile.muid() or ""
- hmac_data = crypto.hmac_sha1(project_id .. imei .. muid .. timestamp .. nonce, project_key)
- end
- -- log.debug(lib_name,"hmac_sha1", hmac_data)
- local lbs_data = {}
- if mobile then
- mobile.reqCellInfo(60)
- sys.waitUntil("CELL_INFO_UPDATE", param.timeout or airlbs_timeout)
- lbs_data.cells = {}
- -- log.info("cell", json.encode(mobile.getCellInfo()))
- for k, v in pairs(mobile.getCellInfo()) do
- lbs_data.cells[k] = {}
- lbs_data.cells[k][1] = v.mcc
- lbs_data.cells[k][2] = v.mnc
- lbs_data.cells[k][3] = v.tac
- lbs_data.cells[k][4] = v.cid
- lbs_data.cells[k][5] = v.rssi or v.rsrp
- lbs_data.cells[k][6] = v.snr
- lbs_data.cells[k][7] = v.pci
- lbs_data.cells[k][8] = v.rsrp
- lbs_data.cells[k][9] = v.rsrq
- lbs_data.cells[k][10] = v.earfcn
- end
- end
- if param.wifi_info and #param.wifi_info > 0 then
- lbs_data.macs = {}
- for k, v in pairs(param.wifi_info) do
- lbs_data.macs[k] = {}
- lbs_data.macs[k][1] = v.bssid:toHex():gsub("(%x%x)", "%1:"):sub(1, -2)
- lbs_data.macs[k][2] = v.rssi
- end
- end
- local lbs_jdata = json.encode(lbs_data)
- log.info("扫描出的数据",lbs_jdata)
- local bsp = rtos.bsp()
- if bsp == "Air8101" then
- -- 此处由于目前属于测试阶段,先将muid写死,后续会进行修改
- -- local muid = mcu.muid() or ""
- local muid = "12345678901234567890123456789012"
- udp_buff:write(string.char(auth_type) .. project_id .. mac .. muid .. timestamp .. nonce .. hmac_data:fromHex() .. string.char(lbs_data_type) .. lbs_jdata)
- else
- local imei = mobile and mobile.imei() or ""
- local muid = mobile and mobile.muid() or ""
- udp_buff:write(string.char(auth_type) .. project_id .. imei .. muid .. timestamp .. nonce .. hmac_data:fromHex() .. string.char(lbs_data_type) .. lbs_jdata)
- end
- sysplus.taskInitEx(airlbs_task, lib_name, netCB, lib_name, udp_buff, param.timeout or airlbs_timeout, param.adapter)
- while 1 do
- local result, tp, data = sys.waitUntil(lib_topic, param.timeout or airlbs_timeout)
- log.info("定位请求的结果", result, "超时时间", tp, data)
- if not result then
- return false, "timeout"
- elseif tp == location_data then
- if not data then
- log.error(lib_name, "无数据, 请检查project_id和project_key")
- return false
- -- data.result 0-找不到 1-成功 2-qps超限 3-欠费 4-其他错误
- elseif data.result == 0 then
- log.error(lib_name, "no location(基站定位服务器查询当前地址失败)")
- return false
- elseif data.result == 1 then
- log.info("多基站请求成功,服务器返回的原始数据", data)
- return true, {
- lng = data.lng,
- lat = data.lat
- }
- elseif data.result == 2 then
- log.error(lib_name, "qps limit(当前请求已到达限制,请检查当前请求是否过于频繁))")
- return false
- elseif data.result == 3 then
- log.error(lib_name, "当前设备已欠费,请联系销售充值")
- return false
- elseif data.result == 4 then
- log.error(lib_name, "other error")
- return false
- else
- log.error("其他错误,错误码", data.result, lib_name)
- end
- else
- log.error(lib_name, "net error")
- return false
- end
- end
- end
- return airlbs
|