最终提交
This commit is contained in:
787
4G/源代码/lib/net.lua
Normal file
787
4G/源代码/lib/net.lua
Normal file
@@ -0,0 +1,787 @@
|
||||
---模块功能:网络管理、信号查询、GSM网络状态查询、网络指示灯控制、临近小区信息查询
|
||||
-- @module net
|
||||
-- @author openLuat
|
||||
-- @license MIT
|
||||
-- @copyright openLuat
|
||||
-- @release 2017.02.17
|
||||
|
||||
require "sys"
|
||||
require "ril"
|
||||
require "pio"
|
||||
require "sim"
|
||||
require "log"
|
||||
require "utils"
|
||||
module(..., package.seeall)
|
||||
|
||||
--加载常用的全局函数至本地
|
||||
local publish = sys.publish
|
||||
|
||||
--netmode define
|
||||
NetMode_noNet= 0
|
||||
NetMode_GSM= 1--2G
|
||||
NetMode_EDGE= 2--2.5G
|
||||
NetMode_TD= 3--3G
|
||||
NetMode_LTE= 4--4G
|
||||
NetMode_WCDMA= 5--3G
|
||||
local netMode = NetMode_noNet
|
||||
|
||||
--网络状态:
|
||||
--INIT:开机初始化中的状态
|
||||
--REGISTERED:注册上GSM网络
|
||||
--UNREGISTER:未注册上GSM网络
|
||||
local state = "INIT"
|
||||
--SIM卡状态:true为异常,false或者nil为正常
|
||||
local simerrsta
|
||||
-- 飞行模式状态
|
||||
flyMode = false
|
||||
|
||||
--lac:位置区ID
|
||||
--ci:小区ID
|
||||
--rssi:信号强度
|
||||
--rsrp:信号接收功率
|
||||
local lac, ci, rssi, rsrp, band = "", "", 0, 0, ""
|
||||
|
||||
--cellinfo:当前小区和临近小区信息表
|
||||
--multicellcb:获取多小区的回调函数
|
||||
local cellinfo, multicellcb = {}
|
||||
local curCellSeted
|
||||
|
||||
local function cops(data)
|
||||
--+COPS: 0,2,"46000",7
|
||||
local fmt,oper = data:match('COPS:%s*%d+%s*,(%d+)%s*,"(%d+)"')
|
||||
log.info("cops",fmt,oper,curCellSeted)
|
||||
if fmt=="2" and not curCellSeted then
|
||||
cellinfo[1].mcc = tonumber(oper:sub(1,3),16)
|
||||
cellinfo[1].mnc = tonumber(oper:sub(4,5),16)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:creg
|
||||
功能 :解析CREG信息
|
||||
参数 :data:CREG信息字符串,例如+CREG: 2、+CREG: 1,"18be","93e1"、+CREG: 5,"18a7","cb51"
|
||||
返回值:无
|
||||
]]
|
||||
local function creg(data)
|
||||
local p1, s,act
|
||||
local prefix = (netMode == NetMode_LTE) and "+CEREG: " or (netMode == NetMode_noNet and "+CREG: " or "+CGREG: ")
|
||||
log.info("net.creg1",netMode,prefix)
|
||||
if not data:match(prefix) then
|
||||
--log.info("net.creg2",prefix)
|
||||
if prefix=="+CREG: " then
|
||||
--log.info("net.creg3")
|
||||
prefix = "+CGREG: "
|
||||
if not data:match("+CGREG: ") then
|
||||
log.warn("net.creg1","no match",data)
|
||||
return
|
||||
end
|
||||
elseif prefix=="+CGREG: " then
|
||||
--log.info("net.creg4")
|
||||
prefix = "+CREG: "
|
||||
if not data:match("+CREG: ") then
|
||||
log.warn("net.creg2","no match",data)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
--获取注册状态
|
||||
_, _, p1 = data:find(prefix .. "%d,(%d+)")
|
||||
--log.info("net.creg5",p1 == nil)
|
||||
if p1 == nil then
|
||||
_, _, p1 = data:find(prefix .. "(%d+)")
|
||||
--log.info("net.creg6",p1 == nil)
|
||||
if p1 == nil then return end
|
||||
act = data:match(prefix .. "%d+,.-,.-,(%d+)")
|
||||
else
|
||||
act = data:match(prefix .. "%d,%d+,.-,.-,(%d+)")
|
||||
end
|
||||
|
||||
log.info("net.creg7",p1,act)
|
||||
|
||||
--设置注册状态
|
||||
s = (p1=="1" or p1=="5") and "REGISTERED" or "UNREGISTER"
|
||||
|
||||
--log.info("net.creg8",s,state)
|
||||
if prefix=="+CGREG: " and s=="UNREGISTER" then
|
||||
log.info("net.creg9 ignore!!!")
|
||||
return
|
||||
end
|
||||
--注册状态发生了改变
|
||||
if s ~= state then
|
||||
--临近小区查询处理
|
||||
if s == "REGISTERED" then
|
||||
--产生一个内部消息NET_STATE_CHANGED,表示GSM网络注册状态发生变化
|
||||
publish("NET_STATE_REGISTERED")
|
||||
cengQueryPoll()
|
||||
end
|
||||
state = s
|
||||
end
|
||||
--已注册并且lac或ci发生了变化
|
||||
if state == "REGISTERED" then
|
||||
p2, p3 = data:match("\"(%x+)\",\"(%x+)\"")
|
||||
if p2 and p3 and (lac ~= p2 or ci ~= p3) then
|
||||
lac = p2
|
||||
ci = p3
|
||||
--产生一个内部消息NET_CELL_CHANGED,表示lac或ci发生了变化
|
||||
publish("NET_CELL_CHANGED")
|
||||
--cellinfo[1].mcc = tonumber(sim.getMcc(),16)
|
||||
--cellinfo[1].mnc = tonumber(sim.getMnc(),16)
|
||||
cellinfo[1].lac = tonumber(lac,16)
|
||||
cellinfo[1].ci = tonumber(ci,16)
|
||||
cellinfo[1].rssi = 28
|
||||
end
|
||||
|
||||
if act then
|
||||
if act=="0" then
|
||||
UpdNetMode("^MODE: 3,1")
|
||||
elseif act=="1" then
|
||||
UpdNetMode("^MODE: 3,2")
|
||||
elseif act=="3" then
|
||||
UpdNetMode("^MODE: 3,3")
|
||||
elseif act=="7" then
|
||||
UpdNetMode("^MODE: 17,17")
|
||||
else
|
||||
UpdNetMode("^MODE: 5,7")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:resetcellinfo
|
||||
功能 :重置当前小区和临近小区信息表
|
||||
参数 :无
|
||||
返回值:无
|
||||
]]
|
||||
local function resetCellInfo()
|
||||
local i
|
||||
cellinfo.cnt = 11 --最大个数
|
||||
for i = 1, cellinfo.cnt do
|
||||
cellinfo[i] = {}
|
||||
cellinfo[i].mcc, cellinfo[i].mnc = nil
|
||||
cellinfo[i].lac = 0
|
||||
cellinfo[i].ci = 0
|
||||
cellinfo[i].rssi = 0
|
||||
cellinfo[i].ta = 0
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:eemMgInfoSvc
|
||||
功能 :解析4G网络,当前小区和临近小区信息
|
||||
参数 :
|
||||
data:当前小区和临近小区信息字符串,例如下面中的每一行:
|
||||
+EEMLTESVC:xx,xx,...
|
||||
返回值:无
|
||||
]]
|
||||
local function eemLteSvc(data)
|
||||
local mcc,mnc,lac,ci,rssi,svcData
|
||||
if data:match("%+EEMLTESVC:%s*%d+,%s*%d+,%s*%d+,%s*.+") then
|
||||
svcData = string.match(data, "%+EEMLTESVC:(.+)")
|
||||
--log.info("eemLteSvc",svcData)
|
||||
if svcData then
|
||||
svcDataT = string.split(svcData, ', ')
|
||||
--log.info("eemLteSvc1",svcDataT[1],svcDataT[3],svcDataT[4],svcDataT[10],svcDataT[15])
|
||||
if not(svcDataT[1] and svcDataT[3] and svcDataT[4] and svcDataT[10] and svcDataT[15]) then
|
||||
svcDataT = string.split(svcData, ',')
|
||||
log.info("eemLteSvc2",svcDataT[1],svcDataT[3],svcDataT[4],svcDataT[10],svcDataT[15])
|
||||
end
|
||||
mcc = svcDataT[1]
|
||||
mnc = svcDataT[3]
|
||||
lac = svcDataT[4]
|
||||
ci = svcDataT[10]
|
||||
band = svcDataT[8]
|
||||
rssi = (tonumber(svcDataT[15])-(tonumber(svcDataT[15])%3))/3
|
||||
if rssi>31 then rssi=31 end
|
||||
if rssi<0 then rssi=0 end
|
||||
end
|
||||
log.info("eemLteSvc1",lac,ci,mcc,mnc)
|
||||
if lac and lac~="0" and ci and ci ~= "0" and mcc and mnc then
|
||||
--如果是第一条,清除信息表
|
||||
resetCellInfo()
|
||||
curCellSeted = true
|
||||
--保存mcc、mnc、lac、ci、rssi、ta
|
||||
cellinfo[1].mcc = mcc
|
||||
cellinfo[1].mnc = mnc
|
||||
cellinfo[1].lac = tonumber(lac)
|
||||
cellinfo[1].ci = tonumber(ci)
|
||||
cellinfo[1].rssi = tonumber(rssi)
|
||||
--cellinfo[id + 1].ta = tonumber(ta or "0")
|
||||
--产生一个内部消息CELL_INFO_IND,表示读取到了新的当前小区和临近小区信息
|
||||
if multicellcb then multicellcb(cellinfo) end
|
||||
publish("CELL_INFO_IND", cellinfo)
|
||||
end
|
||||
elseif data:match("%+EEMLTEINTER") or data:match("%+EEMLTEINTRA") or data:match("%+EEMLTEINTERRAT") then
|
||||
--data = "+EEMLTEINTRA: 0, 98, 39148, 51, 21, 1120, 0, 6311, 25418539"
|
||||
--data = "+EEMLTEINTERRAT:0,16,1120,0,6213,26862,627,1,-77"
|
||||
data = data:gsub(" ","")
|
||||
|
||||
if data:match("%+EEMLTEINTERRAT") then
|
||||
mcc,mnc,lac,ci,rssi = data:match("[-]*%d+,[-]*%d+,([-]*%d+),([-]*%d+),([-]*%d+),([-]*%d+),[-]*%d+,[-]*%d+,([-]*%d+)")
|
||||
else
|
||||
rssi,mcc,mnc,lac,ci = data:match("[-]*%d+,[-]*%d+,[-]*%d+,([-]*%d+),[-]*%d+,([-]*%d+),([-]*%d+),([-]*%d+),([-]*%d+)")
|
||||
end
|
||||
|
||||
--print(mcc,mnc,lac,ci,rssi)
|
||||
|
||||
if rssi then
|
||||
rssi = (rssi-(rssi%3))/3
|
||||
if rssi>31 then rssi=31 end
|
||||
if rssi<0 then rssi=0 end
|
||||
end
|
||||
if lac~="0" and lac~="-1" and ci~="0" and ci~="-1" then
|
||||
for i = 1, cellinfo.cnt do
|
||||
--print("cellinfo["..i.."].lac="..cellinfo[i].lac)
|
||||
if cellinfo[i].lac==0 then
|
||||
cellinfo[i] =
|
||||
{
|
||||
mcc = mcc,
|
||||
mnc = mnc,
|
||||
lac = tonumber(lac),
|
||||
ci = tonumber(ci),
|
||||
rssi = tonumber(rssi)
|
||||
}
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
函数名:eemMgInfoSvc
|
||||
功能 :解析2G网络,当前小区
|
||||
参数 :
|
||||
data:当前小区信息字符串,例如下面中的每一行:
|
||||
+EEMGINFOSVC:xx,xx,...
|
||||
返回值:无
|
||||
]]
|
||||
local function eemGsmInfoSvc(data)
|
||||
--只处理有效的CENG信息
|
||||
if string.find(data, "%+EEMGINFOSVC:%s*%d+,%s*%d+,%s*%d+,%s*.+") then
|
||||
local mcc,mnc,lac,ci,ta,rssi
|
||||
local svcData = string.match(data, "%+EEMGINFOSVC:(.+)")
|
||||
if svcData then
|
||||
svcDataT = string.split(svcData, ', ')
|
||||
mcc = svcDataT[1]
|
||||
mnc = svcDataT[2]
|
||||
lac = svcDataT[3]
|
||||
ci = svcDataT[4]
|
||||
ta = svcDataT[10]
|
||||
rssi = svcDataT[12]
|
||||
if tonumber(rssi) >31
|
||||
then rssi = 31
|
||||
end
|
||||
if tonumber(rssi) < 0
|
||||
then rssi = 0
|
||||
end
|
||||
end
|
||||
if lac and lac~="0" and ci and ci ~= "0" and mcc and mnc then
|
||||
--如果是第一条,清除信息表
|
||||
resetCellInfo()
|
||||
curCellSeted = true
|
||||
--保存mcc、mnc、lac、ci、rssi、ta
|
||||
cellinfo[1].mcc = mcc
|
||||
cellinfo[1].mnc = mnc
|
||||
cellinfo[1].lac = tonumber(lac)
|
||||
cellinfo[1].ci = tonumber(ci)
|
||||
cellinfo[1].rssi = (tonumber(rssi) == 99) and 0 or tonumber(rssi)
|
||||
cellinfo[1].ta = tonumber(ta or "0")
|
||||
--产生一个内部消息CELL_INFO_IND,表示读取到了新的当前小区和临近小区信息
|
||||
if multicellcb then multicellcb(cellinfo) end
|
||||
publish("CELL_INFO_IND", cellinfo)
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
函数名:eemMgInfoSvc
|
||||
功能 :解析2G网络,临近小区信息
|
||||
参数 :
|
||||
data:当前小区和临近小区信息字符串,例如下面中的每一行:
|
||||
+EEMGINFOSVC:xx,xx,...
|
||||
返回值:无
|
||||
]]
|
||||
local function eemGsmNCInfoSvc(data)
|
||||
if string.find(data, "%+EEMGINFONC: %d+, %d+, %d+, .+") then
|
||||
local mcc,mnc,lac,ci,ta,rssi,id
|
||||
local svcData = string.match(data, "%+EEMGINFONC:(.+)")
|
||||
if svcData then
|
||||
svcDataT = string.split(svcData, ', ')
|
||||
id = svcDataT[1]
|
||||
mcc = svcDataT[2]
|
||||
mnc = svcDataT[3]
|
||||
lac = svcDataT[4]
|
||||
ci = svcDataT[6]
|
||||
rssi = svcDataT[7]
|
||||
if tonumber(rssi) >31
|
||||
then rssi = 31
|
||||
end
|
||||
if tonumber(rssi) < 0
|
||||
then rssi = 0
|
||||
end
|
||||
end
|
||||
if lac and ci and mcc and mnc then
|
||||
--保存mcc、mnc、lac、ci、rssi、ta
|
||||
cellinfo[id + 2].mcc = mcc
|
||||
cellinfo[id + 2].mnc = mnc
|
||||
cellinfo[id + 2].lac = tonumber(lac)
|
||||
cellinfo[id + 2].ci = tonumber(ci)
|
||||
cellinfo[id + 2].rssi = (tonumber(rssi) == 99) and 0 or tonumber(rssi)
|
||||
--cellinfo[id + 1].ta = tonumber(ta or "0")
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
函数名:eemMgInfoSvc
|
||||
功能 :解析3G网络,当前小区和临近小区信息
|
||||
参数 :
|
||||
data:当前小区和临近小区信息字符串,例如下面中的每一行:
|
||||
+EEMUMTSSVC:xx,xx,...
|
||||
返回值:无
|
||||
]]
|
||||
local function eemUMTSInfoSvc(data)
|
||||
--只处理有效的CENG信息
|
||||
if string.find(data, "%+EEMUMTSSVC: %d+, %d+, %d+, .+") then
|
||||
local mcc,mnc,lac,ci,rssi
|
||||
local svcData = string.match(data, "%+EEMUMTSSVC:(.+)")
|
||||
local cellMeasureFlag, cellParamFlag = string.match(data, "%+EEMUMTSSVC:%d+, (%d+), (%d+), .+")
|
||||
local svcDataT = string.split(svcData, ', ')
|
||||
local offset = 4
|
||||
if svcData and svcDataT then
|
||||
if tonumber(cellMeasureFlag) ~= 0 then
|
||||
offset = offset + 2
|
||||
rssi = svcDataT[offset]
|
||||
offset = offset + 4
|
||||
else
|
||||
offset = offset + 2
|
||||
rssi = svcDataT[offset]
|
||||
offset = offset + 2
|
||||
end
|
||||
|
||||
if tonumber(cellParamFlag) ~= 0 then
|
||||
offset = offset + 3
|
||||
mcc = svcDataT[offset]
|
||||
mnc = svcDataT[offset + 1]
|
||||
lac = svcDataT[offset + 2]
|
||||
ci = svcDataT[offset + 3]
|
||||
offset = offset + 3
|
||||
end
|
||||
end
|
||||
if lac and lac~="0" and ci and ci ~= "0" and mcc and mnc and rssi then
|
||||
--如果是第一条,清除信息表
|
||||
resetCellInfo()
|
||||
curCellSeted = true
|
||||
--保存mcc、mnc、lac、ci、rssi、ta
|
||||
cellinfo[1].mcc = mcc
|
||||
cellinfo[1].mnc = mnc
|
||||
cellinfo[1].lac = tonumber(lac)
|
||||
cellinfo[1].ci = tonumber(ci)
|
||||
cellinfo[1].rssi = tonumber(rssi)
|
||||
--产生一个内部消息CELL_INFO_IND,表示读取到了新的当前小区和临近小区信息
|
||||
if multicellcb then multicellcb(cellinfo) end
|
||||
publish("CELL_INFO_IND", cellinfo)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:UpdNetMode
|
||||
功能 :解析NetMode
|
||||
参数 :data:NetMode信息字符串,例如"^MODE: 17,17"
|
||||
返回值:无
|
||||
]]
|
||||
function UpdNetMode(data)
|
||||
local _, _, SysMainMode,SysMode = string.find(data, "(%d+),(%d+)")
|
||||
local netMode_cur
|
||||
log.info("net.UpdNetMode",netMode_cur,netMode, SysMainMode,SysMode)
|
||||
if SysMainMode and SysMode then
|
||||
if SysMainMode=="3" then
|
||||
netMode_cur = NetMode_GSM
|
||||
elseif SysMainMode=="5" then
|
||||
netMode_cur = NetMode_WCDMA
|
||||
elseif SysMainMode=="15" then
|
||||
netMode_cur = NetMode_TD
|
||||
elseif SysMainMode=="17" then
|
||||
netMode_cur = NetMode_LTE
|
||||
else
|
||||
netMode_cur = NetMode_noNet
|
||||
end
|
||||
|
||||
if SysMode=="3" then
|
||||
netMode_cur = NetMode_EDGE
|
||||
end
|
||||
end
|
||||
|
||||
if netMode ~= netMode_cur then
|
||||
netMode = netMode_cur
|
||||
publish("NET_UPD_NET_MODE",netMode)
|
||||
log.info("net.NET_UPD_NET_MODE",netMode)
|
||||
ril.request("AT+COPS?")
|
||||
if netMode == NetMode_LTE then
|
||||
ril.request("AT+CEREG?")
|
||||
elseif netMode == NetMode_noNet then
|
||||
ril.request("AT+CREG?")
|
||||
else
|
||||
ril.request("AT+CGREG?")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:neturc
|
||||
功能 :本功能模块内“注册的底层core通过虚拟串口主动上报的通知”的处理
|
||||
参数 :
|
||||
data:通知的完整字符串信息
|
||||
prefix:通知的前缀
|
||||
返回值:无
|
||||
]]
|
||||
local function neturc(data, prefix)
|
||||
if prefix=="+COPS" then
|
||||
cops(data)
|
||||
elseif prefix == "+CREG" or prefix == "+CGREG" or prefix == "+CEREG" then
|
||||
--收到网络状态变化时,更新一下信号值
|
||||
csqQueryPoll()
|
||||
--解析creg信息
|
||||
creg(data)
|
||||
elseif prefix == "+EEMLTESVC" or prefix == "+EEMLTEINTRA" or prefix == "+EEMLTEINTER" or prefix=="+EEMLTEINTERRAT" then
|
||||
eemLteSvc(data)
|
||||
elseif prefix == "+EEMUMTSSVC" then
|
||||
eemUMTSInfoSvc(data)
|
||||
elseif prefix == "+EEMGINFOSVC" then
|
||||
eemGsmInfoSvc(data)
|
||||
elseif prefix == "+EEMGINFONC" then
|
||||
eemGsmNCInfoSvc(data)
|
||||
elseif prefix == "^MODE" then
|
||||
UpdNetMode(data)
|
||||
end
|
||||
end
|
||||
|
||||
--- 设置飞行模式
|
||||
-- 注意:如果要测试飞行模式的功耗,开机后不要立即调用此接口进入飞行模式
|
||||
-- 在模块注册上网络之前,调用此接口进入飞行模式不仅无效,还会导致功耗数据异常
|
||||
-- 详情参考:http://doc.openluat.com/article/488/0
|
||||
-- @bool mode true:飞行模式开,false:飞行模式关
|
||||
-- @return nil
|
||||
-- @usage net.switchFly(mode)
|
||||
function switchFly(mode)
|
||||
if flyMode == mode then return end
|
||||
flyMode = mode
|
||||
-- 处理飞行模式
|
||||
if mode then
|
||||
ril.request("AT+CFUN=0")
|
||||
-- 处理退出飞行模式
|
||||
else
|
||||
ril.request("AT+CFUN=1")
|
||||
--处理查询定时器
|
||||
csqQueryPoll()
|
||||
cengQueryPoll()
|
||||
--复位GSM网络状态
|
||||
neturc("2", "+CREG")
|
||||
end
|
||||
end
|
||||
|
||||
--- 获取netmode
|
||||
-- @return number netMode,注册的网络类型
|
||||
-- 0:未注册
|
||||
-- 1:2G GSM网络
|
||||
-- 2:2.5G EDGE数据网络
|
||||
-- 3:3G TD网络
|
||||
-- 4:4G LTE网络
|
||||
-- 5:3G WCDMA网络
|
||||
-- @usage net.getNetMode()
|
||||
function getNetMode()
|
||||
return netMode
|
||||
end
|
||||
|
||||
--- 获取网络注册状态
|
||||
-- @return string state,GSM网络注册状态,
|
||||
-- "INIT"表示正在初始化
|
||||
-- "REGISTERED"表示已注册
|
||||
-- "UNREGISTER"表示未注册
|
||||
-- @usage net.getState()
|
||||
function getState()
|
||||
return state
|
||||
end
|
||||
|
||||
--- 获取当前小区的mcc
|
||||
-- @return string mcc,当前小区的mcc,如果还没有注册GSM网络,则返回sim卡的mcc
|
||||
-- @usage net.getMcc()
|
||||
function getMcc()
|
||||
return cellinfo[1].mcc and string.format("%x",cellinfo[1].mcc) or sim.getMcc()
|
||||
end
|
||||
|
||||
--- 获取当前小区的mnc
|
||||
-- @return string mcn,当前小区的mnc,如果还没有注册GSM网络,则返回sim卡的mnc
|
||||
-- @usage net.getMnc()
|
||||
function getMnc()
|
||||
return cellinfo[1].mnc and string.format("%x",cellinfo[1].mnc) or sim.getMnc()
|
||||
end
|
||||
|
||||
--- 获取当前位置区ID
|
||||
-- @return string lac,当前位置区ID(16进制字符串,例如"18be"),如果还没有注册GSM网络,则返回""
|
||||
-- @usage net.getLac()
|
||||
function getLac()
|
||||
return lac
|
||||
end
|
||||
|
||||
--- 获取当前注册的网络频段
|
||||
-- @return string band,当前注册的网络频段,如果还没有注册网络,则返回""
|
||||
-- @usage net.getBand()
|
||||
function getBand()
|
||||
return band
|
||||
end
|
||||
|
||||
--- 获取当前小区ID
|
||||
-- @return string ci,当前小区ID(16进制字符串,例如"93e1"),如果还没有注册GSM网络,则返回""
|
||||
-- @usage net.getCi()
|
||||
function getCi()
|
||||
return ci
|
||||
end
|
||||
|
||||
--- 获取信号强度
|
||||
-- 当前注册的是2G网络,就是2G网络的信号强度
|
||||
-- 当前注册的是4G网络,就是4G网络的信号强度
|
||||
-- @return number rssi,当前信号强度(取值范围0-31)
|
||||
-- @usage net.getRssi()
|
||||
function getRssi()
|
||||
return rssi
|
||||
end
|
||||
|
||||
--- 4G网络信号接收功率
|
||||
-- @return number rsrp,当前信号接收功率(取值范围-140 - -40)
|
||||
-- @usage net.getRsrp()
|
||||
function getRsrp()
|
||||
return rsrp
|
||||
end
|
||||
|
||||
function getCell()
|
||||
local i,ret = 1,""
|
||||
for i=1,cellinfo.cnt do
|
||||
if cellinfo[i] and cellinfo[i].lac and cellinfo[i].lac ~= 0 and cellinfo[i].ci and cellinfo[i].ci ~= 0 then
|
||||
ret = ret..cellinfo[i].ci.."."..cellinfo[i].rssi.."."
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- 获取当前和临近位置区、小区以及信号强度的拼接字符串
|
||||
-- @return string cellInfo,当前和临近位置区、小区以及信号强度的拼接字符串,例如:"6311.49234.30;6311.49233.23;6322.49232.18;"
|
||||
-- @usage net.getCellInfo()
|
||||
function getCellInfo()
|
||||
local i, ret = 1, ""
|
||||
for i = 1, cellinfo.cnt do
|
||||
if cellinfo[i] and cellinfo[i].lac and cellinfo[i].lac ~= 0 and cellinfo[i].ci and cellinfo[i].ci ~= 0 then
|
||||
ret = ret .. cellinfo[i].lac .. "." .. cellinfo[i].ci .. "." .. cellinfo[i].rssi .. ";"
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- 获取当前和临近位置区、小区、mcc、mnc、以及信号的拼接字符串
|
||||
-- @bool[opt=nil] rssi 信号是否拼接功率,true表示功率,false或者nil表示强度
|
||||
-- 表示强度时,信号的取值范围是0到31
|
||||
-- 表示功率时,信号的计算公式为 强度*2-113,取值范围为-113dB到-51dB
|
||||
-- @return string cellInfo,当前和临近位置区、小区、mcc、mnc、以及信号的拼接字符串,例如:
|
||||
-- 当rssi参数为true时,"460.01.6311.49234.-73;460.01.6311.49233.-67;460.02.6322.49232.-77;"
|
||||
-- 当rssi参数为false或者nil时,"460.01.6311.49234.30;460.01.6311.49233.23;460.02.6322.49232.18;"
|
||||
-- @usage net.getCellInfoExt()
|
||||
function getCellInfoExt(rssi)
|
||||
local i, ret = 1, ""
|
||||
for i = 1, cellinfo.cnt do
|
||||
if cellinfo[i] and cellinfo[i].mcc and cellinfo[i].mnc and cellinfo[i].lac and cellinfo[i].lac ~= 0 and cellinfo[i].ci and cellinfo[i].ci ~= 0 then
|
||||
ret = ret .. string.format("%x",cellinfo[i].mcc) .. "." .. string.format("%x",cellinfo[i].mnc) .. "." .. cellinfo[i].lac .. "." .. cellinfo[i].ci .. "." .. (rssi and (cellinfo[i].rssi*2-113) or cellinfo[i].rssi) .. ";"
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--- 获取TA值
|
||||
-- @return number ta,TA值
|
||||
-- @usage net.getTa()
|
||||
function getTa()
|
||||
return cellinfo[1].ta
|
||||
end
|
||||
|
||||
--[[
|
||||
函数名:rsp
|
||||
功能 :本功能模块内“通过虚拟串口发送到底层core软件的AT命令”的应答处理
|
||||
参数 :
|
||||
cmd:此应答对应的AT命令
|
||||
success:AT命令执行结果,true或者false
|
||||
response:AT命令的应答中的执行结果字符串
|
||||
intermediate:AT命令的应答中的中间信息
|
||||
返回值:无
|
||||
]]
|
||||
local function rsp(cmd, success, response, intermediate)
|
||||
local prefix = string.match(cmd, "AT(%+%u+)")
|
||||
|
||||
if intermediate ~= nil then
|
||||
if prefix == "+CSQ" then
|
||||
local s = string.match(intermediate, "+CSQ:%s*(%d+)")
|
||||
if s ~= nil then
|
||||
rssi = tonumber(s)
|
||||
rssi = rssi == 99 and 0 or rssi
|
||||
--产生一个内部消息GSM_SIGNAL_REPORT_IND,表示读取到了信号强度
|
||||
publish("GSM_SIGNAL_REPORT_IND", success, rssi)
|
||||
end
|
||||
elseif prefix == "+CESQ" then
|
||||
local s = string.match(intermediate, "+CESQ: %d+,%d+,%d+,%d+,%d+,(%d+)")
|
||||
if s ~= nil then
|
||||
rsrp = tonumber(s)
|
||||
end
|
||||
elseif prefix == "+CENG" then end
|
||||
end
|
||||
if prefix == "+CFUN" then
|
||||
if success then publish("FLYMODE", flyMode) end
|
||||
end
|
||||
end
|
||||
|
||||
--- 实时读取“当前和临近小区信息”
|
||||
-- @function cbFnc 回调函数,当读取到小区信息后,会调用此回调函数,回调函数的调用形式为:
|
||||
-- cbFnc(cells),其中cells为string类型,格式为:当前和临近位置区、小区、mcc、mnc、以及信号强度的拼接字符串,例如:"460.01.6311.49234.30;460.01.6311.49233.23;460.02.6322.49232.18;"
|
||||
-- @return nil
|
||||
function getMultiCell(cbFnc)
|
||||
multicellcb = cbFnc
|
||||
--发送AT+CENG?查询
|
||||
ril.request("AT+EEMGINFO?")
|
||||
end
|
||||
|
||||
--- 发起查询基站信息(当前和临近小区信息)的请求
|
||||
-- @number period 查询间隔,单位毫秒
|
||||
-- @return bool result, true:查询成功,false:查询失败
|
||||
-- @usage net.cengQueryPoll() --查询1次
|
||||
-- @usage net.cengQueryPoll(60000) --每分钟查询1次
|
||||
function cengQueryPoll(period)
|
||||
-- 不是飞行模式 并且 工作模式为完整模式
|
||||
if not flyMode then
|
||||
--发送AT+CENG?查询
|
||||
ril.request("AT+EEMGINFO?")
|
||||
else
|
||||
log.warn("net.cengQueryPoll", "flymode:", flyMode)
|
||||
end
|
||||
if nil ~= period then
|
||||
--启动定时器
|
||||
sys.timerStopAll(cengQueryPoll)
|
||||
sys.timerStart(cengQueryPoll, period, period)
|
||||
end
|
||||
return not flyMode
|
||||
end
|
||||
|
||||
--- 发起查询信号强度的请求
|
||||
-- @number period 查询间隔,单位毫秒
|
||||
-- @return bool , true:查询成功,false:查询停止
|
||||
-- @usage net.csqQueryPoll() --查询1次
|
||||
-- @usage net.csqQueryPoll(60000) --每分钟查询1次
|
||||
function csqQueryPoll(period)
|
||||
--不是飞行模式 并且 工作模式为完整模式
|
||||
if not flyMode then
|
||||
--发送AT+CSQ查询
|
||||
ril.request("AT+CSQ")
|
||||
ril.request("AT+CESQ")
|
||||
else
|
||||
log.warn("net.csqQueryPoll", "flymode:", flyMode)
|
||||
end
|
||||
if nil ~= period then
|
||||
--启动定时器
|
||||
sys.timerStopAll(csqQueryPoll)
|
||||
sys.timerStart(csqQueryPoll, period, period)
|
||||
end
|
||||
return not flyMode
|
||||
end
|
||||
|
||||
|
||||
--- 设置查询信号强度和基站信息的间隔
|
||||
-- @number ... 查询周期,参数可变,参数为nil只查询1次,参数1是信号强度查询周期,参数2是基站查询周期
|
||||
-- @return bool ,true:设置成功,false:设置失败
|
||||
-- @usage net.startQueryAll()
|
||||
-- @usage net.startQueryAll(60000) -- 1分钟查询1次信号强度,只立即查询1次基站信息
|
||||
-- @usage net.startQueryAll(60000,600000) -- 1分钟查询1次信号强度,10分钟查询1次基站信息
|
||||
function startQueryAll(...)
|
||||
local arg = { ... }
|
||||
csqQueryPoll(arg[1])
|
||||
cengQueryPoll(arg[2])
|
||||
if flyMode then
|
||||
log.info("sim.startQuerAll", "flyMode:", flyMode)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- 停止查询信号强度和基站信息
|
||||
-- @return 无
|
||||
-- @usage net.stopQueryAll()
|
||||
function stopQueryAll()
|
||||
sys.timerStopAll(csqQueryPoll)
|
||||
sys.timerStopAll(cengQueryPoll)
|
||||
end
|
||||
|
||||
local sEngMode
|
||||
--- 设置工程模式
|
||||
-- @number[opt=1] mode 工程模式,目前仅支持0和1
|
||||
-- mode为0时,不支持临近小区查询,休眠时功耗较低
|
||||
-- mode为1时,支持临近小区查询,但是休眠时功耗较高
|
||||
-- @return nil
|
||||
-- @usage
|
||||
-- net.setEngMode(0)
|
||||
function setEngMode(mode)
|
||||
sEngMode = mode or 1
|
||||
ril.request("AT+EEMOPT="..sEngMode,nil,function(cmd,success)
|
||||
function retrySetEngMode()
|
||||
setEngMode(sEngMode)
|
||||
end
|
||||
if success then
|
||||
sys.timerStop(retrySetEngMode)
|
||||
else
|
||||
sys.timerStart(retrySetEngMode,3000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- 处理SIM卡状态消息,SIM卡工作不正常时更新网络状态为未注册
|
||||
sys.subscribe("SIM_IND", function(para)
|
||||
log.info("SIM.subscribe", simerrsta, para)
|
||||
if simerrsta ~= (para ~= "RDY") then
|
||||
simerrsta = (para ~= "RDY")
|
||||
end
|
||||
--sim卡工作不正常
|
||||
if para ~= "RDY" then
|
||||
--更新GSM网络状态
|
||||
state = "UNREGISTER"
|
||||
--产生内部消息NET_STATE_CHANGED,表示网络状态发生变化
|
||||
publish("NET_STATE_UNREGISTER")
|
||||
else
|
||||
--state = "INIT"
|
||||
end
|
||||
end)
|
||||
|
||||
--注册+CREG和+CENG通知的处理函数
|
||||
ril.regUrc("+COPS", neturc)
|
||||
ril.regUrc("+CREG", neturc)
|
||||
ril.regUrc("+CGREG", neturc)
|
||||
ril.regUrc("+CEREG", neturc)
|
||||
--ril.regUrc("+CENG", neturc)
|
||||
ril.regUrc("+EEMLTESVC", neturc)
|
||||
ril.regUrc("+EEMLTEINTER", neturc)
|
||||
ril.regUrc("+EEMLTEINTRA", neturc)
|
||||
ril.regUrc("+EEMLTEINTERRAT", neturc)
|
||||
ril.regUrc("+EEMGINFOSVC", neturc)
|
||||
ril.regUrc("+EEMGINFONC", neturc)
|
||||
ril.regUrc("+EEMUMTSSVC", neturc)
|
||||
ril.regUrc("^MODE", neturc)
|
||||
--ril.regUrc("+CRSM", neturc)
|
||||
--注册AT+CCSQ和AT+CENG?命令的应答处理函数
|
||||
ril.regRsp("+CSQ", rsp)
|
||||
ril.regRsp("+CESQ",rsp)
|
||||
--ril.regRsp("+CENG", rsp)
|
||||
ril.regRsp("+CFUN", rsp)-- 飞行模式
|
||||
--发送AT命令
|
||||
ril.request("AT+COPS?")
|
||||
ril.request("AT+CREG=2")
|
||||
ril.request("AT+CGREG=2")
|
||||
ril.request("AT+CEREG=2")
|
||||
ril.request("AT+CREG?")
|
||||
ril.request("AT+CGREG?")
|
||||
ril.request("AT+CEREG?")
|
||||
ril.request("AT+CALIBINFO?")
|
||||
ril.request("AT*BAND?")
|
||||
setEngMode(1)
|
||||
--重置当前小区和临近小区信息表
|
||||
resetCellInfo()
|
||||
Reference in New Issue
Block a user