Exemple #1
0
def build_protocol_sniffer_from_args(arguments: argparse.Namespace):
    bh = build_backend_handler_from_args(arguments)

    result = ProtocolSniffer(arguments.bit_length, arguments.center, arguments.noise, arguments.tolerance,
                             Modulator.MODULATION_TYPES.index(arguments.modulation_type),
                             arguments.device.lower(), bh)
    result.rcv_device.frequency = arguments.frequency
    result.rcv_device.sample_rate = arguments.sample_rate
    result.rcv_device.bandwidth = arguments.sample_rate if arguments.bandwidth is None else arguments.bandwidth
    result.rcv_device.freq_correction = arguments.frequency_correction
    if arguments.gain is not None:
        result.rcv_device.gain = arguments.gain
    if arguments.if_gain is not None:
        result.rcv_device.if_gain = arguments.if_gain
    if arguments.baseband_gain is not None:
        result.rcv_device.baseband_gain = arguments.baseband_gain

    if arguments.device_identifier is not None:
        try:
            result.rcv_device.device_number = int(arguments.device_identifier)
        except ValueError:
            result.rcv_device.device_serial = arguments.device_identifier

    if arguments.encoding:
        result.decoder = build_encoding_from_args(arguments)

    result.rcv_device.fatal_error_occurred.connect(on_fatal_device_error_occurred)
    result.adaptive_noise = arguments.adaptive_noise
    return result
Exemple #2
0
def build_protocol_sniffer_from_args(arguments: argparse.Namespace):
    bh = build_backend_handler_from_args(arguments)

    result = ProtocolSniffer(
        arguments.bit_length, arguments.center, arguments.noise,
        arguments.tolerance,
        Modulator.MODULATION_TYPES.index(arguments.modulation_type),
        arguments.device.lower(), bh)
    result.rcv_device.frequency = arguments.frequency
    result.rcv_device.sample_rate = arguments.sample_rate
    result.rcv_device.bandwidth = arguments.sample_rate if arguments.bandwidth is None else arguments.bandwidth
    if arguments.gain is not None:
        result.rcv_device.gain = arguments.gain
    if arguments.if_gain is not None:
        result.rcv_device.if_gain = arguments.if_gain
    if arguments.baseband_gain is not None:
        result.rcv_device.baseband_gain = arguments.baseband_gain

    if arguments.device_identifier is not None:
        try:
            result.rcv_device.device_number = int(arguments.device_identifier)
        except ValueError:
            result.rcv_device.device_serial = arguments.device_identifier

    if arguments.encoding:
        result.decoder = build_encoding_from_args(arguments)

    result.rcv_device.fatal_error_occurred.connect(
        on_fatal_device_error_occurred)
    result.adaptive_noise = arguments.adaptive_noise
    return result
