diff options
Diffstat (limited to 'wakeup.lua')
-rw-r--r-- | wakeup.lua | 86 |
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 |