Beispiel #1
0
    def prepare_modulation_dialog(self) -> (ModulatorDialog, Message):
        preselected_index = self.ui.cBoxModulations.currentIndex()

        min_row, max_row, start, end = self.ui.tableMessages.selection_range()
        if min_row > -1:
            try:
                selected_message = self.table_model.protocol.messages[min_row]
                preselected_index = selected_message.modulator_index
            except IndexError:
                selected_message = Message([1, 0, 1, 0, 1, 0, 1, 0], 0, [], MessageType("empty"))
        else:
            selected_message = Message([1, 0, 1, 0, 1, 0, 1, 0], 0, [], MessageType("empty"))
            if len(self.table_model.protocol.messages) > 0:
                selected_message.bit_len = self.table_model.protocol.messages[0].bit_len

        for m in self.modulators:
            m.default_sample_rate = self.project_manager.device_conf["sample_rate"]

        modulator_dialog = ModulatorDialog(self.modulators, tree_model=self.tree_model, parent=self.parent())
        modulator_dialog.ui.comboBoxCustomModulations.setCurrentIndex(preselected_index)

        modulator_dialog.finished.connect(self.refresh_modulators)
        modulator_dialog.finished.connect(self.refresh_pause_list)

        return modulator_dialog, selected_message
Beispiel #2
0
    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
Beispiel #3
0
    def __init__(self, destination: Participant, plain_bits,
                 pause: int, message_type: MessageType, decoder=None, source=None, timestamp=None):
        Message.__init__(self, plain_bits, pause, message_type, decoder=decoder, participant=source)
        SimulatorItem.__init__(self)
        if timestamp is not None:
            self.timestamp = timestamp

        self.destination = destination
        self.send_recv_messages = []
        self.repeat = 1
