libfota2.lua 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. --[[
  2. @module libfota2
  3. @summary fota升级v2
  4. @version 1.0
  5. @date 2024.04.09
  6. @author wendal
  7. @demo fota2
  8. @usage
  9. --用法实例
  10. local libfota2 = require("libfota2")
  11. -- 功能:获取fota的回调函数
  12. -- 参数:
  13. -- result:number类型
  14. -- 0表示成功
  15. -- 1表示连接失败
  16. -- 2表示url错误
  17. -- 3表示服务器断开
  18. -- 4表示接收报文错误
  19. -- 5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
  20. function libfota_cb(result)
  21. log.info("fota", "result", result)
  22. -- fota成功
  23. if result == 0 then
  24. rtos.reboot() --如果还有其他事情要做,自行决定reboot的时机
  25. end
  26. end
  27. --下方示例为合宙iot平台,地址:http://iot.openluat.com
  28. libfota2.request(libfota_cb)
  29. --如使用自建服务器,自行更换url
  30. -- 对自定义服务器的要求是:
  31. -- 若需要升级, 响应http 200, body为升级文件的内容
  32. -- 若不需要升级, 响应300或以上的代码,务必注意
  33. local opts = {url="http://xxxxxx.com/xxx/upgrade"}
  34. -- opts的详细说明, 看后面的函数API文档
  35. libfota2.request(libfota_cb, opts)
  36. -- 若需要定时升级
  37. -- 合宙iot平台
  38. sys.timerLoopStart(libfota2.request, 4*3600*1000, libfota_cb)
  39. -- 自建平台
  40. sys.timerLoopStart(libfota2.request, 4*3600*1000, libfota_cb, opts)
  41. ]]
  42. local sys = require "sys"
  43. require "sysplus"
  44. local libfota2 = {}
  45. local function fota_task(cbFnc, opts)
  46. local ret = 0
  47. local code, headers, body = http.request(opts.method, opts.url, opts.headers, opts.body, opts, opts.server_cert, opts.client_cert, opts.client_key, opts.client_password).wait()
  48. log.info("http fota", code, headers, body)
  49. if code == 200 or code == 206 then
  50. if body == 0 then
  51. ret = 4
  52. else
  53. ret = 0
  54. end
  55. elseif code == -4 then
  56. ret = 1
  57. elseif code == -5 then
  58. ret = 3
  59. else
  60. ret = 4
  61. end
  62. cbFnc(ret)
  63. end
  64. --[[
  65. fota升级
  66. @api libfota.request(cbFnc, opts)
  67. @table fota参数, 后面有详细描述
  68. @function cbFnc 用户回调函数,回调函数的调用形式为:cbFnc(result) , 必须传
  69. @return nil 无返回值
  70. @usaga
  71. -- opts参数说明, 所有参数都是可选的
  72. -- 1. opts.url string 升级所需要的URL, 若使用合宙iot平台,则不需要填
  73. -- 2. opts.version string 版本号, 默认是 BSP版本号.x.z格式
  74. -- 3. opts.timeout int 请求超时时间, 默认300000毫秒,单位毫秒
  75. -- 4. opts.project_key string 合宙IOT平台的项目key, 默认取全局变量PRODUCT_KEY. 自建服务器不用填
  76. -- 5. opts.imei string 设备识别码, 默认取IMEI(Cat.1模块)或WLAN MAC地址(wifi模块)或MCU唯一ID
  77. -- 6. opts.firmware_name string 固件名称,默认是 _G.PROJECT.. "_LuatOS-SoC_" .. rtos.bsp()
  78. -- 7. opts.server_cert string 服务器证书, 默认不使用
  79. -- 8. opts.client_cert string 客户端证书, 默认不使用
  80. -- 9. opts.client_key string 客户端私钥, 默认不使用
  81. -- 10. opts.client_password string 客户端私钥口令, 默认不使用
  82. -- 11. opts.method string 请求方法, 默认是GET
  83. -- 12. opts.headers table 额外添加的请求头,默认不需要
  84. -- 13. opts.body string 额外添加的请求body,默认不需要
  85. ]]
  86. function libfota2.request(cbFnc, opts)
  87. if not opts then
  88. opts = {}
  89. end
  90. if fota then
  91. opts.fota = true
  92. else
  93. opts.dst = "/update.bin"
  94. end
  95. if not cbFnc then
  96. cbFnc = function() end
  97. end
  98. -- 处理URL
  99. if not opts.url then
  100. opts.url = "http://iot.openluat.com/api/site/firmware_upgrade"
  101. end
  102. if opts.url:sub(1, 4) ~= "###" then
  103. -- 补齐project_key函数
  104. if not opts.project_key then
  105. opts.project_key = _G.PRODUCT_KEY
  106. if not opts.project_key then
  107. log.error("fota", "iot.openluat.com need PRODUCT_KEY!!!")
  108. cbFnc(5)
  109. return
  110. end
  111. end
  112. -- 补齐version参数
  113. if not opts.version then
  114. local x,y,z = string.match(_G.VERSION,"(%d+).(%d+).(%d+)")
  115. opts.version = rtos.version():sub(2) .. "." .. x.."."..z
  116. end
  117. -- 补齐firmware_name参数
  118. if not opts.firmware_name then
  119. opts.firmware_name = _G.PROJECT.. "_LuatOS-SoC_" .. rtos.bsp()
  120. end
  121. -- 补齐imei参数
  122. if not opts.imei then
  123. local imei = ""
  124. if mobile then
  125. imei = mobile.imei()
  126. elseif wlan and wlan.getMac then
  127. imei = wlan.getMac()
  128. else
  129. imei = mcu.unique_id():toHex()
  130. end
  131. opts.imei = imei
  132. end
  133. -- 然后拼接到最终的url里
  134. opts.url = string.format("%s?imei=%s&project_key=%s&firmware_name=%s&version=%s", opts.url, opts.imei, opts.project_key, opts.firmware_name, opts.version)
  135. else
  136. opts.url = opts.url:sub(4)
  137. end
  138. -- 处理method
  139. if not opts.method then
  140. opts.method = "GET"
  141. end
  142. log.info("fota.url", opts.method, opts.url)
  143. log.info("fota.imei", opts.imei)
  144. log.info("fota.project_key", opts.project_key)
  145. log.info("fota.firmware_name", opts.firmware_name)
  146. log.info("fota.version", opts.version)
  147. sys.taskInit(fota_task, cbFnc, opts)
  148. end
  149. return libfota2