mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-23 18:08:05 +11:00
79 lines
1.8 KiB
Lua
79 lines
1.8 KiB
Lua
|
-- I, 20kdc, release this into the public domain.
|
||
|
-- No warranty is provided, implied or otherwise.
|
||
|
|
||
|
-- Light Copper Base node that communicates to a server via an
|
||
|
-- Internet Card.
|
||
|
-- Only handles one modem for now.
|
||
|
|
||
|
local args = {...}
|
||
|
if #args ~= 3 then error("name, tcphost, tcpport") end
|
||
|
|
||
|
local component = require("component")
|
||
|
local cdlib = require("cdlib")
|
||
|
local event = require("event")
|
||
|
|
||
|
-- Adjust to taste.
|
||
|
local tcp = require("internet").open(tostring(args[2]), tonumber(args[3]))
|
||
|
|
||
|
local md = component.modem
|
||
|
md.open(4957)
|
||
|
|
||
|
tcp:setTimeout(0.05)
|
||
|
tcp:write(string.char((#(args[1])) - 1) .. args[1])
|
||
|
tcp:flush()
|
||
|
|
||
|
print("TCP up")
|
||
|
|
||
|
local function verify(d)
|
||
|
local hops, src, dst, data = cdlib.decode(d)
|
||
|
if not data then return end
|
||
|
-- Just a bit of filtering
|
||
|
if dst:sub(1, 1) ~= "<" then return end
|
||
|
if d:len() > 2021 then return end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local function readByte()
|
||
|
while true do
|
||
|
local ok, err = pcall(tcp.read, tcp, 1)
|
||
|
if ok then return err end
|
||
|
-- not nice :(
|
||
|
if err:find("timeout") then
|
||
|
coroutine.yield()
|
||
|
else
|
||
|
error(err)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
local function readerRoutine()
|
||
|
while true do
|
||
|
local h = readByte()
|
||
|
local l = readByte()
|
||
|
local sz = string.byte(l) + (string.byte(h) * 256)
|
||
|
print("Incoming packet size " .. sz)
|
||
|
local dat = ""
|
||
|
for i = 1, sz do
|
||
|
dat = dat .. readByte()
|
||
|
end
|
||
|
md.broadcast(4957, "copper", dat)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local primary = coroutine.create(readerRoutine)
|
||
|
while true do
|
||
|
local et, _, _, p, _, m, d = event.pull(0.1)
|
||
|
local ok, o = coroutine.resume(primary)
|
||
|
if not ok then error(o) end
|
||
|
if et == "modem_message" and p == 4957 then
|
||
|
if m == "copper" then
|
||
|
-- Incoming Copper packet.
|
||
|
if verify(d) then
|
||
|
local h = math.floor(d:len() / 256)
|
||
|
local l = d:len() % 256
|
||
|
tcp:write(string.char(h, l) .. d)
|
||
|
tcp:flush()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|