Advertisement
Guest User

Test code for connection API

a guest
Jan 21st, 2014
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.87 KB | None | 0 0
  1. -- Crafted this code specifically for lyqyd net testing, there may be bugs and
  2. -- odd architecture in here due to the fact that I ripped all this out of my
  3. -- framework. :)
  4.  
  5. os.loadAPI("connection")
  6. os.loadAPI("net")
  7. os.loadAPI("netfile")
  8. os.loadAPI("netscreen")
  9.  
  10. -- Logging
  11. local fd = nil
  12. function logToFile(filename)
  13.    if (filename ~= nil) then
  14.       fd = fs.open(filename,"a")
  15.       if (fd == nil) then
  16.      log("Unable to open '%s' for logging", filename)
  17.      return false
  18.       end
  19.       return true
  20.    else
  21.       log("Filename not provided to logToFile")
  22.       return false
  23.    end
  24. end
  25. function log(fmt, ... )
  26.    local out = nil
  27.    if (arg == nil or arg[1] == nil) then
  28.       out = fmt
  29.    else
  30.       out = string.format(fmt,unpack(arg))
  31.    end
  32.    print(out)
  33.    if (fd ~= nil) then
  34.       fd.writeLine(out)
  35.       fd.flush()
  36.    end
  37. end
  38.  
  39. -- Peripheral checking
  40. local sides = { "left", "right", "top", "bottom", "front", "back" }
  41. local mon = {}
  42. local monfound = false
  43. local modemside = nil
  44.  
  45. for i,v in ipairs(sides) do
  46.    local ptype = peripheral.getType(v)
  47.    if (ptype ~= nil) then
  48.       log("...Found '%s' on the %s", ptype, v)
  49.       if (peripheral.getType(v) == "monitor") then
  50.      mon[v] = peripheral.wrap(v)
  51.      monfound = true
  52.       end
  53.       if (peripheral.getType(v) == "modem") then
  54.      modemside = v
  55.       end
  56.    end
  57. end
  58.  
  59. function hasModem()
  60.    if (modemside ~= nil) then
  61.       return true
  62.    else
  63.       return false
  64.    end
  65. end
  66.  
  67. function hasMonitor()
  68.    return monfound
  69. end
  70.  
  71. function getMonitors()
  72.    return mon
  73. end
  74.  
  75. -- Table dump with recursion
  76. local function tval(v,l)
  77.   local tv = type(v)
  78.  
  79.   if tv == 'string' then
  80.      return v
  81.   elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
  82.      return tostring(v)
  83.   elseif tv == 'table' then
  84.      return tdump(v,l+1)
  85.   else
  86.      return '(unknown)'
  87.   end
  88.  
  89. end
  90.  
  91.  
  92. function tdump(t,l)
  93.    if (type(t) ~= "table") then
  94.       return '(not a table)'
  95.    end
  96.    if (l == nil) then
  97.       l = 0
  98.    end
  99.    local str = "tbl["
  100.    local nulltable = true
  101.    for k,v in pairs(t) do
  102.       nulltable = false
  103.       str = str .. tostring(k)..":"..tval(v,l) .."|"
  104.    end
  105.    if (not nulltable) then
  106.       str = string.sub(str,0,string.len(str)-1)
  107.    end
  108.    str = str .. "]lbt"
  109.    return str
  110. end
  111.  
  112.  
  113. -- Port (Socket) numbers we use
  114. S_sock_echo = 7
  115.  
  116. --- Hosts file stuff
  117. csep = 'ZZZ'
  118. local hosttable = {}
  119. local typetable = {}
  120. function readHosts()
  121.    hosttable = {}
  122.    if fs.exists("/etc/hosts") then
  123.       local file = io.open("/etc/hosts", "r" )
  124.       local line = file:read()
  125.       while line do
  126.      local id,type,host = string.match(line,"^(%d+)%:.*%;([CRT]) (%w+)")
  127.      if (host) then
  128.         hosttable[host] = id
  129.         typetable[host] = type
  130.      else
  131.         log("Unparsable hosts line: '%s'",line)
  132.      end
  133.      line = file:read()
  134.       end
  135.       file:close()
  136.    end
  137. end
  138.  
  139. function displayHosts()
  140.    return function()
  141.          readHosts();
  142.          log("##>> Hosts file")
  143.          for host,id in pairs(hosttable) do
  144.         print(string.format("%3d - %s",id,host))
  145.          end
  146.          log("##<< Hosts file")
  147.       end
  148. end
  149.  
  150. function doDisplayHosts()
  151.    f = displayHosts()
  152.    f()
  153. end
  154.  
  155. function getClass(host)
  156.    return string.match(host,"^(%w+)"..csep..".*")
  157. end
  158.  
  159. function getID(host)
  160.    return hosttable[host]
  161. end
  162.  
  163. function getType(host)
  164.    return typetable[host]
  165. end
  166.  
  167. function getInstances(class)
  168.    local insts = {}
  169.    for host,id in pairs(hosttable) do
  170.       if (string.match(host, "^"..class..csep)) then
  171.      table.insert(insts, host)
  172.       end
  173.    end
  174.    return insts
  175. end
  176.  
  177.  
  178. ------- SERVER CODE
  179. --- Standard daemon skeleton code, this returns a function with your server handling the
  180. --- valid message types below, in the foreground (no coroutine.yield).
  181. --- Note the serverCode is called like so:
  182. ---   serverCode(conn, packet)
  183. ---
  184. local validMessages = {
  185.    ["data"]=1,
  186.    ["instruction"]=1,
  187.    ["event"]=1
  188. }
  189. function newServer(serverName, serverPort, serverCode)
  190.    log("Creating new daemon '%s' port %d ", serverName, serverPort)
  191.    return function ()
  192.      log("Daemon '%s' starting up",serverName)
  193.      local connections = {}
  194.      
  195.      while true do
  196.         local p, conn = connection.listen(serverPort)
  197.         local messType = packet.types[p.type]
  198.         local key = conn:name()
  199.         log("Received packet: %s - %s - %s",
  200.         tostring(conn:name()), tostring(messType), tostring(p.payload))
  201.         if connections[key] and connections[key].status == "open" then
  202.            if validMessages[messType] then
  203.           serverCode(conn, p)
  204.            elseif messType == "close" then
  205.           conn:close()
  206.           connections[key].status = "closed"
  207.            end
  208.         elseif messType == "query" then
  209.            log("Query received?")
  210.            if connections[key] then
  211.           log("Interpreting as already open")
  212.           connections[key].status = open
  213.            else
  214.           local connect = {}
  215.           connect.status = "open"
  216.           connect.conn = conn
  217.           connections[key] = connect
  218.            end
  219.            if conn:send("response", "ok") then
  220.           log("Response sent")
  221.            else
  222.           log("Response not sent!")
  223.                end
  224.         end
  225.      end
  226.       end
  227. end
  228.  
  229. ------CLIENT CODE
  230. local cfac = "client"
  231. local contbl = {}
  232.  
  233. -- Common connection code, returns true or false based on success
  234. -- if you provide a timeout note that deep in there is os.timer stuff
  235. function connectTo( name, port, timeout )
  236.    if (not name) then
  237.       log("Must specify a name in connectTo()")
  238.       return false
  239.    end
  240.      
  241.    if (not port) then
  242.       log("Must specify a port in connectTo()")
  243.       return false
  244.    end
  245.      
  246.    log("Connecting to %s:%d", name, port)
  247.    if (contbl[name]) then
  248.       return contbl[name]
  249.    else
  250.       local conn = connection.new(name, port)
  251.       if (not conn) then
  252.      log("Failed to get new connection")
  253.      return false
  254.       end
  255.       if (conn:open(timeout)) then
  256.      contbl[conn:name()] = conn
  257.      return conn
  258.       else
  259.      log("Failed to open %s:%d", name, port)
  260.      return false
  261.       end
  262.    end
  263. end
  264.  
  265. -- Echo client
  266. function echoToRouter( routerName, message )
  267.    conn = connectTo(routerName, S_sock_echo, 10)
  268.    if (not conn) then
  269.       return false
  270.    end
  271.    log("Echo client connected to '%s'", routerName)
  272.    conn:send("data", message)
  273.    log("Data message sent '%s'", message)
  274.    local p = conn:listen(10)
  275.    if (p) then
  276.       log("Message recieved '%s'", p.payload)
  277.       return true
  278.    else
  279.       log("No message recieved '%s'")
  280.       return false
  281.    end
  282. end
  283.  
  284.  
  285. if (not hasModem()) then
  286.    log("Needs modem")
  287.    os.exit()
  288. end
  289.  
  290. local router = false
  291. local myname = "pinger"
  292. local args = { ... }
  293. if (args[1] ~= nil) then
  294.    router = true
  295.    myname = "router"
  296. end
  297. os.setComputerLabel(myname)
  298. local myid = os.getComputerID()
  299. log("Pinger started: I am %s (%d)",myname, myid)
  300.  
  301. shell.run("lyqydnet")
  302. log("Lyqyd net done")
  303. if (router) then
  304.    shell.run("router")
  305. end
  306. net.netInit()
  307. log("netInit done")
  308.  
  309. if (router) then
  310.    log("Running router...")
  311.    readHosts()
  312.  
  313.    local echoServe = newServer("echo", S_sock_echo,
  314.                    function(conn, packet)
  315.                   if (packet.types[packet.type] == "data") then
  316.                      if (conn:send("data", packet.payload)) then
  317.                     log("Echoing [%s]",packet.payload)
  318.                      else
  319.                     log("Could not echo: send failed")
  320.                      end
  321.                   else
  322.                      log("Illegal packet: %s (%s)", packet.types[packet.type], packet.payload);
  323.                   end
  324.                    end)
  325.    echoServe()               
  326.  
  327. else
  328.    log("Running pinger...")
  329.    readHosts()
  330.  
  331.    while true do
  332.       local timerid = os.startTimer(5)
  333.       while true do
  334.      local event = { os.pullEvent() }
  335.      if (event[1] == "timer" and event[2] == timerid) then
  336.         for i,v in ipairs(getInstances("router")) do
  337.            log("%s sending", v)
  338.            if (echoToRouter(v, "ping")) then
  339.           log("%s responded", v)
  340.            end
  341.         end
  342.         break
  343.      else
  344.         log("Discarding event: %s",tdump(event))
  345.      end
  346.       end
  347.    end
  348. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement