Browse Source

Started http

master
Chris Mahoney 1 year ago
parent
commit
2d274d3d75
  1. 108
      eeprom-server.lua
  2. 18
      eeprom-worker.lua
  3. 37
      lib/http.lua
  4. 6
      lib/net.lua
  5. 83
      lib/socket.lua
  6. 11
      lib/webflashlib.lua
  7. 12
      webflash.lua

108
eeprom-server.lua

@ -1,16 +1,20 @@
local net = require("net")
local component = require("component")
local sides = require("sides")
local os = require("os")
local Socket = Socket or require("socket")
local net = net or require("net")
local component = component or require("component")
local computer = computer or require("computer")
local event = event or require("event")
local sides = sides or require("sides")
local os = os or require("os")
-- location of eeprom in computer case
local EEPROM_SLOT = 10
local transposer = component.transposer
-- Waits for a SYN from a worker and responds with an ACK
-- Returns the workers address
-- Waits for a SYN from the worker and responds with an ACK
-- Returns a socket connected to the worker
local function meetWorker(port)
print("Waiting for worker")
print("Waiting for worker...")
local function syn(name, ...)
-- local addr, remote addr, port, distance, msg
@ -23,10 +27,12 @@ local function meetWorker(port)
local pkt, err = net.recv{port, filter = syn}
-- ACK the worker
net.send(pkt.raddr, port, "ACK")
print("Found worker", pkt.raddr)
local s = Socket(pkt.raddr, port)
s:send("ACK")
print("Found worker " .. pkt.raddr)
return pkt.raddr
return s
end
-- Checks if the top chest is filled
@ -45,32 +51,36 @@ end
-- Optionally include the slot
-- Returns the slot the eeprom was moved to
local function removeEEPROM(sink_slot)
print("REMOVING - ", sink_slot)
if sink_slot == nil then
local i = 1
for k in transposer.getAllStacks(sides.top) do
for m, n in pairs(k) do print(m, n) end
if k.size == nil then break end
i = i + 1
end
if i == 27 then
print("Inventory filled")
return nil, "Inventory filled"
end
sink_slot = i
end
print("Moving EEPROM to slot " .. tostring(sink_slot))
-- Remove the OpenOS Bios and store it in the top chest
transposer.transferItem(sides.left, sides.top, 1, EEPROM_SLOT, sink_slot)
print("Move complete")
return sink_slot
end
-- Moves a blank EEPROM from storage into the worker
local function loadNewEEPROM()
print("LOADING")
print("Loading new EEPROM...")
-- Find largest inventory slot in the storage with an eeprom
local i = 1
@ -85,27 +95,25 @@ local function loadNewEEPROM()
end
if last == nil then
print("No blank EEPROMS")
return nil, "No EEPROMS"
end
-- Move the new EEPROM into computer
print("Loading complete")
transposer.transferItem(sides.right, sides.left, 1, last, EEPROM_SLOT)
return true
end
local function flashEEPROM(worker, port, data, label)
print("Send", worker, port, "flash", label)
local function flashEEPROM(worker, data, label)
print("Asking worker to flash " .. "...")
net.send(worker, port, "flash", data, label)
worker:send("flash", data, label)
local function fromWorker(name, ...)
t = {...}
return t[2] == worker
end
local pkt, error = net.recv{port, filter=fromWorker}
local pkt = worker:recieve(true)
for k, v in pairs(pkt) do print(k, v) end
print("Flash complete " .. pkt.msg)
if pkt.msg == "flash-good" then
return true
@ -114,45 +122,44 @@ local function flashEEPROM(worker, port, data, label)
end
end
local function respond(pkt, code, error)
print("SEND", pkt.raddr, pkt.port, code, error)
net.send(pkt.raddr, pkt.port, code, error)
computer.beep(200)
end
-- Waits to recv a message
local function waitForJob(port, worker)
local pkt, err = net.recv{port}
local function ignore(_, _, raddr) return raddr ~= net.addr and raddr ~= worker.raddr end
local pkt, err = net.recv{port, filter=ignore}
if pkt == nil and err ~= "interrupted" then
return pkt
end
-- "eeprom-flash file-contents"
if pkt.msg == "eeprom-flash" then
-- Create a new socket
local client = Socket(pkt.raddr, port)
-- "eeprom-flash file-contents label"
if pkt.msg == "webflash" then
-- 4k is the largest an eeprom can hold
if #pkt.data[2] > 4096 then
respond(pkt, 400, "file too large")
client:send(400, "file too large")
return pkt
end
if isFilled() then respond(pkt, 500, "inventory filled") return end
if isFilled() then client:send(500, "inventory filled") return end
-- Remove the OpenOS Bios and store it in the last slot of top chest
local res, err = removeEEPROM(27)
if res == nil then respond(pkt, 500, err) return end
if res == nil then client:send(500, err) return end
computer.beep(100)
local res, err = loadNewEEPROM()
if res == nil then respond(pkt, 500, err) return end
if res == nil then client:send(500, err) return end
computer.beep(100)
if pkt.data[3] == nil then
pkt.data[3] = "Flashed EEPROM"
end
local res, err = flashEEPROM(worker, port, pkt.data[2], pkt.data[3])
if res == nil then respond(pkt, 500, err) return end
local res, err = flashEEPROM(worker, pkt.data[2], pkt.data[3])
if res == nil then client:send(500, err) return end
-- Now the NBT data of the eeprom will update on the next auto save
-- To detect this we're going to check the item stack every few seconds until the labels match
@ -168,24 +175,39 @@ local function waitForJob(port, worker)
computer.beep(1000)
local location, err = removeEEPROM()
if location == nil then respond(pkt, 500, err) return end
if location == nil then client:send(500, err) return end
computer.beep(100)
-- Load the old EERPOM
transposer.transferItem(sides.top, sides.left, 1, 27, EEPROM_SLOT)
computer.beep(100)
respond(pkt, 200, location)
client:send(200, location)
computer.beep(1000)
print("Success!")
else
client:send(404)
end
client:close()
end
local function startServer(port)
worker = meetWorker(port)
print("I am " .. net.addr)
local worker = meetWorker(port)
local interrupted = false
-- Soft interrupt
local interruptID = event.listen("interrupted", function() interrupted = true end)
while true do
print(waitForJob(port, worker))
while not interrupted do
waitForJob(port, worker)
end
-- Don't forget to close sockets!
worker:close()
event.cancel(interruptID)
end
startServer(10)

