_doTick.lua 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. -- luacheck: globals self
  2. if (self.timer) then self.timer:stop() end--SAFETRIM
  3. -- function _doTick(self)
  4. -- Upvals
  5. local self = ...
  6. local wifi,net = wifi,net
  7. local sta = wifi.sta
  8. local config,log,startApp = self.config,self.log,self.startApp
  9. local tick_count = 0
  10. local function socket_close(socket) --upval: self, startApp
  11. if rawget(self,"socket") then
  12. self.socket=nil -- remove circular reference in upval
  13. pcall(socket.close,socket)
  14. return startApp("Unexpected socket close")
  15. end
  16. end
  17. local function receiveFirstRec(socket, rec) -- upval: self, crypto, startApp, tmr
  18. local cmdlen = (rec:find('\n',1, true) or 0) - 1
  19. local cmd,hash = rec:sub(1,cmdlen-6), rec:sub(cmdlen-5,cmdlen)
  20. if cmd:find('"r":"OK!"',1,true) or cmdlen < 16 or
  21. hash ~= crypto.toHex(crypto.hmac("MD5", cmd, self.secret):sub(-3)) then
  22. print "No provisioning changes required"
  23. self.socket = nil
  24. self.post(function() --upval: socket
  25. if socket then pcall(socket.close, socket) end
  26. end)
  27. return startApp("OK! No further updates needed")
  28. end
  29. -- Else a valid request has been received from the provision service free up
  30. -- some resources that are no longer needed and set backstop timer for general
  31. -- timeout. This also dereferences the previous doTick cb so it can now be GCed.
  32. collectgarbage()
  33. self.timer:alarm(0, 30000, tmr.ALARM_SINGLE, self.startApp)
  34. return self:_provision(socket,rec)
  35. end
  36. local function socket_connect(socket) --upval: self, socket_connect
  37. print "Connected to provisioning service"
  38. self.socket = socket
  39. socket_connect = nil -- make this function available for GC
  40. socket:on("receive", receiveFirstRec)
  41. return self.socket_send(socket, self.config)
  42. end
  43. local conn
  44. return function() -- the proper doTick() timer callback
  45. tick_count = tick_count + 1
  46. log("entering tick", tick_count, sta.getconfig(false), sta.getip())
  47. if (tick_count < 20) then -- (wait up to 10 secs for Wifi connection)
  48. local status, ip = sta.status(),{sta.getip()}
  49. if (status == wifi.STA_GOTIP) then
  50. log("Connected:", unpack(ip))
  51. if (config.nsserver) then
  52. net.dns.setdnsserver(config.nsserver, 0)
  53. end
  54. conn = net.createConnection(net.TCP, 0)
  55. conn:on("connection", socket_connect)
  56. conn:on("disconnection", socket_close)
  57. conn:connect(config.port, config.server)
  58. tick_count = 20
  59. end
  60. elseif (tick_count == 20) then -- assume timeout and exec app CB
  61. return self.startApp("OK: Timeout on waiting for wifi station setup")
  62. elseif (tick_count == 26) then -- wait up to 2.5 secs for TCP response
  63. self.timer:unregister()
  64. pcall(conn.close, conn)
  65. self.socket=nil
  66. return startApp("OK: Timeout on waiting for provision service response")
  67. end
  68. end
  69. -- end