Commit f0c9daeeb5c3777e531a3078f4e250e19c8595c4
1 parent
861b8b8a60
Exists in
master
Mainly cosmetic changes and add decode/encode to read/write procedure on socket
Showing 1 changed file with 28 additions and 38 deletions Side-by-side Diff
eddsctrl_server/eddsctrlserver
| 1 | -#!/usr/bin/python2.7 | |
| 1 | +#!/usr/bin/python3 | |
| 2 | 2 | # -*- coding: utf-8 -*- |
| 3 | 3 | |
| 4 | 4 | """package eddsctrl_server |
| 5 | 5 | |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | |
| ... | ... | @@ -15,36 +15,32 @@ |
| 15 | 15 | for the message using the length prefix technique. |
| 16 | 16 | """ |
| 17 | 17 | |
| 18 | -import logging | |
| 19 | -CONSOLE_LOG_LEVEL = logging.DEBUG | |
| 20 | -FILE_LOG_LEVEL = logging.DEBUG | |
| 18 | +# Ctrl-c closes the application | |
| 19 | +import signal | |
| 20 | +signal.signal(signal.SIGINT, signal.SIG_DFL) | |
| 21 | 21 | |
| 22 | 22 | import os |
| 23 | -try: | |
| 24 | - import configparser | |
| 25 | -except ImportError: | |
| 26 | - import ConfigParser as configparser | |
| 27 | -try: | |
| 28 | - from queue import Queue, Empty | |
| 29 | -except ImportError: | |
| 30 | - from Queue import Queue, Empty | |
| 23 | +import logging | |
| 24 | +import configparser | |
| 25 | +from queue import Queue, Empty | |
| 31 | 26 | from struct import pack, unpack |
| 32 | 27 | from select import select |
| 33 | 28 | from socket import socket, AF_INET, SOCK_STREAM |
| 34 | 29 | |
| 35 | 30 | from dds.ad9912dev import Ad9912Dev as DdsDevice # for actual use |
| 36 | 31 | #from dds.dds_emul import TestUsbDds as DdsDevice # for test without DDS |
| 37 | - | |
| 38 | -from eddsctrl_server.constants import APP_NAME, SERVER_PORT, SERVERHOST, \ | |
| 32 | +from eddsctrl_server.constants import SERVER_PORT, SERVERHOST, \ | |
| 39 | 33 | DEFAULT_IFREQ, DEFAULT_OFREQ, DEFAULT_AMP, DEFAULT_PHY, \ |
| 40 | 34 | CFG_SERVER_FILE, LOG_SERVER_FILE |
| 41 | 35 | |
| 36 | +CONSOLE_LOG_LEVEL = logging.DEBUG | |
| 37 | +FILE_LOG_LEVEL = logging.DEBUG | |
| 42 | 38 | |
| 43 | 39 | #============================================================================== |
| 44 | 40 | class EDdsCtrlServer(object): |
| 45 | 41 | """Class dedicated to interface socket client with DDS device. |
| 46 | 42 | Provide a basic interface to handle client queries: |
| 47 | - Message is built using the length prefix technique: length is sent as a | |
| 43 | + Message is built using the length prefix technique: length is sent as a | |
| 48 | 44 | packed 4-byte little-endian integer. |
| 49 | 45 | Allow only 4 queries, changement of output frequency, input frequency, |
| 50 | 46 | phase or amplitude value. |
| ... | ... | @@ -108,7 +104,7 @@ |
| 108 | 104 | raise Exception("Unexpected error during DDS initialisation: %s" \ |
| 109 | 105 | % str(ex)) |
| 110 | 106 | logging.debug("DDS inititialization done") |
| 111 | - | |
| 107 | + | |
| 112 | 108 | def _init_server(self): |
| 113 | 109 | """Create and configure a basic server object. |
| 114 | 110 | :returns: None |
| 115 | 111 | |
| 116 | 112 | |
| ... | ... | @@ -163,14 +159,14 @@ |
| 163 | 159 | # Established connection |
| 164 | 160 | else: |
| 165 | 161 | header_data = self._recv_n_bytes(sock, 4) |
| 166 | - if header_data == None: | |
| 162 | + if header_data is None: | |
| 167 | 163 | logging.error("Message seems received but no data to read") |
| 168 | 164 | return |
| 169 | 165 | if len(header_data) == 4: |
| 170 | 166 | msg_len = unpack('<L', header_data)[0] |
| 171 | - data = self._recv_n_bytes(sock, msg_len) | |
| 167 | + data = self._recv_n_bytes(sock, msg_len).decode('utf-8') | |
| 172 | 168 | # Check message validity |
| 173 | - if data == None: | |
| 169 | + if data is None: | |
| 174 | 170 | logging.error("Message received but no data to read") |
| 175 | 171 | return |
| 176 | 172 | if len(data) != msg_len: |
| 177 | 173 | |
| ... | ... | @@ -221,14 +217,14 @@ |
| 221 | 217 | sock.getpeername()) |
| 222 | 218 | # Stop listening for input on the connection |
| 223 | 219 | self.inputs.remove(sock) |
| 224 | - if sock in outputs: | |
| 220 | + if sock in self.outputs: | |
| 225 | 221 | self.outputs.remove(sock) |
| 226 | 222 | sock.close() |
| 227 | 223 | # Remove message queue |
| 228 | 224 | del self.message_queues[sock] |
| 229 | 225 | except Exception as ex: |
| 230 | 226 | logging.error("Unexpected error: %s", ex) |
| 231 | - | |
| 227 | + | |
| 232 | 228 | def _input_msg_handler(self, msg): |
| 233 | 229 | """Handle message from clients. Message format is defined in |
| 234 | 230 | :class:`eddsctrl.server.eddsctrlsserver.EDdsCtrlServer`. |
| 235 | 231 | |
| ... | ... | @@ -262,18 +258,14 @@ |
| 262 | 258 | elif index == "i?": |
| 263 | 259 | retval = self._dds.get_ifreq() |
| 264 | 260 | else: # Bad identifier, message not valid |
| 265 | - logging.error("Bad identifier," \ | |
| 266 | - "expected o[?], p[?], a[?] or i[?]: ", \ | |
| 267 | - index, " given") | |
| 261 | + logging.error("Bad identifier, expected o[?], p[?], a[?] or i[?]: " | |
| 262 | + + index + " given") | |
| 268 | 263 | return |
| 269 | 264 | # Write modification to setting file |
| 270 | 265 | with open(self._settingsf, 'w') as fd: |
| 271 | 266 | config.write(fd) |
| 272 | 267 | # Note that value actually writed in DDS (retval) can be a bit different |
| 273 | 268 | # than value sended to DDS (value). |
| 274 | - | |
| 275 | - | |
| 276 | - | |
| 277 | 269 | msg = "!" + index + "!" + str(retval) + "!" |
| 278 | 270 | return msg |
| 279 | 271 | |
| 280 | 272 | |
| 281 | 273 | |
| 282 | 274 | |
| 283 | 275 | |
| ... | ... | @@ -288,22 +280,22 @@ |
| 288 | 280 | """ |
| 289 | 281 | header = pack('<L', len(msg)) |
| 290 | 282 | try: |
| 291 | - sock.sendall(header + msg) | |
| 283 | + sock.sendall(header + msg.encode('utf-8')) | |
| 292 | 284 | except IOError as ex: |
| 293 | 285 | logging.error("Error during sending: %s", ex) |
| 294 | 286 | |
| 295 | 287 | @staticmethod |
| 296 | - def _recv_n_bytes(sock, n): | |
| 288 | + def _recv_n_bytes(sock, nb): | |
| 297 | 289 | """Convenience method for receiving exactly n bytes from socket |
| 298 | 290 | (assuming it's open and connected). |
| 299 | 291 | :param sock: socket object which receives the n bytes |
| 300 | - :param n: number of bytes to be received (int) | |
| 292 | + :param nb: number of bytes to be received (int) | |
| 301 | 293 | :returns: data received (str) |
| 302 | 294 | """ |
| 303 | 295 | data = '' |
| 304 | - while len(data) < n: | |
| 296 | + while len(data) < nb: | |
| 305 | 297 | try: |
| 306 | - chunk = sock.recv(n - len(data)) | |
| 298 | + chunk = sock.recv(nb - len(data)) | |
| 307 | 299 | if chunk == '': |
| 308 | 300 | break |
| 309 | 301 | data += chunk |
| ... | ... | @@ -375,7 +367,9 @@ |
| 375 | 367 | |
| 376 | 368 | |
| 377 | 369 | #============================================================================== |
| 378 | -def eddsctrlserver(settings_file): | |
| 370 | +def main(settings_file): | |
| 371 | + """Main | |
| 372 | + """ | |
| 379 | 373 | configure_logging() |
| 380 | 374 | if os.path.isfile(settings_file) is False: |
| 381 | 375 | logging.error("Settings file missing: create one with default values.") |
| ... | ... | @@ -385,10 +379,5 @@ |
| 385 | 379 | |
| 386 | 380 | #============================================================================== |
| 387 | 381 | if __name__ == '__main__': |
| 388 | - # Ctrl-c closes the application | |
| 389 | - import signal | |
| 390 | - signal.signal(signal.SIGINT, signal.SIG_DFL) | |
| 391 | - | |
| 392 | - eddsctrlserver(CFG_SERVER_FILE) | |
| 393 | - | |
| 382 | + main(CFG_SERVER_FILE) |