Exemple #3
0
    def __init__(self,
                 freq,
                 samp_rate,
                 bw,
                 gain,
                 device,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 parent=None,
                 testing_mode=False):
        self.is_rx = True
        super().__init__(freq,
                         samp_rate,
                         bw,
                         gain,
                         device,
                         parent=parent,
                         testing_mode=testing_mode)

        self.ui.stackedWidget.setCurrentIndex(2)
        self.hide_send_ui_items()
        self.hide_receive_ui_items()
        self.ui.sliderYscale.hide()
        self.ui.label_y_scale.hide()

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        device = self.ui.cbDevice.currentText()
        self.sniffer = ProtocolSniffer(bit_length,
                                       center,
                                       noise,
                                       tolerance,
                                       modulation_type_index,
                                       samp_rate,
                                       freq,
                                       gain,
                                       bw,
                                       device,
                                       testing_mode=testing_mode)

        self.set_sniff_ui_items_visible(True)
        self.set_device_ui_items_visible(
            device != NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.create_connects()
Exemple #4
0
    def __init__(self,
                 device_name: str,
                 project_manager: ProjectManager,
                 signal=None,
                 backend_handler=None,
                 network_raw_mode=False,
                 signals=None,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        signals = signals if signals is not None else []
        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.bootstrap(project_manager.device_conf,
                       signal,
                       enforce_default=True)

        self.sniffer = ProtocolSniffer(
            bit_len=self.ui.spinbox_sniff_BitLen.value(),
            center=self.ui.spinbox_sniff_Center.value(),
            noise=self.ui.spinbox_sniff_Noise.value(),
            tolerance=self.ui.spinbox_sniff_ErrorTolerance.value(),
            modulation_type=self.ui.combox_sniff_Modulation.currentIndex(),
            device=device_name,
            backend_handler=BackendHandler()
            if backend_handler is None else backend_handler,
            network_raw_mode=network_raw_mode)

        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()
        self.sniffer.automatic_center = self.ui.checkBoxAutoCenter.isChecked()

        self.create_connects()
        self.ui.comboBox_sniff_encoding.currentIndexChanged.emit(
            self.ui.comboBox_sniff_encoding.currentIndex())
        self.ui.comboBox_sniff_viewtype.setCurrentIndex(
            constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)
    def __init__(self, freq, samp_rate, bw, gain, device, noise,
                 center, bit_length, tolerance, modulation_type_index,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffProtocol()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.ui.spinBoxFreq.setValue(freq)
        self.ui.spinBoxSampleRate.setValue(samp_rate)
        self.ui.spinBoxBandwidth.setValue(bw)
        self.ui.spinBoxGain.setValue(gain)
        self.ui.spinboxNoise.setValue(noise)
        self.ui.spinboxCenter.setValue(center)
        self.ui.spinboxBitLen.setValue(bit_length)
        self.ui.spinboxErrorTolerance.setValue(tolerance)
        self.ui.comboxModulation.setCurrentIndex(modulation_type_index)

        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index, samp_rate, freq,
                                       gain, bw, device)

        self.sniffer.usrp_ip = self.ui.lineEditIP.text()

        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(False)

        self.ui.cbDevice.clear()
        items = []
        if constants.SETTINGS.value('usrp_available', type=bool):
            items.append("USRP")
        if constants.SETTINGS.value('hackrf_available', type=bool):
            items.append("HackRF")
        self.ui.cbDevice.addItems(items)
        if device in items:
            self.ui.cbDevice.setCurrentIndex(items.index(device))

        self.on_device_edited()

        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        ipRegex = QRegExp("^" + ipRange
                          + "\\." + ipRange
                          + "\\." + ipRange
                          + "\\." + ipRange + "$")
        self.ui.lineEditIP.setValidator(QRegExpValidator(ipRegex))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditOutputFile.setCompleter(completer)

        self.create_connects()
Exemple #6
0
    def test_sniff(self):
        sniffer = ProtocolSniffer(self.bit_len, self.center, self.noise,
                                  self.tolerance, self.modulation_type,
                                  self.sample_rate, self.freq, self.gain,
                                  self.bandwidth, self.device)

        sniffer.sniff()

        timer = QTimer()
        timer.timeout.connect(self.__confirm_message_box)
        timer.start(100)

        while sniffer.rcv_thrd.isRunning():
            QTest.qWait(100)

        self.assertTrue(True)
Exemple #7
0
    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, real_time=False, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        conf = project_manager.device_conf
        bit_length = conf.get("bit_len", signal.bit_len if signal else 100)
        modulation_type_index = conf.get("modulation_index", signal.modulation_type if signal else 1)
        tolerance = conf.get("tolerance", signal.tolerance if signal else 5)
        noise = conf.get("noise", signal.noise_threshold if signal else 0.001)
        center = conf.get("center", signal.qad_center if signal else 0.02)
        decoding_name = conf.get("decoding_name", "")

        self.sniffer = ProtocolSniffer(bit_len=bit_length,
                                       center=center,
                                       noise=noise,
                                       tolerance=tolerance,
                                       modulation_type=modulation_type_index,
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode,
                                       real_time=real_time)

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.create_connects()

        if decoding_name:
            self.ui.comboBox_sniff_encoding.setCurrentText(decoding_name)

        self.ui.comboBox_sniff_viewtype.setCurrentIndex(constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)
    def test_protocol_sniffer(self):
        samples_per_symbol = 100
        center = 0.0942
        noise = 0.1
        tolerance = 2
        modulation_type = "FSK"
        sample_rate = 1e6
        device_name = NetworkSDRInterfacePlugin.NETWORK_SDR_NAME
        sniffer = ProtocolSniffer(samples_per_symbol=samples_per_symbol, center=center, center_spacing=0.1,
                                  noise=noise, tolerance=tolerance,
                                  modulation_type=modulation_type, bits_per_symbol=1,
                                  device=device_name, backend_handler=BackendHandler(),
                                  network_raw_mode=True)

        port = self.get_free_port()
        sniffer.rcv_device.set_server_port(port)

        self.network_sdr_plugin_sender = NetworkSDRInterfacePlugin(raw_mode=True)
        self.network_sdr_plugin_sender.client_port = port

        sniffer.sniff()
        QTest.qWait(10)

        data = ["101010", "000111", "1111000"]
        pause = 10 * samples_per_symbol
        modulator = Modulator("test")
        modulator.samples_per_symbol = samples_per_symbol
        modulator.sample_rate = sample_rate
        modulator.modulation_type = modulation_type
        modulator.parameters[1] = 20e3
        modulator.parameters[0] = 10e3

        packages = []
        for d in data:
            packages.append(modulator.modulate(list(map(int, d)), pause))

        # verify modulation was correct
        pa = ProtocolAnalyzer(None)
        signal = Signal("", "", sample_rate=sample_rate)
        signal.iq_array = IQArray.concatenate(packages)
        signal.modulation_type = modulation_type
        signal.samples_per_symbol = samples_per_symbol
        signal.tolerance = tolerance
        signal.noise_threshold = noise
        signal.center = center
        pa.signal = signal
        pa.get_protocol_from_signal()
        self.assertEqual(pa.plain_bits_str, data)

        # send data
        send_data = IQArray.concatenate(packages)
        self.network_sdr_plugin_sender.send_raw_data(send_data, 1)
        time.sleep(1)

        # Send enough pauses to end sniffing
        self.network_sdr_plugin_sender.send_raw_data(IQArray(None, np.float32, 10 * 2 * samples_per_symbol), 1)
        time.sleep(1)

        sniffer.stop()
        self.assertEqual(sniffer.plain_bits_str, data)
    def test_protocol_sniffer(self):
        bit_len = 100
        center = 0.0942
        noise = 0.1
        tolerance = 2
        modulation_type = 1
        sample_rate = 1e6
        device_name = NetworkSDRInterfacePlugin.NETWORK_SDR_NAME
        sniffer = ProtocolSniffer(bit_len=bit_len, center=center, noise=noise, tolerance=tolerance,
                                  modulation_type=modulation_type, device=device_name, backend_handler=BackendHandler(),
                                  network_raw_mode=True)

        port = self.get_free_port()
        sniffer.rcv_device.set_server_port(port)

        self.network_sdr_plugin_sender = NetworkSDRInterfacePlugin(raw_mode=True)
        self.network_sdr_plugin_sender.client_port = port

        sniffer.sniff()
        QTest.qWait(10)

        data = ["101010", "000111", "1111000"]
        pause = 10 * bit_len
        modulator = Modulator("test")
        modulator.samples_per_bit = bit_len
        modulator.sample_rate = sample_rate
        modulator.modulation_type = modulation_type
        modulator.param_for_one = 20e3
        modulator.param_for_zero = 10e3

        packages = []
        for d in data:
            packages.append(modulator.modulate(list(map(int, d)), pause))

        # verify modulation was correct
        pa = ProtocolAnalyzer(None)
        signal = Signal("", "", sample_rate=sample_rate)
        signal._fulldata = np.concatenate(packages)
        signal.modulation_type = modulation_type
        signal.bit_len = bit_len
        signal.tolerance = tolerance
        signal.noise_threshold = noise
        signal.qad_center = center
        pa.signal = signal
        pa.get_protocol_from_signal()
        self.assertEqual(pa.plain_bits_str, data)

        # send data
        send_data = np.concatenate(packages)
        self.network_sdr_plugin_sender.send_raw_data(send_data, 1)
        time.sleep(1)

        # Send enough pauses to end sniffing
        self.network_sdr_plugin_sender.send_raw_data(np.zeros(10 * bit_len, dtype=np.complex64), 1)
        time.sleep(1)

        sniffer.stop()
        self.assertEqual(sniffer.plain_bits_str, data)
Exemple #10
0
    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, signals=None, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        signals = signals if signals is not None else []
        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.bootstrap(project_manager.device_conf, signal, enforce_default=True)

        self.sniffer = ProtocolSniffer(bit_len=self.ui.spinbox_sniff_BitLen.value(),
                                       center=self.ui.spinbox_sniff_Center.value(),
                                       noise=self.ui.spinbox_sniff_Noise.value(),
                                       tolerance=self.ui.spinbox_sniff_ErrorTolerance.value(),
                                       modulation_type=self.ui.combox_sniff_Modulation.currentIndex(),
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode)

        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()
        self.sniffer.automatic_center = self.ui.checkBoxAutoCenter.isChecked()

        self.create_connects()
        self.ui.comboBox_sniff_encoding.currentIndexChanged.emit(self.ui.comboBox_sniff_encoding.currentIndex())
        self.ui.comboBox_sniff_viewtype.setCurrentIndex(constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)
    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.complex16s"))
        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.01, 0.1, 5, "FSK", 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_symbol = 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()
Exemple #12
0
class SniffSettingsWidget(QWidget):
    sniff_setting_edited = pyqtSignal()
    sniff_file_edited = pyqtSignal()
    sniff_parameters_changed = pyqtSignal(dict)

    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, signals=None, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        signals = signals if signals is not None else []
        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.bootstrap(project_manager.device_conf, signal, enforce_default=True)

        self.sniffer = ProtocolSniffer(samples_per_symbol=self.ui.spinbox_sniff_SamplesPerSymbol.value(),
                                       center=self.ui.spinbox_sniff_Center.value(),
                                       center_spacing=self.ui.spinBoxCenterSpacing.value(),
                                       noise=self.ui.spinbox_sniff_Noise.value(),
                                       tolerance=self.ui.spinbox_sniff_ErrorTolerance.value(),
                                       modulation_type=self.ui.combox_sniff_Modulation.currentText(),
                                       bits_per_symbol=self.ui.spinBoxBitsPerSymbol.value(),
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode)

        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()
        self.sniffer.automatic_center = self.ui.checkBoxAutoCenter.isChecked()

        self.__set_center_offset_visibility()

        self.create_connects()
        self.ui.comboBox_sniff_encoding.currentIndexChanged.emit(self.ui.comboBox_sniff_encoding.currentIndex())
        self.ui.comboBox_sniff_viewtype.setCurrentIndex(settings.read('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)

    def __set_center_offset_visibility(self):
        visible = self.ui.spinBoxBitsPerSymbol.value() > 1
        self.ui.labelCenterSpacing.setVisible(visible)
        self.ui.spinBoxCenterSpacing.setVisible(visible)

    def bootstrap(self, conf_dict: dict, signal=None, enforce_default=False):
        def set_val(widget, key: str, default):
            try:
                value = conf_dict[key]
            except KeyError:
                value = default if enforce_default else None

            if value is not None:
                if hasattr(widget, "setValue"):
                    widget.setValue(value)
                elif hasattr(widget, "setCurrentIndex"):
                    widget.setCurrentIndex(value)

        set_val(self.ui.spinbox_sniff_SamplesPerSymbol, "samples_per_symbol", signal.samples_per_symbol if signal else 100)
        set_val(self.ui.spinbox_sniff_Center, "center", signal.center if signal else 0.02)
        set_val(self.ui.spinBoxCenterSpacing, "center_spacing", signal.center_spacing if signal else 0.1)
        set_val(self.ui.spinbox_sniff_ErrorTolerance, "tolerance", signal.tolerance if signal else 5)
        set_val(self.ui.spinbox_sniff_Noise, "noise", signal.noise_threshold_relative if signal else 0.001)
        self.ui.combox_sniff_Modulation.setCurrentText(conf_dict.get("modulation_type", signal.modulation_type if signal else "FSK"))
        set_val(self.ui.spinBoxBitsPerSymbol, "bits_per_symbol", signal.bits_per_symbol if signal else 1)
        self.ui.comboBox_sniff_encoding.setCurrentText(conf_dict.get("decoding_name", ""))
        self.ui.checkBoxAdaptiveNoise.setChecked(bool(conf_dict.get("adaptive_noise", False)))
        self.ui.checkBoxAutoCenter.setChecked(bool(conf_dict.get("automatic_center", False)))
        self.ui.spinbox_sniff_Center.setDisabled(self.ui.checkBoxAutoCenter.isChecked())

        self.emit_editing_finished_signals()

    def create_connects(self):
        self.ui.spinbox_sniff_Noise.editingFinished.connect(self.on_noise_edited)
        self.ui.spinbox_sniff_Center.editingFinished.connect(self.on_center_edited)
        self.ui.spinBoxCenterSpacing.editingFinished.connect(self.on_center_spacing_edited)
        self.ui.spinbox_sniff_SamplesPerSymbol.editingFinished.connect(self.on_samples_per_symbol_edited)
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.connect(self.on_tolerance_edited)
        self.ui.combox_sniff_Modulation.currentTextChanged.connect(self.on_modulation_changed)
        self.ui.spinBoxBitsPerSymbol.editingFinished.connect(self.on_spin_box_bits_per_symbol_editing_finished)

        self.ui.comboBox_sniff_viewtype.currentIndexChanged.connect(self.on_view_type_changed)
        self.ui.lineEdit_sniff_OutputFile.editingFinished.connect(self.on_line_edit_output_file_editing_finished)
        self.ui.comboBox_sniff_encoding.currentIndexChanged.connect(self.on_combobox_sniff_encoding_index_changed)
        self.ui.checkBox_sniff_Timestamp.clicked.connect(self.on_checkbox_sniff_timestamp_clicked)
        self.ui.btn_sniff_use_signal.clicked.connect(self.on_btn_sniff_use_signal_clicked)
        self.ui.checkBoxAdaptiveNoise.clicked.connect(self.on_check_box_adaptive_noise_clicked)
        self.ui.checkBoxAutoCenter.clicked.connect(self.on_check_box_auto_center_clicked)

    def emit_editing_finished_signals(self):
        self.ui.spinbox_sniff_Noise.editingFinished.emit()
        self.ui.spinbox_sniff_Center.editingFinished.emit()
        self.ui.spinBoxCenterSpacing.editingFinished.emit()
        self.ui.spinbox_sniff_SamplesPerSymbol.editingFinished.emit()
        self.ui.spinBoxBitsPerSymbol.editingFinished.emit()
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.emit()
        self.ui.lineEdit_sniff_OutputFile.editingFinished.emit()
        self.ui.checkBoxAdaptiveNoise.clicked.emit()

    def emit_sniff_parameters_changed(self):
        self.sniff_parameters_changed.emit(dict(samples_per_symbol=self.sniffer.signal.samples_per_symbol,
                                                center=self.sniffer.signal.center,
                                                center_spacing=self.sniffer.signal.center_spacing,
                                                noise=self.sniffer.signal.noise_threshold,
                                                tolerance=self.sniffer.signal.tolerance,
                                                modulation_type=self.sniffer.signal.modulation_type,
                                                bits_per_symbol=self.sniffer.signal.bits_per_symbol,
                                                decoding_name=self.sniffer.decoder.name,
                                                adaptive_noise=self.sniffer.adaptive_noise,
                                                automatic_center=self.sniffer.automatic_center))

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal.noise_threshold_relative = self.ui.spinbox_sniff_Noise.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.center = self.ui.spinbox_sniff_Center.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_center_spacing_edited(self):
        self.sniffer.signal.center_spacing = self.ui.spinBoxCenterSpacing.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_samples_per_symbol_edited(self):
        self.sniffer.signal.samples_per_symbol = self.ui.spinbox_sniff_SamplesPerSymbol.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_spin_box_bits_per_symbol_editing_finished(self):
        self.sniffer.signal.bits_per_symbol = self.ui.spinBoxBitsPerSymbol.value()
        self.__set_center_offset_visibility()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinbox_sniff_ErrorTolerance.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot(str)
    def on_modulation_changed(self, new_modulation: str):
        self.sniffer.signal.silent_set_modulation_type(new_modulation)
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_view_type_changed(self):
        self.sniff_setting_edited.emit()

    @pyqtSlot(int)
    def on_combobox_sniff_encoding_index_changed(self, index: int):
        if self.sniffer.decoder != self.project_manager.decodings[index]:
            self.sniffer.set_decoder_for_messages(self.project_manager.decodings[index])
            self.sniffer.decoder = self.project_manager.decodings[index]
            self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_line_edit_output_file_editing_finished(self):
        self.ui.lineEdit_sniff_OutputFile.setStyleSheet("")
        text = self.ui.lineEdit_sniff_OutputFile.text()
        if text and not text.endswith(".txt"):
            text += ".txt"
            self.ui.lineEdit_sniff_OutputFile.setText(text)

        if text and not os.path.isfile(text):
            try:
                open(text, "w").close()
            except Exception as e:
                self.ui.lineEdit_sniff_OutputFile.setStyleSheet("color:red;")
                return

        self.sniffer.sniff_file = text
        self.sniff_file_edited.emit()

    @pyqtSlot()
    def on_checkbox_sniff_timestamp_clicked(self):
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_btn_sniff_use_signal_clicked(self):
        try:
            signal = self.signals[self.ui.comboBox_sniff_signal.currentIndex()]
        except IndexError:
            return

        self.ui.spinbox_sniff_SamplesPerSymbol.setValue(signal.samples_per_symbol)
        self.ui.spinbox_sniff_Center.setValue(signal.center)
        self.ui.spinbox_sniff_Noise.setValue(signal.noise_threshold_relative)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(signal.tolerance)
        self.ui.combox_sniff_Modulation.setCurrentText(signal.modulation_type)

        self.emit_editing_finished_signals()

    @pyqtSlot()
    def on_check_box_adaptive_noise_clicked(self):
        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()

    @pyqtSlot()
    def on_check_box_auto_center_clicked(self):
        self.sniffer.automatic_center = self.ui.checkBoxAutoCenter.isChecked()
        self.ui.spinbox_sniff_Center.setDisabled(self.ui.checkBoxAutoCenter.isChecked())
class ProtocolSniffDialogController(QDialog):
    protocol_accepted = pyqtSignal(list)

    def __init__(self, freq, samp_rate, bw, gain, device, noise,
                 center, bit_length, tolerance, modulation_type_index,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffProtocol()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.ui.spinBoxFreq.setValue(freq)
        self.ui.spinBoxSampleRate.setValue(samp_rate)
        self.ui.spinBoxBandwidth.setValue(bw)
        self.ui.spinBoxGain.setValue(gain)
        self.ui.spinboxNoise.setValue(noise)
        self.ui.spinboxCenter.setValue(center)
        self.ui.spinboxBitLen.setValue(bit_length)
        self.ui.spinboxErrorTolerance.setValue(tolerance)
        self.ui.comboxModulation.setCurrentIndex(modulation_type_index)

        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index, samp_rate, freq,
                                       gain, bw, device)

        self.sniffer.usrp_ip = self.ui.lineEditIP.text()

        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(False)

        self.ui.cbDevice.clear()
        items = []
        if constants.SETTINGS.value('usrp_available', type=bool):
            items.append("USRP")
        if constants.SETTINGS.value('hackrf_available', type=bool):
            items.append("HackRF")
        self.ui.cbDevice.addItems(items)
        if device in items:
            self.ui.cbDevice.setCurrentIndex(items.index(device))

        self.on_device_edited()

        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        ipRegex = QRegExp("^" + ipRange
                          + "\\." + ipRange
                          + "\\." + ipRange
                          + "\\." + ipRange + "$")
        self.ui.lineEditIP.setValidator(QRegExpValidator(ipRegex))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditOutputFile.setCompleter(completer)

        self.create_connects()

    def create_connects(self):
        self.ui.btnStart.clicked.connect(self.on_start_clicked)
        self.ui.btnStop.clicked.connect(self.on_stop_clicked)
        self.ui.btnClear.clicked.connect(self.on_clear_clicked)
        self.ui.btnAccept.clicked.connect(self.on_btn_accept_clicked)
        self.ui.btnClose.clicked.connect(self.close)

        self.sniffer.rcv_thrd.started.connect(self.on_sniffer_rcv_started)
        self.sniffer.rcv_thrd.stopped.connect(self.on_sniffer_rcv_stopped)
        self.sniffer.qt_signals.data_sniffed.connect(self.on_data_sniffed)
        self.sniffer.qt_signals.sniff_device_errors_changed.connect(
            self.on_device_errors_changed)

        self.ui.spinBoxSampleRate.editingFinished.connect(
            self.on_sample_rate_edited)
        self.ui.spinBoxGain.editingFinished.connect(self.on_gain_edited)
        self.ui.spinBoxFreq.editingFinished.connect(self.on_freq_edited)
        self.ui.spinBoxBandwidth.editingFinished.connect(self.on_bw_edited)
        self.ui.lineEditIP.editingFinished.connect(self.on_usrp_ip_edited)
        self.ui.cbDevice.currentIndexChanged.connect(self.on_device_edited)

        self.ui.spinboxNoise.editingFinished.connect(self.on_noise_edited)
        self.ui.spinboxCenter.editingFinished.connect(self.on_center_edited)
        self.ui.spinboxBitLen.editingFinished.connect(self.on_bit_len_edited)
        self.ui.spinboxErrorTolerance.editingFinished.connect(
            self.on_tolerance_edited)
        self.ui.comboxModulation.currentIndexChanged.connect(
            self.on_modulation_changed)
        self.ui.comboBoxViewType.currentIndexChanged.connect(
            self.on_view_type_changed)
    @property
    def view_type(self):
        return self.ui.comboBoxViewType.currentIndex()

    @property
    def has_empty_device_list(self):
        return self.ui.cbDevice.count() == 0

    @pyqtSlot()
    def on_sample_rate_edited(self):
        self.sniffer.rcv_thrd.sample_rate = self.ui.spinBoxSampleRate.value()

    @pyqtSlot()
    def on_freq_edited(self):
        self.sniffer.rcv_thrd.freq = self.ui.spinBoxFreq.value()

    @pyqtSlot()
    def on_bw_edited(self):
        self.sniffer.rcv_thrd.bandwidth = self.ui.spinBoxBandwidth.value()

    @pyqtSlot()
    def on_usrp_ip_edited(self):
        self.sniffer.usrp_ip = self.ui.lineEditIP.text()

    @pyqtSlot()
    def on_gain_edited(self):
        self.sniffer.rcv_thrd.gain = self.ui.spinBoxGain.value()

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_treshold = self.ui.spinboxNoise.value()

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinboxCenter.value()

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinboxBitLen.value()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinboxErrorTolerance.value()

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)

    @pyqtSlot()
    def on_device_edited(self):
        dev = self.ui.cbDevice.currentText()
        self.sniffer.device = dev
        self.ui.lineEditIP.setVisible(dev == "USRP")
        self.ui.labelIP.setVisible(dev == "USRP")

    @pyqtSlot()
    def on_start_clicked(self):
        self.ui.spinBoxFreq.editingFinished.emit()
        self.ui.lineEditIP.editingFinished.emit()
        self.ui.spinBoxBandwidth.editingFinished.emit()
        self.ui.spinBoxSampleRate.editingFinished.emit()
        self.ui.spinboxNoise.editingFinished.emit()
        self.ui.spinboxCenter.editingFinished.emit()
        self.ui.spinboxBitLen.editingFinished.emit()
        self.ui.spinboxErrorTolerance.editingFinished.emit()

        self.sniffer.sniff()

    @pyqtSlot()
    def on_stop_clicked(self):
        self.sniffer.stop()

    @pyqtSlot()
    def on_sniffer_rcv_stopped(self):
        self.ui.btnStart.setEnabled(True)
        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(True)

        self.ui.spinBoxSampleRate.setEnabled(True)
        self.ui.spinBoxFreq.setEnabled(True)
        self.ui.lineEditIP.setEnabled(True)
        self.ui.spinBoxBandwidth.setEnabled(True)
        self.ui.spinBoxGain.setEnabled(True)
        self.ui.cbDevice.setEnabled(True)

        self.ui.spinboxNoise.setEnabled(True)
        self.ui.spinboxCenter.setEnabled(True)
        self.ui.spinboxBitLen.setEnabled(True)
        self.ui.spinboxErrorTolerance.setEnabled(True)
        self.ui.comboxModulation.setEnabled(True)

    @pyqtSlot()
    def on_sniffer_rcv_started(self):
        self.ui.txtEditErrors.clear()
        self.ui.btnStart.setEnabled(False)
        self.ui.btnClear.setEnabled(False)
        self.ui.btnStop.setEnabled(True)

        self.ui.spinBoxSampleRate.setDisabled(True)
        self.ui.spinBoxFreq.setDisabled(True)
        self.ui.spinBoxGain.setDisabled(True)
        self.ui.spinBoxBandwidth.setDisabled(True)

        self.ui.spinboxNoise.setDisabled(True)
        self.ui.spinboxCenter.setDisabled(True)
        self.ui.spinboxBitLen.setDisabled(True)
        self.ui.spinboxErrorTolerance.setDisabled(True)
        self.ui.comboxModulation.setDisabled(True)

        self.ui.lineEditIP.setDisabled(True)
        self.ui.cbDevice.setDisabled(True)

    @pyqtSlot()
    def on_clear_clicked(self):
        self.ui.btnClear.setEnabled(False)
        self.ui.txtEdPreview.clear()
        self.sniffer.clear()

    @pyqtSlot(int)
    def on_data_sniffed(self, from_index: int):
        self.ui.txtEdPreview.appendPlainText(self.sniffer.plain_to_string(
            self.view_type, start=from_index))
        self.ui.txtEdPreview.verticalScrollBar().setValue(
            self.ui.txtEdPreview.verticalScrollBar().maximum())

    @pyqtSlot(int)
    def on_view_type_changed(self, new_index: int):
        self.ui.txtEdPreview.setPlainText(
            self.sniffer.plain_to_string(new_index))

    @pyqtSlot()
    def on_btn_accept_clicked(self):
        self.protocol_accepted.emit(self.sniffer.blocks)
        self.close()

    @pyqtSlot(str)
    def on_device_errors_changed(self, txt: str):
        self.ui.txtEditErrors.append(txt)

    def closeEvent(self, event: QCloseEvent):
        self.sniffer.stop()
        event.accept()

    @pyqtSlot(str)
    def on_lineEditOutputFile_textChanged(self, text: str):
        self.sniffer.sniff_file = text
        self.ui.btnAccept.setDisabled(bool(self.sniffer.sniff_file))
    def __init__(self,
                 freq,
                 samp_rate,
                 bw,
                 gain,
                 device,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffProtocol()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.ui.spinBoxFreq.setValue(freq)
        self.ui.spinBoxSampleRate.setValue(samp_rate)
        self.ui.spinBoxBandwidth.setValue(bw)
        self.ui.spinBoxGain.setValue(gain)
        self.ui.spinboxNoise.setValue(noise)
        self.ui.spinboxCenter.setValue(center)
        self.ui.spinboxBitLen.setValue(bit_length)
        self.ui.spinboxErrorTolerance.setValue(tolerance)
        self.ui.comboxModulation.setCurrentIndex(modulation_type_index)

        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(False)

        self.ui.cbDevice.clear()
        items = []
        bh = BackendHandler()
        for device_name in bh.DEVICE_NAMES:
            dev = bh.device_backends[device_name.lower()]
            if dev.is_enabled and dev.supports_rx:
                items.append(device_name)

        pm = PluginManager()
        if pm.is_plugin_enabled("NetworkSDRInterface"):
            items.append(NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)

        self.ui.cbDevice.addItems(items)
        del bh
        if device in items:
            self.ui.cbDevice.setCurrentIndex(items.index(device))

        if self.ui.cbDevice.count() == 0:
            Errors.no_device()
            self.close()
            return

        device = self.ui.cbDevice.currentText()
        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index, samp_rate, freq,
                                       gain, bw, device)

        self.set_object_visibility()

        self.sniffer.usrp_ip = self.ui.lineEditIP.text()
        self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked()

        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        ipRegex = QRegExp("^" + ipRange + "\\." + ipRange + "\\." + ipRange +
                          "\\." + ipRange + "$")
        self.ui.lineEditIP.setValidator(QRegExpValidator(ipRegex))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditOutputFile.setCompleter(completer)

        self.create_connects()
Exemple #15
0
class ProtocolSniffDialogController(SendRecvDialogController):
    protocol_accepted = pyqtSignal(list)

    def __init__(self,
                 freq,
                 samp_rate,
                 bw,
                 gain,
                 device,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 parent=None,
                 testing_mode=False):
        self.is_rx = True
        super().__init__(freq,
                         samp_rate,
                         bw,
                         gain,
                         device,
                         parent=parent,
                         testing_mode=testing_mode)

        self.ui.stackedWidget.setCurrentIndex(2)
        self.hide_send_ui_items()
        self.hide_receive_ui_items()
        self.ui.sliderYscale.hide()
        self.ui.label_y_scale.hide()

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        device = self.ui.cbDevice.currentText()
        self.sniffer = ProtocolSniffer(bit_length,
                                       center,
                                       noise,
                                       tolerance,
                                       modulation_type_index,
                                       samp_rate,
                                       freq,
                                       gain,
                                       bw,
                                       device,
                                       testing_mode=testing_mode)

        self.set_sniff_ui_items_visible(True)
        self.set_device_ui_items_visible(
            device != NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.create_connects()

    def create_connects(self):
        super().create_connects()
        self.ui.btnAccept.clicked.connect(self.on_btn_accept_clicked)

        self.sniffer.started.connect(self.on_sniffer_rcv_started)
        self.sniffer.stopped.connect(self.on_sniffer_rcv_stopped)
        self.sniffer.qt_signals.data_sniffed.connect(self.on_data_sniffed)
        self.sniffer.qt_signals.sniff_device_errors_changed.connect(
            self.on_device_errors_changed)

        self.ui.spinbox_sniff_Noise.editingFinished.connect(
            self.on_noise_edited)
        self.ui.spinbox_sniff_Center.editingFinished.connect(
            self.on_center_edited)
        self.ui.spinbox_sniff_BitLen.editingFinished.connect(
            self.on_bit_len_edited)
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.connect(
            self.on_tolerance_edited)
        self.ui.combox_sniff_Modulation.currentIndexChanged.connect(
            self.on_modulation_changed)
        self.ui.comboBox_sniff_viewtype.currentIndexChanged.connect(
            self.on_view_type_changed)
        self.ui.lineEdit_sniff_OutputFile.textChanged.connect(
            self.on_line_edit_output_file_text_changed)

    def set_device_ui_items_visible(self, visible: bool):
        super().set_device_ui_items_visible(visible)
        for item in ("spinbox_sniff_Noise", "combox_sniff_Modulation",
                     "label_sniff_Modulation", "spinbox_sniff_Center",
                     "spinbox_sniff_BitLen", "spinbox_sniff_ErrorTolerance",
                     "label_sniff_Noise", "label_sniff_Center",
                     "label_sniff_BitLength", "label_sniff_Tolerance"):
            getattr(self.ui, item).setVisible(visible)

    def closeEvent(self, event: QCloseEvent):
        if hasattr(self, "sniffer"):
            self.sniffer.stop()
        event.accept()

    @property
    def device(self):
        if hasattr(self, "sniffer"):
            return self.sniffer.rcv_device
        else:
            return None

    @device.setter
    def device(self, value):
        if hasattr(self, "sniffer"):
            self.sniffer.rcv_device = value
        else:
            pass

    @property
    def view_type(self):
        return self.ui.comboBox_sniff_viewtype.currentIndex()

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_threshold = self.ui.spinbox_sniff_Noise.value(
        )

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinbox_sniff_Center.value()

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinbox_sniff_BitLen.value()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinbox_sniff_ErrorTolerance.value(
        )

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)

    @pyqtSlot()
    def on_selected_device_changed(self):
        dev_name = self.ui.cbDevice.currentText()
        self.sniffer.device_name = dev_name
        self.set_device_ui_items_visible(
            dev_name != NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)
        self.ui.lineEditIP.setVisible(dev_name == "USRP")
        self.ui.labelIP.setVisible(dev_name == "USRP")

    @pyqtSlot()
    def on_start_clicked(self):
        self.ui.spinBoxFreq.editingFinished.emit()
        self.ui.lineEditIP.editingFinished.emit()
        self.ui.spinBoxBandwidth.editingFinished.emit()
        self.ui.spinBoxSampleRate.editingFinished.emit()
        self.ui.spinbox_sniff_Noise.editingFinished.emit()
        self.ui.spinbox_sniff_Center.editingFinished.emit()
        self.ui.spinbox_sniff_BitLen.editingFinished.emit()
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.emit()

        self.sniffer.sniff()

    @pyqtSlot()
    def on_stop_clicked(self):
        self.sniffer.stop()

    @pyqtSlot()
    def on_sniffer_rcv_stopped(self):
        self.ui.btnStart.setEnabled(True)
        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(True)

        self.ui.spinBoxSampleRate.setEnabled(True)
        self.ui.spinBoxFreq.setEnabled(True)
        self.ui.lineEditIP.setEnabled(True)
        self.ui.spinBoxBandwidth.setEnabled(True)
        self.ui.spinBoxGain.setEnabled(True)
        self.ui.cbDevice.setEnabled(True)

        self.ui.spinbox_sniff_Noise.setEnabled(True)
        self.ui.spinbox_sniff_Center.setEnabled(True)
        self.ui.spinbox_sniff_BitLen.setEnabled(True)
        self.ui.spinbox_sniff_ErrorTolerance.setEnabled(True)
        self.ui.combox_sniff_Modulation.setEnabled(True)

    @pyqtSlot()
    def on_sniffer_rcv_started(self):
        self.ui.txtEditErrors.clear()
        self.ui.btnStart.setEnabled(False)
        self.ui.btnClear.setEnabled(False)
        self.ui.btnStop.setEnabled(True)

        self.ui.spinBoxSampleRate.setDisabled(True)
        self.ui.spinBoxFreq.setDisabled(True)
        self.ui.spinBoxGain.setDisabled(True)
        self.ui.spinBoxBandwidth.setDisabled(True)

        self.ui.spinbox_sniff_Noise.setDisabled(True)
        self.ui.spinbox_sniff_Center.setDisabled(True)
        self.ui.spinbox_sniff_BitLen.setDisabled(True)
        self.ui.spinbox_sniff_ErrorTolerance.setDisabled(True)
        self.ui.combox_sniff_Modulation.setDisabled(True)

        self.ui.lineEditIP.setDisabled(True)
        self.ui.cbDevice.setDisabled(True)

    @pyqtSlot()
    def on_clear_clicked(self):
        self.ui.btnClear.setEnabled(False)
        self.ui.txtEd_sniff_Preview.clear()
        self.sniffer.clear()

    @pyqtSlot(int)
    def on_data_sniffed(self, from_index: int):
        new_data = self.sniffer.plain_to_string(self.view_type,
                                                start=from_index,
                                                show_pauses=False)
        if new_data.strip():
            self.ui.txtEd_sniff_Preview.appendPlainText(new_data)
            self.ui.txtEd_sniff_Preview.verticalScrollBar().setValue(
                self.ui.txtEd_sniff_Preview.verticalScrollBar().maximum())

    @pyqtSlot(int)
    def on_view_type_changed(self, new_index: int):
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.plain_to_string(new_index, show_pauses=False))

    @pyqtSlot()
    def on_btn_accept_clicked(self):
        self.protocol_accepted.emit(self.sniffer.messages)
        self.close()

    @pyqtSlot(str)
    def on_device_errors_changed(self, txt: str):
        self.ui.txtEditErrors.append(txt)

    @pyqtSlot(str)
    def on_line_edit_output_file_text_changed(self, text: str):
        self.sniffer.sniff_file = text
        self.ui.btnAccept.setDisabled(bool(self.sniffer.sniff_file))
Exemple #16
0
class SniffSettingsWidget(QWidget):
    sniff_setting_edited = pyqtSignal()
    sniff_file_edited = pyqtSignal()
    sniff_parameters_changed = pyqtSignal(dict)

    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, real_time=False, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        conf = project_manager.device_conf
        bit_length = conf.get("bit_len", signal.bit_len if signal else 100)
        modulation_type_index = conf.get("modulation_index", signal.modulation_type if signal else 1)
        tolerance = conf.get("tolerance", signal.tolerance if signal else 5)
        noise = conf.get("noise", signal.noise_threshold if signal else 0.001)
        center = conf.get("center", signal.qad_center if signal else 0.02)
        decoding_name = conf.get("decoding_name", "")

        self.sniffer = ProtocolSniffer(bit_len=bit_length,
                                       center=center,
                                       noise=noise,
                                       tolerance=tolerance,
                                       modulation_type=modulation_type_index,
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode,
                                       real_time=real_time)

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.create_connects()

        if decoding_name:
            self.ui.comboBox_sniff_encoding.setCurrentText(decoding_name)

        self.ui.comboBox_sniff_viewtype.setCurrentIndex(constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

    def create_connects(self):
        self.ui.spinbox_sniff_Noise.editingFinished.connect(self.on_noise_edited)
        self.ui.spinbox_sniff_Center.editingFinished.connect(self.on_center_edited)
        self.ui.spinbox_sniff_BitLen.editingFinished.connect(self.on_bit_len_edited)
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.connect(self.on_tolerance_edited)
        self.ui.combox_sniff_Modulation.currentIndexChanged.connect(self.on_modulation_changed)
        self.ui.comboBox_sniff_viewtype.currentIndexChanged.connect(self.on_view_type_changed)
        self.ui.lineEdit_sniff_OutputFile.editingFinished.connect(self.on_line_edit_output_file_editing_finished)
        self.ui.comboBox_sniff_encoding.currentIndexChanged.connect(self.on_combobox_sniff_encoding_index_changed)
        self.ui.checkBox_sniff_Timestamp.clicked.connect(self.on_checkbox_sniff_timestamp_clicked)

    def emit_editing_finished_signals(self):
        self.ui.spinbox_sniff_Noise.editingFinished.emit()
        self.ui.spinbox_sniff_Center.editingFinished.emit()
        self.ui.spinbox_sniff_BitLen.editingFinished.emit()
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.emit()
        self.ui.lineEdit_sniff_OutputFile.editingFinished.emit()

    def emit_sniff_parameters_changed(self):
        self.sniff_parameters_changed.emit(dict(bit_len=self.sniffer.signal.bit_len,
                                                center=self.sniffer.signal.qad_center,
                                                noise=self.sniffer.signal.noise_threshold,
                                                tolerance=self.sniffer.signal.tolerance,
                                                modulation_index=self.sniffer.signal.modulation_type,
                                                decoding_name=self.sniffer.decoder.name))

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_threshold = self.ui.spinbox_sniff_Noise.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinbox_sniff_Center.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinbox_sniff_BitLen.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinbox_sniff_ErrorTolerance.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_view_type_changed(self):
        self.sniff_setting_edited.emit()

    @pyqtSlot(int)
    def on_combobox_sniff_encoding_index_changed(self, index: int):
        if self.sniffer.decoder != self.project_manager.decodings[index]:
            self.sniffer.set_decoder_for_messages(self.project_manager.decodings[index])
            self.sniffer.decoder = self.project_manager.decodings[index]
            self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_line_edit_output_file_editing_finished(self):
        self.ui.lineEdit_sniff_OutputFile.setStyleSheet("")
        text = self.ui.lineEdit_sniff_OutputFile.text()
        if text and not text.endswith(".txt"):
            text += ".txt"
            self.ui.lineEdit_sniff_OutputFile.setText(text)

        if text and not os.path.isfile(text):
            try:
                open(text, "w").close()
            except Exception as e:
                self.ui.lineEdit_sniff_OutputFile.setStyleSheet("color:red;")
                return

        self.sniffer.sniff_file = text
        self.sniff_file_edited.emit()

    @pyqtSlot()
    def on_checkbox_sniff_timestamp_clicked(self):
        self.sniff_setting_edited.emit()
    def __init__(self,
                 project_manager,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 encodings,
                 encoding_index=0,
                 parent=None,
                 testing_mode=False):
        super().__init__(project_manager,
                         is_tx=False,
                         parent=parent,
                         testing_mode=testing_mode)

        self.set_sniff_ui_items_visible(True)

        self.graphics_view = self.ui.graphicsView_sniff_Preview
        self.ui.stackedWidget.setCurrentWidget(self.ui.page_sniff)
        self.hide_send_ui_items()
        self.hide_receive_ui_items()
        self.ui.sliderYscale.hide()
        self.ui.label_y_scale.hide()

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index,
                                       self.ui.cbDevice.currentText(),
                                       self.backend_handler)

        # set really in on_device_started
        self.scene_manager = None  # type: LiveSceneManager
        self.init_device()
        self.set_bandwidth_status()

        self.graphics_view.setScene(self.scene_manager.scene)
        self.graphics_view.scene_manager = self.scene_manager

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.setWindowTitle(self.tr("Sniff Protocol"))
        self.setWindowIcon(QIcon.fromTheme(":/icons/data/icons/sniffer.svg"))

        self.encodings = encodings
        for encoding in self.encodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.create_connects()

        if encoding_index > -1:
            self.ui.comboBox_sniff_encoding.setCurrentIndex(encoding_index)

        self.ui.comboBox_sniff_viewtype.setCurrentIndex(
            constants.SETTINGS.value('default_view', 0, int))
class ProtocolSniffDialogController(SendRecvDialogController):
    protocol_accepted = pyqtSignal(list)

    def __init__(self,
                 project_manager,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 encodings,
                 encoding_index=0,
                 parent=None,
                 testing_mode=False):
        super().__init__(project_manager,
                         is_tx=False,
                         parent=parent,
                         testing_mode=testing_mode)

        self.set_sniff_ui_items_visible(True)

        self.graphics_view = self.ui.graphicsView_sniff_Preview
        self.ui.stackedWidget.setCurrentWidget(self.ui.page_sniff)
        self.hide_send_ui_items()
        self.hide_receive_ui_items()
        self.ui.sliderYscale.hide()
        self.ui.label_y_scale.hide()

        self.ui.spinbox_sniff_Noise.setValue(noise)
        self.ui.spinbox_sniff_Center.setValue(center)
        self.ui.spinbox_sniff_BitLen.setValue(bit_length)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(modulation_type_index)

        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index,
                                       self.ui.cbDevice.currentText(),
                                       self.backend_handler)

        # set really in on_device_started
        self.scene_manager = None  # type: LiveSceneManager
        self.init_device()
        self.set_bandwidth_status()

        self.graphics_view.setScene(self.scene_manager.scene)
        self.graphics_view.scene_manager = self.scene_manager

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.setWindowTitle(self.tr("Sniff Protocol"))
        self.setWindowIcon(QIcon.fromTheme(":/icons/data/icons/sniffer.svg"))

        self.encodings = encodings
        for encoding in self.encodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.create_connects()

        if encoding_index > -1:
            self.ui.comboBox_sniff_encoding.setCurrentIndex(encoding_index)

        self.ui.comboBox_sniff_viewtype.setCurrentIndex(
            constants.SETTINGS.value('default_view', 0, int))

    @property
    def device(self):
        if hasattr(self, "sniffer"):
            return self.sniffer.rcv_device
        else:
            return None

    @device.setter
    def device(self, value):
        if hasattr(self, "sniffer"):
            self.sniffer.rcv_device = value
        else:
            pass

    @property
    def view_type(self):
        return self.ui.comboBox_sniff_viewtype.currentIndex()

    def create_connects(self):
        super().create_connects()
        self.ui.btnAccept.clicked.connect(self.on_btn_accept_clicked)

        self.sniffer.qt_signals.data_sniffed.connect(self.on_data_sniffed)
        self.sniffer.qt_signals.sniff_device_errors_changed.connect(
            self.on_device_errors_changed)

        self.ui.spinbox_sniff_Noise.editingFinished.connect(
            self.on_noise_edited)
        self.ui.spinbox_sniff_Center.editingFinished.connect(
            self.on_center_edited)
        self.ui.spinbox_sniff_BitLen.editingFinished.connect(
            self.on_bit_len_edited)
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.connect(
            self.on_tolerance_edited)
        self.ui.combox_sniff_Modulation.currentIndexChanged.connect(
            self.on_modulation_changed)
        self.ui.comboBox_sniff_viewtype.currentIndexChanged.connect(
            self.on_view_type_changed)
        self.ui.lineEdit_sniff_OutputFile.editingFinished.connect(
            self.on_line_edit_output_file_editing_finished)
        self.ui.comboBox_sniff_encoding.currentIndexChanged.connect(
            self.on_combobox_sniff_encoding_index_changed)

    def set_device_ui_items_visibility(self,
                                       device_name: str,
                                       adjust_gains=True):
        super().set_device_ui_items_visibility(device_name, adjust_gains)
        visible = device_name != NetworkSDRInterfacePlugin.NETWORK_SDR_NAME
        for item in ("spinbox_sniff_Noise", "combox_sniff_Modulation",
                     "label_sniff_Modulation", "graphicsView_sniff_Preview",
                     "spinbox_sniff_Center", "spinbox_sniff_BitLen",
                     "spinbox_sniff_ErrorTolerance", "label_sniff_Noise",
                     "label_sniff_Center", "label_sniff_BitLength",
                     "label_sniff_Tolerance"):
            getattr(self.ui, item).setVisible(visible)

    def init_device(self):
        dev_name = self.ui.cbDevice.currentText()
        self.sniffer.device_name = dev_name

        self._create_device_connects()
        self.scene_manager = SniffSceneManager(np.array([]), parent=self)

    def emit_editing_finished_signals(self):
        super().emit_editing_finished_signals()
        self.ui.spinbox_sniff_Noise.editingFinished.emit()
        self.ui.spinbox_sniff_Center.editingFinished.emit()
        self.ui.spinbox_sniff_BitLen.editingFinished.emit()
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.emit()

    def update_view(self):
        if super().update_view():
            self.scene_manager.end = self.device.current_index
            self.scene_manager.init_scene()
            self.scene_manager.show_full_scene()
            self.graphics_view.update()

    @pyqtSlot()
    def on_device_started(self):
        self.scene_manager.data_array = self.device.data.real if hasattr(
            self.device.data, "real") else None

        super().on_device_started()

        self.ui.btnStart.setEnabled(False)
        self.set_device_ui_items_enabled(False)

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_threshold = self.ui.spinbox_sniff_Noise.value(
        )
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(self.view_type))

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinbox_sniff_Center.value()
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(self.view_type))

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinbox_sniff_BitLen.value()
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(self.view_type))

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinbox_sniff_ErrorTolerance.value(
        )
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(self.view_type))

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(self.view_type))

    @pyqtSlot()
    def on_start_clicked(self):
        super().on_start_clicked()
        self.sniffer.sniff()

    @pyqtSlot()
    def on_stop_clicked(self):
        self.sniffer.stop()

    @pyqtSlot()
    def on_clear_clicked(self):
        self.ui.btnClear.setEnabled(False)
        self.ui.txtEd_sniff_Preview.clear()
        self.scene_manager.clear_path()
        self.device.current_index = 0
        self.sniffer.clear()

    @pyqtSlot(int)
    def on_data_sniffed(self, from_index: int):
        new_data = self.sniffer.decoded_to_string(self.view_type,
                                                  start=from_index)
        if new_data.strip():
            self.ui.txtEd_sniff_Preview.appendPlainText(new_data)
            self.ui.txtEd_sniff_Preview.verticalScrollBar().setValue(
                self.ui.txtEd_sniff_Preview.verticalScrollBar().maximum())

    @pyqtSlot(int)
    def on_view_type_changed(self, new_index: int):
        self.ui.txtEd_sniff_Preview.setPlainText(
            self.sniffer.decoded_to_string(new_index))

    @pyqtSlot()
    def on_btn_accept_clicked(self):
        self.protocol_accepted.emit(self.sniffer.messages)
        self.close()

    @pyqtSlot(str)
    def on_device_errors_changed(self, txt: str):
        self.ui.txtEditErrors.append(txt)

    @pyqtSlot()
    def on_line_edit_output_file_editing_finished(self):
        text = self.ui.lineEdit_sniff_OutputFile.text()
        if text and not text.endswith(".txt"):
            text += ".txt"
            self.ui.lineEdit_sniff_OutputFile.setText(text)

        self.sniffer.sniff_file = text
        self.ui.btnAccept.setDisabled(bool(self.sniffer.sniff_file))

    @pyqtSlot(int)
    def on_combobox_sniff_encoding_index_changed(self, index: int):
        if self.sniffer.decoder != self.encodings[index]:
            self.sniffer.set_decoder_for_messages(self.encodings[index])
            self.sniffer.decoder = self.encodings[index]
            self.ui.txtEd_sniff_Preview.setPlainText(
                self.sniffer.decoded_to_string(self.view_type))
