/* Copyright 2012, Sebastian Reichel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ public class RPCServer { SocketService srv; public RPCServer(uint16 port) throws Error { srv = new SocketService(); srv.add_inet_port(port, null); srv.incoming.connect(on_incoming_connection); srv.start(); } bool on_incoming_connection(SocketConnection con) { log("RPCServer", LogLevelFlags.LEVEL_DEBUG, "Got incoming connection"); process_request.begin(con); return true; } async void process_request(SocketConnection con) { var dis = new DataInputStream(con.input_stream); var dos = new DataOutputStream(con.output_stream); bool exit = false; try { while(!exit) { string msg = yield dis.read_line_async(Priority.HIGH_IDLE); if(msg != null) { var pkg = new Variant.parsed(msg); var cmd = pkg.get_child_value(0).get_byte(); switch(cmd) { case Command.SetEngineSpeed: var engine = pkg.get_child_value(1).get_byte(); var speed = pkg.get_child_value(2).get_byte(); log("RPCServer", LogLevelFlags.LEVEL_DEBUG, "set engine speed: %d = %d", engine, speed); set_speed(engine, speed); break; case Command.SetEngineSpeedAll: var speed = pkg.get_child_value(1).get_byte(); log("RPCServer", LogLevelFlags.LEVEL_DEBUG, "set engine speed of all engines: %d", speed); set_speed_all(speed); break; default: log("RPCServer", LogLevelFlags.LEVEL_WARNING, "Unknown Command: %s\n".printf(pkg.print(false))); break; } dos.put_string("OK\n"); } else { exit = true; } } } catch(Error e) { log("RPCServer", LogLevelFlags.LEVEL_CRITICAL, "%s\n", e.message); } } public signal void set_speed(uint8 engine, uint8 speed); public signal void set_speed_all(uint8 speed); } public class Socket : Receiver { int32 channel_data[4]; RPCServer srv; public override uint8 size { get { return (uint8) channel_data.length; } } public override void init(KeyFile cfg) throws Error { uint16 port = (uint16) cfg.get_uint64("Socket", "port"); srv = new RPCServer(port); srv.set_speed.connect((id, speed) => {set_speed(id, speed);}); } public override int32 get_value(uint8 channel) { return channel_data[channel]; } public override void set_value(uint8 channel, int32 value) { /* TODO */ } } public Type register_plugin(Module module) { // types are registered automatically typeof(RPCServer); return typeof(Socket); }