工程提交
This commit is contained in:
229
4G/tools/resource/soc_script/v2025.12.31.22/lib/exfotawifi.lua
Normal file
229
4G/tools/resource/soc_script/v2025.12.31.22/lib/exfotawifi.lua
Normal file
@@ -0,0 +1,229 @@
|
||||
--[[
|
||||
@module exfotawifi
|
||||
@summary 用于Air8000/8000A/8000W型号模组自动升级WIFI
|
||||
@version 1.0.3
|
||||
@date 2025.9.23
|
||||
@author 拓毅恒
|
||||
@usage
|
||||
注:使用时在创建的一个task处理函数中直接调用exfotawifi.request()即可开始执行WiFi升级任务
|
||||
升级完毕后最好取消调用,防止后期版本升级过高导致程序使用不稳定
|
||||
|
||||
-- 用法实例
|
||||
local exfotawifi = require("exfotawifi")
|
||||
|
||||
local function fota_wifi_task()
|
||||
-- ...此处省略很多代码
|
||||
|
||||
local result = exfotawifi.request()
|
||||
if result then
|
||||
log.info("exfotawifi", "升级任务执行成功")
|
||||
else
|
||||
log.info("exfotawifi", "升级任务执行失败")
|
||||
end
|
||||
|
||||
-- ...此处省略很多代码
|
||||
end
|
||||
|
||||
-- 启动WiFi自动更新任务
|
||||
sys.taskInit(fota_wifi_task)
|
||||
]]
|
||||
local exfotawifi = {}
|
||||
local is_request = false -- 标记是否正在执行request任务
|
||||
local fota_result = false -- 记录fota任务的执行结果
|
||||
|
||||
-- 判断是否为空
|
||||
local function is_nil(s)
|
||||
return s == nil or s == ""
|
||||
end
|
||||
|
||||
-- 判断json是否合法
|
||||
local function is_json(str)
|
||||
local success, result = pcall(json.decode, str)
|
||||
return success and type(result) == "table"
|
||||
end
|
||||
|
||||
-- 解析服务器响应的json数据
|
||||
local function parse_response(body)
|
||||
if not body or body == "" then
|
||||
log.error("exfotawifi", "返回的body为空")
|
||||
return nil
|
||||
end
|
||||
|
||||
local success, json_body = pcall(json.decode, body)
|
||||
if success and type(json_body) == "table" then
|
||||
log.info("exfotawifi", "解析服务器响应成功")
|
||||
return json_body
|
||||
else
|
||||
log.error("exfotawifi", "解析服务器响应失败,body内容:", body)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- 判断是否需要升级,返回true或false
|
||||
local function need_fota(version, server_version)
|
||||
local version_num = tonumber(version)
|
||||
local server_version_num = tonumber(server_version)
|
||||
if version_num < server_version_num then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 下载升级文件,支持断点续传
|
||||
local function download_file(url)
|
||||
local download_dir = "/http_download/"
|
||||
local result, reason = io.mkdir(download_dir)
|
||||
if not result then
|
||||
log.error("download_file","io.mkdir error", reason)
|
||||
end
|
||||
|
||||
local file_path = download_dir.."fotawifi.bin"
|
||||
local downloaded_size = 0
|
||||
|
||||
-- 检查文件是否存在,获取已下载的大小
|
||||
if io.exists(file_path) then
|
||||
downloaded_size = io.fileSize(file_path)
|
||||
log.info("exfotawifi", "检测到未完成的下载,已下载大小:", downloaded_size)
|
||||
end
|
||||
|
||||
-- 设置请求头,支持断点续传
|
||||
local headers = {}
|
||||
if downloaded_size > 0 then
|
||||
headers["Range"] = "bytes=" .. downloaded_size .. "-"
|
||||
end
|
||||
|
||||
local code, headers, body = http.request("GET", url, headers, nil, nil).wait()
|
||||
if code == 200 or code == 206 then
|
||||
-- 开始写入文件
|
||||
local file_mode = downloaded_size > 0 and "a+" or "w+"
|
||||
local file = io.open(file_path, file_mode)
|
||||
if file then
|
||||
file:seek("end", downloaded_size)
|
||||
file:write(body)
|
||||
file:close()
|
||||
|
||||
-- 判断文件是否下载完整
|
||||
local file_size = io.fileSize(file_path)
|
||||
local content_length = tonumber(headers["content-length"] or headers["Content-Length"])
|
||||
if file_size >= (content_length or file_size) then
|
||||
log.info("exfotawifi", "下载升级文件成功,文件路径:", file_path)
|
||||
return file_path
|
||||
else
|
||||
log.info("exfotawifi", "下载中...当前大小:", file_size, "目标大小:", content_length)
|
||||
end
|
||||
else
|
||||
log.error("exfotawifi", "无法创建文件")
|
||||
-- 删除不完整的文件
|
||||
os.remove(file_path)
|
||||
end
|
||||
else
|
||||
log.error("exfotawifi", "下载失败,状态码:", code)
|
||||
-- 删除不完整的文件
|
||||
if io.exists(file_path) then
|
||||
os.remove(file_path)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- 执行升级操作
|
||||
local function fota_start(file_path)
|
||||
-- 检查文件是否存在
|
||||
if not io.exists(file_path) then
|
||||
log.error("exfotawifi", "升级文件不存在")
|
||||
return false
|
||||
end
|
||||
|
||||
-- 检查文件大小是否超过256K (256 * 1024 Bytes)
|
||||
local file_size = io.fileSize(file_path)
|
||||
if file_size < 256 * 1024 then
|
||||
log.error("exfotawifi", "升级文件大小不足256K,文件大小:", file_size)
|
||||
return false
|
||||
end
|
||||
|
||||
-- 执行airlink.sfota操作
|
||||
local result = airlink.sfota(file_path)
|
||||
if result then
|
||||
log.info("exfotawifi", "升级成功")
|
||||
-- 释放文件占用的空间
|
||||
-- 因为sfota是异步执行的,所以这里不能用os.remove()删除文件
|
||||
file_path = nil
|
||||
return true
|
||||
else
|
||||
log.error("exfotawifi", "升级失败")
|
||||
os.remove(file_path)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function exfotawifi.request()
|
||||
local result, ip, adapter = sys.waitUntil("IP_READY", 30000)
|
||||
if result then
|
||||
log.info("exfotawifi", "开始执行升级任务")
|
||||
|
||||
if is_request then
|
||||
log.warn("exfotawifi", "升级任务正在执行中,请勿重复调用")
|
||||
return false
|
||||
end
|
||||
|
||||
is_request = true
|
||||
fota_result = false
|
||||
|
||||
-- 构建请求URL
|
||||
local url = "http://wififota.openluat.com/air8000/update.json"
|
||||
local imei = is_nil(mobile.imei()) and "未知imei" or mobile.imei()
|
||||
local version = is_nil(airlink.sver()) and "未知版本" or airlink.sver()
|
||||
local muid = is_nil(mobile.muid()) and "未知muid" or mobile.muid()
|
||||
local hw = is_nil(hmeta.hwver()) and "未知硬件版本" or hmeta.hwver()
|
||||
local coreversion = is_nil(rtos.version()) and "未知4G固件版本" or rtos.version()
|
||||
local model = is_nil(hmeta.model()) and "未知4G设备型号" or hmeta.model()
|
||||
local request_url = string.format("%s?imei=%s&version=%s&muid=%s&hw=%s&coreversion=%s&model=%s", url, imei, version, muid, hw, coreversion, model)
|
||||
|
||||
log.info("exfotawifi", "正在请求升级信息, URL:", request_url)
|
||||
|
||||
-- 发送HTTP请求获取服务器响应
|
||||
local code, headers, body = http.request("GET", request_url, {}, nil, {timeout = 30000}).wait()
|
||||
if code == 200 then
|
||||
log.info("exfotawifi", "获取服务器响应成功")
|
||||
-- 打印返回的body内容
|
||||
-- log.info("exfotawifi", "body:", body)
|
||||
-- 解析服务器响应的json数据
|
||||
local response = parse_response(body)
|
||||
if response then
|
||||
-- 获取服务器返回的版本号和下载链接
|
||||
local server_version = response.version
|
||||
local download_url = response.url
|
||||
|
||||
-- 获取本地版本号
|
||||
local local_version = airlink.sver()
|
||||
|
||||
-- 判断是否需要升级
|
||||
if need_fota(local_version, server_version) then
|
||||
log.info("exfotawifi", "需要升级, 本地版本:", local_version, "服务器版本:", server_version)
|
||||
-- 下载升级文件
|
||||
local file_path = download_file(download_url)
|
||||
if file_path then
|
||||
-- 开始升级
|
||||
fota_result = fota_start(file_path)
|
||||
end
|
||||
else
|
||||
log.info("exfotawifi", "当前已是最新WIFI固件")
|
||||
fota_result = true
|
||||
end
|
||||
else
|
||||
log.error("exfotawifi", "解析服务器响应失败")
|
||||
end
|
||||
else
|
||||
log.error("exfotawifi", "获取服务器响应失败,状态码:", code)
|
||||
end
|
||||
else
|
||||
log.error("当前正在升级WIFI&蓝牙固件,请插入可以上网的SIM卡并重新启动")
|
||||
end
|
||||
|
||||
-- 释放请求标记
|
||||
is_request = false
|
||||
return fota_result
|
||||
end
|
||||
|
||||
return exfotawifi
|
||||
Reference in New Issue
Block a user