libfota.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. --[[
  2. @module libfota
  3. @summary libfota fota升级
  4. @version 1.0
  5. @date 2023.02.01
  6. @author Dozingfiretruck
  7. @demo fota
  8. @usage
  9. --注意:因使用了sys.wait()所有api需要在协程中使用
  10. --用法实例
  11. local libfota = require("libfota")
  12. -- 功能:获取fota的回调函数
  13. -- 参数:
  14. -- result:number类型
  15. -- 0表示成功
  16. -- 1表示连接失败
  17. -- 2表示url错误
  18. -- 3表示服务器断开
  19. -- 4表示接收报文错误
  20. -- 5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
  21. function libfota_cb(result)
  22. log.info("fota", "result", result)
  23. -- fota成功
  24. if result == 0 then
  25. rtos.reboot() --如果还有其他事情要做,就不要立刻reboot
  26. end
  27. end
  28. --注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
  29. --注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
  30. --注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
  31. --下方示例为合宙iot平台,地址:http://iot.openluat.com
  32. libfota.request(libfota_cb)
  33. --如使用自建服务器,自行更换url
  34. -- 对自定义服务器的要求是:
  35. -- 若需要升级, 响应http 200, body为升级文件的内容
  36. -- 若不需要升级, 响应300或以上的代码,务必注意
  37. libfota.request(libfota_cb,"http://xxxxxx.com/xxx/upgrade?version=" .. _G.VERSION)
  38. -- 若需要定时升级
  39. -- 合宙iot平台
  40. sys.timerLoopStart(libfota.request, 4*3600*1000, libfota_cb)
  41. -- 自建平台
  42. sys.timerLoopStart(libfota.request, 4*3600*1000, libfota_cb, "http://xxxxxx.com/xxx/upgrade?version=" .. _G.VERSION)
  43. ]]
  44. local sys = require "sys"
  45. local sysplus = require "sysplus"
  46. local libfota = {}
  47. local function fota_task(cbFnc,storge_location, len, param1,ota_url,ota_port,libfota_timeout,server_cert, client_cert, client_key, client_password, show_otaurl)
  48. if cbFnc == nil then
  49. cbFnc = function() end
  50. end
  51. -- 若ota_url没有传,那就是用合宙iot平台
  52. if ota_url == nil then
  53. if _G.PRODUCT_KEY == nil then
  54. -- 必须在main.lua定义 PRODUCT_KEY = "xxx"
  55. -- iot平台新建项目后, 项目详情中可以查到
  56. log.error("fota", "iot.openluat.com need PRODUCT_KEY!!!")
  57. cbFnc(5)
  58. return
  59. else
  60. local x,y,z = string.match(_G.VERSION,"(%d+).(%d+).(%d+)")
  61. if x and y and z then
  62. local query = ""
  63. local firmware_name = _G.PROJECT.. "_" .. rtos.firmware()
  64. local version = _G.VERSION
  65. if mobile then
  66. query = "imei=" .. mobile.imei()
  67. version = rtos.version():sub(2) .. "." .. x .. "." .. z
  68. firmware_name = _G.PROJECT.. "_LuatOS-SoC_" .. rtos.bsp()
  69. elseif wlan and wlan.getMac then
  70. query = "mac=" .. wlan.getMac()
  71. version = rtos.version():sub(2) .. "." .. x .. "." .. z
  72. firmware_name = _G.PROJECT.. "_LuatOS-SoC_" .. rtos.bsp()
  73. else
  74. query = "uid=" .. mcu.unique_id():toHex()
  75. end
  76. local tmp = "http://iot.openluat.com/api/site/firmware_upgrade?project_key=%s&firmware_name=%s&version=%s&%s"
  77. ota_url = string.format(tmp, _G.PRODUCT_KEY, firmware_name, version, query)
  78. else
  79. log.error("fota", "_G.VERSION must be xxx.yyy.zzz!!!")
  80. cbFnc(5)
  81. return
  82. end
  83. end
  84. end
  85. local ret
  86. local opts = {timeout = libfota_timeout}
  87. if fota then
  88. opts.fota = true
  89. else
  90. os.remove("/update.bin")
  91. opts.dst = "/update.bin"
  92. end
  93. if show_otaurl == nil or show_otaurl == true then
  94. log.info("fota.url", ota_url)
  95. end
  96. local code, headers, body = http.request("GET", ota_url, nil, nil, opts, server_cert, client_cert, client_key, client_password).wait()
  97. log.info("http fota", code, headers, body)
  98. if code == 200 or code == 206 then
  99. if body == 0 then
  100. ret = 4
  101. else
  102. ret = 0
  103. end
  104. elseif code == -4 then
  105. ret = 1
  106. elseif code == -5 then
  107. ret = 3
  108. else
  109. ret = 4
  110. end
  111. cbFnc(ret)
  112. end
  113. --[[
  114. fota升级
  115. @api libfota.request(cbFnc,ota_url,storge_location, len, param1,ota_port,libfota_timeout,server_cert, client_cert, client_key, client_password)
  116. @function cbFnc 用户回调函数,回调函数的调用形式为:cbFnc(result) , 必须传
  117. @string ota_url 升级URL, 若不填则自动使用合宙iot平台
  118. @number/string storge_location 可选,fota数据存储的起始位置<br>如果是int,则是由芯片平台具体判断<br>如果是string,则存储在文件系统中<br>如果为nil,则由底层决定存储位置
  119. @number len 可选,数据存储的最大空间
  120. @userdata param1,可选,如果数据存储在spiflash时,为spi_device
  121. @number ota_port 可选,请求端口,默认80
  122. @number libfota_timeout 可选,请求超时时间,单位毫秒,默认30000毫秒
  123. @string server_cert 可选,服务器ca证书数据
  124. @string client_cert 可选,客户端证书数据
  125. @string client_key 可选,客户端私钥加密数据
  126. @string client_password 可选,客户端私钥口令数据
  127. @boolean show_otaurl 可选,是否从日志中输出打印OTA升级包的URL路径,默认会打印
  128. @return nil 无返回值
  129. ]]
  130. function libfota.request(cbFnc,ota_url,storge_location, len, param1,ota_port,libfota_timeout,server_cert, client_cert, client_key, client_password, show_otaurl)
  131. sys.taskInit(fota_task, cbFnc,storge_location, len, param1,ota_url, ota_port,libfota_timeout or 30000,server_cert, client_cert, client_key, client_password, show_otaurl)
  132. end
  133. return libfota