summaryrefslogtreecommitdiffstats
path: root/receiver/socket.vala
blob: 27f02f77bebb1231dd3ee822e2a53aa7a12ee2c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* Copyright 2012, Sebastian Reichel <sre@ring0.de>
 *
 * 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) {
		stdout.printf("Got incoming connection\n");
		process_request(con);
		return true;
	}

	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) {
				size_t length;
				string message = dis.read_line(out length);

				if(length > 0) {
					var pkg = new Variant.parsed(message);

					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();
							stdout.printf("set engine speed: %d = %d\n", engine, speed);
							set_speed(engine, speed);
							break;
						case Command.SetEngineSpeedAll:
							var speed  = pkg.get_child_value(1).get_byte();
							stdout.printf("set engine speed of all engines: %d\n", speed);
							set_speed_all(speed);
							break;
						default:
							stdout.printf("Unknown Command: %s\n".printf(pkg.print(false)));
							break;
					}

					dos.put_string("OK\n");
				} else {
					exit = true;
				}
			}
		} catch(Error e) {
			stderr.printf("%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_all.connect((speed) => {channel_data[0] = 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);
}