def parse(bitstream, payload_length): control = Control.parse(bitstream) payload_length = payload_length - 1 # subtract control byte dialog_id = bitstream.read("uint:8") payload_length = payload_length - 1 transaction_id = bitstream.read("uint:8") payload_length = payload_length - 1 target_rx_level_i = None if control.has_agc: target_rx_level_i = bitstream.read("uint:8") payload_length -= 1 tl = None if control.has_tl: tl = CT.parse(bitstream) payload_length -= 1 te = None if control.has_te: te = CT.parse(bitstream) payload_length -= 1 tc = None # TODO currently we have no way to know if Tc is present or not # Tc is present when control.is_ack_requested AND when we are requester, # while responders copy this flag but do NOT provide a Tc. # When parsing single frames without knowledge of dialogs we cannot determine this. # We use control.is_dialog_start for now but this will break when we start supporting multiple transactions per dialog if control.is_ack_requested and control.is_dialog_start: tc = CT.parse(bitstream) payload_length -= 1 ack_template = None if control.is_ack_not_void: transaction_id_start = bitstream.read("uint:8") payload_length = payload_length - 1 transaction_id_stop = bitstream.read("uint:8") payload_length = payload_length - 1 assert transaction_id_start == transaction_id, "Other case not implemented yet" assert transaction_id_stop == transaction_id, "Other case not implemented yet" # TODO ack bitmap (for when transaction_id_start != transaction_id) ack_template = [transaction_id_start, transaction_id_stop] assert control.is_ack_record_requested == False, "Not implemented yet" assert control.is_ack_not_void == False, "Not implemented yet" alp_command = AlpParser().parse(bitstream, payload_length) return Frame(control=control, dialog_id=dialog_id, transaction_id=transaction_id, agc_rx_level_i=target_rx_level_i, tl=tl, te=te, tc=tc, ack_template=ack_template, alp_command=alp_command)
def test_parsing(self): ctrl = Control.parse(ConstBitStream(bytes=[0x93])) self.assertEqual(ctrl.is_dialog_start, True) self.assertEqual(ctrl.has_tl, False) self.assertEqual(ctrl.has_te, True) self.assertEqual(ctrl.is_ack_requested, False) self.assertEqual(ctrl.is_ack_not_void, False) self.assertEqual(ctrl.is_ack_record_requested, True) self.assertEqual(ctrl.has_agc, True)
def test_byte_generation(self): ctrl = Control(is_dialog_start=True, has_tl=True, has_te=False, is_ack_requested=True, is_ack_not_void=True, is_ack_record_requested=False, has_agc=False) data = bytearray(ctrl) self.assertEqual(len(data), 1) self.assertEqual(data[0], 0xAC)
def parse(self, bitstream, payload_length): is_dialog_start = bitstream.read("bool") is_dialog_end = bitstream.read("bool") _ = bitstream.read("pad:2"), is_ack_return_template_requested = bitstream.read("bool") is_ack_not_void = bitstream.read("bool") is_ack_recorded = bitstream.read("bool") _ = bitstream.read("pad:1") payload_length = payload_length - 1 # subtract control byte control = Control(is_dialog_start, is_dialog_end, is_ack_return_template_requested, is_ack_not_void, is_ack_recorded) dialog_id = bitstream.read("uint:8") payload_length = payload_length - 1 transaction_id = bitstream.read("uint:8") payload_length = payload_length - 1 ack_template = None if is_ack_not_void: transaction_id_start = bitstream.read("uint:8") payload_length = payload_length - 1 transaction_id_stop = bitstream.read("uint:8") payload_length = payload_length - 1 assert transaction_id_start == transaction_id, "Other case not implemented yet" assert transaction_id_stop == transaction_id, "Other case not implemented yet" # TODO ack bitmap (for when transaction_id_start != transaction_id) ack_template = [transaction_id_start, transaction_id_stop] assert is_ack_recorded == False, "Not implemented yet" assert is_ack_not_void == False, "Not implemented yet" alp_command = AlpParser().parse(bitstream, payload_length) return Frame(control=control, dialog_id=dialog_id, transaction_id=transaction_id, ack_template=ack_template, alp_command=alp_command)