Beispiel #4
0
    def get_protocol_from_string(message_strings: list, is_hex=None, default_pause=0, sample_rate=1e6):
        """

        :param message_strings:
        :param is_hex: None means auto detects
        :return:
        """
        protocol = ProtocolAnalyzer(None)

        def parse_line(line: str):
            # support transcript files e.g 1 (A->B): 10101111
            index = line.rfind(" ")
            line = line[index + 1:]

            # support pauses given like 100101/10s
            try:
                data, pause = line.split(constants.PAUSE_SEP)
            except ValueError:
                data, pause = line, str(default_pause)
            if pause.endswith("ms"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e3
            elif pause.endswith("µs"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e6
            elif pause.endswith("ns"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e9
            elif pause.endswith("s"):
                pause = float(pause[:-1]) * float(sample_rate)
            else:
                pause = float(pause)

            return data, int(pause)

        if not is_hex:
            for line in filter(None, map(str.strip, message_strings)):
                bits, pause = parse_line(line)
                try:
                    protocol.messages.append(Message.from_plain_bits_str(bits, pause=pause))
                except ValueError:
                    is_hex = True if is_hex is None else is_hex
                    break

        if is_hex:
            protocol.messages.clear()
            lookup = {"{0:0x}".format(i): "{0:04b}".format(i) for i in range(16)}

            for line in filter(None, map(str.strip, message_strings)):
                bits, pause = parse_line(line)
                bit_str = [lookup[bits[i].lower()] for i in range(0, len(bits))]
                protocol.messages.append(Message.from_plain_bits_str("".join(bit_str), pause=pause))

        return protocol
Beispiel #5
0
    def __demodulate_data(self, data):
        """
        Demodulates received IQ data and adds demodulated bits to messages
        :param data:
        :return:
        """
        if self.__are_bits_in_data(data):
            self.reading_data = True
        elif self.conseq_non_data == 5:
            self.reading_data = False
            self.conseq_non_data = 0
        else:
            self.conseq_non_data += 1

        if self.reading_data:
            self.data_cache.append(data)
            return
        elif len(self.data_cache) == 0:
            return

        self.signal._fulldata = np.concatenate(self.data_cache)
        self.data_cache.clear()
        self.signal._qad = None

        bit_len = self.signal.bit_len
        ppseq = grab_pulse_lens(self.signal.qad, self.signal.qad_center,
                                self.signal.tolerance, self.signal.modulation_type)

        bit_data, pauses, bit_sample_pos = self._ppseq_to_bits(ppseq, bit_len)

        i = 0
        first_msg = True

        for bits, pause in zip(bit_data, pauses):
            if first_msg or self.messages[-1].pause > 8 * bit_len:
                # Create new Message
                middle_bit_pos = bit_sample_pos[i][int(len(bits) / 2)]
                start, end = middle_bit_pos, middle_bit_pos + bit_len
                rssi = np.mean(np.abs(self.signal._fulldata[start:end]))
                message = Message(bits, pause, bit_len=bit_len, rssi=rssi, message_type=self.default_message_type,
                                  decoder=self.decoder)
                self.messages.append(message)
                first_msg = False
            else:
                # Append to last message
                message = self.messages[-1]
                nzeros = int(np.round(message.pause / bit_len))
                message.plain_bits.extend([False] * nzeros)
                message.plain_bits.extend(bits)
                message.pause = pause
            i += 1
Beispiel #6
0
 def message_to_string(self, message: Message, view: int, include_timestamps=True):
     msg_str_data = []
     if include_timestamps:
         msg_date = datetime.fromtimestamp(message.timestamp)
         msg_str_data.append(msg_date.strftime("[%Y-%m-%d %H:%M:%S.%f]"))
     msg_str_data.append(message.view_to_string(view, decoded=True, show_pauses=False))
     return " ".join(msg_str_data)
Beispiel #7
0
    def check_for_data(self):
        old_index = 0
        while self.is_running:
            time.sleep(0.01)
            if self.rcv_device.is_raw_mode:
                if old_index <= self.rcv_device.current_index:
                    data = self.rcv_device.data[old_index:self.rcv_device.current_index]
                else:
                    data = np.concatenate((self.rcv_device.data[old_index:],
                                           self.rcv_device.data[:self.rcv_device.current_index]))
                old_index = self.rcv_device.current_index
                self.__demodulate_data(data)
            elif self.rcv_device.backend == Backends.network:
                # We receive the bits here
                for bit_str in self.rcv_device.data:
                    msg = Message.from_plain_bits_str(bit_str)
                    msg.decoder = self.decoder
                    self.messages.append(msg)
                    self.message_sniffed.emit(len(self.messages) - 1)

                self.rcv_device.free_data()  # do not store received bits twice

            if self.sniff_file and not os.path.isdir(self.sniff_file):
                plain_bits_str = self.plain_bits_str
                if plain_bits_str:
                    with open(self.sniff_file, "a") as f:
                        f.write("\n".join(plain_bits_str) + "\n")

            if not self.__store_data:
                self.messages.clear()
Beispiel #8
0
    def test_cli_modulate_messages(self):
        modulator = Modulator("test")
        modulator.sample_rate = 2e3
        modulator.samples_per_bit = 100
        modulator.modulation_type_str = "ASK"
        modulator.param_for_zero = 0
        modulator.param_for_one = 100

        bits = "1010111100001"

        self.assertIsNone(urh_cli.modulate_messages([], modulator))

        message = Message.from_plain_bits_str(bits, pause=1000)

        modulated = urh_cli.modulate_messages([message], modulator)

        # Demodulate for testing
        s = Signal("", "", modulation="ASK", sample_rate=2e6)
        s.bit_len = 100
        s.noise_threshold = 0
        s._fulldata = modulated

        pa = ProtocolAnalyzer(s)
        pa.get_protocol_from_signal()
        self.assertEqual(len(pa.messages), 1)
        self.assertEqual(pa.messages[0].plain_bits_str, bits)
    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']))
        self.decodings.append(Encoding(['DeWhitening', constants.DECODING_DATAWHITENING, '0x67686768;0x21']))
Beispiel #10
0
    def test_format_finding_enocean(self):
        enocean_protocol = ProtocolAnalyzer(None)
        with open(get_path_for_data_file("enocean_bits.txt")) as f:
            for line in f:
                enocean_protocol.messages.append(Message.from_plain_bits_str(line.replace("\n", "")))
                enocean_protocol.messages[-1].message_type = enocean_protocol.default_message_type

        preamble_start = 3
        preamble_end = 10
        sof_start = 11
        sof_end = 14

        preamble_label = ProtocolLabel(name=self.preamble_field_type.caption, field_type=self.preamble_field_type,
                                       start=preamble_start, end=preamble_end, color_index=0)
        sync_label = ProtocolLabel(name=self.sync_field_type.caption, field_type=self.sync_field_type,
                                   start=sof_start, end=sof_end, color_index=1)

        ff = FormatFinder(enocean_protocol, self.participants, field_types=self.field_types)
        ff.perform_iteration()

        self.assertEqual(len(enocean_protocol.message_types), 1)

        self.assertIn(preamble_label, enocean_protocol.default_message_type)
        self.assertIn(sync_label, enocean_protocol.default_message_type)
        self.assertTrue(
            not any(lbl.name == self.length_field_type.caption for lbl in enocean_protocol.default_message_type))
        self.assertTrue(not any("address" in lbl.name.lower() for lbl in enocean_protocol.default_message_type))
def generate_random_messages(num_messages: int, num_bits: int,
                             preamble: str, sync: str, eof: str, message_pause: int):
    return [
        Message.from_plain_bits_str(
            generate_message_bits(num_bits, preamble, sync, eof), pause=message_pause
        )
        for _ in range(num_messages)
    ]
Beispiel #12
0
 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)
Beispiel #13
0
    def add_plain_bits_from_txt(self, filename: str):
        protocol = ProtocolAnalyzer(None)
        protocol.filename = filename
        with open(filename) as f:
            for line in f:
                protocol.messages.append(Message.from_plain_bits_str(line.strip()))

        self.compare_frame_controller.add_protocol(protocol)
        self.compare_frame_controller.refresh()
        self.__add_empty_frame_for_filename(protocol, filename)
Beispiel #14
0
    def log_message_labels(self, message: Message):
        message.split(decode=False)
        for lbl in message.message_type:
            if not lbl.logging_active:
                continue

            try:
                data = message.plain_bits[lbl.start:lbl.end]
            except IndexError:
                return None

            lsb = lbl.display_bit_order_index == 1
            lsd = lbl.display_bit_order_index == 2

            data = util.convert_bits_to_string(data, lbl.display_format_index, pad_zeros=True, lsb=lsb, lsd=lsd)
            if data is None:
                continue

            log_msg = lbl.name + ": " + HTMLFormatter.monospace(data)
            self.log_messages.append(HTMLFormatter.indent_string(log_msg))
Beispiel #15
0
    def get_protocol_from_string(message_strings: list):
        protocol = ProtocolAnalyzer(None)
        is_hex = False
        for line in filter(None, map(str.strip, message_strings)):
            # support transcript files e.g 1 (A->B): 10101111
            index = line.rfind(" ")
            try:
                protocol.messages.append(Message.from_plain_bits_str(line[index + 1:]))
            except ValueError:
                is_hex = True
                break

        if is_hex:
            protocol.messages.clear()
            lookup = {"{0:0x}".format(i): "{0:04b}".format(i) for i in range(16)}
            for line in filter(None, map(str.strip, message_strings)):
                # support transcript files e.g 1 (A->B): 10101111
                index = line.rfind(" ")
                bit_str = [lookup[line[i].lower()] for i in range(index+1, len(line))]
                protocol.messages.append(Message.from_plain_bits_str("".join(bit_str)))

        return protocol
    def test_assign_decodings(self):
        self.undecoded_protocol = ProtocolAnalyzer(None)
        with open(get_path_for_data_file("undecoded.txt")) as f:
            for line in f:
                self.undecoded_protocol.messages.append(Message.from_plain_bits_str(line.replace("\n", "")))

        self.undecoded_protocol.auto_assign_decodings(self.decodings)

        for i, message in enumerate(self.undecoded_protocol.messages):
            if message.plain_hex_str[8:16] == "9a7d9a7d":
                self.assertEqual(message.decoder.name, "DeWhitening Special", msg=str(i))
            elif message.plain_hex_str[8:16] == "67686768":
                self.assertEqual(message.decoder.name, "DeWhitening", msg=str(i))
Beispiel #17
0
    def from_xml_tag(self, root: ET.Element, read_bits=False, participants=None, decodings=None):
        if not root:
            return None

        if root.find("modulators") and hasattr(self, "modulators"):
            self.modulators[:] = []
            for mod_tag in root.find("modulators").findall("modulator"):
                self.modulators.append(Modulator.from_xml(mod_tag))

        decoders = self.read_decoders_from_xml_tag(root) if decodings is None else decodings

        if participants is None:
            participants = self.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:
                    message = Message.from_plain_bits_str(bits=message_tag.get("bits"))
                    message.from_xml(tag=message_tag, participants=participants, decoders=decoders,
                                     message_types=self.message_types)
                    self.messages.append(message)
                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
Beispiel #18
0
    def detect_source_destination(self, message: Message):
        participants = self.simulator_config.participants

        source = None if len(participants) < 2 else participants[0]
        destination = self.simulator_config.broadcast_part

        if message.participant:
            source = message.participant
            dst_address_label = next((lbl for lbl in message.message_type if lbl.field_type and
                                      lbl.field_type.function == FieldType.Function.DST_ADDRESS), None)
            if dst_address_label:
                start, end = message.get_label_range(dst_address_label, view=1, decode=True)
                dst_address = message.decoded_hex_str[start:end]
                dst = next((p for p in participants if p.address_hex == dst_address), None)
                if dst is not None and dst != source:
                    destination = dst

        return source, destination
Beispiel #19
0
    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
Beispiel #20
0
    def get_protocol_from_signal(self):
        signal = self.signal
        if signal is None:
            self.messages = None
            return

        if self.messages is not None:
            self.messages[:] = []
        else:
            self.messages = []

        bit_len = signal.bit_len

        rel_symbol_len = self._read_symbol_len()
        self.used_symbols.clear()

        ppseq = signalFunctions.grab_pulse_lens(signal.qad, signal.qad_center,
                                                signal.tolerance,
                                                signal.modulation_type)

        bit_data, pauses, bit_sample_pos = self._ppseq_to_bits(
            ppseq, bit_len, rel_symbol_len)

        i = 0
        for bits, pause in zip(bit_data, pauses):
            middle_bit_pos = bit_sample_pos[i][int(len(bits) / 2)]
            start, end = middle_bit_pos, middle_bit_pos + bit_len
            rssi = np.mean(np.abs(signal._fulldata[start:end]))
            message = Message(bits,
                              pause,
                              message_type=self.default_message_type,
                              bit_len=bit_len,
                              rssi=rssi,
                              decoder=self.decoder,
                              bit_sample_pos=bit_sample_pos[i])
            self.messages.append(message)
            i += 1

        self.qt_signals.protocol_updated.emit()
Beispiel #21
0
    def on_rcv_thread_index_changed(self, old_index, new_index):
        old_nmsgs = len(self.messages)
        if self.rcv_device.backend in (Backends.native, Backends.grc):
            if old_index == new_index:
                return
            self.__demodulate_data(self.rcv_device.data[old_index:new_index])
        elif self.rcv_device.backend == Backends.network:
            # We receive the bits here
            for bit_str in self.rcv_device.data:
                msg = Message.from_plain_bits_str(bit_str)
                msg.decoder = self.decoder
                self.messages.append(msg)

            self.rcv_device.free_data()  # do not store received bits twice

        self.qt_signals.data_sniffed.emit(old_nmsgs)

        if self.sniff_file and not os.path.isdir(self.sniff_file):
            with open(self.sniff_file, "a") as myfile:
                myfile.write("\n".join(self.plain_bits_str))

        if not self.__store_data:
            self.messages.clear()
Beispiel #22
0
    def on_rcv_thread_index_changed(self, old_index, new_index):
        old_nmsgs = len(self.messages)
        if self.rcv_device.backend in (Backends.native, Backends.grc):
            if old_index == new_index:
                return
            self.__demodulate_data(self.rcv_device.data[old_index:new_index])
        elif self.rcv_device.backend == Backends.network:
            # We receive the bits here
            for bit_str in self.rcv_device.data:
                msg = Message.from_plain_bits_str(bit_str)
                msg.decoder = self.decoder
                self.messages.append(msg)

            self.rcv_device.free_data()  # do not store received bits twice

        self.qt_signals.data_sniffed.emit(old_nmsgs)

        if self.sniff_file and not os.path.isdir(self.sniff_file):
            with open(self.sniff_file, "a") as myfile:
                myfile.write("\n".join(self.plain_bits_str))

        if not self.__store_data:
            self.messages.clear()
Beispiel #23
0
    def test_configure_crc_ranges(self):
        checksum_label = ChecksumLabel(
            "checksum_label", 50, 100, 0,
            FieldType("crc", FieldType.Function.CHECKSUM))

        crc_widget_controller = ChecksumWidgetController(
            checksum_label, Message([0] * 100, 0, MessageType("test")), 0)
        model = crc_widget_controller.data_range_table_model
        self.assertEqual(model.data(model.index(0, 0)), 1)
        self.assertEqual(model.data(model.index(0, 1)), 50)
        self.assertEqual(model.rowCount(), 1)

        crc_widget_controller.ui.btnAddRange.click()
        self.assertEqual(model.rowCount(), 2)
        crc_widget_controller.ui.btnAddRange.click()
        self.assertEqual(model.rowCount(), 3)

        crc_widget_controller.ui.btnRemoveRange.click()
        self.assertEqual(model.rowCount(), 2)
        crc_widget_controller.ui.btnRemoveRange.click()
        self.assertEqual(model.rowCount(), 1)
        crc_widget_controller.ui.btnRemoveRange.click()
        self.assertEqual(model.rowCount(), 1)
Beispiel #24
0
    def get_protocol_from_signal(self):
        signal = self.signal
        if signal is None:
            self.messages = None
            return

        if self.messages is not None:
            self.messages[:] = []
        else:
            self.messages = []

        bit_len = signal.bit_len

        try:
            ppseq = signalFunctions.grab_pulse_lens(signal.qad, signal.qad_center, signal.tolerance,
                                                    signal.modulation_type, signal.bit_len)
        except TypeError:
            # Remove this check in version 1.7
            print("Extension method has changed! To fix this, first move to URHs base directory "
                  "then recompile the extensions using the following command:")
            print("python3 src/urh/cythonext/build.py")
            print("and finally restart the application")
            sys.exit(1)

        bit_data, pauses, bit_sample_pos = self._ppseq_to_bits(ppseq, bit_len, pause_threshold=signal.pause_threshold)

        i = 0
        for bits, pause in zip(bit_data, pauses):
            middle_bit_pos = bit_sample_pos[i][int(len(bits) / 2)]
            start, end = middle_bit_pos, middle_bit_pos + bit_len
            rssi = np.mean(np.abs(signal.data[start:end]))
            message = Message(bits, pause, message_type=self.default_message_type,
                              bit_len=bit_len, rssi=rssi, decoder=self.decoder, bit_sample_pos=bit_sample_pos[i])
            self.messages.append(message)
            i += 1

        self.qt_signals.protocol_updated.emit()
Beispiel #25
0
    def detect_source_destination(self, message: Message):
        participants = self.simulator_config.participants

        source = None if len(participants) < 2 else participants[0]
        destination = self.simulator_config.broadcast_part

        if message.participant:
            source = message.participant
            dst_address_label = next(
                (lbl for lbl in message.message_type if lbl.field_type and
                 lbl.field_type.function == FieldType.Function.DST_ADDRESS),
                None)
            if dst_address_label:
                start, end = message.get_label_range(dst_address_label,
                                                     view=1,
                                                     decode=True)
                dst_address = message.decoded_hex_str[start:end]
                dst = next(
                    (p for p in participants if p.address_hex == dst_address),
                    None)
                if dst is not None and dst != source:
                    destination = dst

        return source, destination
Beispiel #26
0
 def __build_protocol(self):
     result = ProtocolAnalyzer(signal=None)
     for _ in range(self.NUM_MESSAGES):
         b = Message([True] * self.BITS_PER_MESSAGE, pause=1000, message_type=result.default_message_type)
         result.messages.append(b)
     return result
Beispiel #27
0
    def __demodulate_data(self, data):
        """
        Demodulates received IQ data and adds demodulated bits to messages
        :param data:
        :return:
        """
        if len(data) == 0:
            return

        power_spectrum = data.real**2.0 + data.imag**2.0
        is_above_noise = np.sqrt(
            np.mean(power_spectrum)) > self.signal.noise_threshold

        if self.adaptive_noise and not is_above_noise:
            self.signal.noise_threshold = 0.9 * self.signal.noise_threshold + 0.1 * np.sqrt(
                np.max(power_spectrum))

        if is_above_noise:
            self.__add_to_buffer(data)
            self.pause_length = 0
            if not self.__buffer_is_full():
                return
        else:
            self.pause_length += len(data)
            if self.pause_length < 10 * self.signal.samples_per_symbol:
                self.__add_to_buffer(data)
                if not self.__buffer_is_full():
                    return

        if self.__current_buffer_index == 0:
            return

        # clear cache and start a new message
        self.signal.iq_array = IQArray(
            self.__buffer[0:self.__current_buffer_index])
        self.__clear_buffer()
        self.signal._qad = None

        samples_per_symbol = self.signal.samples_per_symbol
        if self.automatic_center:
            self.signal.center = AutoInterpretation.detect_center(
                self.signal.qad, max_size=150 * samples_per_symbol)

        ppseq = grab_pulse_lens(self.signal.qad, self.signal.center,
                                self.signal.tolerance,
                                self.signal.modulation_type,
                                self.signal.samples_per_symbol,
                                self.signal.bits_per_symbol,
                                self.signal.center_spacing)

        bit_data, pauses, bit_sample_pos = self._ppseq_to_bits(
            ppseq,
            samples_per_symbol,
            self.signal.bits_per_symbol,
            write_bit_sample_pos=False)

        for bits, pause in zip(bit_data, pauses):
            message = Message(bits,
                              pause,
                              samples_per_symbol=samples_per_symbol,
                              message_type=self.default_message_type,
                              decoder=self.decoder)
            self.messages.append(message)
            self.message_sniffed.emit(len(self.messages) - 1)
Beispiel #28
0
    def get_protocol_from_string(message_strings: list,
                                 is_hex=None,
                                 default_pause=0,
                                 sample_rate=1e6):
        """

        :param message_strings:
        :param is_hex: None means auto detects
        :return:
        """
        protocol = ProtocolAnalyzer(None)

        def parse_line(line: str):
            # support transcript files e.g 1 (A->B): 10101111
            index = line.rfind(" ")
            line = line[index + 1:]

            # support pauses given like 100101/10s
            try:
                data, pause = line.split(constants.PAUSE_SEP)
            except ValueError:
                data, pause = line, str(default_pause)
            if pause.endswith("ms"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e3
            elif pause.endswith("µs"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e6
            elif pause.endswith("ns"):
                pause = float(pause[:-2]) * float(sample_rate) / 1e9
            elif pause.endswith("s"):
                pause = float(pause[:-1]) * float(sample_rate)
            else:
                pause = float(pause)

            return data, int(pause)

        if not is_hex:
            for line in filter(None, map(str.strip, message_strings)):
                bits, pause = parse_line(line)
                try:
                    protocol.messages.append(
                        Message.from_plain_bits_str(bits, pause=pause))
                except ValueError:
                    is_hex = True if is_hex is None else is_hex
                    break

        if is_hex:
            protocol.messages.clear()
            lookup = {
                "{0:0x}".format(i): "{0:04b}".format(i)
                for i in range(16)
            }

            for line in filter(None, map(str.strip, message_strings)):
                bits, pause = parse_line(line)
                bit_str = [
                    lookup[bits[i].lower()] for i in range(0, len(bits))
                ]
                protocol.messages.append(
                    Message.from_plain_bits_str("".join(bit_str), pause=pause))

        return protocol
Beispiel #29
0
    def from_xml_tag(self,
                     root: ET.Element,
                     read_bits=False,
                     participants=None,
                     decodings=None):
        if not root:
            return None

        if root.find("modulators") and hasattr(self, "modulators"):
            self.modulators[:] = []
            for mod_tag in root.find("modulators").findall("modulator"):
                self.modulators.append(Modulator.from_xml(mod_tag))

        decoders = self.read_decoders_from_xml_tag(
            root) if decodings is None else decodings

        self.used_symbols.clear()
        try:
            for symbol_tag in root.find("symbols").findall("symbol"):
                s = Symbol(symbol_tag.get("name"),
                           int(symbol_tag.get("nbits")),
                           int(symbol_tag.get("pulsetype")),
                           int(symbol_tag.get("nsamples")))
                self.used_symbols.add(s)
        except AttributeError:
            pass

        if participants is None:
            participants = self.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:
                    message = Message.from_plain_bits_str(
                        bits=message_tag.get("bits"),
                        symbols={s.name: s
                                 for s in self.used_symbols})
                    message.from_xml(tag=message_tag,
                                     participants=participants,
                                     decoders=decoders,
                                     message_types=self.message_types)
                    self.messages.append(message)
                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
Beispiel #30
0
    def process_message(self):
        assert isinstance(self.current_item, SimulatorMessage)
        msg = self.current_item

        if msg.source is None:
            return

        new_message = self.generate_message_from_template(msg)

        if msg.source.simulate:
            # we have to send a message
            sender = self.sender
            if sender is None:
                self.log_message("Fatal: No sender configured")
                return

            for lbl in new_message.message_type:
                if isinstance(lbl.label, ChecksumLabel):
                    checksum = lbl.label.calculate_checksum_for_message(new_message, use_decoded_bits=False)
                    label_range = new_message.get_label_range(lbl=lbl.label, view=0, decode=False)
                    start, end = label_range[0], label_range[1]
                    new_message.plain_bits[start:end] = checksum + array.array("B", [0] * (
                            (end - start) - len(checksum)))

            self.transcript.append(msg.source, msg.destination, new_message, msg.index())
            self.send_message(new_message, msg.repeat, sender, msg.modulator_index)
            self.log_message("Sending message " + msg.index())
            self.log_message_labels(new_message)
            msg.send_recv_messages.append(new_message)
            self.last_sent_message = msg
        else:
            # we have to receive a message
            self.log_message("<i>Waiting for message {}</i>".format(msg.index()))
            sniffer = self.sniffer
            if sniffer is None:
                self.log_message("Fatal: No sniffer configured")
                return

            retry = 0

            max_retries = self.project_manager.simulator_retries
            while self.is_simulating and not self.simulation_is_finished() and retry < max_retries:
                received_msg = self.receive_message(sniffer)

                if not self.is_simulating:
                    return

                if received_msg is None:
                    if self.project_manager.simulator_error_handling_index == 0:
                        self.resend_last_message()
                        retry += 1
                        continue
                    elif self.project_manager.simulator_error_handling_index == 1:
                        self.stop()
                        return
                    elif self.project_manager.simulator_error_handling_index == 2:
                        self.do_restart = True
                        return

                received_msg.decoder = new_message.decoder
                received_msg.message_type = new_message.message_type

                check_result, error_msg = self.check_message(received_msg, new_message, retry=retry,
                                                             msg_index=msg.index())

                if check_result:
                    decoded_msg = Message(received_msg.decoded_bits, 0,
                                          received_msg.message_type, decoder=received_msg.decoder)
                    msg.send_recv_messages.append(decoded_msg)
                    self.transcript.append(msg.source, msg.destination, decoded_msg, msg.index())
                    self.log_message("Received message " + msg.index() + ": ")
                    self.log_message_labels(decoded_msg)
                    return
                elif self.verbose:
                    self.log_message(error_msg)

                retry += 1

            if retry == self.project_manager.simulator_retries:
                self.log_message("Message " + msg.index() + " not received")
                self.stop()
 def __get_modulator_of_message(self, message: Message) -> Modulator:
     if message.modulator_index > len(self.modulators) - 1:
         message.modulator_index = 0
     return self.modulators[message.modulator_index]
Beispiel #32
0
 def from_binary(self, filename: str):
     aggregated = np.fromfile(filename, dtype=np.uint8)
     unaggregated = [int(b) for n in aggregated for b in "{0:08b}".format(n)]
     self.messages.append(Message(unaggregated, 0, self.default_message_type))
Beispiel #33
0
 def __create_messages(self):
     mt = MessageType("test")
     return [
         Message([True] * self.BITS_PER_MESSAGE, 1000, mt)
         for _ in range(self.NUM_MESSAGES)
     ]
Beispiel #34
0
    def generate_message(self,
                         message_type=None,
                         data="0x00",
                         source: Participant = None,
                         destination: Participant = None):
        for participant in (source, destination):
            if isinstance(
                    participant,
                    Participant) and participant not in self.participants:
                self.participants.append(participant)

        if isinstance(message_type, MessageType):
            message_type_index = self.protocol.message_types.index(
                message_type)
        elif isinstance(message_type, int):
            message_type_index = message_type
        else:
            message_type_index = 0

        data = self.to_bits(data)

        mt = self.protocol.message_types[
            message_type_index]  # type: MessageType
        mt.sort()

        bits = []

        start = 0

        data_label_present = mt.get_first_label_with_type(
            FieldType.Function.DATA) is not None

        if data_label_present:
            message_length = mt[-1].end - 1
        else:
            message_length = mt[-1].end - 1 + len(data)

        checksum_labels = []

        for lbl in mt:  # type: ProtocolLabel
            bits.append("0" * (lbl.start - start))
            len_field = lbl.end - lbl.start  # in bits

            if isinstance(lbl, ChecksumLabel):
                checksum_labels.append(lbl)
                continue  # processed last

            if lbl.field_type.function == FieldType.Function.PREAMBLE:
                preamble = self.preambles_by_message_type[mt]
                assert len(preamble) == len_field
                bits.append(preamble)
                message_length -= len(preamble)
            elif lbl.field_type.function == FieldType.Function.SYNC:
                sync = self.syncs_by_message_type[mt]
                assert len(sync) == len_field
                bits.append(sync)
                message_length -= len(sync)
            elif lbl.field_type.function == FieldType.Function.LENGTH:
                value = int(math.ceil(message_length / 8))

                if not self.length_in_bytes:
                    value *= 8

                bits.append(self.decimal_to_bits(value, len_field))
            elif lbl.field_type.function == FieldType.Function.TYPE:
                bits.append(
                    self.decimal_to_bits(
                        self.message_type_codes[mt] % (2**len_field),
                        len_field))
            elif lbl.field_type.function == FieldType.Function.SEQUENCE_NUMBER:
                bits.append(
                    self.decimal_to_bits(
                        self.sequence_numbers[mt] % (2**len_field), len_field))
            elif lbl.field_type.function == FieldType.Function.DST_ADDRESS:
                dst_bits = self.__get_address_for_participant(destination)

                if len(dst_bits) != len_field:
                    raise ValueError(
                        "Length of dst ({0} bits) != length dst field ({1} bits)"
                        .format(len(dst_bits), len_field))

                bits.append(dst_bits)
            elif lbl.field_type.function == FieldType.Function.SRC_ADDRESS:
                src_bits = self.__get_address_for_participant(source)

                if len(src_bits) != len_field:
                    raise ValueError(
                        "Length of src ({0} bits) != length src field ({1} bits)"
                        .format(len(src_bits), len_field))

                bits.append(src_bits)
            elif lbl.field_type.function == FieldType.Function.DATA:
                if len(data) != len_field:
                    raise ValueError(
                        "Length of data ({} bits) != length data field ({} bits)"
                        .format(len(data), len_field))
                bits.append(data)

            start = lbl.end

        if not data_label_present:
            bits.append(data)

        msg = Message.from_plain_bits_str("".join(bits))
        msg.message_type = mt
        msg.participant = source
        self.sequence_numbers[mt] += self.sequence_number_increment

        for checksum_label in checksum_labels:
            msg[checksum_label.start:checksum_label.
                end] = checksum_label.calculate_checksum_for_message(
                    msg, False)

        self.protocol.messages.append(msg)
Beispiel #35
0
    def push_data(self, data: np.ndarray):
        self.ringbuffer.push(data)


if __name__ == '__main__':
    from urh.dev.BackendHandler import BackendHandler
    from urh.signalprocessing.Message import Message
    from urh.signalprocessing.MessageType import MessageType
    from urh.signalprocessing.Modulator import Modulator
    from urh.util.Logger import logger
    import time

    endless_sender = EndlessSender(BackendHandler(), "HackRF")
    msg = Message([1, 0] * 16 + [1, 1, 0, 0] * 8 + [0, 0, 1, 1] * 8 +
                  [1, 0, 1, 1, 1, 0, 0, 1, 1, 1] * 4, 0,
                  MessageType("empty_message_type"))
    modulator = Modulator("test_modulator")
    modulator.samples_per_bit = 1000
    modulator.carrier_freq_hz = 55e3

    logger.debug("Starting endless sender")
    endless_sender.start()
    time.sleep(1)
    logger.debug("Pushing data")
    endless_sender.push_data(modulator.modulate(msg.encoded_bits))
    logger.debug("Pushed data")
    time.sleep(5)
    logger.debug("Stopping endless sender")
    endless_sender.stop()
    time.sleep(1)
Beispiel #36
0
 def __get_modulator_of_message(self, message: Message) -> Modulator:
     if message.modulator_index > len(self.modulators) - 1:
         message.modulator_index = 0
     return self.modulators[message.modulator_index]