def test_paper_example(self): alice = Participant("Alice", "A") bob = Participant("Bob", "B") participants = [alice, bob] msg1 = Message.from_plain_hex_str("aabb1234") msg1.participant = alice msg2 = Message.from_plain_hex_str("aabb6789") msg2.participant = alice msg3 = Message.from_plain_hex_str("bbaa4711") msg3.participant = bob msg4 = Message.from_plain_hex_str("bbaa1337") msg4.participant = bob protocol = ProtocolAnalyzer(None) protocol.messages.extend([msg1, msg2, msg3, msg4]) #self.save_protocol("paper_example", protocol) bitvectors = FormatFinder.get_bitvectors_from_messages( protocol.messages) hexvectors = FormatFinder.get_hexvectors(bitvectors) address_engine = AddressEngine(hexvectors, participant_indices=[ participants.index(msg.participant) for msg in protocol.messages ])
def setUp(self): super().setUp() alice = Participant("Alice", "A") bob = Participant("Bob", "B") self.form.project_manager.participants.append(alice) self.form.project_manager.participants.append(bob) self.form.project_manager.project_updated.emit() mt = self.form.compare_frame_controller.proto_analyzer.default_message_type msg1 = SimulatorMessage(destination=alice, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) msg2 = SimulatorMessage(destination=bob, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) simulator_manager = self.form.simulator_tab_controller.simulator_config simulator_manager.add_items([msg1, msg2], 0, simulator_manager.rootItem) simulator_manager.add_label( 5, 15, "test", parent_item=simulator_manager.rootItem.children[0]) self.dialog = SimulatorDialog( self.form.simulator_tab_controller.simulator_config, self.form.generator_tab_controller.modulators, self.form.simulator_tab_controller.sim_expression_parser, self.form.project_manager) if self.SHOW: self.dialog.show()
def test_participants_list(self): alice = Participant("Alice", "A") bob = Participant("Bob", "B") self.form.project_manager.participants.append(alice) self.form.project_manager.participants.append(bob) self.form.project_manager.project_updated.emit() mt = self.form.compare_frame_controller.proto_analyzer.default_message_type msg1 = SimulatorMessage(destination=alice, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) msg2 = SimulatorMessage(destination=bob, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) simulator_manager = self.form.simulator_tab_controller.simulator_config simulator_manager.add_items([msg1, msg2], 0, simulator_manager.rootItem) simulator_manager.add_label(5, 15, "test", parent_item=simulator_manager.rootItem.children[0]) stc = self.form.simulator_tab_controller # type: SimulatorTabController model = stc.ui.listViewSimulate.model() self.assertEqual(model.rowCount(), 2) self.assertEqual(model.data(model.index(0, 0)), "Alice (A)") self.assertEqual(model.data(model.index(1, 0)), "Bob (B)") self.assertFalse(self.form.project_manager.participants[0].simulate) self.assertEqual(model.data(model.index(0, 0), role=Qt.CheckStateRole), Qt.Unchecked) self.assertFalse(self.form.project_manager.participants[1].simulate) self.assertEqual(model.data(model.index(1, 0), role=Qt.CheckStateRole), Qt.Unchecked) model.setData(model.index(0, 0), Qt.Checked, role=Qt.CheckStateRole) self.assertTrue(self.form.project_manager.participants[0].simulate)
def _prepare_protocol_3() -> ProtocolGenerator: alice = Participant("Alice", address_hex="1337") bob = Participant("Bob", address_hex="beef") checksum = GenericCRC.from_standard_checksum("CRC8 CCITT") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 16) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8) mb.add_label(FieldType.Function.DATA, 10 * 8) mb.add_checksum_label(8, checksum) mb_ack = MessageTypeBuilder("ack") mb_ack.add_label(FieldType.Function.PREAMBLE, 16) mb_ack.add_label(FieldType.Function.SYNC, 16) mb_ack.add_label(FieldType.Function.LENGTH, 8) mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16) mb_ack.add_checksum_label(8, checksum) pg = ProtocolGenerator([mb.message_type, mb_ack.message_type], syncs_by_mt={ mb.message_type: "0x9a7d", mb_ack.message_type: "0x9a7d" }, preambles_by_mt={ mb.message_type: "10" * 8, mb_ack.message_type: "10" * 8 }, participants=[alice, bob]) return pg
def _prepare_protocol_5() -> ProtocolGenerator: alice = Participant("Alice", address_hex="1337") bob = Participant("Bob", address_hex="beef") carl = Participant("Carl", address_hex="cafe") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 16) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8) mb_ack = MessageTypeBuilder("ack") mb_ack.add_label(FieldType.Function.PREAMBLE, 16) mb_ack.add_label(FieldType.Function.SYNC, 16) mb_ack.add_label(FieldType.Function.LENGTH, 8) mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16) pg = ProtocolGenerator([mb.message_type, mb_ack.message_type], syncs_by_mt={ mb.message_type: "0x9a7d", mb_ack.message_type: "0x9a7d" }, preambles_by_mt={ mb.message_type: "10" * 8, mb_ack.message_type: "10" * 8 }, participants=[alice, bob, carl]) return pg
def on_btn_add_participant_clicked(self): used_shortnames = {p.shortname for p in self.participants} used_colors = set(p.color_index for p in self.participants) avail_colors = set(range(0, len( constants.PARTICIPANT_COLORS))) - used_colors if len(avail_colors) > 0: color_index = avail_colors.pop() else: color_index = random.choice( range(len(constants.PARTICIPANT_COLORS))) num_chars = 0 participant = None while participant is None: num_chars += 1 for c in string.ascii_uppercase: shortname = num_chars * str(c) if shortname not in used_shortnames: participant = Participant("Device " + shortname, shortname=shortname, color_index=color_index) break self.participants.append(participant) participant.relative_rssi = len(self.participants) - 1 self.__set_relative_rssi_delegate() self.participant_table_model.update() self.ui.btnRemoveParticipant.setEnabled(True) self.open_editors()
def __prepare_simple_example_protocol(self): random.seed(0) alice = Participant("Alice", "A", address_hex="1234") bob = Participant("Bob", "B", address_hex="cafe") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 8) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.TYPE, 8) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x6768"}, participants=[alice, bob]) for i in range(10): pg.generate_message(data="".join( [random.choice(["0", "1"]) for _ in range(16)]), source=alice, destination=bob) pg.generate_message(data="".join( [random.choice(["0", "1"]) for _ in range(8)]), source=bob, destination=alice) return pg.protocol
def setUp(self): self.field_types = FieldType.default_field_types() self.preamble_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.PREAMBLE) self.sync_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.SYNC) self.length_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.LENGTH) self.sequence_number_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.SEQUENCE_NUMBER) self.dst_address_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.DST_ADDRESS) self.src_address_field_type = self.__field_type_with_function(self.field_types, FieldType.Function.SRC_ADDRESS) self.protocol = ProtocolAnalyzer(None) with open(get_path_for_data_file("awre_consistent_addresses.txt")) as f: for line in f: self.protocol.messages.append(Message.from_plain_bits_str(line.replace("\n", ""))) self.protocol.messages[-1].message_type = self.protocol.default_message_type # Assign participants alice = Participant("Alice", "A") bob = Participant("Bob", "B") alice_indices = {1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 20, 22, 23, 26, 27, 30, 31, 34, 35, 38, 39, 41} for i, message in enumerate(self.protocol.messages): message.participant = alice if i in alice_indices else bob self.participants = [alice, bob] self.zero_crc_protocol = ProtocolAnalyzer(None) with open(get_path_for_data_file("awre_zeroed_crc.txt")) as f: for line in f: self.zero_crc_protocol.messages.append(Message.from_plain_bits_str(line.replace("\n", ""))) self.zero_crc_protocol.messages[-1].message_type = self.protocol.default_message_type for i, message in enumerate(self.zero_crc_protocol.messages): message.participant = alice if i in alice_indices else bob
def setUp(self): super().setUp() alice = Participant("Alice", "A") bob = Participant("Bob", "B") alice.simulate = True bob.simulate = True self.form.project_manager.participants.append(alice) self.form.project_manager.participants.append(bob) self.form.project_manager.project_updated.emit() mt = self.form.compare_frame_controller.proto_analyzer.default_message_type msg1 = SimulatorMessage(source=bob, destination=alice, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) msg2 = SimulatorMessage(source=alice, destination=bob, plain_bits=array("B", [1, 0, 1, 1]), pause=100, message_type=mt) simulator_manager = self.form.simulator_tab_controller.simulator_config simulator_manager.add_items([msg1, msg2], 0, simulator_manager.rootItem) simulator_manager.add_label(5, 15, "test", parent_item=simulator_manager.rootItem.children[0]) print(self.form.simulator_tab_controller.simulator_config.tx_needed) self.dialog = SimulatorDialog(self.form.simulator_tab_controller.simulator_config, self.form.generator_tab_controller.modulators, self.form.simulator_tab_controller.sim_expression_parser, self.form.project_manager) if self.SHOW: self.dialog.show()
def setUp(self): super().setUp() self.carl = Participant("Carl", "C") self.dennis = Participant("Dennis", "D") self.participants = [self.carl, self.dennis] self.project_folder = os.path.join(tempfile.gettempdir(), "simulator_project") self.menus_to_ignore = []
def test_sync_word_finding_common_prefix(self): """ Messages are very similar (odd and even ones are the same) However, they do not have two different sync words! The algorithm needs to check for a common prefix of the two found sync words :return: """ sync = "0x1337" num_messages = 10 alice = Participant("Alice", address_hex="dead01") bob = Participant("Bob", address_hex="beef24") mb = MessageTypeBuilder("protocol_with_one_message_type") mb.add_label(FieldType.Function.PREAMBLE, 72) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 24) mb.add_label(FieldType.Function.DST_ADDRESS, 24) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 16) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x1337"}, preambles_by_mt={mb.message_type: "10" * 36}, participants=[alice, bob]) random.seed(0) for i in range(num_messages): if i % 2 == 0: source, destination = alice, bob data_length = 8 else: source, destination = bob, alice data_length = 16 pg.generate_message(data=pg.decimal_to_bits( random.randint(0, 2**(data_length - 1)), data_length), source=source, destination=destination) preprocessor = Preprocessor([ np.array(msg.plain_bits, dtype=np.uint8) for msg in pg.protocol.messages ]) possible_syncs = preprocessor.find_possible_syncs() #self.save_protocol("sync_by_common_prefix", pg) self.assertEqual(len(possible_syncs), 1) # +0000 is okay, because this will get fixed by correction in FormatFinder self.assertIn(possible_syncs[0], [ ProtocolGenerator.to_bits(sync), ProtocolGenerator.to_bits(sync) + "0000" ])
def setUp(self): super().setUp() settings.OVERWRITE_RECEIVE_BUFFER_SIZE = 50000 self.carl = Participant("Carl", "C") self.dennis = Participant("Dennis", "D") self.participants = [self.carl, self.dennis] self.project_folder = os.path.join(tempfile.gettempdir(), "simulator_project") self.menus_to_ignore = []
def _prepare_protocol_4() -> ProtocolGenerator: alice = Participant("Alice", address_hex="1337") bob = Participant("Bob", address_hex="beef") checksum = GenericCRC.from_standard_checksum("CRC16 CCITT") mb = MessageTypeBuilder("data1") mb.add_label(FieldType.Function.PREAMBLE, 16) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.DATA, 8 * 8) mb.add_checksum_label(16, checksum) mb2 = MessageTypeBuilder("data2") mb2.add_label(FieldType.Function.PREAMBLE, 16) mb2.add_label(FieldType.Function.SYNC, 16) mb2.add_label(FieldType.Function.LENGTH, 8) mb2.add_label(FieldType.Function.SRC_ADDRESS, 16) mb2.add_label(FieldType.Function.DST_ADDRESS, 16) mb2.add_label(FieldType.Function.DATA, 64 * 8) mb2.add_checksum_label(16, checksum) mb_ack = MessageTypeBuilder("ack") mb_ack.add_label(FieldType.Function.PREAMBLE, 16) mb_ack.add_label(FieldType.Function.SYNC, 16) mb_ack.add_label(FieldType.Function.LENGTH, 8) mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16) mb_ack.add_checksum_label(16, checksum) mt1, mt2, mt3 = mb.message_type, mb2.message_type, mb_ack.message_type preamble = "10001000" * 2 pg = ProtocolGenerator([mt1, mt2, mt3], syncs_by_mt={ mt1: "0x9a7d", mt2: "0x9a7d", mt3: "0x9a7d" }, preambles_by_mt={ mt1: preamble, mt2: preamble, mt3: preamble }, participants=[alice, bob]) return pg
def add_participant(self): used_colors = set(p.color_index for p in self.participants) avail_colors = set(range(0, len(constants.PARTICIPANT_COLORS))) - used_colors if len(avail_colors) > 0: color_index = avail_colors.pop() else: color_index = random.choice(range(len(constants.PARTICIPANT_COLORS))) name, shortname = self.__get_initial_name() participant = Participant(name, shortname=shortname, color_index=color_index) self.participants.append(participant) participant.relative_rssi = len(self.participants) - 1 self.update() self.participant_edited.emit()
def setUp(self): self.protocol = ProtocolAnalyzer(None) with open(get_path_for_data_file("decoded_bits.txt")) as f: for line in f: self.protocol.messages.append( Message.from_plain_bits_str(line.replace("\n", ""))) self.protocol.messages[ -1].message_type = self.protocol.default_message_type # Assign participants alice = Participant("Alice", "A") bob = Participant("Bob", "B") alice_indices = { 1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 20, 22, 23, 26, 27, 30, 31, 34, 35, 38, 39, 41 } for i, message in enumerate(self.protocol.messages): if i in alice_indices: message.participant = alice else: message.participant = bob self.assertEqual(self.protocol.num_messages, 42) self.assertEqual(self.protocol.plain_hex_str[0][16:18], "2d") self.decodings = [] self.decodings.append(Encoding(['Non Return To Zero (NRZ)'])) self.decodings.append( Encoding(['Non Return To Zero Inverted (NRZ-I)', 'Invert'])) self.decodings.append(Encoding(['Manchester I', 'Edge Trigger'])) self.decodings.append( Encoding(['Manchester II', 'Edge Trigger', 'Invert'])) self.decodings.append( Encoding([ 'Differential Manchester', 'Edge Trigger', 'Differential Encoding', ])) self.decodings.append( Encoding([ 'DeWhitening Special', constants.DECODING_DATAWHITENING, '0x9a7d9a7d;0x21;0' ])) self.decodings.append( Encoding([ 'DeWhitening', constants.DECODING_DATAWHITENING, '0x67686768;0x21;0' ]))
def _prepare_protocol_6() -> ProtocolGenerator: alice = Participant("Alice", address_hex="24") broadcast = Participant("Bob", address_hex="ff") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 8) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x8e88"}, preambles_by_mt={mb.message_type: "10" * 8}, participants=[alice, broadcast]) return pg
def _prepare_protocol_8() -> ProtocolGenerator: alice = Participant("Alice") mb = MessageTypeBuilder("data1") mb.add_label(FieldType.Function.PREAMBLE, 4) mb.add_label(FieldType.Function.SYNC, 4) mb.add_label(FieldType.Function.LENGTH, 16) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 16) mb.add_label(FieldType.Function.DATA, 8 * 542) mb2 = MessageTypeBuilder("data2") mb2.add_label(FieldType.Function.PREAMBLE, 4) mb2.add_label(FieldType.Function.SYNC, 4) mb2.add_label(FieldType.Function.LENGTH, 16) mb2.add_label(FieldType.Function.SEQUENCE_NUMBER, 16) mb2.add_label(FieldType.Function.DATA, 8 * 260) pg = ProtocolGenerator([mb.message_type, mb2.message_type], syncs_by_mt={ mb.message_type: "0x9", mb2.message_type: "0x9" }, preambles_by_mt={ mb.message_type: "10" * 2, mb2.message_type: "10" * 2 }, sequence_number_increment=32, participants=[alice], little_endian=True) return pg
def _prepare_protocol_1() -> ProtocolGenerator: alice = Participant("Alice", address_hex="dead") bob = Participant("Bob", address_hex="beef") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 8) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x1337"}, participants=[alice, bob]) return pg
def load_from_xml(self, xml_tag: ET.Element, message_types): assert xml_tag.tag == "simulator_config" items = [] modulators_tag = xml_tag.find("modulators") if modulators_tag: self.project_manager.modulators = Modulator.modulators_from_xml_tag(modulators_tag) participants_tag = xml_tag.find("participants") if participants_tag: for participant in Participant.read_participants_from_xml_tag(participants_tag): if participant not in self.project_manager.participants: self.project_manager.participants.append(participant) self.participants_changed.emit() decodings_tag = xml_tag.find("decodings") if decodings_tag: self.project_manager.decodings = Encoding.read_decoders_from_xml_tag(decodings_tag) rx_config_tag = xml_tag.find("simulator_rx_conf") if rx_config_tag: ProjectManager.read_device_conf_dict(rx_config_tag, self.project_manager.simulator_rx_conf) tx_config_tag = xml_tag.find("simulator_tx_conf") if tx_config_tag: ProjectManager.read_device_conf_dict(tx_config_tag, self.project_manager.simulator_tx_conf) for child_tag in xml_tag.find("items"): items.append(self.load_item_from_xml(child_tag, message_types)) self.add_items(items, pos=0, parent_item=None)
def load_from_xml(self, xml_tag: ET.Element, message_types): assert xml_tag.tag == "simulator_config" items = [] modulators_tag = xml_tag.find("modulators") if modulators_tag: self.project_manager.modulators = Modulator.modulators_from_xml_tag(modulators_tag) participants_tag = xml_tag.find("participants") if participants_tag: self.project_manager.participants[:] = Participant.read_participants_from_xml_tag(participants_tag) self.participants_changed.emit() decodings_tag = xml_tag.find("decodings") if decodings_tag: self.project_manager.decodings = Encoding.read_decoders_from_xml_tag(decodings_tag) rx_config_tag = xml_tag.find("simulator_rx_conf") if rx_config_tag: ProjectManager.read_device_conf_dict(rx_config_tag, self.project_manager.simulator_rx_conf) tx_config_tag = xml_tag.find("simulator_tx_conf") if tx_config_tag: ProjectManager.read_device_conf_dict(tx_config_tag, self.project_manager.simulator_tx_conf) for child_tag in xml_tag.find("items"): items.append(self.load_item_from_xml(child_tag, message_types)) self.add_items(items, pos=0, parent_item=None)
def to_xml_tag(self, decodings, participants, tag_name="protocol", include_message_type=False, write_bits=False, messages=None, modulators=None) -> ET.Element: root = ET.Element(tag_name) messages = self.messages if messages is None else messages # Save modulators if modulators is not None: # For protocol analyzer container root.append(Modulator.modulators_to_xml_tag(modulators)) root.append(Encoding.decodings_to_xml_tag(decodings)) root.append(Participant.participants_to_xml_tag(participants)) # Save data data_tag = ET.SubElement(root, "messages") for i, message in enumerate(messages): message_tag = message.to_xml( decoders=decodings, include_message_type=include_message_type, write_bits=write_bits) data_tag.append(message_tag) # Save message types separatively as not saved in messages already if not include_message_type: message_types_tag = ET.SubElement(root, "message_types") for message_type in self.message_types: message_types_tag.append(message_type.to_xml()) return root
def test_context_menu_text_edit_protocol_view(self): self.add_signal_to_form("esaver.complex") self.form.signal_tab_controller.signal_frames[ 0].ui.cbProtoView.setCurrentIndex(2) text_edit = self.form.signal_tab_controller.signal_frames[ 0].ui.txtEdProto menu = text_edit.create_context_menu() line_wrap_action = next(action for action in menu.actions() if action.text().startswith("Linewrap")) checked = line_wrap_action.isChecked() line_wrap_action.trigger() menu = text_edit.create_context_menu() line_wrap_action = next(action for action in menu.actions() if action.text().startswith("Linewrap")) self.assertNotEqual(checked, line_wrap_action.isChecked()) self.assertEqual( len([ action for action in menu.actions() if action.text() == "Participant" ]), 0) self.form.project_manager.participants.append(Participant( "Alice", "A")) text_edit.selectAll() menu = text_edit.create_context_menu() self.assertEqual( len([ action for action in menu.actions() if action.text() == "Participant" ]), 1)
def to_xml_tag(self, decodings, participants, tag_name="protocol", include_message_type=False, write_bits=False, messages=None, modulators=None) -> ET.Element: root = ET.Element(tag_name) messages = self.messages if messages is None else messages # Save modulators if modulators is not None: # For protocol analyzer container root.append(Modulator.modulators_to_xml_tag(modulators)) root.append(Encoding.decodings_to_xml_tag(decodings)) root.append(Participant.participants_to_xml_tag(participants)) # Save data data_tag = ET.SubElement(root, "messages") for i, message in enumerate(messages): message_tag = message.to_xml(decoders=decodings, include_message_type=include_message_type, write_bits=write_bits) data_tag.append(message_tag) # Save message types separatively as not saved in messages already if not include_message_type: message_types_tag = ET.SubElement(root, "message_types") for message_type in self.message_types: message_types_tag.append(message_type.to_xml()) return root
def from_xml(self, tag: ET.Element, participants, decoders=None, message_types=None): timestamp = tag.get("timestamp", None) if timestamp: self.timestamp = float(timestamp) part_id = tag.get("participant_id", None) message_type_id = tag.get("message_type_id", None) self.modulator_index = int(tag.get("modulator_index", self.modulator_index)) self.pause = int(tag.get("pause", self.pause)) decoding_index = tag.get("decoding_index", None) if decoding_index and decoders is not None: try: self.decoder = decoders[int(decoding_index)] except IndexError: pass if part_id: self.participant = Participant.find_matching(part_id, participants) if self.participant is None: logger.warning("No participant matched the id {0} from xml".format(part_id)) if message_type_id and message_types: for message_type in message_types: if message_type.id == message_type_id: self.message_type = message_type break message_type_tag = tag.find("message_type") if message_type_tag: self.message_type = MessageType.from_xml(message_type_tag)
def test_without_preamble(self): alice = Participant("Alice", address_hex="24") broadcast = Participant("Broadcast", address_hex="ff") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 8) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 8) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x8e88"}, preambles_by_mt={mb.message_type: "10" * 8}, participants=[alice, broadcast]) for i in range(20): data_bits = 16 if i % 2 == 0 else 32 source = pg.participants[i % 2] destination = pg.participants[(i + 1) % 2] pg.generate_message(data="1010" * (data_bits // 4), source=source, destination=destination) #self.save_protocol("without_preamble", pg) self.clear_message_types(pg.messages) ff = FormatFinder(pg.messages) ff.known_participant_addresses.clear() ff.run() self.assertEqual(len(ff.message_types), 1) mt = ff.message_types[0] sync = mt.get_first_label_with_type(FieldType.Function.SYNC) self.assertEqual(sync.start, 0) self.assertEqual(sync.length, 16) length = mt.get_first_label_with_type(FieldType.Function.LENGTH) self.assertEqual(length.start, 16) self.assertEqual(length.length, 8) dst = mt.get_first_label_with_type(FieldType.Function.SRC_ADDRESS) self.assertEqual(dst.start, 24) self.assertEqual(dst.length, 8) seq = mt.get_first_label_with_type(FieldType.Function.SEQUENCE_NUMBER) self.assertEqual(seq.start, 32) self.assertEqual(seq.length, 8)
def _prepare_protocol_7() -> ProtocolGenerator: alice = Participant("Alice", address_hex="313370") bob = Participant("Bob", address_hex="031337") charly = Participant("Charly", address_hex="110000") daniel = Participant("Daniel", address_hex="001100") # broadcast = Participant("Broadcast", address_hex="ff") #TODO: Sometimes messages to broadcast checksum = GenericCRC.from_standard_checksum("CRC16 CC1101") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 16) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.DST_ADDRESS, 24) mb.add_label(FieldType.Function.SRC_ADDRESS, 24) mb.add_label(FieldType.Function.DATA, 8 * 8) mb.add_checksum_label(16, checksum) mb_ack = MessageTypeBuilder("ack") mb_ack.add_label(FieldType.Function.PREAMBLE, 8) mb_ack.add_label(FieldType.Function.SYNC, 16) mb_ack.add_label(FieldType.Function.DST_ADDRESS, 24) mb_ack.add_checksum_label(16, checksum) mb_kex = MessageTypeBuilder("kex") mb_kex.add_label(FieldType.Function.PREAMBLE, 24) mb_kex.add_label(FieldType.Function.SYNC, 16) mb_kex.add_label(FieldType.Function.DST_ADDRESS, 24) mb_kex.add_label(FieldType.Function.SRC_ADDRESS, 24) mb_kex.add_label(FieldType.Function.DATA, 64 * 8) mb_kex.add_checksum_label(16, checksum) pg = ProtocolGenerator( [mb.message_type, mb_ack.message_type, mb_kex.message_type], syncs_by_mt={ mb.message_type: "0x0420", mb_ack.message_type: "0x2222", mb_kex.message_type: "0x6767" }, preambles_by_mt={ mb.message_type: "10" * 8, mb_ack.message_type: "10" * 4, mb_kex.message_type: "10" * 12 }, participants=[alice, bob, charly, daniel]) return pg
def __prepare_example_protocol(self) -> ProtocolAnalyzer: alice = Participant("Alice", "A", address_hex="1234") bob = Participant("Bob", "B", address_hex="cafe") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 8) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.TYPE, 8) mb.add_label(FieldType.Function.DST_ADDRESS, 16) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb_ack = MessageTypeBuilder("ack") mb_ack.add_label(FieldType.Function.PREAMBLE, 8) mb_ack.add_label(FieldType.Function.SYNC, 16) mb_ack.add_label(FieldType.Function.LENGTH, 8) mb_ack.add_label(FieldType.Function.DST_ADDRESS, 16) num_messages = 50 pg = ProtocolGenerator([mb.message_type, mb_ack.message_type], syncs_by_mt={ mb.message_type: "0x6768", mb_ack.message_type: "0x6768" }, participants=[alice, bob]) random.seed(0) for i in range(num_messages): if i % 2 == 0: source, destination = alice, bob data_length = 8 else: source, destination = bob, alice data_length = 16 pg.generate_message(data=pg.decimal_to_bits( random.randint(0, 2**(data_length - 1)), data_length), source=source, destination=destination) pg.generate_message(data="", message_type=mb_ack.message_type, destination=source, source=destination) #self.save_protocol("labeled_protocol", pg) return pg.protocol
def new_from_xml(cls, tag: ET.Element, participants, decoders=None, message_types=None): msg = Message.new_from_xml(tag.find("message"), participants=participants, decoders=decoders, message_types=message_types) destination = Participant.find_matching(tag.get("destination_id", ""), participants) return SimulatorMessage(destination, msg.plain_bits, msg.pause, msg.message_type, msg.decoder, msg.participant, timestamp=msg.timestamp)
def test_two_assign_participants_by_rssi(self): rssis = [[0.65389872, 0.13733707, 0.1226876, 0.73320961, 0.64940965, 0.12463234, 0.12296994, 0.68053716, 0.66020358, 0.12428901, 0.12312815, 0.69160986, 0.65582329, 0.12536003, 0.12587067, 0.66315573, 0.66313261, 0.12816505, 0.13491708, 0.66950738, 0.14047238], [0.26651502, 0.2073856, 0.13547869, 0.25948182, 0.28204739, 0.13716124, 0.13526952, 0.24828221, 0.25431305, 0.13681877, 0.13650328, 0.28083691, 0.25550124, 0.13498682, 0.13611424, 0.2629154, 0.26388499, 0.13780586, 0.13561584, 0.27228078, 0.1356563]] proto1 = ProtocolAnalyzer(None) proto2 = ProtocolAnalyzer(None) for i in range(0, len(rssis[0])): message = copy.deepcopy(self.protocol.messages[i]) message.participant = None proto1.messages.append(message) proto1.messages[i].rssi = rssis[0][i] self.assertEqual(len(proto1.messages), 21) for i in range(0, len(rssis[1])): message = copy.deepcopy(self.protocol.messages[21 + i]) message.participant = None proto2.messages.append(message) proto2.messages[i].rssi = rssis[1][i] self.assertEqual(len(proto2.messages), 21) alice = Participant(name="Alice", shortname="A") alice.relative_rssi = 1 bob = Participant(name="Bob", shortname="B") bob.relative_rssi = 0 excpected_partis = [[alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, bob], [alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, alice, bob, bob, alice, bob]] proto1.auto_assign_participants([alice, bob]) for i, message in enumerate(proto1.messages): self.assertEqual(message.participant, excpected_partis[0][i]) proto2.auto_assign_participants([alice, bob]) for i, message in enumerate(proto2.messages): self.assertEqual(message.participant, excpected_partis[1][i])
def test_save_and_load_participants(self): target_dir = os.path.join(tempfile.gettempdir(), "urh", "multi_participant_test") os.makedirs(target_dir, exist_ok=True) if os.path.isfile(os.path.join(target_dir, settings.PROJECT_FILE)): os.remove(os.path.join(target_dir, settings.PROJECT_FILE)) self.form.project_manager.set_project_folder(target_dir, ask_for_new_project=False) self.form.project_manager.participants = [Participant("Alice", "A"), Participant("Bob", "B")] self.add_signal_to_form("esaver.complex16s") self.assertEqual(len(self.form.signal_tab_controller.signal_frames[0].proto_analyzer.messages), 3) self.add_signal_to_form("two_participants.complex16s") self.assertEqual(len(self.form.signal_tab_controller.signal_frames[1].proto_analyzer.messages), 18) self.add_signal_to_form("fsk.complex") self.assertEqual(len(self.form.signal_tab_controller.signal_frames[2].proto_analyzer.messages), 1) self.assertEqual(self.form.compare_frame_controller.protocol_model.row_count, 22) target = {0: "A", 1: "A", 2: "B", 3: "B", 4: "A", 5: "B", 6: "A", 7: "A", 8: "A", 9: "B", 10: "B", 11: "A", 12: "B", 13: "A", 14: "A", 15: "B", 16: "A", 17: "B", 18: "B", 19: "B", 20: "A", 21: "B"} for row, shortname in target.items(): participant = next(p for p in self.form.project_manager.participants if p.shortname == shortname) self.form.compare_frame_controller.proto_analyzer.messages[row].participant = participant self.form.compare_frame_controller.proto_tree_model.rootItem.child(0).child(0).show = False self.assertEqual(self.form.compare_frame_controller.protocol_model.row_count, 19) for row, shortname in target.items(): row -= 3 if row >= 0: self.assertEqual(self.form.compare_frame_controller.proto_analyzer.messages[row].participant.shortname, shortname) self.form.compare_frame_controller.refresh_assigned_participants_ui() self.form.save_project() self.form.close_all_files() self.wait_before_new_file() self.assertEqual(self.form.compare_frame_controller.protocol_model.row_count, 0) self.form.project_manager.set_project_folder(target_dir, ask_for_new_project=False) self.assertEqual(self.form.compare_frame_controller.protocol_model.row_count, 22) for row, shortname in target.items(): self.assertEqual(self.form.compare_frame_controller.proto_analyzer.messages[row].participant.shortname, shortname, msg=str(row))
def test_no_sequence_number(self): """ Ensure no sequence number is labeled, when it cannot be found :return: """ alice = Participant("Alice", address_hex="dead") bob = Participant("Bob", address_hex="beef") mb = MessageTypeBuilder("protocol_with_one_message_type") mb.add_label(FieldType.Function.PREAMBLE, 8) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 16) mb.add_label(FieldType.Function.DST_ADDRESS, 16) num_messages = 3 pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x1337"}, participants=[alice, bob]) for i in range(num_messages): if i % 2 == 0: source, destination = alice, bob else: source, destination = bob, alice pg.generate_message(data="", source=source, destination=destination) #self.save_protocol("protocol_1", pg) # Delete message type information -> no prior knowledge self.clear_message_types(pg.protocol.messages) ff = FormatFinder(pg.protocol.messages) ff.known_participant_addresses.clear() ff.perform_iteration() self.assertEqual(len(ff.message_types), 1) self.assertEqual( ff.message_types[0].num_labels_with_type( FieldType.Function.SEQUENCE_NUMBER), 0)
def read_participants_from_xml_tag(root: ET.Element): try: participants = [] for parti_tag in root.find("participants").findall("participant"): participants.append(Participant.from_xml(parti_tag)) return participants except AttributeError: logger.warning("no participants found in xml") return []
def read_participants_from_xml_tag(root: ET.Element): try: participants = [] for parti_tag in root.find("participants").findall("participant"): participants.append(Participant.from_xml(parti_tag)) return participants except AttributeError: logger.warning("no participants found in xml") return []
def from_xml(self, tag: ET.Element, participants, decoders=None, message_types=None): super().from_xml(tag, participants, decoders, message_types) self.destination = Participant.find_matching( tag.get("destination_id", ""), participants) self.repeat = Formatter.str2val(tag.get("repeat", "1"), int, 1)
def _prepare_protocol_2() -> ProtocolGenerator: alice = Participant("Alice", address_hex="dead01") bob = Participant("Bob", address_hex="beef24") mb = MessageTypeBuilder("data") mb.add_label(FieldType.Function.PREAMBLE, 72) mb.add_label(FieldType.Function.SYNC, 16) mb.add_label(FieldType.Function.LENGTH, 8) mb.add_label(FieldType.Function.SRC_ADDRESS, 24) mb.add_label(FieldType.Function.DST_ADDRESS, 24) mb.add_label(FieldType.Function.SEQUENCE_NUMBER, 16) pg = ProtocolGenerator([mb.message_type], syncs_by_mt={mb.message_type: "0x1337"}, preambles_by_mt={mb.message_type: "10" * 36}, sequence_number_increment=32, participants=[alice, bob]) return pg
def add_participant(self): used_colors = set(p.color_index for p in self.participants) avail_colors = set(range(0, len( constants.PARTICIPANT_COLORS))) - used_colors if len(avail_colors) > 0: color_index = avail_colors.pop() else: color_index = random.choice( range(len(constants.PARTICIPANT_COLORS))) name, shortname = self.__get_initial_name() participant = Participant(name, shortname=shortname, color_index=color_index) self.participants.append(participant) participant.relative_rssi = len(self.participants) - 1 self.update() self.participant_edited.emit()
def save_to_xml(self, standalone=False) -> ET.Element: result = ET.Element("simulator_config") if standalone: result.append(Modulator.modulators_to_xml_tag(self.project_manager.modulators)) result.append(Encoding.decodings_to_xml_tag(self.project_manager.decodings)) result.append(Participant.participants_to_xml_tag(self.project_manager.participants)) result.append(self.project_manager.simulator_rx_conf_to_xml()) result.append(self.project_manager.simulator_tx_conf_to_xml()) items_tag = ET.SubElement(result, "items") for item in self.rootItem.children: self.__save_item_to_xml(items_tag, item) return result
def from_xml_tag(self, root: ET.Element, read_bits=False, participants=None, decodings=None): if not root: return None decoders = Encoding.read_decoders_from_xml_tag(root) if decodings is None else decodings if participants is None: participants = Participant.read_participants_from_xml_tag(root) if read_bits: self.messages[:] = [] try: message_types = [] for message_type_tag in root.find("message_types").findall("message_type"): message_types.append(MessageType.from_xml(message_type_tag)) except AttributeError: message_types = [] for message_type in message_types: if message_type not in self.message_types: self.message_types.append(message_type) try: message_tags = root.find("messages").findall("message") for i, message_tag in enumerate(message_tags): if read_bits: self.messages.append(Message.new_from_xml(tag=message_tag, participants=participants, decoders=decoders, message_types=self.message_types)) else: try: self.messages[i].from_xml(tag=message_tag, participants=participants, decoders=decoders, message_types=self.message_types) except IndexError: pass # Part of signal was copied in last session but signal was not saved except AttributeError: pass
def test_performance(self): self.form = MainController() self.cfc = self.form.compare_frame_controller self.stc = self.form.simulator_tab_controller self.gtc = self.form.generator_tab_controller self.form.add_signalfile(get_path_for_data_file("esaver.coco")) self.sframe = self.form.signal_tab_controller.signal_frames[0] self.sim_frame = self.form.simulator_tab_controller self.form.ui.tabWidget.setCurrentIndex(3) self.cfc.proto_analyzer.auto_assign_labels() self.network_sdr_plugin_sender = NetworkSDRInterfacePlugin(raw_mode=True) part_a = Participant("Device A", shortname="A", color_index=0) part_b = Participant("Device B", shortname="B", color_index=1) part_b.simulate = True self.form.project_manager.participants.append(part_a) self.form.project_manager.participants.append(part_b) self.form.project_manager.project_updated.emit() sniffer = ProtocolSniffer(100, 0.01, 0.1, 5, 1, NetworkSDRInterfacePlugin.NETWORK_SDR_NAME, BackendHandler(), network_raw_mode=True) sender = EndlessSender(BackendHandler(), NetworkSDRInterfacePlugin.NETWORK_SDR_NAME) simulator = Simulator(self.stc.simulator_config, self.gtc.modulators, self.stc.sim_expression_parser, self.form.project_manager, sniffer=sniffer, sender=sender) pause = 100 msg_a = SimulatorMessage(part_b, [1, 0] * 16 + [1, 1, 0, 0] * 8 + [0, 0, 1, 1] * 8 + [1, 0, 1, 1, 1, 0, 0, 1, 1, 1] * 4, pause=pause, message_type=MessageType("empty_message_type"), source=part_a) msg_b = SimulatorMessage(part_a, [1, 0] * 16 + [1, 1, 0, 0] * 8 + [1, 1, 0, 0] * 8 + [1, 0, 1, 1, 1, 0, 0, 1, 1, 1] * 4, pause=pause, message_type=MessageType("empty_message_type"), source=part_b) self.stc.simulator_config.add_items([msg_a, msg_b], 0, None) self.stc.simulator_config.update_active_participants() port = self.get_free_port() sniffer = simulator.sniffer sniffer.rcv_device.set_server_port(port) self.network_sdr_plugin_sender.client_port = port sender = simulator.sender port = self.get_free_port() sender.device.set_client_port(port) sender.device._VirtualDevice__dev.name = "simulator_sender" current_index = Value("L") elapsed = Value("f") target_num_samples = 13600 + pause receive_process = Process(target=receive, args=(port, current_index, target_num_samples, elapsed)) receive_process.daemon = True receive_process.start() # Ensure receiver is running time.sleep(2) # spy = QSignalSpy(self.network_sdr_plugin_receiver.rcv_index_changed) simulator.start() modulator = Modulator("test_modulator") modulator.samples_per_bit = 100 modulator.carrier_freq_hz = 55e3 # yappi.start() self.network_sdr_plugin_sender.send_raw_data(modulator.modulate(msg_a.encoded_bits), 1) time.sleep(0.5) # send some zeros to simulate the end of a message self.network_sdr_plugin_sender.send_raw_data(np.zeros(self.num_zeros_for_pause, dtype=np.complex64), 1) time.sleep(0.5) receive_process.join(15) logger.info("PROCESS TIME: {0:.2f}ms".format(elapsed.value)) # self.assertEqual(current_index.value, target_num_samples) self.assertLess(elapsed.value, 200) # timeout = spy.wait(2000) # yappi.get_func_stats().print_all() # yappi.get_thread_stats().print_all()
def from_xml(self, tag: ET.Element, participants, decoders=None, message_types=None): super().from_xml(tag, participants, decoders, message_types) self.destination = Participant.find_matching(tag.get("destination_id", ""), participants) self.repeat = Formatter.str2val(tag.get("repeat", "1"), int, 1)
def set_project_folder(self, path, ask_for_new_project=True, close_all=True): if self.project_file is not None or close_all: # Close existing project (if any) or existing files if requested self.main_controller.close_all_files() FileOperator.RECENT_PATH = path util.PROJECT_PATH = path self.project_path = path self.project_file = os.path.join(self.project_path, constants.PROJECT_FILE) collapse_project_tabs = False if not os.path.isfile(self.project_file): if ask_for_new_project: reply = QMessageBox.question(self.main_controller, "Project File", "Do you want to create a Project File for this folder?\n" "If you chose No, you can do it later via File->Convert Folder to Project.", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.main_controller.show_project_settings() else: self.project_file = None if self.project_file is not None: root = ET.Element("UniversalRadioHackerProject") tree = ET.ElementTree(root) tree.write(self.project_file) self.modulation_was_edited = False else: tree = ET.parse(self.project_file) root = tree.getroot() collapse_project_tabs = bool(int(root.get("collapse_project_tabs", 0))) self.modulation_was_edited = bool(int(root.get("modulation_was_edited", 0))) cfc = self.main_controller.compare_frame_controller self.read_parameters(root) self.participants[:] = Participant.read_participants_from_xml_tag(xml_tag=root.find("protocol")) self.main_controller.add_files(self.read_opened_filenames()) self.read_compare_frame_groups(root) self.decodings = Encoding.read_decoders_from_xml_tag(root.find("protocol")) cfc.proto_analyzer.message_types[:] = self.read_message_types() cfc.message_type_table_model.update() cfc.proto_analyzer.from_xml_tag(root=root.find("protocol"), participants=self.participants, decodings=cfc.decodings) cfc.updateUI() try: for message_type in cfc.proto_analyzer.message_types: for lbl in filter(lambda x: not x.show, message_type): cfc.set_protocol_label_visibility(lbl) except Exception as e: logger.exception(e) self.modulators = self.read_modulators_from_project_file() self.main_controller.simulator_tab_controller.load_config_from_xml_tag(root.find("simulator_config")) if len(self.project_path) > 0 and self.project_file is None: self.main_controller.ui.actionConvert_Folder_to_Project.setEnabled(True) else: self.main_controller.ui.actionConvert_Folder_to_Project.setEnabled(False) self.main_controller.adjust_for_current_file(path) self.main_controller.filemodel.setRootPath(path) self.main_controller.ui.fileTree.setRootIndex( self.main_controller.file_proxy_model.mapFromSource(self.main_controller.filemodel.index(path))) self.main_controller.ui.fileTree.setToolTip(path) self.main_controller.ui.splitter.setSizes([1, 1]) if collapse_project_tabs: self.main_controller.collapse_project_tab_bar() else: self.main_controller.expand_project_tab_bar() self.main_controller.setWindowTitle("Universal Radio Hacker [" + path + "]") self.project_loaded_status_changed.emit(self.project_loaded) self.project_updated.emit()