Exemple #19
0
    def test_performance(self):
        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.001,
                                  5,
                                  1,
                                  NetworkSDRInterfacePlugin.NETWORK_SDR_NAME,
                                  BackendHandler(),
                                  network_raw_mode=True,
                                  real_time=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)

        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,
                                 100000,
                                 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,
                                 100000,
                                 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 = 113600
        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(1)

        # 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
        modulator.modulate(msg_a.encoded_bits)

        # yappi.start()

        self.network_sdr_plugin_sender.send_raw_data(
            modulator.modulated_samples, 1)
        QTest.qWait(100)
        receive_process.join(10)

        print("PROCESS TIME: {0:.2f}ms".format(elapsed.value))

        self.assertEqual(current_index.value, target_num_samples)
        self.assertLess(elapsed.value, 200)
class ProtocolSniffDialogController(QDialog):
    protocol_accepted = pyqtSignal(list)

    def __init__(self,
                 freq,
                 samp_rate,
                 bw,
                 gain,
                 device,
                 noise,
                 center,
                 bit_length,
                 tolerance,
                 modulation_type_index,
                 parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffProtocol()
        self.ui.setupUi(self)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.ui.spinBoxFreq.setValue(freq)
        self.ui.spinBoxSampleRate.setValue(samp_rate)
        self.ui.spinBoxBandwidth.setValue(bw)
        self.ui.spinBoxGain.setValue(gain)
        self.ui.spinboxNoise.setValue(noise)
        self.ui.spinboxCenter.setValue(center)
        self.ui.spinboxBitLen.setValue(bit_length)
        self.ui.spinboxErrorTolerance.setValue(tolerance)
        self.ui.comboxModulation.setCurrentIndex(modulation_type_index)

        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(False)

        self.ui.cbDevice.clear()
        items = []
        bh = BackendHandler()
        for device_name in bh.DEVICE_NAMES:
            dev = bh.device_backends[device_name.lower()]
            if dev.is_enabled and dev.supports_rx:
                items.append(device_name)

        pm = PluginManager()
        if pm.is_plugin_enabled("NetworkSDRInterface"):
            items.append(NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)

        self.ui.cbDevice.addItems(items)
        del bh
        if device in items:
            self.ui.cbDevice.setCurrentIndex(items.index(device))

        if self.ui.cbDevice.count() == 0:
            Errors.no_device()
            self.close()
            return

        device = self.ui.cbDevice.currentText()
        self.sniffer = ProtocolSniffer(bit_length, center, noise, tolerance,
                                       modulation_type_index, samp_rate, freq,
                                       gain, bw, device)

        self.set_object_visibility()

        self.sniffer.usrp_ip = self.ui.lineEditIP.text()
        self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked()

        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        ipRegex = QRegExp("^" + ipRange + "\\." + ipRange + "\\." + ipRange +
                          "\\." + ipRange + "$")
        self.ui.lineEditIP.setValidator(QRegExpValidator(ipRegex))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEditOutputFile.setCompleter(completer)

        self.create_connects()

    def create_connects(self):
        self.ui.btnStart.clicked.connect(self.on_start_clicked)
        self.ui.btnStop.clicked.connect(self.on_stop_clicked)
        self.ui.btnClear.clicked.connect(self.on_clear_clicked)
        self.ui.btnAccept.clicked.connect(self.on_btn_accept_clicked)
        self.ui.btnClose.clicked.connect(self.close)

        self.sniffer.started.connect(self.on_sniffer_rcv_started)
        self.sniffer.stopped.connect(self.on_sniffer_rcv_stopped)
        self.sniffer.qt_signals.data_sniffed.connect(self.on_data_sniffed)
        self.sniffer.qt_signals.sniff_device_errors_changed.connect(
            self.on_device_errors_changed)

        self.ui.spinBoxSampleRate.editingFinished.connect(
            self.on_sample_rate_edited)
        self.ui.spinBoxGain.editingFinished.connect(self.on_gain_edited)
        self.ui.spinBoxFreq.editingFinished.connect(self.on_freq_edited)
        self.ui.spinBoxBandwidth.editingFinished.connect(self.on_bw_edited)
        self.ui.lineEditIP.editingFinished.connect(self.on_usrp_ip_edited)
        self.ui.cbDevice.currentIndexChanged.connect(self.on_device_edited)

        self.ui.btnLockBWSR.clicked.connect(self.on_btn_lock_bw_sr_clicked)

        self.ui.spinboxNoise.editingFinished.connect(self.on_noise_edited)
        self.ui.spinboxCenter.editingFinished.connect(self.on_center_edited)
        self.ui.spinboxBitLen.editingFinished.connect(self.on_bit_len_edited)
        self.ui.spinboxErrorTolerance.editingFinished.connect(
            self.on_tolerance_edited)
        self.ui.comboxModulation.currentIndexChanged.connect(
            self.on_modulation_changed)
        self.ui.comboBoxViewType.currentIndexChanged.connect(
            self.on_view_type_changed)
        self.ui.lineEditOutputFile.textChanged.connect(
            self.on_line_edit_output_file_text_changed)

    @property
    def view_type(self):
        return self.ui.comboBoxViewType.currentIndex()

    @property
    def has_empty_device_list(self):
        return self.ui.cbDevice.count() == 0

    def closeEvent(self, event: QCloseEvent):
        if hasattr(self, "sniffer"):
            self.sniffer.stop()
        event.accept()

    @pyqtSlot()
    def on_sample_rate_edited(self):
        self.sniffer.rcv_device.sample_rate = self.ui.spinBoxSampleRate.value()
        if self.bw_sr_are_locked:
            self.ui.spinBoxBandwidth.setValue(
                self.ui.spinBoxSampleRate.value())
            self.sniffer.rcv_device.bandwidth = self.ui.spinBoxBandwidth.value(
            )

    @pyqtSlot()
    def on_freq_edited(self):
        self.sniffer.rcv_device.frequency = self.ui.spinBoxFreq.value()

    @pyqtSlot()
    def on_bw_edited(self):
        self.sniffer.rcv_device.bandwidth = self.ui.spinBoxBandwidth.value()
        if self.bw_sr_are_locked:
            self.ui.spinBoxSampleRate.setValue(
                self.ui.spinBoxBandwidth.value())
            self.sniffer.rcv_device.sample_rate = self.ui.spinBoxSampleRate.value(
            )

    @pyqtSlot()
    def on_usrp_ip_edited(self):
        self.sniffer.usrp_ip = self.ui.lineEditIP.text()

    @pyqtSlot()
    def on_gain_edited(self):
        self.sniffer.rcv_device.gain = self.ui.spinBoxGain.value()

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_threshold = self.ui.spinboxNoise.value()

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinboxCenter.value()

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinboxBitLen.value()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinboxErrorTolerance.value()

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)

    @pyqtSlot()
    def on_device_edited(self):
        dev = self.ui.cbDevice.currentText()
        self.sniffer.device_name = dev
        self.set_object_visibility()

    def set_object_visibility(self):
        self.ui.lineEditIP.setVisible(self.sniffer.device_name == "USRP")
        self.ui.labelIP.setVisible(self.sniffer.device_name == "USRP")
        for object in ("spinBoxFreq", "spinBoxSampleRate", "spinBoxBandwidth",
                       "spinBoxGain", "spinboxNoise", "spinboxCenter",
                       "spinboxBitLen", "spinboxErrorTolerance",
                       "comboxModulation", "btnLockBWSR", "labelFreq",
                       "labelSampleRate", "labelBandWidth", "labelGain",
                       "labelNoise", "labelCenter", "labelBitLength",
                       "labelTolerance", "labelModulation"):
            getattr(
                self.ui,
                object).setHidden(self.sniffer.device_name ==
                                  NetworkSDRInterfacePlugin.NETWORK_SDR_NAME)

    @pyqtSlot()
    def on_start_clicked(self):
        self.ui.spinBoxFreq.editingFinished.emit()
        self.ui.lineEditIP.editingFinished.emit()
        self.ui.spinBoxBandwidth.editingFinished.emit()
        self.ui.spinBoxSampleRate.editingFinished.emit()
        self.ui.spinboxNoise.editingFinished.emit()
        self.ui.spinboxCenter.editingFinished.emit()
        self.ui.spinboxBitLen.editingFinished.emit()
        self.ui.spinboxErrorTolerance.editingFinished.emit()

        self.sniffer.sniff()

    @pyqtSlot()
    def on_stop_clicked(self):
        self.sniffer.stop()

    @pyqtSlot()
    def on_sniffer_rcv_stopped(self):
        self.ui.btnStart.setEnabled(True)
        self.ui.btnStop.setEnabled(False)
        self.ui.btnClear.setEnabled(True)

        self.ui.spinBoxSampleRate.setEnabled(True)
        self.ui.spinBoxFreq.setEnabled(True)
        self.ui.lineEditIP.setEnabled(True)
        self.ui.spinBoxBandwidth.setEnabled(True)
        self.ui.spinBoxGain.setEnabled(True)
        self.ui.cbDevice.setEnabled(True)

        self.ui.spinboxNoise.setEnabled(True)
        self.ui.spinboxCenter.setEnabled(True)
        self.ui.spinboxBitLen.setEnabled(True)
        self.ui.spinboxErrorTolerance.setEnabled(True)
        self.ui.comboxModulation.setEnabled(True)

    @pyqtSlot()
    def on_sniffer_rcv_started(self):
        self.ui.txtEditErrors.clear()
        self.ui.btnStart.setEnabled(False)
        self.ui.btnClear.setEnabled(False)
        self.ui.btnStop.setEnabled(True)

        self.ui.spinBoxSampleRate.setDisabled(True)
        self.ui.spinBoxFreq.setDisabled(True)
        self.ui.spinBoxGain.setDisabled(True)
        self.ui.spinBoxBandwidth.setDisabled(True)

        self.ui.spinboxNoise.setDisabled(True)
        self.ui.spinboxCenter.setDisabled(True)
        self.ui.spinboxBitLen.setDisabled(True)
        self.ui.spinboxErrorTolerance.setDisabled(True)
        self.ui.comboxModulation.setDisabled(True)

        self.ui.lineEditIP.setDisabled(True)
        self.ui.cbDevice.setDisabled(True)

    @pyqtSlot()
    def on_btn_lock_bw_sr_clicked(self):
        self.bw_sr_are_locked = self.ui.btnLockBWSR.isChecked()
        if self.bw_sr_are_locked:
            self.ui.btnLockBWSR.setIcon(QIcon(":/icons/data/icons/lock.svg"))
        else:
            self.ui.btnLockBWSR.setIcon(QIcon(":/icons/data/icons/unlock.svg"))

    @pyqtSlot()
    def on_clear_clicked(self):
        self.ui.btnClear.setEnabled(False)
        self.ui.txtEdPreview.clear()
        self.sniffer.clear()

    @pyqtSlot(int)
    def on_data_sniffed(self, from_index: int):
        self.ui.txtEdPreview.appendPlainText(
            self.sniffer.plain_to_string(self.view_type,
                                         start=from_index,
                                         show_pauses=False))
        self.ui.txtEdPreview.verticalScrollBar().setValue(
            self.ui.txtEdPreview.verticalScrollBar().maximum())

    @pyqtSlot(int)
    def on_view_type_changed(self, new_index: int):
        self.ui.txtEdPreview.setPlainText(
            self.sniffer.plain_to_string(new_index, show_pauses=False))

    @pyqtSlot()
    def on_btn_accept_clicked(self):
        self.protocol_accepted.emit(self.sniffer.messages)
        self.close()

    @pyqtSlot(str)
    def on_device_errors_changed(self, txt: str):
        self.ui.txtEditErrors.append(txt)

    @pyqtSlot(str)
    def on_line_edit_output_file_text_changed(self, text: str):
        self.sniffer.sniff_file = text
        self.ui.btnAccept.setDisabled(bool(self.sniffer.sniff_file))
