From b5784bb35b9968bf977d1319c3301958d671f45c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sat, 6 Jan 2018 22:51:43 +0000 Subject: lifescan binary protocol: make the packet generator a function. This ensures that the command prefix is added directly into the packet structure, simplifying the rest of the code. Per driver changes: - otverio2015: command prefix is changed from 0x04 to 0x03; this ensures that all the responses share the same prefix (READ RECORD COUNT does not repeat the selected command prefix). - otverioiq: command prefix is changed from 0x04 to 0x03, to align with the otverio2015 driver and the trace from OneTouch Diabetes Management Software. --- glucometerutils/drivers/otultraeasy.py | 22 +++++---- glucometerutils/drivers/otverio2015.py | 21 ++++---- glucometerutils/drivers/otverioiq.py | 21 ++++---- .../support/lifescan_binary_protocol.py | 57 ++++++++++++---------- 4 files changed, 65 insertions(+), 56 deletions(-) diff --git a/glucometerutils/drivers/otultraeasy.py b/glucometerutils/drivers/otultraeasy.py index aafc2bd..1876402 100644 --- a/glucometerutils/drivers/otultraeasy.py +++ b/glucometerutils/drivers/otultraeasy.py @@ -30,12 +30,14 @@ from glucometerutils.support import lifescan from glucometerutils.support import lifescan_binary_protocol from glucometerutils.support import serial +_PACKET = lifescan_binary_protocol.LifeScanPacket( + 0x05, True) _INVALID_RECORD = 501 -_COMMAND_SUCCESS = construct.Const(b'\x05\x06') +_COMMAND_SUCCESS = construct.Const(b'\x06') -_VERSION_REQUEST = construct.Const(b'\x05\x0d\x02') +_VERSION_REQUEST = construct.Const(b'\x0d\x02') _VERSION_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -43,7 +45,7 @@ _VERSION_RESPONSE = construct.Struct( ) _SERIAL_NUMBER_REQUEST = construct.Const( - b'\x05\x0B\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00') + b'\x0B\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00') _SERIAL_NUMBER_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -51,7 +53,7 @@ _SERIAL_NUMBER_RESPONSE = construct.Struct( ) _DATETIME_REQUEST = construct.Struct( - construct.Const(b'\x05\x20'), # 0x20 is the datetime + construct.Const(b'\x20'), # 0x20 is the datetime 'request_type' / construct.Enum(construct.Byte, write=0x01, read=0x02), 'timestamp' / construct.Default( construct_extras.Timestamp(construct.Int32ul), @@ -64,7 +66,7 @@ _DATETIME_RESPONSE = construct.Struct( ) _GLUCOSE_UNIT_REQUEST = construct.Const( - b'\x05\x09\x02\x09\x00\x00\x00\x00') + b'\x09\x02\x09\x00\x00\x00\x00') _GLUCOSE_UNIT_RESPONSE = construct.Struct( @@ -73,15 +75,15 @@ _GLUCOSE_UNIT_RESPONSE = construct.Struct( construct.Padding(3), ) -_MEMORY_ERASE_REQUEST = construct.Const(b'\x05\x1A') +_MEMORY_ERASE_REQUEST = construct.Const(b'\x1A') _READING_COUNT_RESPONSE = construct.Struct( - construct.Const(b'\x05\x0f'), + construct.Const(b'\x0f'), 'count' / construct.Int16ul, ) _READ_RECORD_REQUEST = construct.Struct( - construct.Const(b'\x05\x1f'), + construct.Const(b'\x1f'), 'record_id' / construct.Int16ul, ) @@ -102,7 +104,7 @@ class Device(serial.SerialDevice): self.sent_counter_ = False self.expect_receive_ = False self.buffered_reader_ = construct.Rebuffered( - lifescan_binary_protocol.PACKET, tailcutoff=1024) + _PACKET, tailcutoff=1024) def connect(self): try: @@ -115,7 +117,7 @@ class Device(serial.SerialDevice): self.connect() def _send_packet(self, message, acknowledge=False, disconnect=False): - pkt = lifescan_binary_protocol.PACKET.build( + pkt = _PACKET.build( {'value': { 'message': message, 'link_control': { diff --git a/glucometerutils/drivers/otverio2015.py b/glucometerutils/drivers/otverio2015.py index 9aff4d2..5bc11dc 100644 --- a/glucometerutils/drivers/otverio2015.py +++ b/glucometerutils/drivers/otverio2015.py @@ -42,12 +42,13 @@ from glucometerutils.support import lifescan_binary_protocol _REGISTER_SIZE = 512 _PACKET = construct.Padded( - _REGISTER_SIZE, construct.Embedded(lifescan_binary_protocol.PACKET)) + _REGISTER_SIZE, construct.Embedded( + lifescan_binary_protocol.LifeScanPacket(0x03, False))) -_COMMAND_SUCCESS = construct.Const(b'\x04\x06') +_COMMAND_SUCCESS = construct.Const(b'\x06') _QUERY_REQUEST = construct.Struct( - construct.Const(b'\x04\xe6\x02'), + construct.Const(b'\xe6\x02'), 'selector' / construct.Enum( construct.Byte, serial=0x00, model=0x01, software=0x02), ) @@ -59,18 +60,17 @@ _QUERY_RESPONSE = construct.Struct( ) _READ_PARAMETER_REQUEST = construct.Struct( - construct.Const(b'\x04'), 'selector' / construct.Enum( construct.Byte, unit=0x04), ) _READ_UNIT_RESPONSE = construct.Struct( - construct.Const(b'\x03\x06'), # different from _COMMAND_SUCCESS + _COMMAND_SUCCESS, 'unit' / lifescan_binary_protocol.GLUCOSE_UNIT, construct.Padding(3), ) -_READ_RTC_REQUEST = construct.Const(b'\x04\x20\x02') +_READ_RTC_REQUEST = construct.Const(b'\x20\x02') _READ_RTC_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -78,13 +78,13 @@ _READ_RTC_RESPONSE = construct.Struct( ) _WRITE_RTC_REQUEST = construct.Struct( - construct.Const(b'\x04\x20\x01'), + construct.Const(b'\x20\x01'), 'timestamp' / lifescan_binary_protocol.VERIO_TIMESTAMP, ) -_MEMORY_ERASE_REQUEST = construct.Const(b'\x04\x1a') +_MEMORY_ERASE_REQUEST = construct.Const(b'\x1a') -_READ_RECORD_COUNT_REQUEST = construct.Const(b'\x04\x27\x00') +_READ_RECORD_COUNT_REQUEST = construct.Const(b'\x27\x00') _READ_RECORD_COUNT_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -92,7 +92,7 @@ _READ_RECORD_COUNT_RESPONSE = construct.Struct( ) _READ_RECORD_REQUEST = construct.Struct( - construct.Const(b'\x04\x31\x02'), + construct.Const(b'\x31\x02'), 'record_id' / construct.Int16ul, construct.Const(b'\x00'), ) @@ -161,7 +161,6 @@ class Device(object): request = request_format.build(request_obj) request_raw = _PACKET.build({'value': { 'message': request, - 'link_control': {}, # Verio does not use link_control. }}) logging.debug( 'Request sent: %s', binascii.hexlify(request_raw)) diff --git a/glucometerutils/drivers/otverioiq.py b/glucometerutils/drivers/otverioiq.py index 9cd9e16..c4e70cf 100644 --- a/glucometerutils/drivers/otverioiq.py +++ b/glucometerutils/drivers/otverioiq.py @@ -24,9 +24,12 @@ from glucometerutils.support import lifescan from glucometerutils.support import lifescan_binary_protocol from glucometerutils.support import serial -_COMMAND_SUCCESS = construct.Const(b'\x04\x06') +_PACKET = lifescan_binary_protocol.LifeScanPacket( + 0x03, True) -_VERSION_REQUEST = construct.Const(b'\x04\x0d\x02') # Untested +_COMMAND_SUCCESS = construct.Const(b'\x06') + +_VERSION_REQUEST = construct.Const(b'\x0d\x02') # Untested _VERSION_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -34,14 +37,14 @@ _VERSION_RESPONSE = construct.Struct( ) _SERIAL_NUMBER_REQUEST = construct.Const( - b'\x04\x0b\x00\x02') + b'\x0b\x00\x02') _SERIAL_NUMBER_RESPONSE = construct.Struct( _COMMAND_SUCCESS, 'serial_number' / construct.CString(encoding='ascii'), ) -_READ_RTC_REQUEST = construct.Const(b'\x04\x20\x02') +_READ_RTC_REQUEST = construct.Const(b'\x20\x02') _READ_RTC_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -49,12 +52,12 @@ _READ_RTC_RESPONSE = construct.Struct( ) _WRITE_RTC_REQUEST = construct.Struct( - construct.Const(b'\x04\x20\x01'), + construct.Const(b'\x20\x01'), 'timestamp' / lifescan_binary_protocol.VERIO_TIMESTAMP, ) _GLUCOSE_UNIT_REQUEST = construct.Const( - b'\x04\x09\x02\x02') + b'\x09\x02\x02') _GLUCOSE_UNIT_RESPONSE = construct.Struct( @@ -63,9 +66,9 @@ _GLUCOSE_UNIT_RESPONSE = construct.Struct( construct.Padding(3), ) -_MEMORY_ERASE_REQUEST = construct.Const(b'\x04\x1a') # Untested +_MEMORY_ERASE_REQUEST = construct.Const(b'\x1a') # Untested -_READ_RECORD_COUNT_REQUEST = construct.Const(b'\x04\x27\x00') +_READ_RECORD_COUNT_REQUEST = construct.Const(b'\x27\x00') _READ_RECORD_COUNT_RESPONSE = construct.Struct( _COMMAND_SUCCESS, @@ -73,7 +76,7 @@ _READ_RECORD_COUNT_RESPONSE = construct.Struct( ) _READ_RECORD_REQUEST = construct.Struct( - construct.Const(b'\x04\x21'), + construct.Const(b'\x21'), 'record_id' / construct.Int16ul, ) diff --git a/glucometerutils/support/lifescan_binary_protocol.py b/glucometerutils/support/lifescan_binary_protocol.py index 0143cd4..92a0002 100644 --- a/glucometerutils/support/lifescan_binary_protocol.py +++ b/glucometerutils/support/lifescan_binary_protocol.py @@ -18,36 +18,41 @@ from glucometerutils import common from glucometerutils.support import construct_extras from glucometerutils.support import lifescan +_LINK_CONTROL = construct.BitStruct( + construct.Padding(3), + 'more' / construct.Default(construct.Flag, False), + 'disconnect' / construct.Default(construct.Flag, False), + 'acknowledge' / construct.Default(construct.Flag, False), + 'expect_receive' / construct.Default(construct.Flag, False), + 'sequence_number' / construct.Default(construct.Flag, False), +) + +def LifeScanPacket(command_prefix, include_link_control): + if include_link_control: + link_control_construct = _LINK_CONTROL + else: + link_control_construct = construct.Const(b'\x00') -PACKET = construct.Struct( - construct.RawCopy( - construct.Embedded( - construct.Struct( - construct.Const(b'\x02'), # stx - 'length' / construct.Rebuild( - construct.Byte, lambda ctx: len(ctx.message) + 6), - # The following structure is only used by some of the devices. - 'link_control' / construct.BitStruct( - construct.Padding(3), - 'more' / construct.Default( - construct.Flag, False), - 'disconnect' / construct.Default( - construct.Flag, False), - 'acknowledge' / construct.Default( - construct.Flag, False), - 'expect_receive' / construct.Default( - construct.Flag, False), - 'sequence_number' / construct.Default( - construct.Flag, False), + command_prefix_construct = construct.Const(construct.Byte, command_prefix) + + return construct.Struct( + construct.RawCopy( + construct.Embedded( + construct.Struct( + construct.Const(b'\x02'), # stx + 'length' / construct.Rebuild( + construct.Byte, lambda ctx: len(ctx.message) + 7), + 'link_control' / link_control_construct, + 'command_prefix' / command_prefix_construct, + 'message' / construct.Bytes( + length=lambda ctx: ctx.length - 7), + construct.Const(b'\x03'), # etx ), - 'message' / construct.Bytes(length=lambda ctx: ctx.length - 6), - construct.Const(b'\x03'), # etx ), ), - ), - 'checksum' / construct.Checksum( - construct.Int16ul, lifescan.crc_ccitt, construct.this.data), -) + 'checksum' / construct.Checksum( + construct.Int16ul, lifescan.crc_ccitt, construct.this.data), + ) VERIO_TIMESTAMP = construct_extras.Timestamp( construct.Int32ul, epoch=946684800) # 2010-01-01 00:00 -- cgit v1.2.3