mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-11 12:28:06 +11:00
b26a48165d
The light node system should only be used where necessary, as light nodes contribute absolutely nothing to network messaging. Maybe a minified full port of culib could be made for a "medium node", which would be (protocol behavior-wise) exactly like normal nodes, but minified and with interfaces cut down internally.
132 lines
3.5 KiB
Lua
132 lines
3.5 KiB
Lua
-- I, 20kdc, release this into the public domain.
|
|
-- No warranty is provided, implied or otherwise.
|
|
|
|
-- Controller for objects following the 'IoT protocol'
|
|
-- (see provided microcontroller source for a lightweight OC implementation)
|
|
|
|
local occure = require("occure")
|
|
local event = require("event")
|
|
local args = {...}
|
|
local cmdinfo = {
|
|
["help"] = {"Lists the commands"},
|
|
["discover"] = {"Sends a packet on the discovery port to a given address", "target"},
|
|
["get"] = {"Gets a value", "target", "index"},
|
|
["set"] = {"Sets a value", "target", "index", "data"},
|
|
["invoke"] = {"Runs an action", "target", "index", "data"}
|
|
}
|
|
|
|
local function packet(tp, idx, data)
|
|
return string.char(idx + (tp * 64)) .. data
|
|
end
|
|
|
|
local didGet = false
|
|
local getTarg = 0
|
|
local function getHelper(tp, tfrom, tto, p, d, u)
|
|
if tp ~= "copper_packet" then return end
|
|
if p == 4 then
|
|
if tto == occure.getHostname() then
|
|
if d:sub(1, 1) == packet(3, getTarg, "") then
|
|
print(d:sub(2))
|
|
didGet = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function displayDisc(d)
|
|
local types = {
|
|
[0] = "void",
|
|
[0x40] = "void=",
|
|
[0x80] = "action(void)",
|
|
[1] = "string",
|
|
[0x41] = "string=",
|
|
[0x81] = "action(string)",
|
|
[2] = "boolean",
|
|
[0x42] = "boolean=",
|
|
[0x82] = "action(boolean)",
|
|
[3] = "float",
|
|
[0x43] = "float=",
|
|
[0x83] = "action(float)",
|
|
[4] = "descriptor",
|
|
[0x44] = "descriptor=",
|
|
[0x84] = "action(descriptor)",
|
|
}
|
|
while #d > 7 do
|
|
local tp = d:byte()
|
|
local n = types[tp] or ("unknown " .. tp)
|
|
print(" " .. d:sub(2, 8) .. ": " .. n)
|
|
d = d:sub(9)
|
|
end
|
|
end
|
|
local function discHelper(tp, tfrom, tto, p, d, u)
|
|
if tp ~= "copper_packet" then return end
|
|
if p == 4 then
|
|
if tto == occure.getHostname() then
|
|
if d:byte() == 0xC0 then
|
|
-- Discovery response.
|
|
print("\"" .. tfrom .. "\"")
|
|
displayDisc(d:sub(2))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local commands = {
|
|
["help"] = function ()
|
|
for k, v in pairs(cmdinfo) do
|
|
print(k .. ": " .. v[1])
|
|
for i = 2, #v do
|
|
print(" " .. v[i])
|
|
end
|
|
end
|
|
end,
|
|
["discover"] = function (target)
|
|
occure.output(target, 1, "", true)
|
|
event.listen("copper_packet", discHelper)
|
|
pcall(os.sleep, 10)
|
|
event.ignore("copper_packet", discHelper)
|
|
end,
|
|
["get"] = function (target, index)
|
|
index = tonumber(index)
|
|
local ack = false
|
|
getTarg = index
|
|
didGet = false
|
|
occure.output(target, 4, packet(0, index, ""), false, function() ack = true end)
|
|
event.listen("copper_packet", getHelper)
|
|
local safety = 0
|
|
while (not didGet) and (safety < 30) do
|
|
os.sleep(1)
|
|
safety = safety + 1
|
|
end
|
|
event.ignore("copper_packet", getHelper)
|
|
if not didGet then
|
|
if ack then
|
|
print("ACK'd but no response - bad parameters likely.")
|
|
else
|
|
print("Didn't get any response, not even an ACK.")
|
|
end
|
|
end
|
|
end,
|
|
["set"] = function (target, index, data)
|
|
index = tonumber(index)
|
|
local complete = nil
|
|
occure.output(target, 4, packet(1, index, data), false, function() complete = "acknowledged!" end, function() complete = "unacknowledged :(" end)
|
|
while not complete do
|
|
os.sleep(1)
|
|
end
|
|
print(complete)
|
|
end,
|
|
["invoke"] = function (target, index, data)
|
|
index = tonumber(index)
|
|
local complete = nil
|
|
occure.output(target, 4, packet(2, index, data), false, function() complete = "acknowledged!" end, function() complete = "unacknowledged :(" end)
|
|
while not complete do
|
|
os.sleep(1)
|
|
end
|
|
print(complete)
|
|
end
|
|
}
|
|
if not commands[args[1]] then error("No such command - try 'iot-mgr help'") end
|
|
if #args ~= #cmdinfo[args[1]] then error("Parameter count mismatch.") end
|
|
commands[args[1]](select(2, table.unpack(args)))
|