source: xplra/misc/client.py@ 5:94fdd791268f

Last change on this file since 5:94fdd791268f was 3:459106f9bf9a, checked in by István Váradi <ivaradi@…>, 11 years ago

Very basic client and server functionality works

File size: 5.1 KB
Line 
1#!/usr/bin/env python
2
3import cmd
4import struct
5import socket
6import os
7
8#------------------------------------------------------------------------------
9
10class CLI(cmd.Cmd):
11 """Simple command-line interface for the X-Plane Remote Access plugin."""
12 _types = { "i" : 0x01,
13 "f" : 0x02,
14 "d" : 0x03,
15 "fa" : 0x11,
16 "ia" : 0x12,
17 "ba" : 0x13 }
18
19 @staticmethod
20 def _packLength(x):
21 """Pack the given integer as a variable-length value."""
22 s = ""
23 while True:
24 y = x&0x7f
25 x >>= 7
26 if x>0: y |= 0x80
27 s += struct.pack("B", y)
28 if x==0:
29 return s
30
31 @staticmethod
32 def _packString(s):
33 """Pack the given string."""
34 return CLI._packLength(len(s)) + s
35
36 def __init__(self, stream):
37 """Construct the CLI."""
38 cmd.Cmd.__init__(self)
39
40 self._stream = stream
41
42 self.use_rawinput = True
43 self.intro = "\nX-Plane Remote Access plugin command prompt\n"
44 self.prompt = "XPLRA>"
45
46 self.daemon = True
47
48 def default(self, line):
49 """Handle uhandled commands"""
50 if line=="EOF":
51 print
52 return self.do_quit("")
53 else:
54 return super(CLI, self).default(line)
55
56 def do_get(self, args):
57 """Handle the 'get' command"""
58 words = args.split()
59 if len(words)<2:
60 print >> sys.stderr, "missing parameters"
61 return False
62
63 name = words[0]
64
65 type = words[1]
66 if type not in self._types:
67 print >> sys.stderr, "invalid type"
68 return False
69
70 length = None
71 if len(words)>2:
72 length = int(words[2])
73
74 self._writeU8(0x01)
75 self._writeString(name)
76 self._writeU8(self._types[type])
77 if length is not None:
78 self._writeS32(length)
79 self._flush()
80
81 result = self._readU8()
82 print "result:", result
83 if result==0:
84 if type=="i":
85 value = self._readS32()
86 elif type=="f":
87 value = self._readFloat()
88 elif type=="d":
89 value = self._readDouble()
90 elif type=="fa":
91 length = self._readS32()
92 if length>0:
93 value = [self._readFloat() for i in range(0, length)]
94 else:
95 value = None
96 elif type=="ia":
97 length = self._readS32()
98 if length>0:
99 value = [self._readS32() for i in range(0, length)]
100 else:
101 value = None
102 elif type=="ba":
103 length = self._readS32()
104 if length>0:
105 bytes = [self._readU8() for i in range(0, length)]
106 value = ""
107 for b in bytes:
108 if b==0: break
109 value += chr(b)
110 else:
111 value = None
112
113 print "value:", value, len(value)
114
115 def _writeU8(self, x):
116 """Write the given value as an unsigned, 8-bit value."""
117 self._stream.write(struct.pack("B", x))
118
119 def _writeS32(self, x):
120 """Write the given value as a signed, 32-bit value."""
121 self._stream.write(struct.pack("i", x))
122
123 def _writeLength(self, length):
124 """Write the given value is a variable-length value into our stream."""
125 self._stream.write(self._packLength(length))
126
127 def _writeString(self, str):
128 """Write the given string into the stream."""
129 self._stream.write(self._packString(str))
130
131 def _flush(self):
132 """Flush our stream."""
133 self._stream.flush()
134
135 def _readU8(self):
136 """Read an unsigned, 8-bit value from the stream."""
137 (value,) = struct.unpack("B", self._stream.read(1))
138 return value
139
140 def _readS32(self):
141 """Read a signed, 32-bit value from the stream."""
142 (value,) = struct.unpack("i", self._stream.read(4))
143 return value
144
145 def _readFloat(self):
146 """Read a single-precision floating point value from the stream."""
147 (value,) = struct.unpack("f", self._stream.read(4))
148 return value
149
150 def _readDouble(self):
151 """Read a double-precision floating point value from the stream."""
152 (value,) = struct.unpack("d", self._stream.read(8))
153 return value
154
155 def _readLength(self):
156 """Read a variable-length value from our stream."""
157 length = 0
158 while True:
159 (x,) = struct.unpack("B", self._stream.read(1))
160 length <<= 7
161 length |= x&0x7f
162 if x&0x80==0:
163 return length
164
165 @staticmethod
166 def _readString(self):
167 """Read a string from our stream."""
168 length = self._readLength()
169 return self._stream.read(length)
170
171#------------------------------------------------------------------------------
172
173if __name__ == "__main__":
174 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
175 s.connect("/tmp/xplra-" + os.environ["LOGNAME"])
176 CLI(s.makefile()).cmdloop()
Note: See TracBrowser for help on using the repository browser.