工程提交
This commit is contained in:
229
4G/tools/resource/soc_script/v2025.12.31.22/lib/lbsLoc2.lua
Normal file
229
4G/tools/resource/soc_script/v2025.12.31.22/lib/lbsLoc2.lua
Normal file
@@ -0,0 +1,229 @@
|
||||
--[[
|
||||
@module lbsLoc2
|
||||
@summary 基站定位v2
|
||||
@version 1.0
|
||||
@date 2023.5.23
|
||||
@author wendal
|
||||
@demo lbsLoc2
|
||||
@usage
|
||||
-- lbsloc 是异步回调接口,
|
||||
-- lbsloc2 是是同步接口。
|
||||
-- lbsloc比lbsloc2多了一个请求地址文本的功能。
|
||||
-- lbsloc 和 lbsloc2 都是免费LBS定位的实现方式;
|
||||
-- airlbs 扩展库是收费 LBS 的实现方式。
|
||||
|
||||
-- 注意:
|
||||
-- 1. 因使用了sys.wait()所有api需要在协程中使用
|
||||
-- 2. 仅支持单基站定位, 即当前联网的基站
|
||||
-- 3. 本服务当前处于测试状态
|
||||
sys.taskInit(function()
|
||||
sys.waitUntil("IP_READY", 30000)
|
||||
-- mobile.reqCellInfo(60)
|
||||
-- sys.wait(1000)
|
||||
while mobile do -- 没有mobile库就没有基站定位
|
||||
mobile.reqCellInfo(15)
|
||||
sys.waitUntil("CELL_INFO_UPDATE", 3000)
|
||||
local lat, lng, t = lbsLoc2.request(5000)
|
||||
-- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
|
||||
log.info("lbsLoc2", lat, lng, (json.encode(t or {})))
|
||||
sys.wait(60000)
|
||||
end
|
||||
end)
|
||||
]]
|
||||
|
||||
local sys = require "sys"
|
||||
|
||||
local lbsLoc2 = {}
|
||||
|
||||
local function numToBcdNum(inStr,destLen)
|
||||
local l,t,num = string.len(inStr or ""),{}
|
||||
destLen = destLen or (inStr:len()+1)/2
|
||||
for i=1,l,2 do
|
||||
num = tonumber(inStr:sub(i,i+1),16)
|
||||
if i==l then
|
||||
num = 0xf0+num
|
||||
else
|
||||
num = (num%0x10)*0x10 + (num-(num%0x10))/0x10
|
||||
end
|
||||
table.insert(t,num)
|
||||
end
|
||||
|
||||
local s = string.char(unpack(t))
|
||||
|
||||
l = string.len(s)
|
||||
if l < destLen then
|
||||
s = s .. string.rep("\255",destLen-l)
|
||||
elseif l > destLen then
|
||||
s = string.sub(s,1,destLen)
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
--- BCD编码格式字符串 转化为 号码ASCII字符串(仅支持数字)
|
||||
-- @string num 待转换字符串
|
||||
-- @return string data,转换后的字符串
|
||||
-- @usage
|
||||
local function bcdNumToNum(num)
|
||||
local byte,v1,v2
|
||||
local t = {}
|
||||
|
||||
for i=1,num:len() do
|
||||
byte = num:byte(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
|
||||
|
||||
lbsLoc2.imei = numToBcdNum(mobile.imei())
|
||||
|
||||
local function enCellInfo(s)
|
||||
-- 改造成单基站, 反正服务器也只认单基站
|
||||
local v = s[1]
|
||||
log.info("cell", json.encode(v))
|
||||
local ret = pack.pack(">HHbbi",v.tac,v.mcc,v.mnc,31,v.cid)
|
||||
return string.char(1)..ret
|
||||
end
|
||||
|
||||
local function trans(str)
|
||||
local s = str
|
||||
if str:len()<10 then
|
||||
s = str..string.rep("0",10-str:len())
|
||||
end
|
||||
|
||||
return s:sub(1,3).."."..s:sub(4,10)
|
||||
end
|
||||
|
||||
--[[
|
||||
执行定位请求
|
||||
@api lbsLoc2.request(timeout, host, port, reqTime)
|
||||
@number 请求超时时间,单位毫秒,默认15000
|
||||
@number 服务器地址,有默认值,可以是域名,一般不需要填
|
||||
@number 服务器端口,默认12411,一般不需要填
|
||||
@bool 是否要求返回服务器时间
|
||||
@return string 若成功,返回定位坐标的纬度,否则会返还nil
|
||||
@return string 若成功,返回定位坐标的经度,否则会返还nil
|
||||
@return table 服务器时间,东八区时间. 当reqTime为true且定位成功才会返回
|
||||
@usage
|
||||
-- 关于坐标系
|
||||
-- 部分情况下会返回GCJ02坐标系, 部分情况返回的是WGS84坐标
|
||||
-- 历史数据已经无法分辨具体坐标系
|
||||
-- 鉴于两种坐标系之间的误差并不大,小于基站定位本身的误差, 纠偏的意义不大
|
||||
sys.taskInit(function()
|
||||
sys.waitUntil("IP_READY", 30000)
|
||||
-- mobile.reqCellInfo(60)
|
||||
-- sys.wait(1000)
|
||||
while mobile do -- 没有mobile库就没有基站定位
|
||||
mobile.reqCellInfo(15)
|
||||
sys.waitUntil("CELL_INFO_UPDATE", 3000)
|
||||
local lat, lng, t = lbsLoc2.request(5000)
|
||||
-- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
|
||||
log.info("lbsLoc2", lat, lng, (json.encode(t or {})))
|
||||
sys.wait(60000)
|
||||
end
|
||||
end)
|
||||
]]
|
||||
function lbsLoc2.request(timeout, host, port, reqTime)
|
||||
if mobile.status() == 0 then
|
||||
return
|
||||
end
|
||||
local hosts = host and {host} or {"free.bs.air32.cn", "bs.openluat.com"}
|
||||
port = port and tonumber(port) or 12411
|
||||
local sc = socket.create(nil, function(sc, event)
|
||||
-- log.info("lbsLoc", "event", event, socket.ON_LINE, socket.TX_OK, socket.EVENT)
|
||||
if event == socket.ON_LINE then
|
||||
--log.info("lbsLoc", "已连接")
|
||||
sys.publish("LBS_CONACK")
|
||||
elseif event == socket.TX_OK then
|
||||
--log.info("lbsLoc", "发送完成")
|
||||
sys.publish("LBS_TX")
|
||||
elseif event == socket.EVENT then
|
||||
--log.info("lbsLoc", "有数据来")
|
||||
sys.publish("LBS_RX")
|
||||
end
|
||||
end)
|
||||
if sc == nil then
|
||||
return
|
||||
end
|
||||
-- socket.debug(sc, true)
|
||||
socket.config(sc, nil, true)
|
||||
local rxbuff = zbuff.create(64)
|
||||
for k, rhost in pairs(hosts) do
|
||||
local reqStr = string.char(0, (reqTime and 4 or 0) +8) .. lbsLoc2.imei
|
||||
local tmp = nil
|
||||
if mobile.scell then
|
||||
local scell = mobile.scell()
|
||||
if scell and scell.mcc then
|
||||
-- log.debug("lbsLoc2", "使用当前驻网基站的信息")
|
||||
tmp = pack.pack(">bHHbbi", 1, scell.tac, scell.mcc, scell.mnc, 31, scell.eci)
|
||||
end
|
||||
end
|
||||
if tmp == nil then
|
||||
local cells = mobile.getCellInfo()
|
||||
if cells == nil or #cells == 0 then
|
||||
socket.release(sc)
|
||||
return
|
||||
end
|
||||
reqStr = reqStr .. enCellInfo(cells)
|
||||
else
|
||||
reqStr = reqStr .. tmp
|
||||
end
|
||||
-- log.debug("lbsLoc2", "待发送数据", (reqStr:toHex()))
|
||||
log.debug("lbsLoc2", rhost, port)
|
||||
if socket.connect(sc, rhost, port) and sys.waitUntil("LBS_CONACK", 1000) then
|
||||
if socket.tx(sc, reqStr) and sys.waitUntil("LBS_TX", 1000) then
|
||||
socket.wait(sc)
|
||||
if sys.waitUntil("LBS_RX", timeout or 15000) then
|
||||
local succ, data_len = socket.rx(sc, rxbuff)
|
||||
-- log.debug("lbsLoc", "rx", succ, data_len)
|
||||
if succ and data_len > 0 then
|
||||
socket.close(sc)
|
||||
break
|
||||
else
|
||||
log.debug("lbsLoc", "rx数据失败", rhost)
|
||||
end
|
||||
else
|
||||
log.debug("lbsLoc", "等待数据超时", rhost)
|
||||
end
|
||||
else
|
||||
log.debug("lbsLoc", "tx调用失败或TX_ACK超时", rhost)
|
||||
end
|
||||
else
|
||||
log.debug("lbsLoc", "connect调用失败或CONACK超时", rhost)
|
||||
end
|
||||
socket.close(sc)
|
||||
--sys.wait(100)
|
||||
end
|
||||
sys.wait(100)
|
||||
socket.release(sc)
|
||||
if rxbuff:used() > 0 then
|
||||
local resp = rxbuff:toStr(0, rxbuff:used())
|
||||
log.debug("lbsLoc2", "rx", (resp:toHex()))
|
||||
if resp:len() >= 11 and(resp:byte(1) == 0 or resp:byte(1) == 0xFF) then
|
||||
local lat = trans(bcdNumToNum(resp:sub(2, 6)))
|
||||
local lng = trans(bcdNumToNum(resp:sub(7, 11)))
|
||||
local t = nil
|
||||
if resp:len() >= 17 then
|
||||
t = {
|
||||
year=resp:byte(12) + 2000,
|
||||
month=resp:byte(13),
|
||||
day=resp:byte(14),
|
||||
hour=resp:byte(15),
|
||||
min=resp:byte(16),
|
||||
sec=resp:byte(17),
|
||||
}
|
||||
end
|
||||
return lat, lng, t
|
||||
end
|
||||
end
|
||||
rxbuff:del()
|
||||
end
|
||||
|
||||
return lbsLoc2
|
||||
Reference in New Issue
Block a user