最终提交

This commit is contained in:
2026-05-21 13:24:05 +08:00
parent a1d1f19585
commit 1ab5940cbd
78 changed files with 313 additions and 4814 deletions

243
4G/源代码/core/cmd.lua Normal file
View File

@@ -0,0 +1,243 @@
-- 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