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