class SniffSettingsWidget(QWidget):
    sniff_setting_edited = pyqtSignal()
    sniff_file_edited = pyqtSignal()
    sniff_parameters_changed = pyqtSignal(dict)

    def __init__(self, device_name: str, project_manager: ProjectManager, signal=None, backend_handler=None,
                 network_raw_mode=False, signals=None, parent=None):
        super().__init__(parent)
        self.ui = Ui_SniffSettings()
        self.ui.setupUi(self)

        signals = signals if signals is not None else []
        self.project_manager = project_manager

        for encoding in self.project_manager.decodings:
            self.ui.comboBox_sniff_encoding.addItem(encoding.name)

        self.bootstrap(project_manager.device_conf, signal, enforce_default=True)

        self.sniffer = ProtocolSniffer(bit_len=self.ui.spinbox_sniff_BitLen.value(),
                                       center=self.ui.spinbox_sniff_Center.value(),
                                       noise=self.ui.spinbox_sniff_Noise.value(),
                                       tolerance=self.ui.spinbox_sniff_ErrorTolerance.value(),
                                       modulation_type=self.ui.combox_sniff_Modulation.currentIndex(),
                                       device=device_name,
                                       backend_handler=BackendHandler() if backend_handler is None else backend_handler,
                                       network_raw_mode=network_raw_mode)

        self.create_connects()
        self.ui.comboBox_sniff_encoding.currentIndexChanged.emit(self.ui.comboBox_sniff_encoding.currentIndex())
        self.ui.comboBox_sniff_viewtype.setCurrentIndex(constants.SETTINGS.value('default_view', 0, int))

        # Auto Complete like a Boss
        completer = QCompleter()
        completer.setModel(QDirModel(completer))
        self.ui.lineEdit_sniff_OutputFile.setCompleter(completer)

        self.signals = signals

        if len(signals) == 0:
            self.ui.label_sniff_Signal.hide()
            self.ui.btn_sniff_use_signal.hide()
            self.ui.comboBox_sniff_signal.hide()
        else:
            for signal in signals:
                self.ui.comboBox_sniff_signal.addItem(signal.name)

    def bootstrap(self, conf_dict: dict, signal=None, enforce_default=False):
        def set_val(widget, key: str, default):
            try:
                value = conf_dict[key]
            except KeyError:
                value = default if enforce_default else None

            if value is not None:
                if hasattr(widget, "setValue"):
                    widget.setValue(value)
                elif hasattr(widget, "setCurrentIndex"):
                    widget.setCurrentIndex(value)

        set_val(self.ui.spinbox_sniff_BitLen, "bit_len", signal.bit_len if signal else 100)
        set_val(self.ui.spinbox_sniff_Center, "center", signal.qad_center if signal else 0.02)
        set_val(self.ui.spinbox_sniff_ErrorTolerance, "tolerance", signal.tolerance if signal else 5)
        set_val(self.ui.spinbox_sniff_Noise, "noise", signal.noise_threshold if signal else 0.001)
        set_val(self.ui.combox_sniff_Modulation, "modulation_index", signal.modulation_type if signal else 1)
        self.ui.comboBox_sniff_encoding.setCurrentText(conf_dict.get("decoding_name", ""))
        self.ui.checkBoxAdaptiveNoise.setChecked(bool(conf_dict.get("adaptive_noise", False)))

        self.emit_editing_finished_signals()

    def create_connects(self):
        self.ui.spinbox_sniff_Noise.editingFinished.connect(self.on_noise_edited)
        self.ui.spinbox_sniff_Center.editingFinished.connect(self.on_center_edited)
        self.ui.spinbox_sniff_BitLen.editingFinished.connect(self.on_bit_len_edited)
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.connect(self.on_tolerance_edited)
        self.ui.combox_sniff_Modulation.currentIndexChanged.connect(self.on_modulation_changed)
        self.ui.comboBox_sniff_viewtype.currentIndexChanged.connect(self.on_view_type_changed)
        self.ui.lineEdit_sniff_OutputFile.editingFinished.connect(self.on_line_edit_output_file_editing_finished)
        self.ui.comboBox_sniff_encoding.currentIndexChanged.connect(self.on_combobox_sniff_encoding_index_changed)
        self.ui.checkBox_sniff_Timestamp.clicked.connect(self.on_checkbox_sniff_timestamp_clicked)
        self.ui.btn_sniff_use_signal.clicked.connect(self.on_btn_sniff_use_signal_clicked)
        self.ui.checkBoxAdaptiveNoise.clicked.connect(self.on_check_box_adaptive_noise_clicked)

    def emit_editing_finished_signals(self):
        self.ui.spinbox_sniff_Noise.editingFinished.emit()
        self.ui.spinbox_sniff_Center.editingFinished.emit()
        self.ui.spinbox_sniff_BitLen.editingFinished.emit()
        self.ui.spinbox_sniff_ErrorTolerance.editingFinished.emit()
        self.ui.lineEdit_sniff_OutputFile.editingFinished.emit()
        self.ui.checkBoxAdaptiveNoise.clicked.emit()

    def emit_sniff_parameters_changed(self):
        self.sniff_parameters_changed.emit(dict(bit_len=self.sniffer.signal.bit_len,
                                                center=self.sniffer.signal.qad_center,
                                                noise=self.sniffer.signal.noise_threshold,
                                                tolerance=self.sniffer.signal.tolerance,
                                                modulation_index=self.sniffer.signal.modulation_type,
                                                decoding_name=self.sniffer.decoder.name,
                                                adaptive_noise=self.sniffer.adaptive_noise))

    @pyqtSlot()
    def on_noise_edited(self):
        self.sniffer.signal._noise_threshold = self.ui.spinbox_sniff_Noise.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_center_edited(self):
        self.sniffer.signal.qad_center = self.ui.spinbox_sniff_Center.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_bit_len_edited(self):
        self.sniffer.signal.bit_len = self.ui.spinbox_sniff_BitLen.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_tolerance_edited(self):
        self.sniffer.signal.tolerance = self.ui.spinbox_sniff_ErrorTolerance.value()
        self.sniff_setting_edited.emit()

    @pyqtSlot(int)
    def on_modulation_changed(self, new_index: int):
        self.sniffer.signal.silent_set_modulation_type(new_index)
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_view_type_changed(self):
        self.sniff_setting_edited.emit()

    @pyqtSlot(int)
    def on_combobox_sniff_encoding_index_changed(self, index: int):
        if self.sniffer.decoder != self.project_manager.decodings[index]:
            self.sniffer.set_decoder_for_messages(self.project_manager.decodings[index])
            self.sniffer.decoder = self.project_manager.decodings[index]
            self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_line_edit_output_file_editing_finished(self):
        self.ui.lineEdit_sniff_OutputFile.setStyleSheet("")
        text = self.ui.lineEdit_sniff_OutputFile.text()
        if text and not text.endswith(".txt"):
            text += ".txt"
            self.ui.lineEdit_sniff_OutputFile.setText(text)

        if text and not os.path.isfile(text):
            try:
                open(text, "w").close()
            except Exception as e:
                self.ui.lineEdit_sniff_OutputFile.setStyleSheet("color:red;")
                return

        self.sniffer.sniff_file = text
        self.sniff_file_edited.emit()

    @pyqtSlot()
    def on_checkbox_sniff_timestamp_clicked(self):
        self.sniff_setting_edited.emit()

    @pyqtSlot()
    def on_btn_sniff_use_signal_clicked(self):
        try:
            signal = self.signals[self.ui.comboBox_sniff_signal.currentIndex()]
        except IndexError:
            return

        self.ui.spinbox_sniff_BitLen.setValue(signal.bit_len)
        self.ui.spinbox_sniff_Center.setValue(signal.qad_center)
        self.ui.spinbox_sniff_Noise.setValue(signal.noise_threshold)
        self.ui.spinbox_sniff_ErrorTolerance.setValue(signal.tolerance)
        self.ui.combox_sniff_Modulation.setCurrentIndex(signal.modulation_type)

        self.emit_editing_finished_signals()

    @pyqtSlot()
    def on_check_box_adaptive_noise_clicked(self):
        self.sniffer.adaptive_noise = self.ui.checkBoxAdaptiveNoise.isChecked()