10 -- 1. 因使用了sys.wait()所有api需要在协程中使用
11 -- 2. 仅支持单基站定位, 即当前联网的基站
13 sys.taskInit(function()
14 sys.waitUntil("IP_READY", 30000)
15 -- mobile.reqCellInfo(60)
17 while mobile do -- 没有mobile库就没有基站定位
18 mobile.reqCellInfo(15)
19 sys.waitUntil("CELL_INFO_UPDATE", 3000)
20 local lat, lng, t = lbsLoc2.request(5000)
21 -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
22 log.info("lbsLoc2", lat, lng, (json.encode(t or {})))
28 local sys
= require
"sys"
32 local function numToBcdNum(inStr
,destLen
)
33 local l
,t
,num
= string.len(inStr
or ""),{}
34 destLen
= destLen
or (inStr
:len()+1)/2
36 num
= tonumber(inStr
:sub(i
,i
+1),16)
40 num
= (num
%0x10)*0x10 + (num
-(num
%0x10))/0x10
45 local s
= string.char(unpack(t
))
49 s
= s
.. string.rep("\255",destLen
-l
)
50 elseif l
> destLen
then
51 s
= string.sub(s
,1,destLen
)
57 --- BCD编码格式字符串 转化为 号码ASCII字符串(仅支持数字)
59 -- @return string data,转换后的字符串
61 local function bcdNumToNum(num
)
67 v1
,v2
= bit
.band(byte
,0x0f),bit
.band(bit
.rshift(byte
,4),0x0f)
69 if v1
== 0x0f then break end
72 if v2
== 0x0f then break end
76 return table.concat(t
)
79 lbsLoc2
.imei
= numToBcdNum(mobile
.imei())
81 local function enCellInfo(s
)
82 -- 改造成单基站, 反正服务器也只认单基站
84 log.info("cell", json
.encode(v
))
85 local ret
= pack
.pack(">HHbbi",v
.tac
,v
.mcc
,v
.mnc
,31,v
.cid
)
86 return string.char(1)..ret
89 local function trans(str
)
92 s
= str
..string.rep("0",10-str
:len())
95 return s
:sub(1,3).."."..s
:sub(4,10)
100 @api lbsLoc2.request(timeout, host, port, reqTime)
101 @number 请求超时时间,单位毫秒,默认15000
102 @number 服务器地址,有默认值,可以是域名,一般不需要填
103 @number 服务器端口,默认12411,一般不需要填
105 @return string 若成功,返回定位坐标的纬度,否则会返还nil
106 @return string 若成功,返回定位坐标的精度,否则会返还nil
107 @return table 服务器时间,东八区时间. 当reqTime为true且定位成功才会返回
110 -- 部分情况下会返回GCJ02坐标系, 部分情况返回的是WGS84坐标
112 -- 鉴于两种坐标系之间的误差并不大,小于基站定位本身的误差, 纠偏的意义不大
113 sys.taskInit(function()
114 sys.waitUntil("IP_READY", 30000)
115 -- mobile.reqCellInfo(60)
117 while mobile do -- 没有mobile库就没有基站定位
118 mobile.reqCellInfo(15)
119 sys.waitUntil("CELL_INFO_UPDATE", 3000)
120 local lat, lng, t = lbsLoc2.request(5000)
121 -- local lat, lng, t = lbsLoc2.request(5000, "bs.openluat.com")
122 log.info("lbsLoc2", lat, lng, (json.encode(t or {})))
127 function lbsLoc2
.request(timeout
, host
, port
, reqTime
)
128 if mobile
.status() == 0 then
131 local hosts
= host
and {host
} or {"free.bs.air32.cn", "bs.openluat.com"}
132 port
= port
and tonumber(port
) or 12411
133 local sc
= socket
.create(nil, function(sc
, event
)
134 -- log.info("lbsLoc", "event", event, socket.ON_LINE, socket.TX_OK, socket.EVENT)
135 if event
== socket
.ON_LINE
then
136 --log.info("lbsLoc", "已连接")
137 sys
.publish("LBS_CONACK")
138 elseif event
== socket
.TX_OK
then
139 --log.info("lbsLoc", "发送完成")
140 sys
.publish("LBS_TX")
141 elseif event
== socket
.EVENT
then
142 --log.info("lbsLoc", "有数据来")
143 sys
.publish("LBS_RX")
149 -- socket.debug(sc, true)
150 socket
.config(sc
, nil, true)
151 local rxbuff
= zbuff
.create(64)
152 for k
, rhost
in pairs(hosts
) do
153 local reqStr
= string.char(0, (reqTime
and 4 or 0) +8) .. lbsLoc2
.imei
156 local scell
= mobile
.scell()
157 if scell
and scell
.mcc
then
158 -- log.debug("lbsLoc2", "使用当前驻网基站的信息")
159 tmp
= pack
.pack(">bHHbbi", 1, scell
.tac
, scell
.mcc
, scell
.mnc
, 31, scell
.eci
)
163 local cells
= mobile
.getCellInfo()
164 if cells
== nil or #cells
== 0 then
168 reqStr
= reqStr
.. enCellInfo(cells
)
170 reqStr
= reqStr
.. tmp
172 -- log.debug("lbsLoc2", "待发送数据", (reqStr:toHex()))
173 log.debug("lbsLoc2", rhost
, port
)
174 if socket
.connect(sc
, rhost
, port
) and sys
.waitUntil("LBS_CONACK", 1000) then
175 if socket
.tx(sc
, reqStr
) and sys
.waitUntil("LBS_TX", 1000) then
177 if sys
.waitUntil("LBS_RX", timeout
or 15000) then
178 local succ
, data_len
= socket
.rx(sc
, rxbuff
)
179 -- log.debug("lbsLoc", "rx", succ, data_len)
180 if succ
and data_len
> 0 then
184 log.debug("lbsLoc", "rx数据失败", rhost
)
187 log.debug("lbsLoc", "等待数据超时", rhost
)
190 log.debug("lbsLoc", "tx调用失败或TX_ACK超时", rhost
)
193 log.debug("lbsLoc", "connect调用失败或CONACK超时", rhost
)
200 if rxbuff
:used() > 0 then
201 local resp
= rxbuff
:toStr(0, rxbuff
:used())
202 log.debug("lbsLoc2", "rx", (resp
:toHex()))
203 if resp
:len() >= 11 and(resp
:byte(1) == 0 or resp
:byte(1) == 0xFF) then
204 local lat
= trans(bcdNumToNum(resp
:sub(2, 6)))
205 local lng
= trans(bcdNumToNum(resp
:sub(7, 11)))
207 if resp
:len() >= 17 then
209 year
=resp
:byte(12) + 2000,