|
@@ -54,7 +54,8 @@ class tcp_base(object):
|
54
|
54
|
|
55
|
55
|
.. note:: This class is not designed for direct usage.
|
56
|
56
|
"""
|
57
|
|
- LOG_PREFIX = 'TCP_IP:'
|
|
57
|
+ DEFAULT_CHANNEL_NAME = 'all_others'
|
|
58
|
+
|
58
|
59
|
RX_LENGTH = 0xff
|
59
|
60
|
COM_TIMEOUT = 0.5
|
60
|
61
|
IS_CLIENT = False
|
|
@@ -62,6 +63,7 @@ class tcp_base(object):
|
62
|
63
|
def __init__(self, host, port, rx_log_lvl=logging.INFO):
|
63
|
64
|
self.host = host
|
64
|
65
|
self.port = port
|
|
66
|
+ self.init_channel_name()
|
65
|
67
|
self.__socket__ = None
|
66
|
68
|
self.__data_available_callback__ = None
|
67
|
69
|
self.__supress_data_available_callback__ = False
|
|
@@ -75,6 +77,12 @@ class tcp_base(object):
|
75
|
77
|
self.__queue__.enqueue(5, self.__receive_task__, rx_log_lvl)
|
76
|
78
|
self.__queue__.run()
|
77
|
79
|
|
|
80
|
+ def init_channel_name(self, channel_name=None):
|
|
81
|
+ if channel_name is None:
|
|
82
|
+ self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + self.DEFAULT_CHANNEL_NAME)
|
|
83
|
+ else:
|
|
84
|
+ self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
|
|
85
|
+
|
78
|
86
|
def is_connected(self):
|
79
|
87
|
return self.__connection__ is not None
|
80
|
88
|
|
|
@@ -105,7 +113,7 @@ class tcp_base(object):
|
105
|
113
|
if self.__connection__ is None:
|
106
|
114
|
return None
|
107
|
115
|
if time.time() > tm + timeout:
|
108
|
|
- logger.warning('%s TIMEOUT (%ss): Not enough data in buffer. Requested %s and buffer size is %d.', self.LOG_PREFIX, repr(timeout), repr(num or 'all'), len(self.__receive_buffer__))
|
|
116
|
+ self.logger.warning('TIMEOUT (%ss): Not enough data in buffer. Requested %s and buffer size is %d.', repr(timeout), repr(num or 'all'), len(self.__receive_buffer__))
|
109
|
117
|
return None
|
110
|
118
|
time.sleep(0.05)
|
111
|
119
|
if num is None:
|
|
@@ -129,17 +137,24 @@ class tcp_base(object):
|
129
|
137
|
|
130
|
138
|
This method sends data via the initiated communication channel.
|
131
|
139
|
"""
|
132
|
|
- cnt = 0
|
133
|
|
- while self.__connection__ is None and cnt < int(10 * timeout):
|
134
|
|
- time.sleep(.1) # give some time to establish the connection
|
135
|
|
- cnt += 1
|
136
|
|
- if self.__connection__ is not None:
|
137
|
|
- self.__connection__.sendall(data)
|
138
|
|
- logger.log(log_lvl, '%s TX -> "%s"', self.LOG_PREFIX, stringtools.hexlify(data))
|
139
|
|
- return True
|
140
|
|
- else:
|
141
|
|
- logger.warning('%s Cound NOT send -> "%s"', self.LOG_PREFIX, stringtools.hexlify(data))
|
142
|
|
- return False
|
|
140
|
+ tm = time.time()
|
|
141
|
+ while time.time() - tm < timeout:
|
|
142
|
+ if self.__connection__ is not None:
|
|
143
|
+ try:
|
|
144
|
+ self.__connection__.sendall(data)
|
|
145
|
+ except BlockingIOError:
|
|
146
|
+ time.sleep(.1) # try again till timeout exceeds
|
|
147
|
+ except BrokenPipeError:
|
|
148
|
+ self.logger.exception('Exception while sending data')
|
|
149
|
+ self.__connection_lost__()
|
|
150
|
+ return False
|
|
151
|
+ else:
|
|
152
|
+ self.logger.log(log_lvl, 'TX -> "%s"', stringtools.hexlify(data))
|
|
153
|
+ return True
|
|
154
|
+ else:
|
|
155
|
+ time.sleep(.1) # give some time to establish the connection
|
|
156
|
+ self.logger.warning('Cound NOT send -> "%s"', stringtools.hexlify(data))
|
|
157
|
+ return False
|
143
|
158
|
|
144
|
159
|
def register_callback(self, callback):
|
145
|
160
|
"""
|
|
@@ -184,7 +199,7 @@ class tcp_base(object):
|
184
|
199
|
time.sleep(.05)
|
185
|
200
|
else:
|
186
|
201
|
if len(data) > 0:
|
187
|
|
- logger.log(rx_log_lvl, '%s RX <- "%s"', self.LOG_PREFIX, stringtools.hexlify(data))
|
|
202
|
+ self.logger.log(rx_log_lvl, 'RX <- "%s"', stringtools.hexlify(data))
|
188
|
203
|
self.__receive_buffer__ += data
|
189
|
204
|
else:
|
190
|
205
|
self.__connection_lost__()
|
|
@@ -204,12 +219,12 @@ class tcp_base(object):
|
204
|
219
|
self.__connection__.close()
|
205
|
220
|
self.__connection__ = None
|
206
|
221
|
self.__client_address__ = None
|
207
|
|
- logger.info('%s Connection lost...', self.LOG_PREFIX)
|
|
222
|
+ self.logger.info('Connection lost...')
|
208
|
223
|
if self.__disconnect_callback__ is not None:
|
209
|
224
|
self.__disconnect_callback__()
|
210
|
225
|
|
211
|
226
|
def __clean_receive_buffer__(self):
|
212
|
|
- logger.debug("%s Cleaning up receive-buffer", self.LOG_PREFIX)
|
|
227
|
+ self.logger.debug("Cleaning up receive-buffer")
|
213
|
228
|
self.__receive_buffer__ = ""
|
214
|
229
|
|
215
|
230
|
def close(self):
|
|
@@ -258,7 +273,7 @@ class tcp_server(tcp_base):
|
258
|
273
|
self.__socket__.settimeout(self.COM_TIMEOUT)
|
259
|
274
|
self.__socket__.setblocking(False)
|
260
|
275
|
if not self.__listening_message_displayed__:
|
261
|
|
- logger.info('%s Server listening to %s:%d', self.LOG_PREFIX, self.host, self.port)
|
|
276
|
+ self.logger.info('Server listening to %s:%d', self.host, self.port)
|
262
|
277
|
self.__listening_message_displayed__ = True
|
263
|
278
|
try:
|
264
|
279
|
self.__connection__, self.__client_address__ = self.__socket__.accept()
|
|
@@ -268,7 +283,7 @@ class tcp_server(tcp_base):
|
268
|
283
|
else:
|
269
|
284
|
time.sleep(.05)
|
270
|
285
|
else:
|
271
|
|
- logger.info('%s Connection established... (from %s)', self.LOG_PREFIX, self.client_address())
|
|
286
|
+ self.logger.info('Connection established... (from %s)', self.client_address())
|
272
|
287
|
self.__clean_receive_buffer__()
|
273
|
288
|
self.__connection__.setblocking(False)
|
274
|
289
|
if self.__connect_callback__ is not None:
|
|
@@ -313,7 +328,7 @@ class tcp_client(tcp_base):
|
313
|
328
|
self.__connection__ = None
|
314
|
329
|
time.sleep(.05)
|
315
|
330
|
else:
|
316
|
|
- logger.info('%s Connection to %s:%s established', self.LOG_PREFIX, self.host, self.port)
|
|
331
|
+ self.logger.info('Connection to %s:%s established', self.host, self.port)
|
317
|
332
|
self.__clean_receive_buffer__()
|
318
|
333
|
self.__connection__ = self.__socket__
|
319
|
334
|
if self.__connect_callback__ is not None:
|
|
@@ -346,7 +361,7 @@ class tcp_base_stp(tcp_base):
|
346
|
361
|
self.__stp__ = stringtools.stp.stp()
|
347
|
362
|
|
348
|
363
|
def __clean_receive_buffer__(self):
|
349
|
|
- logger.debug("%s Cleaning up receive-buffer", self.LOG_PREFIX)
|
|
364
|
+ self.logger.debug("Cleaning up receive-buffer")
|
350
|
365
|
self.__receive_buffer__ = []
|
351
|
366
|
|
352
|
367
|
def receive(self, timeout=1):
|
|
@@ -377,7 +392,7 @@ class tcp_base_stp(tcp_base):
|
377
|
392
|
This method sends one message via the initiated communication channel.
|
378
|
393
|
"""
|
379
|
394
|
if tcp_base.send(self, stringtools.stp.build_frame(data), timeout=timeout, log_lvl=logging.DEBUG):
|
380
|
|
- logger.log(log_lvl, '%s TX -> "%s"', self.LOG_PREFIX, stringtools.hexlify(data))
|
|
395
|
+ self.logger.log(log_lvl, 'TX -> "%s"', stringtools.hexlify(data))
|
381
|
396
|
return True
|
382
|
397
|
else:
|
383
|
398
|
return False
|
|
@@ -395,10 +410,10 @@ class tcp_base_stp(tcp_base):
|
395
|
410
|
time.sleep(.05)
|
396
|
411
|
else:
|
397
|
412
|
if len(data) > 0:
|
398
|
|
- logger.debug('%s -- <- "%s"', self.LOG_PREFIX, stringtools.hexlify(data))
|
|
413
|
+ self.logger.debug('-- <- "%s"', stringtools.hexlify(data))
|
399
|
414
|
content = self.__stp__.process(data)
|
400
|
415
|
for msg in content:
|
401
|
|
- logger.log(rx_log_lvl, '%s RX <- "%s"', self.LOG_PREFIX, stringtools.hexlify(msg))
|
|
416
|
+ self.logger.log(rx_log_lvl, 'RX <- "%s"', stringtools.hexlify(msg))
|
402
|
417
|
self.__receive_buffer__.append(msg)
|
403
|
418
|
else:
|
404
|
419
|
self.__connection_lost__()
|