_doTick.lua 2.9 KB

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