summaryrefslogtreecommitdiff
path: root/wakeup.lua
diff options
context:
space:
mode:
Diffstat (limited to 'wakeup.lua')
-rw-r--r--wakeup.lua86
1 files changed, 86 insertions, 0 deletions
diff --git a/wakeup.lua b/wakeup.lua
new file mode 100644
index 0000000..9239fe1
--- /dev/null
+++ b/wakeup.lua
@@ -0,0 +1,86 @@
+local wakeup = require("+wakeup")
+
+
+--- Builds and returns a Wake-on-LAN magic packet for [[mac]] address.
+local
+function magic_packet (mac)
+ local data = ""
+ for octet in mac:gmatch("%x%x") do
+ data = data .. string.char(tonumber(octet, 16))
+ end
+ if #data ~= 6 then
+ error(string.format("Invalid MAC\t%q", mac), 2)
+ end
+ return string.char(0xff):rep(6) .. data:rep(16)
+end
+
+
+function wakeup:open ()
+ self.udp = net.createUDPSocket()
+end
+
+
+function wakeup:close ()
+ if self.udp then
+ self.udp:close()
+ end
+end
+
+
+--- Creates a new counter that has :up() method that returns true until it gets called N [[times]]. Then it returns only
+--- false.
+local
+function new_counter (times)
+ return {
+ count = 0,
+ times = times,
+ up = function (self)
+ self.count = self.count + 1
+ return self.count <= self.times
+ end,
+ }
+end
+
+
+--- Begins to send Wake-on-LAN magic packets to the broadcast [[.addr]] for selected [[.mac]]. Packets are sent several
+--- [[times]] each separated by [[interval]]. Callback is called [[after]] all packets are sent.
+function wakeup:sendout (interval, times, after)
+ self:open()
+ local count = new_counter(times)
+ return tmr.create():alarm(interval, tmr.ALARM_SEMI, function (timer)
+ if count:up() then
+ print("Waking up", self.mac, self.addr)
+ self.udp:send(self.port, self.addr, self.data)
+ timer:start()
+ else
+ timer:unregister()
+ self:close()
+ after()
+ end
+ end)
+end
+
+
+function wakeup:init ()
+ gpio.write(4, gpio.HIGH)
+ gpio.mode(4, gpio.OUTPUT)
+ self.data = magic_packet(self.mac)
+
+ wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function ()
+ gpio.write(4, gpio.LOW)
+
+ self:sendout(500, 5, function ()
+ wifi.setmode(wifi.NULLMODE, false)
+ gpio.write(4, gpio.HIGH)
+ end)
+ end)
+end
+
+
+function wakeup:run ()
+ wifi.setmode(wifi.STATION, false)
+ wifi.sta.connect()
+end
+
+
+return wakeup