Advertisement
osmarks

Microcontroller GPS Host

May 26th, 2020
1,185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.46 KB | None | 0 0
  1. local eeprom = component.proxy(component.list "eeprom"())
  2. local wlan = component.proxy(component.list "modem"())
  3. local comp = component.proxy(component.list "computer"())
  4.  
  5. local function serialize(a)local b=type(a)if b=="number"then return tostring(a)elseif b=="string"then return ("%q"):format(a)elseif b=="table"then local c="{"for d,e in pairs(a)do c=c..string.format("[%s]=%s,",serialize(d),serialize(e))end;return c.."}"elseif b=="boolean"then return tostring(a)else return("%q"):format(tostring(a))end end
  6. local function unserialize(a) local fn, e = load("return "..a:gsub("functio".."n", ""), "@deser", "t", {}) if not fn then return false, e end return fn() end
  7. local a=string.byte;local function crc32(c)local d,e,f;e=0xffffffff;for g=1,#c do d=a(c,g)e=e~d;for h=1,8 do f=-(e&1);e=(e>>1)~(0xedb88320&f)end end;return(~e)&0xffffffff end
  8. local conf, e = unserialize(eeprom.getData())
  9. if e then error("Config parse error: " .. e) end
  10.  
  11. wlan.open(2048)
  12. wlan.open(2049)
  13.  
  14. local function respond(main, auth)
  15.     local data, e = unserialize(main)
  16.     if not data then error("unserialization: " .. e) end
  17.     if type(data) ~= "table" then error "command format invalid" end
  18.     local authed = false
  19.     if data.time and auth then
  20.         local timediff = math.abs(os.time() - data.time)
  21.         if timediff > 1000 then error "tdiff too high" end
  22.         local vauth = crc32(main .. conf.psk)
  23.         if auth ~= vauth then error "auth invalid" end
  24.         authed = true
  25.     end
  26.     local ctype = data[1]
  27.     if ctype == "ping" then return conf.uid end
  28.     if authed then
  29.         if ctype == "reflash" and data[2] then
  30.             eeprom.set(data[2])
  31.             for i = 1, 5 do
  32.                 comp.beep(800, 0.2)
  33.                 comp.beep(1200, 0.2)
  34.             end
  35.             return #data[2]
  36.         elseif ctype == "setpos" and data[2] and data[3] then
  37.             if data[2] == conf.uid then
  38.                 conf.pos = data[3]
  39.                 eeprom.setData(serialize(conf))
  40.                 eeprom.setLabel("GPS"..conf.uid)
  41.                 return true
  42.             end
  43.             return "ignoring"
  44.         end
  45.     end
  46.     error("invalid command (auth: " .. tostring(authed) .. ")")
  47. end
  48.  
  49. while true do
  50.     local ev, _, from, port, distance, m1, m2 = computer.pullSignal()
  51.     if ev == "modem_message" then
  52.         if port == 2048 and m1 == "PING" then
  53.             if conf.pos then
  54.                 wlan.broadcast(2047, table.unpack(conf.pos))
  55.             else
  56.                 comp.beep(400, 2)
  57.             end
  58.         elseif port == 2049 and distance < 8 then
  59.             comp.beep(1000, 0.5)
  60.             local ok, res = pcall(respond, m1, m2)
  61.             wlan.broadcast(2050, conf.uid, ok, serialize(res))
  62.             if not ok then comp.beep(1500, 2) end
  63.         end
  64.     end
  65. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement