555 lines
6.4 KiB
Lua
555 lines
6.4 KiB
Lua
|
|
|
|
|
|
|
|
|
|
|
|
|
|
require "uart"
|
|
require "rtos"
|
|
require "sys"
|
|
require "log"
|
|
module(..., package.seeall)
|
|
|
|
|
|
local vwrite = uart.write
|
|
local vread = uart.read
|
|
|
|
|
|
|
|
local transparentmode
|
|
|
|
local rcvfunc
|
|
|
|
|
|
local TIMEOUT = 60000*3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local NORESULT, NUMBERIC, SLINE, MLINE, STRING, SPECIAL = 0, 1, 2, 3, 4, 10
|
|
|
|
|
|
local RILCMD = {
|
|
["+CSQ"] = 2,
|
|
["+CESQ"] = 2,
|
|
["+CGMM"] = 2,
|
|
["+RFTEMPERATURE"] =2,
|
|
["+MUID"] = 2,
|
|
["+CGSN"] = 1,
|
|
["+WISN"] = 4,
|
|
["+CIMI"] = 1,
|
|
["+ICCID"] = 2,
|
|
["+SIMCROSS"] = 2,
|
|
["+CGATT"] = 2,
|
|
["+CCLK"] = 2,
|
|
['+CNUM'] = 3,
|
|
|
|
["+CMGR"] = 3,
|
|
["+CMGS"] = 2,
|
|
["+CPBF"] = 3,
|
|
["+CPBR"] = 3,
|
|
['+CLCC'] = 3,
|
|
["+CTFSGETID"] = 2,
|
|
["+CTFSDECRYPT"] = 2,
|
|
["+CTFSAUTH"] = 2,
|
|
["+CGDATA"] = 10,
|
|
["+CIND"] = 2,
|
|
|
|
["+CGACT"] = 3,
|
|
["+CALIBINFO"] = 4,
|
|
["*CALINFO"] = 3,
|
|
}
|
|
|
|
|
|
|
|
local radioready, delaying = false
|
|
|
|
|
|
local cmdqueue = {
|
|
"ATE0",
|
|
"AT+CMEE=0",
|
|
}
|
|
|
|
local currcmd, currarg, currsp, curdelay, cmdhead, cmdtype, rspformt
|
|
|
|
local result, interdata, respdata
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function atimeout()
|
|
|
|
sys.restart("ril.atimeout_" .. (currcmd or ""))
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function defrsp(cmd, success, response, intermediate)
|
|
log.info("ril.defrsp", cmd, success, response, intermediate)
|
|
end
|
|
|
|
|
|
local rsptable = {}
|
|
setmetatable(rsptable, {__index = function() return defrsp end})
|
|
|
|
|
|
local formtab = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function regRsp(head, fnc, typ, formt)
|
|
|
|
if typ == nil then
|
|
rsptable[head] = fnc
|
|
return true
|
|
end
|
|
|
|
if typ == 0 or typ == 1 or typ == 2 or typ == 3 or typ == 4 or typ == 10 then
|
|
|
|
if RILCMD[head] and RILCMD[head] ~= typ then
|
|
return false
|
|
end
|
|
|
|
RILCMD[head] = typ
|
|
rsptable[head] = fnc
|
|
formtab[head] = formt
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
|
|
|
|
local app_rilcb=nil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setrilcb(cb)
|
|
app_rilcb =cb
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function rsp()
|
|
|
|
sys.timerStopAll(atimeout)
|
|
|
|
if currsp then
|
|
currsp(currcmd, result, respdata, interdata)
|
|
|
|
else
|
|
rsptable[cmdhead](currcmd, result, respdata, interdata)
|
|
end
|
|
|
|
currcmd, currarg, currsp, curdelay, cmdhead, cmdtype, rspformt = nil
|
|
result, interdata, respdata = nil
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function defurc(data)
|
|
log.info("ril.defurc", data)
|
|
end
|
|
|
|
|
|
local urctable = {}
|
|
setmetatable(urctable, {__index = function() return defurc end})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function regUrc(prefix, handler)
|
|
urctable[prefix] = handler
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function deRegUrc(prefix)
|
|
urctable[prefix] = nil
|
|
end
|
|
|
|
|
|
local urcfilter
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function urc(data)
|
|
|
|
if data == "RDY" then
|
|
radioready = true
|
|
else
|
|
local prefix = string.match(data, "([%+%^%*]*[%u%d& ]+)")
|
|
|
|
urcfilter = urctable[prefix](data, prefix)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function procatc(data)
|
|
|
|
|
|
|
|
if interdata and cmdtype == MLINE then
|
|
|
|
if data ~= "OK\r\n" then
|
|
|
|
if string.find(data, "\r\n", -2) then
|
|
data = string.sub(data, 1, -3)
|
|
end
|
|
|
|
interdata = interdata .. "\r\n" .. data
|
|
return
|
|
end
|
|
end
|
|
|
|
if urcfilter then
|
|
data, urcfilter = urcfilter(data)
|
|
end
|
|
|
|
if string.find(data, "\r\n", -2) then
|
|
data = string.sub(data, 1, -3)
|
|
end
|
|
|
|
if data == "" then
|
|
return
|
|
end
|
|
|
|
if data:match("^%+EEMLTEINTER") or data:match("^%+EEMLTEINTRA") or data:match("^%+EEMUMTSINTER") or data:match("^%+EEMUMTSINTRA") then
|
|
|
|
else
|
|
log.info("ril.proatc", data)
|
|
end
|
|
|
|
|
|
if currcmd == nil then
|
|
urc(data)
|
|
return
|
|
end
|
|
|
|
local isurc = false
|
|
|
|
|
|
if data:match("^%+CMS ERROR:") or data:match("^%+CME ERROR:") then
|
|
data = "ERROR"
|
|
end
|
|
|
|
if data == "OK" or data == "SHUT OK" then
|
|
result = true
|
|
respdata = data
|
|
|
|
elseif data == "ERROR" or data == "NO ANSWER" or data == "NO DIALTONE" then
|
|
result = false
|
|
respdata = data
|
|
|
|
elseif data == "> " then
|
|
|
|
if cmdhead == "+CMGS" then
|
|
log.info("ril.procatc.send", currarg)
|
|
vwrite(uart.ATC, currarg, "\026")
|
|
else
|
|
log.error("error promot cmd:", currcmd)
|
|
end
|
|
else
|
|
|
|
if cmdtype == NORESULT then
|
|
isurc = true
|
|
|
|
elseif cmdtype == NUMBERIC then
|
|
local numstr = data:match("(%x+)")
|
|
if numstr == data then
|
|
interdata = data
|
|
else
|
|
isurc = true
|
|
end
|
|
|
|
elseif cmdtype == STRING then
|
|
|
|
if data:match(rspformt or "^.+$") and not data:match("^%+CPIN:") then
|
|
interdata = data
|
|
else
|
|
isurc = true
|
|
end
|
|
elseif cmdtype == SLINE or cmdtype == MLINE then
|
|
if interdata == nil and string.find(data, cmdhead) == 1 then
|
|
interdata = data
|
|
else
|
|
isurc = true
|
|
end
|
|
|
|
elseif cmdhead == "+CGDATA" then
|
|
if string.find(data, "CONNECT") == 1 then
|
|
result = true
|
|
respdata = data
|
|
else
|
|
isurc = true
|
|
end
|
|
else
|
|
isurc = true
|
|
end
|
|
end
|
|
|
|
if isurc then
|
|
urc(data)
|
|
|
|
elseif result ~= nil then
|
|
rsp()
|
|
end
|
|
end
|
|
|
|
|
|
local readat = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function getcmd(item)
|
|
local cmd, arg, rsp, delay
|
|
|
|
if type(item) == "string" then
|
|
|
|
cmd = item
|
|
|
|
elseif type(item) == "table" then
|
|
|
|
cmd = item.cmd
|
|
|
|
arg = item.arg
|
|
|
|
rsp = item.rsp
|
|
|
|
delay = item.delay
|
|
else
|
|
log.info("ril.getcmd", "getpack unknown item")
|
|
return
|
|
end
|
|
|
|
local head = string.match(cmd, "AT([%+%*%^]*%u+)")
|
|
|
|
if head == nil then
|
|
log.error("ril.getcmd", "request error cmd:", cmd)
|
|
return
|
|
end
|
|
|
|
if head == "+CMGS" or head == "+CIPSEND" then
|
|
if arg == nil or arg == "" then
|
|
log.error("ril.getcmd", "request error no arg", head)
|
|
return
|
|
end
|
|
end
|
|
|
|
|
|
currcmd = cmd
|
|
currarg = arg
|
|
currsp = rsp
|
|
curdelay = delay
|
|
cmdhead = head
|
|
cmdtype = RILCMD[head] or NORESULT
|
|
rspformt = formtab[head]
|
|
|
|
return currcmd
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function sendat()
|
|
|
|
if not radioready or readat or currcmd ~= nil or delaying then
|
|
return
|
|
end
|
|
|
|
local item
|
|
|
|
while true do
|
|
|
|
if #cmdqueue == 0 then
|
|
return
|
|
end
|
|
|
|
item = table.remove(cmdqueue, 1)
|
|
|
|
getcmd(item)
|
|
|
|
if curdelay then
|
|
|
|
sys.timerStart(delayfunc, curdelay)
|
|
|
|
currcmd, currarg, currsp, curdelay, cmdhead, cmdtype, rspformt = nil
|
|
item.delay = nil
|
|
|
|
delaying = true
|
|
|
|
table.insert(cmdqueue, 1, item)
|
|
return
|
|
end
|
|
|
|
if currcmd ~= nil then
|
|
break
|
|
end
|
|
end
|
|
|
|
sys.timerStart(atimeout, TIMEOUT)
|
|
|
|
log.info("ril.sendat", currcmd)
|
|
|
|
if currcmd:match("^AT%+POC=") then
|
|
vwrite(uart.ATC, currcmd .. "\r\n")
|
|
else
|
|
vwrite(uart.ATC, currcmd .. "\r")
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
function delayfunc()
|
|
|
|
delaying = nil
|
|
|
|
sendat()
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function atcreader()
|
|
local s
|
|
|
|
if not transparentmode then readat = true end
|
|
|
|
while true do
|
|
|
|
s = vread(uart.ATC, "*l", 0)
|
|
if string.len(s) ~= 0 then
|
|
if transparentmode then
|
|
|
|
rcvfunc(s)
|
|
else
|
|
|
|
procatc(s)
|
|
|
|
if app_rilcb ~=nil then app_rilcb(s) end
|
|
end
|
|
else
|
|
break
|
|
end
|
|
end
|
|
if not transparentmode then
|
|
readat = false
|
|
|
|
sendat()
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function request(cmd, arg, onrsp, delay)
|
|
if transparentmode then return end
|
|
|
|
if arg or onrsp or delay or formt then
|
|
table.insert(cmdqueue, {cmd = cmd, arg = arg, rsp = onrsp, delay = delay})
|
|
else
|
|
table.insert(cmdqueue, cmd)
|
|
end
|
|
|
|
sendat()
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setransparentmode(fnc)
|
|
transparentmode, rcvfunc = true, fnc
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function sendtransparentdata(data)
|
|
if not transparentmode then return end
|
|
vwrite(uart.ATC, data)
|
|
return true
|
|
end
|
|
|
|
|
|
uart.on(uart.ATC, "receive", atcreader)
|