HTTP_OTA.lua 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. --
  2. -- If you have the LFS _init loaded then you invoke the provision by
  3. -- executing LFS.HTTP_OTA('your server','directory','image name'). Note
  4. -- that is unencrypted and unsigned. But the loader does validate that
  5. -- the image file is a valid and complete LFS image before loading.
  6. --
  7. local host, dir, image = ...
  8. local doRequest, firstRec, subsRec, finalise
  9. local n, total, size = 0, 0
  10. doRequest = function(socket, hostIP) -- luacheck: no unused
  11. if hostIP then
  12. local con = net.createConnection(net.TCP,0)
  13. con:connect(80,hostIP)
  14. -- Note that the current dev version can only accept uncompressed LFS images
  15. con:on("connection",function(sck)
  16. local request = table.concat( {
  17. "GET "..dir..image.." HTTP/1.1",
  18. "User-Agent: ESP8266 app (linux-gnu)",
  19. "Accept: application/octet-stream",
  20. "Accept-Encoding: identity",
  21. "Host: "..host,
  22. "Connection: close",
  23. "", "", }, "\r\n")
  24. print(request)
  25. sck:send(request)
  26. sck:on("receive",firstRec)
  27. end)
  28. end
  29. end
  30. firstRec = function (sck,rec)
  31. -- Process the headers; only interested in content length
  32. local i = rec:find('\r\n\r\n',1,true) or 1
  33. local header = rec:sub(1,i+1):lower()
  34. size = tonumber(header:match('\ncontent%-length: *(%d+)\r') or 0)
  35. print(rec:sub(1, i+1))
  36. if size > 0 then
  37. sck:on("receive",subsRec)
  38. file.open(image, 'w')
  39. subsRec(sck, rec:sub(i+4))
  40. else
  41. sck:on("receive", nil)
  42. sck:close()
  43. print("GET failed")
  44. end
  45. end
  46. subsRec = function(sck,rec)
  47. total, n = total + #rec, n + 1
  48. if n % 4 == 1 then
  49. sck:hold()
  50. node.task.post(0, function() sck:unhold() end)
  51. end
  52. uart.write(0,('%u of %u, '):format(total, size))
  53. file.write(rec)
  54. if total == size then finalise(sck) end
  55. end
  56. finalise = function(sck)
  57. file.close()
  58. sck:on("receive", nil)
  59. sck:close()
  60. local s = file.stat(image)
  61. if (s and size == s.size) then
  62. wifi.setmode(wifi.NULLMODE, false)
  63. collectgarbage();collectgarbage()
  64. -- run as separate task to maximise RAM available
  65. node.task.post(function() node.flashreload(image) end)
  66. else
  67. print"Invalid save of image file"
  68. end
  69. end
  70. net.dns.resolve(host, doRequest)