18
eeprom-worker.lua

@ -1,7 +1,9 @@
local net = require("net")
local component = require("component")
local sides = require("sides")
local os = require("os")
local computer = computer or require("computer")
local component = component or require("component")
local sides = sides or require("sides")
local os = os or require("os")
local function meet_server(port)
while true do
@ -18,10 +20,12 @@ local function meet_server(port)
print("recv 10 ack")
local pkt, err = net.recv{port, filter = ack, timeout = 5}
print(pkt)
if pkt ~= nil then
return pkt.raddr
print("found server " .. pkt.raddr)
if pkt ~= nil then
return pkt.raddr
end
end
end
end
@ -45,7 +49,7 @@ local function wait_for_job(port, server)
local eeprom = require("component").eeprom
print("Found eeprom", eeprom.getData())
print("Flashing EEPROM", #pkt.data[2], "bytes")
print("Flashing EEPROM " .. tostring(#pkt.data[2]) .. " bytes")
eeprom.set(pkt.data[2])
computer.beep(500)

37
lib/http.lua

@ -0,0 +1,37 @@
local computer = computer or require("computer")
local event = event or require("event")
local modem = component.proxy(component.list("modem")())
local function unknown()
-- do nothing
end
local http = {}
local http.handlers = setmetatable({}, { __index = function() return unknown end })
local function http.example()
http.handlers["/example"] = function (...)
-- "modem_message", local addr, remote addr, port, distance, "/example"
tmp = {...}
modem.send(tmp[3], tmp[4], "hello world")
end
end
local function http.listen(port)
modem.open(port)
eventID = event.listen("modem_message", function (_, ...)
-- event type, local addr, remote addr, port, distance, msg
tmp = {...}
-- Filter out messages coming from the wrong port
if tmp[3] ~= port then return end
-- Forward message to the correct handler
http.handlers[tmp[5]](tmp)
end)
return eventID
end

6
lib/net.lua

@ -35,7 +35,7 @@ function isUUID(s)
end
-- Resolve addresses if they aren't UUIDs
function checkAddr(addr)
function net.checkAddr(addr)
if not isUUID(addr) then
return dns.query(addr)
end
@ -71,7 +71,7 @@ end
-- Send network packets
-- Auto serializes data for you
function net.send(addr, port, ...)
addr = checkAddr(addr)
addr = net.checkAddr(addr)
local arg = table.pack(...)
for k, v in ipairs(arg) do
-- Only serialize tables
@ -125,7 +125,7 @@ function net.recv(t)
t[6] or t.nonblocking
if addr ~= nil then
addr = checkAddr(addr)
addr = net.checkAddr(addr)
end
-- Automatically open port to listen on

83
lib/socket.lua

@ -4,6 +4,11 @@ local event = event or require("event")
local Queue = require("queue")
local net = require("net")
-- Sockets allow for simplier 2 way communicatation
-- An event listener is created to recieve incoming messages and automatically queue them
-- You should probably remember to close the socket when your done
-- You don't _nessacrily_ have to create a socket on both sides
local Socket = {}
Socket.__index = Socket
@ -13,42 +18,88 @@ setmetatable(Socket, {
end,
})
function Socket.new(addr, port)
function Socket.new(raddr, port)
local self = setmetatable({}, Socket)
self.addr = addr
self.raddr = net.checkAddr(raddr)
self.port = port
self.q = Queue()
self._queue = Queue()
-- name, local addr, remote addr, port, distance, msg
listener = function(...)
tmp = {...}
-- local addr, remote addr, port, distance, msg
self.listener = function(name, ...)
t = {...}
for k, v in pairs(tmp) do print(k, v) end
if t[2] ~= self.addr or t[3] ~= self.port then return end
-- Check if port and raddr match
if tmp[3] ~= self.raddr or tmp[4] ~= self.port then
print("denied")
return
end
print("accepted")
self.q:push(t)
pkt = {}
pkt.laddr, pkt.raddr, pkt.port, pkt.distance, pkt.msg = tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]
self._queue:push(pkt)
end
net.open(port)
self.id = event.listen("modem_message", self.listener)
-- Create modem_message listener
self._listener = event.listen("modem_message", listener)
-- Close socket on interrupt
self._interrupter = event.listen("interrupted", function() self:close() end)
return self
end
function Socket:close()
net.close(self.port)
self.queue = nil
event.cancel(self.id)
event.cancel(self._listener)
event.cancel(self._interrupter)
-- Mark for garbage collection. Maybe this isn't needed?
self._queue = nil
self = nil
end
-- Send along msg, data
function Socket:send(msg, ...)
net.send(self.addr, self.port, msg, ...)
t = {...}
if t ~= nil then
print("Sending " .. self.raddr .. " " .. tostring(self.port) .. " " .. msg .. " ")
else
print("Sending " .. self.raddr .. " " .. tostring(self.port) .. " " .. msg .. " ")
end
net.send(self.raddr, self.port, msg, ...)
end
-- Pop results of queue
function Socket:recieve()
return self.q:pop()
-- Pop off the queue
-- blocking true if you want to block main execution until we recieve a message
-- if blocking is true you can also optionally add a timeout
function Socket:recieve(blocking, timeout)
if blocking == nil then blocking = false end
-- Get the result from the queue
local result = self._queue:pop()
-- If there is not a result and we're blocking then wait until we recieve one
if result == nil and blocking then
print("blocking")
if timeout == nil then
pkt, err = net.recv{self.port, self.raddr}
else
pkt, err = net.recv{self.port, self.raddr, timeout=timeout}
end
result = pkt
print("Some reason we got : " .. pkt.laddr .. " " .. pkt.raddr)
end
return result
end
return Socket

11
lib/webflash.lua → lib/webflashlib.lua

@ -3,15 +3,14 @@ local net = net or require("net")
local function webflash(bytes, label)
if label == nil then
net.broadcast(10, "eeprom-flash", bytes)
net.broadcast(10, "webflash", bytes)
else
net.broadcast(10, "eeprom-flash", bytes, label)
net.broadcast(10, "webflash", bytes, label)
end
computer.beep(200)
local pkt, err = net.recv{10}
computer.beep(1000)
return pkt.data[1], tostring(pkt.data[2])
end
end
return webflash

12
webflash-client.lua → webflash.lua

@ -1,7 +1,8 @@
-- This file takes as input a script and a label
-- it will ask the local eeprom machine to flash it to an eeprom
require("webflash")
local computer = computer or require("computer")
local webflash = require("webflashlib")
local args = {...}
@ -11,6 +12,11 @@ local file = assert(io.open(args[1], "rb"))
local bios = file:read("*a")
file:close()
computer.beep(100)
print("Sending " .. tostring(#bios) .. " bytes")
webflash(bios, args[2])
resp, msg = webflash(bios, args[2])
print("Reponse:")
print(resp, msg)
computer.beep(1000)
Loading…
Cancel
Save