Files
BR_YKC/4G/源代码/core/cmd.lua
2026-05-21 13:24:05 +08:00

244 lines
7.8 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- cmd.lua
-- 功能:解析串口帧,调用 linksocket 接口,执行系统命令
local log = require "log"
local sys = require "sys"
local uart = require "uart"
local ril = require "ril"
local linksocket = require "linksocket"
local uartID = 1
-- 辅助函数:字节转十六进制(调试用)
local function toHexcode(str)
if not str then return "" end
local hex = ""
for i = 1, #str do
hex = hex .. string.format("%02X", str:byte(i))
end
return hex
end
-- 发送通用响应帧55 AA mainCmd subCmd [payload] AA 55
local function sendCmdResponse(mainCmd, subCmd, payload)
local frame = string.char(0x55, 0xAA, mainCmd, subCmd)
if payload and #payload > 0 then
frame = frame .. payload
end
frame = frame .. string.char(0xAA, 0x55)
uart.write(uartID, frame)
log.debug("sendCmdResponse: mainCmd=", string.format("0x%02X", mainCmd),
"subCmd=", string.format("0x%02X", subCmd))
end
-- 发送通用响应帧55 AA 83 subCmd socketId status AA 55
local function sendResponse(subCmd, socketId, status)
sendCmdResponse(0x83, subCmd, string.char(socketId, status or 0))
log.debug("Response: subCmd=", subCmd, "socketId=", socketId, "status=", status)
end
-- 命令处理函数 ---------------------------------------------------------------
-- 0x01: 数据发送到指定Socket
local function handleCmd01(subCmd, payload)
local socketId = subCmd
if socketId < 1 or socketId > 6 then
log.error("Invalid socket id in cmd 0x01:", socketId)
sendResponse(0x03, socketId, 1)
return
end
local success = linksocket.sendToSocket(socketId, payload)
if not success then
log.warn("Send failed, socket", socketId, "not connected")
sendResponse(0x03, socketId, 1)
else
log.info("Data sent to socket", socketId, "len=", #payload)
end
end
-- 0x02: 系统重启
local function handleCmd02()
log.info("System restart command received")
sys.restart()
end
-- 0x03: Socket连接/断开控制
-- subCmd: 0x01=连接 0x02=断开
-- payload: socket_id (1字节)
local function handleCmd03(subCmd, payload)
if #payload < 1 then return end
local socketId = payload:byte(1)
if socketId < 1 or socketId > 6 then
log.error("Cmd 0x03 invalid socket:", socketId)
return
end
if subCmd == 0x01 then
log.info("STM32 request connect socket", socketId)
linksocket.connectSocket(socketId)
elseif subCmd == 0x02 then
log.info("STM32 request disconnect socket", socketId)
linksocket.disconnectSocket(socketId)
else
log.error("Unknown subCmd for 0x03:", subCmd)
end
end
-- 0x04: 设置服务器地址
-- payload: ip_len(1) + ip_str(ip_len) + port_hi(1) + port_lo(1)
local function handleCmd04(subCmd, payload)
if #payload < 3 then
log.error("Cmd 0x04 payload too short")
sendCmdResponse(0x87, 0x00, string.char(1))
return
end
local ip_len = payload:byte(1)
if ip_len > 100 or #payload < (2 + ip_len + 1) then
log.error("Cmd 0x04 invalid ip_len")
sendCmdResponse(0x87, 0x00, string.char(1))
return
end
local ip_str = payload:sub(2, 1 + ip_len)
local port_hi = payload:byte(2 + ip_len)
local port_lo = payload:byte(3 + ip_len)
local port = port_hi * 256 + port_lo
log.info("Set server address:", ip_str, port)
local ok = linksocket.setServerAddress(ip_str, port)
if ok then
sendCmdResponse(0x87, 0x00, string.char(0))
else
sendCmdResponse(0x87, 0x00, string.char(1))
end
end
-- 0x05: 查询SIM卡信息
-- subCmd: 0x01=ICCID 0x02=IMSI 0x03=IMEI
local function handleCmd05(subCmd)
local at_cmds = {
[0x01] = "AT+ICCID",
[0x02] = "AT+CIMI",
[0x03] = "AT+CGSN",
}
local at_cmd = at_cmds[subCmd]
if not at_cmd then
log.error("Unknown SIM query type:", string.format("0x%02X", subCmd))
return
end
ril.request(at_cmd, nil, function(cmd, result, respdata, interdata)
-- interdata才是实际的AT命令响应数据result只是布尔值表示成功/失败
local response = interdata or ""
-- 去除可能的空白字符
response = response:gsub("^[\r\n]+", ""):gsub("[\r\n]+$", "")
local value = ""
if subCmd == 0x01 then
value = string.match(response, "%+ICCID:%s*(%S+)") or string.match(response, "ICCID:%s*(%S+)") or response:match("^(%S+)") or ""
elseif subCmd == 0x02 then
value = string.match(response, "%+CIMI:%s*(%S+)") or string.match(response, "CIMI:%s*(%S+)") or response:match("^(%S+)") or ""
elseif subCmd == 0x03 then
value = string.match(response, "%+CGSN:%s*(%S+)") or string.match(response, "CGSN:%s*(%S+)") or response:match("^(%S+)") or ""
end
value = value or ""
log.info("SIM query result type=", string.format("0x%02X", subCmd), "value=", value)
local data = string.char(#value) .. value
sendCmdResponse(0x84, subCmd, data)
end)
end
-- 0x06: 查询信号强度CSQ
local function handleCmd06()
ril.request("AT+CSQ", nil, function(cmd, result)
local csq = 0
local ber = 99
-- result可能是布尔值需要确保是字符串才能进行模式匹配
if result and type(result) == "string" then
local c, b = string.match(result, "CSQ:%s*(%d+),%s*(%d+)")
if c then csq = tonumber(c) or 0 end
if b then ber = tonumber(b) or 99 end
end
log.info("Signal query: CSQ=", csq, "BER=", ber)
sendCmdResponse(0x85, 0x01, string.char(csq, ber))
end)
end
-- 0x07: 查询链路状态
local function handleCmd07()
local status = linksocket.getLinkStatus()
if status then
local payload = ""
for i = 1, 6 do
payload = payload .. string.char(status[i] and 1 or 0)
end
sendCmdResponse(0x86, 0x01, payload)
log.info("Link status sent, 6 sockets")
end
end
local frameBuffer = ""
-- 对外接口:处理串口接收到的原始数据
local function process(rawData)
if not rawData or #rawData < 1 then
return
end
frameBuffer = frameBuffer .. rawData
while true do
if #frameBuffer < 7 then break end
if frameBuffer:byte(1) == 0x55 and frameBuffer:byte(2) == 0xAA then
local tail = frameBuffer:find(string.char(0xAA, 0x55), 5, true)
if not tail then break end
tail = tail + 1
local frame = frameBuffer:sub(1, tail)
frameBuffer = frameBuffer:sub(tail + 1)
log.info("CMD raw data:", toHexcode(frame))
local mainCmd = frame:byte(3)
local subCmd = frame:byte(4)
local payload = frame:sub(5, -3)
if mainCmd == 0x01 then
handleCmd01(subCmd, payload)
elseif mainCmd == 0x02 then
handleCmd02()
elseif mainCmd == 0x03 then
handleCmd03(subCmd, payload)
elseif mainCmd == 0x04 then
handleCmd04(subCmd, payload)
elseif mainCmd == 0x05 then
handleCmd05(subCmd)
elseif mainCmd == 0x06 then
handleCmd06()
elseif mainCmd == 0x07 then
handleCmd07()
else
log.warn("Unknown main command:", string.format("0x%02X", mainCmd))
end
else
local skip = frameBuffer:find(string.char(0x55, 0xAA), 2, true)
if skip then
log.warn("Skipped", skip - 1, "bytes before frame header")
frameBuffer = frameBuffer:sub(skip)
else
frameBuffer = ""
break
end
end
end
end
-- 模块接口
local M = {
process = process,
}
return M