|
@@ -94,6 +94,16 @@ STATUS_CHECKSUM_ERROR = 5
|
94
|
94
|
"""Status for 'checksum error'"""
|
95
|
95
|
STATUS_OPERATION_NOT_PERMITTED = 6
|
96
|
96
|
"""Status for 'operation not permitted'"""
|
|
97
|
+STATUS_LOG_LVL = {
|
|
98
|
+ STATUS_OKAY: logging.INFO,
|
|
99
|
+ STATUS_BUFFERING_UNHANDLED_REQUEST: logging.WARNING,
|
|
100
|
+ STATUS_CALLBACK_ERROR: logging.ERROR,
|
|
101
|
+ STATUS_AUTH_REQUIRED: logging.WARNING,
|
|
102
|
+ STATUS_SERVICE_OR_DATA_UNKNOWN: logging.ERROR,
|
|
103
|
+ STATUS_CHECKSUM_ERROR: logging.ERROR,
|
|
104
|
+ STATUS_OPERATION_NOT_PERMITTED: logging.WARNING,
|
|
105
|
+}
|
|
106
|
+"""Status depending log level for messages"""
|
97
|
107
|
|
98
|
108
|
AUTH_STATE_UNTRUSTED_CONNECTION = 0
|
99
|
109
|
"""Authentification Status for an 'Untrusted Connection'"""
|
|
@@ -271,8 +281,8 @@ class pure_json_protocol(object):
|
271
|
281
|
#
|
272
|
282
|
self.__status_name_dict = {}
|
273
|
283
|
self.add_status(STATUS_OKAY, 'okay')
|
274
|
|
- self.add_status(STATUS_BUFFERING_UNHANDLED_REQUEST, 'no callback for service, data buffered.')
|
275
|
|
- self.add_status(STATUS_CALLBACK_ERROR, 'callback error.')
|
|
284
|
+ self.add_status(STATUS_BUFFERING_UNHANDLED_REQUEST, 'no callback for service, data buffered')
|
|
285
|
+ self.add_status(STATUS_CALLBACK_ERROR, 'callback error')
|
276
|
286
|
self.add_status(STATUS_AUTH_REQUIRED, 'authentification required')
|
277
|
287
|
self.add_status(STATUS_SERVICE_OR_DATA_UNKNOWN, 'service or data unknown')
|
278
|
288
|
self.add_status(STATUS_CHECKSUM_ERROR, 'checksum error')
|
|
@@ -374,8 +384,8 @@ class pure_json_protocol(object):
|
374
|
384
|
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
|
375
|
385
|
self.logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.__log_prefix__())
|
376
|
386
|
|
377
|
|
- def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
|
378
|
|
- data_frame = json.dumps(self.__mk_msg__(status, service_id, data_id, data))
|
|
387
|
+ def __build_frame__(self, msg):
|
|
388
|
+ data_frame = json.dumps(self.__mk_msg__(msg.get_status(), msg.get_service_id(), msg.get_data_id(), msg.get_data()))
|
379
|
389
|
if sys.version_info >= (3, 0):
|
380
|
390
|
data_frame = bytes(data_frame, 'utf-8')
|
381
|
391
|
checksum = self.__calc_chksum__(data_frame)
|
|
@@ -424,48 +434,52 @@ class pure_json_protocol(object):
|
424
|
434
|
if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
|
425
|
435
|
self.authentificate()
|
426
|
436
|
|
|
437
|
+ def __log_msg__(self, msg, rx_tx_prefix):
|
|
438
|
+ self.logger.log(
|
|
439
|
+ self.__status_log_lvl__(msg.get_status()),
|
|
440
|
+ '%s %s %s, %s, data: "%s"',
|
|
441
|
+ self.__log_prefix__(),
|
|
442
|
+ rx_tx_prefix,
|
|
443
|
+ self.__get_message_name__(msg.get_service_id(), msg.get_data_id()),
|
|
444
|
+ self.__get_status_name__(msg.get_status()),
|
|
445
|
+ repr(msg.get_data())
|
|
446
|
+ )
|
|
447
|
+
|
427
|
448
|
def __data_available_callback__(self, comm_inst):
|
428
|
449
|
frame = comm_inst.receive()
|
429
|
450
|
msg = self.__analyse_frame__(frame)
|
430
|
451
|
if not self.__check_frame_checksum__(frame):
|
431
|
452
|
# Wrong Checksum
|
432
|
|
- self.logger.warning("%s RX <- Received message has a wrong checksum. Message will be ignored.", self.__log_prefix__())
|
|
453
|
+ self.logger.log(self.__status_log_lvl__(STATUS_CHECKSUM_ERROR), "%s Received message has an invalid checksum. Message will be ignored.", self.__log_prefix__())
|
433
|
454
|
return # No response needed
|
434
|
455
|
elif not self.check_authentification_state() and self.__authentification_required__(msg.get_service_id(), msg.get_data_id()):
|
435
|
456
|
# Authentification required
|
|
457
|
+ self.__log_msg__(msg, 'RX <-')
|
436
|
458
|
if msg.get_service_id() in self.__sid_response_dict__.keys():
|
437
|
|
- self.logger.warning("%s RX <- Authentification is required. Just sending negative response.", self.__log_prefix__())
|
|
459
|
+ self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Just sending negative response.", self.__log_prefix__())
|
438
|
460
|
status = STATUS_AUTH_REQUIRED
|
439
|
461
|
data = None
|
440
|
462
|
else:
|
441
|
|
- self.logger.warning("%s RX <- Authentification is required. Message will be ignored.", self.__log_prefix__())
|
|
463
|
+ self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Incomming message will be ignored.", self.__log_prefix__())
|
442
|
464
|
return # No response needed
|
443
|
465
|
else:
|
444
|
466
|
# Valid message
|
445
|
|
- self.logger.info(
|
446
|
|
- '%s RX <- %s, %s, data: "%s"',
|
447
|
|
- self.__log_prefix__(),
|
448
|
|
- self.__get_message_name__(msg.get_service_id(), msg.get_data_id()),
|
449
|
|
- self.__get_status_name__(msg.get_status()),
|
450
|
|
- repr(msg.get_data())
|
451
|
|
- )
|
452
|
|
- if msg.get_status() not in [STATUS_OKAY]:
|
453
|
|
- self.logger.warning("%s RX <- Message has a peculiar status: %s", self.__log_prefix__(), self.__get_status_name__(msg.get_status()))
|
|
467
|
+ self.__log_msg__(msg, 'RX <-')
|
454
|
468
|
callback, args, kwargs = self.__callbacks__.get(msg.get_service_id(), msg.get_data_id())
|
455
|
469
|
if msg.get_service_id() in self.__sid_response_dict__.keys():
|
456
|
470
|
#
|
457
|
471
|
# REQUEST RECEIVED
|
458
|
472
|
#
|
459
|
473
|
if callback is None:
|
460
|
|
- self.logger.warning("%s RX <- Message with no registered callback. Sending negative response.", self.__log_prefix__())
|
|
474
|
+ self.logger.warning("%s Incomming message with no registered callback. Sending negative response.", self.__log_prefix__())
|
461
|
475
|
status = STATUS_BUFFERING_UNHANDLED_REQUEST
|
462
|
476
|
data = None
|
463
|
477
|
else:
|
464
|
478
|
try:
|
465
|
|
- self.logger.debug("%s RX <- Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
|
|
479
|
+ self.logger.debug("%s Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
|
466
|
480
|
status, data = callback(msg, *args, **kwargs)
|
467
|
481
|
except Exception:
|
468
|
|
- logger.error('{lp} RX <- Exception raised. Check callback {callback_name} and it\'s return values for service_id {service_id} and data_id {data_id}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
|
|
482
|
+ logger.error('{lp} Exception raised. Check callback {callback_name} and it\'s return values for service_id {service_id} and data_id {data_id}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
|
469
|
483
|
status = STATUS_CALLBACK_ERROR
|
470
|
484
|
data = None
|
471
|
485
|
else:
|
|
@@ -498,11 +512,14 @@ class pure_json_protocol(object):
|
498
|
512
|
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
|
499
|
513
|
|
500
|
514
|
def __log_prefix__(self):
|
501
|
|
- return 'SP client:' if self.__comm_inst__.IS_CLIENT else 'SP server:'
|
|
515
|
+ return 'prot-client:' if self.__comm_inst__.IS_CLIENT else 'prot-server:'
|
502
|
516
|
|
503
|
517
|
def __mk_msg__(self, status, service_id, data_id, data):
|
504
|
518
|
return data_storage({data_storage.KEY_DATA_ID: data_id, data_storage.KEY_SERVICE_ID: service_id, data_storage.KEY_STATUS: status, data_storage.KEY_DATA: data})
|
505
|
519
|
|
|
520
|
+ def __status_log_lvl__(self, status):
|
|
521
|
+ return STATUS_LOG_LVL.get(status, logging.CRITICAL)
|
|
522
|
+
|
506
|
523
|
def add_data(self, service_id, data_id, name):
|
507
|
524
|
"""
|
508
|
525
|
Method to add a name for a specific message.
|
|
@@ -711,23 +728,19 @@ class pure_json_protocol(object):
|
711
|
728
|
:rtype: bool
|
712
|
729
|
"""
|
713
|
730
|
if (self.check_authentification_state() or not self.__authentification_required__(service_id, data_id)) or (service_id in self.__sid_response_dict__.values() and status == STATUS_AUTH_REQUIRED and data is None):
|
714
|
|
- self.logger.info(
|
715
|
|
- '%s TX <- %s, %s, data: "%s"',
|
716
|
|
- self.__log_prefix__(),
|
717
|
|
- self.__get_message_name__(service_id, data_id),
|
718
|
|
- self.__get_status_name__(status),
|
719
|
|
- repr(data)
|
720
|
|
- )
|
721
|
|
- return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
|
|
731
|
+ msg = data_storage(service_id=service_id, data_id=data_id, data=data, status=status)
|
|
732
|
+ self.__log_msg__(msg, 'TX ->')
|
|
733
|
+ return self.__comm_inst__.send(self.__build_frame__(msg), timeout=timeout)
|
722
|
734
|
else:
|
723
|
735
|
# Authentification required
|
724
|
|
- self.logger.warning("%s TX -> Authentification is required. Message %s, %s, data: %s will be ignored.", self.__log_prefix__(), self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
|
|
736
|
+ self.logger.warning("%s Authentification is required. TX-Message %s, %s, data: %s will be ignored.", self.__log_prefix__(), self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
|
725
|
737
|
return False
|
726
|
738
|
|
727
|
739
|
|
728
|
740
|
class struct_json_protocol(pure_json_protocol):
|
729
|
741
|
"""
|
730
|
742
|
This Class has the same functionality like :class:`pure_json_protocol`. The message length is less than for :class:`pure_json_protocol`, but the functionality and compatibility is reduced.
|
|
743
|
+ See also parent :py:class:`pure_json_protocol`.
|
731
|
744
|
|
732
|
745
|
.. note::
|
733
|
746
|
This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of :class:`pure_json_protocol` is recommended.
|
|
@@ -743,13 +756,13 @@ class struct_json_protocol(pure_json_protocol):
|
743
|
756
|
data = json.loads(frame[12:-1])
|
744
|
757
|
return self.__mk_msg__(status, service_id, data_id, data)
|
745
|
758
|
|
746
|
|
- def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
|
747
|
|
- frame = struct.pack('>III', status, service_id, data_id)
|
|
759
|
+ def __build_frame__(self, msg):
|
|
760
|
+ frame = struct.pack('>III', msg.get_status(), msg.get_service_id(), msg.get_data_id())
|
748
|
761
|
if sys.version_info >= (3, 0):
|
749
|
|
- frame += bytes(json.dumps(data), 'utf-8')
|
|
762
|
+ frame += bytes(json.dumps(msg.get_data()), 'utf-8')
|
750
|
763
|
frame += self.__calc_chksum__(frame)
|
751
|
764
|
else:
|
752
|
|
- frame += json.dumps(data)
|
|
765
|
+ frame += json.dumps(msg.get_data())
|
753
|
766
|
frame += self.__calc_chksum__(frame)
|
754
|
767
|
return frame
|
755
|
768
|
|