工程提交
This commit is contained in:
230
4G/code/lib/update.lua
Normal file
230
4G/code/lib/update.lua
Normal file
@@ -0,0 +1,230 @@
|
||||
--- 模块功能:远程升级.
|
||||
-- @module update
|
||||
-- @author openLuat
|
||||
-- @license MIT
|
||||
-- @copyright openLuat
|
||||
-- @release 2018.03.29
|
||||
|
||||
require "misc"
|
||||
require "http"
|
||||
require "log"
|
||||
require "common"
|
||||
|
||||
module(..., package.seeall)
|
||||
|
||||
local sUpdating,sCbFnc,sUrl,sPeriod,sRedir,sLocation,fotastart
|
||||
local sProcessedLen = 0
|
||||
--local sBraekTest = 0
|
||||
local httpRspCode
|
||||
local sGetImeiFnc,sDownloadProcessFnc
|
||||
|
||||
local updateMsg
|
||||
|
||||
local otaBegin
|
||||
|
||||
local function httpDownloadCbFnc(result,statusCode,head)
|
||||
log.info("update.httpDownloadCbFnc",result,statusCode,head,sCbFnc,sPeriod)
|
||||
sys.publish("UPDATE_DOWNLOAD",result,statusCode,head)
|
||||
end
|
||||
|
||||
local function processOta(stepData,totalLen,statusCode)
|
||||
|
||||
if stepData and totalLen then
|
||||
if statusCode=="200" or statusCode=="206" then
|
||||
if not otaBegin then sys.publish("LIB_UPDATE_OTA_DOWNLOAD_BEGIN") otaBegin=true end
|
||||
local fotaProcessStatus=rtos.fota_process((sProcessedLen+stepData:len()>totalLen) and stepData:sub(1,totalLen-sProcessedLen) or stepData,totalLen)
|
||||
if fotaProcessStatus~=0 then
|
||||
log.error("update.processOta","fail",fotaProcessStatus,"failFotaProcessStatus")
|
||||
log.error("update.processOta","get_fs_free_size: ",rtos.get_fs_free_size()," Bytes")
|
||||
sys.publish("LIB_UPDATE_OTA_DOWNLOAD_END",false)
|
||||
return false
|
||||
else
|
||||
sProcessedLen = sProcessedLen + stepData:len()
|
||||
if sDownloadProcessFnc then sDownloadProcessFnc(sProcessedLen*100/totalLen) end
|
||||
log.info("update.processOta",totalLen,sProcessedLen,(sProcessedLen*100/totalLen).."%")
|
||||
--if sProcessedLen*100/totalLen==sBraekTest then return false end
|
||||
if sProcessedLen*100/totalLen>=100 then sys.publish("LIB_UPDATE_OTA_DOWNLOAD_END",true) return true end
|
||||
end
|
||||
elseif statusCode:sub(1,1)~="3" and stepData:len()==totalLen and totalLen>0 then
|
||||
if totalLen<=200 then
|
||||
local msg = stepData:match("\"msg\":%s*\"(.-)\"")
|
||||
if msg and msg:len()<=200 then
|
||||
updateMsg = common.ucs2beToUtf8((msg:gsub("\\u","")):fromHex())
|
||||
log.warn("update.error",updateMsg)
|
||||
end
|
||||
end
|
||||
httpRspCode = stepData:match("\"code\":%s*(%d+)")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function clientTask()
|
||||
sUpdating = true
|
||||
--不要省略此处代码,否则下文中的misc.getImei有可能获取不到
|
||||
while not socket.isReady() do sys.waitUntil("IP_READY_IND") end
|
||||
|
||||
|
||||
|
||||
while true do
|
||||
local retryCnt = 0
|
||||
sProcessedLen = 0
|
||||
otaBegin = false
|
||||
updateMsg = nil
|
||||
while true do
|
||||
--sBraekTest = sBraekTest+30
|
||||
log.info("update.http.request",sLocation,sUrl,sProcessedLen,sBraekTest,fotastart)
|
||||
if not fotastart then break end
|
||||
local coreVer = rtos.get_version()
|
||||
local coreName1,coreName2 = coreVer:match("(.-)_V%d+(_.+)")
|
||||
local coreVersion = tonumber(coreVer:match(".-_V(%d+)"))
|
||||
httpRspCode = nil
|
||||
|
||||
-- 合宙云平台升级地址
|
||||
local iotURL="iot.openluat.com/api/site/firmware_upgrade"
|
||||
-- 模块信息
|
||||
local moduleInfo="?project_key=".._G.PRODUCT_KEY
|
||||
.."&imei="..(sGetImeiFnc and sGetImeiFnc() or misc.getImei())
|
||||
.."&firmware_name=".._G.PROJECT.."_"..coreName1..coreName2
|
||||
.."&core_version="..coreVersion
|
||||
.."&dfota=1&version=".._G.VERSION..(sRedir and "&need_oss_url=1" or "")
|
||||
|
||||
|
||||
-- 如果自定义升级地址前三位为“###”,则不拼接模块信息
|
||||
if sUrl and string.sub(sUrl,1,3)=="###" then
|
||||
log.info("1-3",string.sub(sUrl,1,3))
|
||||
log.info("3-0",string.sub(sUrl,4))
|
||||
customizeUrl=string.sub(sUrl,4)
|
||||
elseif sUrl then
|
||||
customizeUrl=sUrl..moduleInfo
|
||||
else
|
||||
-- 默认向合宙云平台地址拼接模块信息
|
||||
iotURL=iotURL..moduleInfo
|
||||
end
|
||||
|
||||
http.request("GET",
|
||||
sLocation or (customizeUrl or iotURL),
|
||||
nil,{["Range"]="bytes="..sProcessedLen.."-"},nil,60000,httpDownloadCbFnc,processOta)
|
||||
|
||||
|
||||
local _,result,statusCode,head = sys.waitUntil("UPDATE_DOWNLOAD")
|
||||
log.info("update.waitUntil UPDATE_DOWNLOAD",result,statusCode,httpRspCode)
|
||||
if result then
|
||||
local needBreak
|
||||
if statusCode=="200" or statusCode=="206" then
|
||||
needBreak = true
|
||||
local check = rtos.fota_end()
|
||||
log.info("update.rtos.fota_end", check)
|
||||
if sCbFnc then
|
||||
if check == 0 then
|
||||
sCbFnc(true)
|
||||
else
|
||||
sCbFnc(false)
|
||||
end
|
||||
else
|
||||
if check == 0 then
|
||||
sys.restart("UPDATE_DOWNLOAD_SUCCESS")
|
||||
end
|
||||
end
|
||||
elseif statusCode:sub(1,1)=="3" and head and head["Location"] then
|
||||
sLocation = head["Location"]
|
||||
sys.wait(2000)
|
||||
elseif httpRspCode=="43" then
|
||||
log.info("update.clientTask","wait server create fota")
|
||||
sys.wait(30000)
|
||||
else
|
||||
log.info("update.rtos.fota_end",rtos.fota_end())
|
||||
if sCbFnc then sCbFnc(false) end
|
||||
needBreak = true
|
||||
end
|
||||
|
||||
if needBreak then
|
||||
break
|
||||
end
|
||||
else
|
||||
retryCnt = retryCnt+1
|
||||
if retryCnt==30 then
|
||||
rtos.fota_end()
|
||||
if sCbFnc then sCbFnc(false) end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sProcessedLen = 0
|
||||
|
||||
if sPeriod then
|
||||
sys.wait(sPeriod)
|
||||
if rtos.fota_start()~=0 then
|
||||
log.error("update.request","fota_start fail")
|
||||
fotastart = false
|
||||
else
|
||||
fotastart = true
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
sUpdating = false
|
||||
end
|
||||
|
||||
--- 启动远程升级功能
|
||||
-- @function[opt=nil] cbFnc 每次执行远程升级功能后的回调函数,回调函数的调用形式为:
|
||||
-- cbFnc(result),result为true表示升级包下载成功,其余表示下载失败
|
||||
--如果没有设置此参数,则升级包下载成功后,会自动重启
|
||||
-- @string[opt=nil] url 使用http的get命令下载升级包的url,如果没有设置此参数,默认使用Luatiot平台的url
|
||||
-- 如果用户设置了url,注意:仅传入完整url的前半部分(如果有参数,即传入?前一部分),http.lua会自动添加?以及后面的参数,例如:
|
||||
-- 设置的url="www.userserver.com/api/site/firmware_upgrade",则http.lua会在此url后面补充下面的参数
|
||||
-- "?project_key=".._G.PRODUCT_KEY
|
||||
-- .."&imei="..misc.getimei()
|
||||
-- .."&device_key="..misc.getsn()
|
||||
-- .."&firmware_name=".._G.PROJECT.."_"..rtos.get_version().."&version=".._G.VERSION
|
||||
-- 如果用户设置了url,且url前面增加三个井号"###",http.lua会自动忽略"###"并以用户填入的url作为请求地址,不会自动添加模块信息,例如:
|
||||
-- 设置的url="###www.userserver.com"/api/site/firmware_upgrade?customparam=test",则http.lua会将此url开头的"###"忽略,并以此url为地址进行请求
|
||||
-- "www.userserver.com"/api/site/firmware_upgrade?customparam=test"
|
||||
-- 如果redir设置为true,还会补充.."&need_oss_url=1"
|
||||
-- @number[opt=nil] period 单位毫秒,定时启动远程升级功能的间隔,如果没有设置此参数,仅执行一次远程升级功能
|
||||
-- @bool[opt=nil] redir 是否访问重定向到阿里云的升级包,使用Luat提供的升级服务器时,此参数才有意义
|
||||
-- 为了缓解Luat的升级服务器压力,从2018年7月11日起,在iot.openluat.com新增或者修改升级包的升级配置时,升级文件会备份一份到阿里云服务器
|
||||
-- 如果此参数设置为true,会从阿里云服务器下载升级包;如果此参数设置为false或者nil,仍然从Luat的升级服务器下载升级包
|
||||
-- @return nil
|
||||
-- @usage
|
||||
-- update.request()
|
||||
-- update.request(cbFnc)
|
||||
-- update.request(cbFnc,"www.userserver.com/update")
|
||||
-- update.request(cbFnc,nil,4*3600*1000)
|
||||
-- update.request(cbFnc,nil,4*3600*1000,true)
|
||||
function request(cbFnc,url,period,redir)
|
||||
if rtos.fota_start()~=0 then
|
||||
log.error("update.request","fota_start fail")
|
||||
fotastart = false
|
||||
return
|
||||
else
|
||||
fotastart = true
|
||||
end
|
||||
sCbFnc,sUrl,sPeriod,sRedir = cbFnc or sCbFnc,url or sUrl,period or sPeriod,sRedir or redir
|
||||
log.info("update.request",sCbFnc,sUrl,sPeriod,sRedir)
|
||||
if not sUpdating then
|
||||
sys.taskInit(clientTask)
|
||||
end
|
||||
end
|
||||
|
||||
function setGetImeiCbFnc(cbFnc)
|
||||
sGetImeiFnc = cbFnc
|
||||
end
|
||||
|
||||
--- 设置升级包下载过程中的下载进度通知回调函数
|
||||
-- @function cbFnc 下载进度通知回调函数,回调函数的调用形式如下:
|
||||
-- cbFnc(step)
|
||||
-- step表示下载进度:取值范围是0到100,下载进度更新很快,建议在回调函数中,每隔5或者10执行一次实际动作
|
||||
-- @return nil
|
||||
-- @usage update.setDownloadProcessCbFnc(function(step) end)
|
||||
function setDownloadProcessCbFnc(cbFnc)
|
||||
sDownloadProcessFnc = cbFnc
|
||||
end
|
||||
|
||||
--- 获取请求升级包时服务器返回的信息
|
||||
-- @return updateMsg, 若没有请求升级或服务器未返回相关信息,则返回值为nil,否则返回服务器返回的相关信息
|
||||
-- @usage local msg = getUpdateMsg()
|
||||
function getUpdateMsg()
|
||||
return updateMsg
|
||||
end
|
||||
Reference in New Issue
Block a user