Esempio n. 1
0
class VirtualDevice(QObject):
    """
    Wrapper class for providing sending methods for grc and native devices

    """
    started = pyqtSignal()
    stopped = pyqtSignal()
    sender_needs_restart = pyqtSignal()

    fatal_error_occurred = pyqtSignal(str)
    ready_for_action = pyqtSignal()

    data_received = pyqtSignal(
        np.ndarray)  # for direct demodulation in sniffer

    continuous_send_msg = "Continuous send mode is not supported for GNU Radio backend. " \
                          "You can change the configured device backend in options."

    def __init__(self,
                 backend_handler,
                 name: str,
                 mode: Mode,
                 freq=None,
                 sample_rate=None,
                 bandwidth=None,
                 gain=None,
                 if_gain=None,
                 baseband_gain=None,
                 samples_to_send=None,
                 device_ip=None,
                 sending_repeats=1,
                 parent=None,
                 resume_on_full_receive_buffer=False,
                 raw_mode=True,
                 portnumber=1234):
        super().__init__(parent)
        self.name = name
        self.mode = mode
        self.backend_handler = backend_handler

        freq = config.DEFAULT_FREQUENCY if freq is None else freq
        sample_rate = config.DEFAULT_SAMPLE_RATE if sample_rate is None else sample_rate
        bandwidth = config.DEFAULT_BANDWIDTH if bandwidth is None else bandwidth
        gain = config.DEFAULT_GAIN if gain is None else gain
        if_gain = config.DEFAULT_IF_GAIN if if_gain is None else if_gain
        baseband_gain = config.DEFAULT_BB_GAIN if baseband_gain is None else baseband_gain

        resume_on_full_receive_buffer = self.mode == Mode.spectrum or resume_on_full_receive_buffer

        if self.name == NetworkSDRInterfacePlugin.NETWORK_SDR_NAME:
            self.backend = Backends.network
        else:
            try:
                self.backend = self.backend_handler.device_backends[
                    name.lower()].selected_backend
            except KeyError:
                logger.warning("Invalid device name: {0}".format(name))
                self.backend = Backends.none
                self.__dev = None
                return

        if self.backend == Backends.grc:
            if mode == Mode.receive:
                from urh.dev.gr.ReceiverThread import ReceiverThread
                self.__dev = ReceiverThread(
                    freq,
                    sample_rate,
                    bandwidth,
                    gain,
                    if_gain,
                    baseband_gain,
                    parent=parent,
                    resume_on_full_receive_buffer=resume_on_full_receive_buffer
                )
            elif mode == Mode.send:
                from urh.dev.gr.SenderThread import SenderThread
                self.__dev = SenderThread(freq,
                                          sample_rate,
                                          bandwidth,
                                          gain,
                                          if_gain,
                                          baseband_gain,
                                          parent=parent)
                self.__dev.data = samples_to_send
                self.__dev.samples_per_transmission = len(
                    samples_to_send) if samples_to_send is not None else 2**15
            elif mode == Mode.spectrum:
                from urh.dev.gr.SpectrumThread import SpectrumThread
                self.__dev = SpectrumThread(freq,
                                            sample_rate,
                                            bandwidth,
                                            gain,
                                            if_gain,
                                            baseband_gain,
                                            parent=parent)
            else:
                raise ValueError("Unknown mode")
            self.__dev.device = name
            self.__dev.started.connect(self.emit_started_signal)
            self.__dev.stopped.connect(self.emit_stopped_signal)
            self.__dev.sender_needs_restart.connect(
                self.emit_sender_needs_restart)
        elif self.backend == Backends.native:
            name = self.name.lower()
            if name in map(str.lower, BackendHandler.DEVICE_NAMES):
                if name == "hackrf":
                    from urh.dev.native.HackRF import HackRF
                    self.__dev = HackRF(freq, sample_rate, bandwidth, gain,
                                        if_gain, baseband_gain,
                                        resume_on_full_receive_buffer)
                elif name.replace("-", "") == "rtlsdr":
                    from urh.dev.native.RTLSDR import RTLSDR
                    self.__dev = RTLSDR(freq,
                                        gain,
                                        sample_rate,
                                        device_number=0,
                                        resume_on_full_receive_buffer=
                                        resume_on_full_receive_buffer)
                elif name.replace("-", "") == "rtltcp":
                    from urh.dev.native.RTLSDRTCP import RTLSDRTCP
                    self.__dev = RTLSDRTCP(freq,
                                           gain,
                                           sample_rate,
                                           bandwidth,
                                           device_number=0,
                                           resume_on_full_receive_buffer=
                                           resume_on_full_receive_buffer)
                elif name == "limesdr":
                    from urh.dev.native.LimeSDR import LimeSDR
                    self.__dev = LimeSDR(freq,
                                         gain,
                                         sample_rate,
                                         bandwidth,
                                         gain,
                                         resume_on_full_receive_buffer=
                                         resume_on_full_receive_buffer)
                elif name.startswith("airspy"):
                    from urh.dev.native.AirSpy import AirSpy
                    self.__dev = AirSpy(freq,
                                        sample_rate,
                                        bandwidth,
                                        gain,
                                        if_gain,
                                        baseband_gain,
                                        resume_on_full_receive_buffer=
                                        resume_on_full_receive_buffer)
                elif name.startswith("usrp"):
                    from urh.dev.native.USRP import USRP
                    self.__dev = USRP(freq,
                                      gain,
                                      sample_rate,
                                      bandwidth,
                                      gain,
                                      resume_on_full_receive_buffer=
                                      resume_on_full_receive_buffer)
                elif name.startswith("sdrplay"):
                    from urh.dev.native.SDRPlay import SDRPlay
                    self.__dev = SDRPlay(freq,
                                         gain,
                                         bandwidth,
                                         gain,
                                         if_gain=if_gain,
                                         resume_on_full_receive_buffer=
                                         resume_on_full_receive_buffer)
                elif name == "soundcard":
                    from urh.dev.native.SoundCard import SoundCard
                    self.__dev = SoundCard(sample_rate,
                                           resume_on_full_receive_buffer=
                                           resume_on_full_receive_buffer)
                else:
                    raise NotImplementedError(
                        "Native Backend for {0} not yet implemented".format(
                            name))

            elif name == "test":
                # For Unittests Only
                self.__dev = Device(freq, sample_rate, bandwidth, gain,
                                    if_gain, baseband_gain,
                                    resume_on_full_receive_buffer)
            else:
                raise ValueError("Unknown device name {0}".format(name))
            self.__dev.portnumber = portnumber
            self.__dev.device_ip = device_ip
            if mode == Mode.send:
                self.__dev.init_send_parameters(samples_to_send,
                                                sending_repeats)
        elif self.backend == Backends.network:
            self.__dev = NetworkSDRInterfacePlugin(
                raw_mode=raw_mode,
                resume_on_full_receive_buffer=resume_on_full_receive_buffer,
                spectrum=self.mode == Mode.spectrum,
                sending=self.mode == Mode.send)
            self.__dev.send_connection_established.connect(
                self.emit_ready_for_action)
            self.__dev.receive_server_started.connect(
                self.emit_ready_for_action)
            self.__dev.error_occurred.connect(self.emit_fatal_error_occurred)
            self.__dev.samples_to_send = samples_to_send
        elif self.backend == Backends.none:
            self.__dev = None
        else:
            raise ValueError("Unsupported Backend")

        if hasattr(self.__dev, "data_received"):
            self.__dev.data_received.connect(self.data_received.emit)

        if mode == Mode.spectrum:
            self.__dev.is_in_spectrum_mode = True

    @property
    def has_multi_device_support(self):
        return hasattr(
            self.__dev,
            "has_multi_device_support") and self.__dev.has_multi_device_support

    @property
    def device_serial(self):
        if hasattr(self.__dev, "device_serial"):
            return self.__dev.device_serial
        else:
            return None

    @device_serial.setter
    def device_serial(self, value):
        if hasattr(self.__dev, "device_serial"):
            self.__dev.device_serial = value

    @property
    def device_number(self):
        if hasattr(self.__dev, "device_number"):
            return self.__dev.device_number
        else:
            return None

    @device_number.setter
    def device_number(self, value):
        if hasattr(self.__dev, "device_number"):
            self.__dev.device_number = value

    @property
    def bandwidth(self):
        return self.__dev.bandwidth

    @bandwidth.setter
    def bandwidth(self, value):
        self.__dev.bandwidth = value

    @property
    def bandwidth_is_adjustable(self):
        if self.backend == Backends.grc:
            return True
        elif self.backend == Backends.native:
            return self.__dev.bandwidth_is_adjustable
        elif self.backend == Backends.network:
            return True
        else:
            raise ValueError("Unsupported Backend")

    @property
    def frequency(self):
        if self.backend == Backends.grc:
            return self.__dev.freq
        elif self.backend == Backends.native:
            return self.__dev.frequency
        else:
            raise ValueError("Unsupported Backend")

    @frequency.setter
    def frequency(self, value):
        if self.backend == Backends.grc:
            self.__dev.freq = value
        elif self.backend == Backends.native:
            self.__dev.frequency = value
        elif self.backend == Backends.network:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def num_samples_to_send(self) -> int:
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.num_samples_to_send
        else:
            raise ValueError(self.continuous_send_msg)

    @num_samples_to_send.setter
    def num_samples_to_send(self, value: int):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.num_samples_to_send = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_send_continuous(self) -> bool:
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.sending_is_continuous
        else:
            raise ValueError(self.continuous_send_msg)

    @is_send_continuous.setter
    def is_send_continuous(self, value: bool):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.sending_is_continuous = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_raw_mode(self) -> bool:
        if self.backend == Backends.network:
            return self.__dev.raw_mode
        else:
            return True

    @property
    def continuous_send_ring_buffer(self):
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.continuous_send_ring_buffer
        else:
            raise ValueError(self.continuous_send_msg)

    @continuous_send_ring_buffer.setter
    def continuous_send_ring_buffer(self, value):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.continuous_send_ring_buffer = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_in_spectrum_mode(self):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            return self.__dev.is_in_spectrum_mode
        else:
            raise ValueError("Unsupported Backend")

    @is_in_spectrum_mode.setter
    def is_in_spectrum_mode(self, value: bool):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            self.__dev.is_in_spectrum_mode = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def gain(self):
        return self.__dev.gain

    @gain.setter
    def gain(self, value):
        try:
            self.__dev.gain = value
        except AttributeError as e:
            logger.warning(str(e))

    @property
    def if_gain(self):
        try:
            return self.__dev.if_gain
        except AttributeError as e:
            logger.warning(str(e))

    @if_gain.setter
    def if_gain(self, value):
        try:
            self.__dev.if_gain = value
        except AttributeError as e:
            logger.warning(str(e))

    @property
    def baseband_gain(self):
        return self.__dev.baseband_gain

    @baseband_gain.setter
    def baseband_gain(self, value):
        self.__dev.baseband_gain = value

    @property
    def sample_rate(self):
        return self.__dev.sample_rate

    @sample_rate.setter
    def sample_rate(self, value):
        self.__dev.sample_rate = value

    @property
    def channel_index(self) -> int:
        return self.__dev.channel_index

    @channel_index.setter
    def channel_index(self, value: int):
        self.__dev.channel_index = value

    @property
    def antenna_index(self) -> int:
        return self.__dev.antenna_index

    @antenna_index.setter
    def antenna_index(self, value: int):
        self.__dev.antenna_index = value

    @property
    def freq_correction(self):
        return self.__dev.freq_correction

    @freq_correction.setter
    def freq_correction(self, value):
        self.__dev.freq_correction = value

    @property
    def direct_sampling_mode(self) -> int:
        return self.__dev.direct_sampling_mode

    @direct_sampling_mode.setter
    def direct_sampling_mode(self, value):
        self.__dev.direct_sampling_mode = value

    @property
    def emit_data_received_signal(self):
        return self.__dev.emit_data_received_signal

    @emit_data_received_signal.setter
    def emit_data_received_signal(self, value):
        self.__dev.emit_data_received_signal = value

    @property
    def samples_to_send(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.samples_to_send
        else:
            raise ValueError("Unsupported Backend")

    @samples_to_send.setter
    def samples_to_send(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            self.__dev.init_send_parameters(value, self.num_sending_repeats)
        elif self.backend == Backends.network:
            self.__dev.samples_to_send = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def ip(self):
        if self.backend == Backends.grc:
            return self.__dev.device_ip
        elif self.backend == Backends.native:
            return self.__dev.device_ip
        else:
            raise ValueError("Unsupported Backend")

    @ip.setter
    def ip(self, value):
        if self.backend == Backends.grc:
            self.__dev.device_ip = value
        elif self.backend == Backends.native:
            self.__dev.device_ip = value
        elif self.backend in (Backends.none, Backends.network):
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def port(self):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            return self.__dev.port
        else:
            raise ValueError("Unsupported Backend")

    @port.setter
    def port(self, value):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            self.__dev.port = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def data(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.samples_to_send
            else:
                return self.__dev.receive_buffer
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                raise NotImplementedError("Todo")
            else:
                if self.__dev.raw_mode:
                    return self.__dev.receive_buffer
                else:
                    return self.__dev.received_bits
        else:
            raise ValueError("Unsupported Backend")

    @data.setter
    def data(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.samples_to_send = value
            else:
                self.__dev.receive_buffer = value
        else:
            logger.warning("{}:{} has no data".format(self.__class__.__name__,
                                                      self.backend.name))

    def free_data(self):
        if self.backend == Backends.grc:
            self.__dev.data = None
        elif self.backend == Backends.native:
            self.__dev.samples_to_send = None
            self.__dev.receive_buffer = None
        elif self.backend == Backends.network:
            self.__dev.free_data()
        elif self.backend == Backends.none:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def resume_on_full_receive_buffer(self) -> bool:
        return self.__dev.resume_on_full_receive_buffer

    @resume_on_full_receive_buffer.setter
    def resume_on_full_receive_buffer(self, value: bool):
        if value != self.__dev.resume_on_full_receive_buffer:
            self.__dev.resume_on_full_receive_buffer = value
            if self.backend == Backends.native:
                self.__dev.receive_buffer = None
            elif self.backend == Backends.grc:
                self.__dev.data = None

    @property
    def num_sending_repeats(self):
        return self.__dev.sending_repeats

    @num_sending_repeats.setter
    def num_sending_repeats(self, value):
        self.__dev.sending_repeats = value

    @property
    def current_index(self):
        if self.backend == Backends.grc:
            return self.__dev.current_index
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_recv_index
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_receive_index
        else:
            raise ValueError("Unsupported Backend")

    @current_index.setter
    def current_index(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_index = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_recv_index = value
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_receive_index = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def current_iteration(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.current_sending_repeat
        else:
            raise ValueError("Unsupported Backend")

    @current_iteration.setter
    def current_iteration(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_iteration = value
        elif self.backend in (Backends.native, Backends.network):
            self.__dev.current_sending_repeat = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def sending_finished(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration is None
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.sending_finished
        else:
            raise ValueError("Unsupported Backend")

    @property
    def spectrum(self):
        if self.mode == Mode.spectrum:
            if self.backend == Backends.grc:
                return self.__dev.x, self.__dev.y
            elif self.backend == Backends.native or self.backend == Backends.network:
                w = np.abs(np.fft.fft(self.__dev.receive_buffer))
                freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
                idx = np.argsort(freqs)
                return freqs[idx].astype(np.float32), w[idx].astype(np.float32)
        else:
            raise ValueError("Spectrum x only available in spectrum mode")

    def start(self):
        if self.backend == Backends.grc:
            self.__dev.setTerminationEnabled(True)
            self.__dev.terminate()
            time.sleep(0.1)
            self.__dev.start(
            )  # Already connected to started signal in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.start_tx_mode(resume=True)
            else:
                self.__dev.start_rx_mode()

            self.emit_started_signal()
        elif self.backend == Backends.network:
            if self.mode == Mode.receive or self.mode == Mode.spectrum:
                self.__dev.start_tcp_server_for_receiving()
            else:
                self.__dev.start_raw_sending_thread()

            self.emit_started_signal()
        else:
            raise ValueError("Unsupported Backend")

    def stop(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.stop_tx_mode(msg)
            else:
                self.__dev.stop_rx_mode(msg)
            self.emit_stopped_signal()
        elif self.backend == Backends.network:
            self.__dev.stop_tcp_server()
            self.__dev.stop_sending_thread()
            self.emit_stopped_signal()
        elif self.backend == Backends.none:
            pass
        else:
            logger.error("Stop device: Unsupported backend " +
                         str(self.backend))

    def stop_on_error(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            self.read_messages()  # Clear errors
            self.__dev.stop_rx_mode("Stop on error")
            self.__dev.stop_tx_mode("Stop on error")
            self.emit_stopped_signal()
        else:
            raise ValueError("Unsupported Backend")

    def cleanup(self):
        if self.backend == Backends.grc:
            if self.mode == Mode.send:
                self.__dev.socket.close()
                time.sleep(0.1)
            self.__dev.quit()
            self.data = None

        elif self.backend == Backends.native:
            self.data = None

        elif self.backend == Backends.none:
            pass

        else:
            raise ValueError("Unsupported Backend")

    def emit_stopped_signal(self):
        self.stopped.emit()

    def emit_started_signal(self):
        self.started.emit()

    def emit_sender_needs_restart(self):
        self.sender_needs_restart.emit()

    def read_messages(self) -> str:
        """
        returns a string of new device messages separated by newlines

        :return:
        """
        if self.backend == Backends.grc:
            errors = self.__dev.read_errors()

            if "FATAL: " in errors:
                self.fatal_error_occurred.emit(
                    errors[errors.index("FATAL: "):])

            return errors
        elif self.backend == Backends.native:
            messages = "\n".join(self.__dev.device_messages)
            self.__dev.device_messages.clear()

            if messages and not messages.endswith("\n"):
                messages += "\n"

            if "successfully started" in messages:
                self.ready_for_action.emit()
            elif "failed to start" in messages:
                self.fatal_error_occurred.emit(
                    messages[messages.index("failed to start"):])

            return messages
        elif self.backend == Backends.network:
            return ""
        else:
            raise ValueError("Unsupported Backend")

    def set_server_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.server_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")

    def set_client_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.client_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")

    def get_device_list(self):
        if hasattr(self.__dev, "get_device_list"):
            return self.__dev.get_device_list()
        else:
            return []

    def increase_gr_port(self):
        if self.backend == Backends.grc:
            self.__dev.gr_port += 1
            logger.info("Retry with port " + str(self.__dev.gr_port))
        else:
            raise ValueError("Only for GR backend")

    def emit_ready_for_action(self):
        """
        Notify observers that device is successfully initialized
        :return:
        """
        self.ready_for_action.emit()

    def emit_fatal_error_occurred(self, msg: str):
        self.fatal_error_occurred.emit(msg)
Esempio n. 2
0
class VirtualDevice(QObject):
    """
    Wrapper class for providing sending methods for grc and native devices

    """
    started = pyqtSignal()
    stopped = pyqtSignal()
    sender_needs_restart = pyqtSignal()

    fatal_error_occurred = pyqtSignal(str)
    ready_for_action = pyqtSignal()

    data_received = pyqtSignal(np.ndarray)  # for direct demodulation in sniffer

    continuous_send_msg = "Continuous send mode is not supported for GNU Radio backend. " \
                          "You can change the configured device backend in options."

    def __init__(self, backend_handler, name: str, mode: Mode, freq=None, sample_rate=None, bandwidth=None,
                 gain=None, if_gain=None, baseband_gain=None, samples_to_send=None,
                 device_ip=None, sending_repeats=1, parent=None, resume_on_full_receive_buffer=False, raw_mode=True,
                 portnumber=1234):
        super().__init__(parent)
        self.name = name
        self.mode = mode
        self.backend_handler = backend_handler

        freq = config.DEFAULT_FREQUENCY if freq is None else freq
        sample_rate = config.DEFAULT_SAMPLE_RATE if sample_rate is None else sample_rate
        bandwidth = config.DEFAULT_BANDWIDTH if bandwidth is None else bandwidth
        gain = config.DEFAULT_GAIN if gain is None else gain
        if_gain = config.DEFAULT_IF_GAIN if if_gain is None else if_gain
        baseband_gain = config.DEFAULT_BB_GAIN if baseband_gain is None else baseband_gain

        resume_on_full_receive_buffer = self.mode == Mode.spectrum or resume_on_full_receive_buffer

        if self.name == NetworkSDRInterfacePlugin.NETWORK_SDR_NAME:
            self.backend = Backends.network
        else:
            try:
                self.backend = self.backend_handler.device_backends[name.lower()].selected_backend
            except KeyError:
                logger.warning("Invalid device name: {0}".format(name))
                self.backend = Backends.none
                self.__dev = None
                return

        if self.backend == Backends.grc:
            if mode == Mode.receive:
                from urh.dev.gr.ReceiverThread import ReceiverThread
                self.__dev = ReceiverThread(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                            parent=parent, resume_on_full_receive_buffer=resume_on_full_receive_buffer)
            elif mode == Mode.send:
                from urh.dev.gr.SenderThread import SenderThread
                self.__dev = SenderThread(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                          parent=parent)
                self.__dev.data = samples_to_send
                self.__dev.samples_per_transmission = len(samples_to_send) if samples_to_send is not None else 2 ** 15
            elif mode == Mode.spectrum:
                from urh.dev.gr.SpectrumThread import SpectrumThread
                self.__dev = SpectrumThread(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                            parent=parent)
            else:
                raise ValueError("Unknown mode")
            self.__dev.device = name
            self.__dev.started.connect(self.emit_started_signal)
            self.__dev.stopped.connect(self.emit_stopped_signal)
            self.__dev.sender_needs_restart.connect(self.emit_sender_needs_restart)
        elif self.backend == Backends.native:
            name = self.name.lower()
            if name in map(str.lower, BackendHandler.DEVICE_NAMES):
                if name == "hackrf":
                    from urh.dev.native.HackRF import HackRF
                    self.__dev = HackRF(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                        resume_on_full_receive_buffer)
                elif name.replace("-", "") == "rtlsdr":
                    from urh.dev.native.RTLSDR import RTLSDR
                    self.__dev = RTLSDR(freq, gain, sample_rate, device_number=0,
                                        resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name.replace("-", "") == "rtltcp":
                    from urh.dev.native.RTLSDRTCP import RTLSDRTCP
                    self.__dev = RTLSDRTCP(freq, gain, sample_rate, bandwidth, device_number=0,
                                           resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name == "limesdr":
                    from urh.dev.native.LimeSDR import LimeSDR
                    self.__dev = LimeSDR(freq, gain, sample_rate, bandwidth, gain,
                                         resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name.startswith("airspy"):
                    from urh.dev.native.AirSpy import AirSpy
                    self.__dev = AirSpy(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                        resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name.startswith("usrp"):
                    from urh.dev.native.USRP import USRP
                    self.__dev = USRP(freq, gain, sample_rate, bandwidth, gain,
                                      resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name.startswith("sdrplay"):
                    from urh.dev.native.SDRPlay import SDRPlay
                    self.__dev = SDRPlay(freq, gain, bandwidth, gain, if_gain=if_gain,
                                         resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                elif name == "soundcard":
                    from urh.dev.native.SoundCard import SoundCard
                    self.__dev = SoundCard(sample_rate, resume_on_full_receive_buffer=resume_on_full_receive_buffer)
                else:
                    raise NotImplementedError("Native Backend for {0} not yet implemented".format(name))

            elif name == "test":
                # For Unittests Only
                self.__dev = Device(freq, sample_rate, bandwidth, gain, if_gain, baseband_gain,
                                    resume_on_full_receive_buffer)
            else:
                raise ValueError("Unknown device name {0}".format(name))
            self.__dev.portnumber = portnumber
            self.__dev.device_ip = device_ip
            if mode == Mode.send:
                self.__dev.init_send_parameters(samples_to_send, sending_repeats)
        elif self.backend == Backends.network:
            self.__dev = NetworkSDRInterfacePlugin(raw_mode=raw_mode,
                                                   resume_on_full_receive_buffer=resume_on_full_receive_buffer,
                                                   spectrum=self.mode == Mode.spectrum, sending=self.mode == Mode.send)
            self.__dev.send_connection_established.connect(self.emit_ready_for_action)
            self.__dev.receive_server_started.connect(self.emit_ready_for_action)
            self.__dev.error_occurred.connect(self.emit_fatal_error_occurred)
            self.__dev.samples_to_send = samples_to_send
        elif self.backend == Backends.none:
            self.__dev = None
        else:
            raise ValueError("Unsupported Backend")

        if hasattr(self.__dev, "data_received"):
            self.__dev.data_received.connect(self.data_received.emit)

        if mode == Mode.spectrum:
            self.__dev.is_in_spectrum_mode = True

    @property
    def has_multi_device_support(self):
        return hasattr(self.__dev, "has_multi_device_support") and self.__dev.has_multi_device_support

    @property
    def device_serial(self):
        if hasattr(self.__dev, "device_serial"):
            return self.__dev.device_serial
        else:
            return None

    @device_serial.setter
    def device_serial(self, value):
        if hasattr(self.__dev, "device_serial"):
            self.__dev.device_serial = value

    @property
    def device_number(self):
        if hasattr(self.__dev, "device_number"):
            return self.__dev.device_number
        else:
            return None

    @device_number.setter
    def device_number(self, value):
        if hasattr(self.__dev, "device_number"):
            self.__dev.device_number = value

    @property
    def bandwidth(self):
        return self.__dev.bandwidth

    @bandwidth.setter
    def bandwidth(self, value):
        self.__dev.bandwidth = value

    @property
    def bandwidth_is_adjustable(self):
        if self.backend == Backends.grc:
            return True
        elif self.backend == Backends.native:
            return self.__dev.bandwidth_is_adjustable
        elif self.backend == Backends.network:
            return True
        else:
            raise ValueError("Unsupported Backend")

    @property
    def frequency(self):
        if self.backend == Backends.grc:
            return self.__dev.freq
        elif self.backend == Backends.native:
            return self.__dev.frequency
        else:
            raise ValueError("Unsupported Backend")

    @frequency.setter
    def frequency(self, value):
        if self.backend == Backends.grc:
            self.__dev.freq = value
        elif self.backend == Backends.native:
            self.__dev.frequency = value
        elif self.backend == Backends.network:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def num_samples_to_send(self) -> int:
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.num_samples_to_send
        else:
            raise ValueError(self.continuous_send_msg)

    @num_samples_to_send.setter
    def num_samples_to_send(self, value: int):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.num_samples_to_send = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_send_continuous(self) -> bool:
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.sending_is_continuous
        else:
            raise ValueError(self.continuous_send_msg)

    @is_send_continuous.setter
    def is_send_continuous(self, value: bool):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.sending_is_continuous = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_raw_mode(self) -> bool:
        if self.backend == Backends.network:
            return self.__dev.raw_mode
        else:
            return True

    @property
    def continuous_send_ring_buffer(self):
        if self.backend in (Backends.native, Backends.network):
            return self.__dev.continuous_send_ring_buffer
        else:
            raise ValueError(self.continuous_send_msg)

    @continuous_send_ring_buffer.setter
    def continuous_send_ring_buffer(self, value):
        if self.backend in (Backends.native, Backends.network):
            self.__dev.continuous_send_ring_buffer = value
        else:
            raise ValueError(self.continuous_send_msg)

    @property
    def is_in_spectrum_mode(self):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            return self.__dev.is_in_spectrum_mode
        else:
            raise ValueError("Unsupported Backend")

    @is_in_spectrum_mode.setter
    def is_in_spectrum_mode(self, value: bool):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            self.__dev.is_in_spectrum_mode = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def gain(self):
        return self.__dev.gain

    @gain.setter
    def gain(self, value):
        try:
            self.__dev.gain = value
        except AttributeError as e:
            logger.warning(str(e))

    @property
    def if_gain(self):
        try:
            return self.__dev.if_gain
        except AttributeError as e:
            logger.warning(str(e))

    @if_gain.setter
    def if_gain(self, value):
        try:
            self.__dev.if_gain = value
        except AttributeError as e:
            logger.warning(str(e))

    @property
    def baseband_gain(self):
        return self.__dev.baseband_gain

    @baseband_gain.setter
    def baseband_gain(self, value):
        self.__dev.baseband_gain = value

    @property
    def sample_rate(self):
        return self.__dev.sample_rate

    @sample_rate.setter
    def sample_rate(self, value):
        self.__dev.sample_rate = value

    @property
    def channel_index(self) -> int:
        return self.__dev.channel_index

    @channel_index.setter
    def channel_index(self, value: int):
        self.__dev.channel_index = value

    @property
    def antenna_index(self) -> int:
        return self.__dev.antenna_index

    @antenna_index.setter
    def antenna_index(self, value: int):
        self.__dev.antenna_index = value

    @property
    def freq_correction(self):
        return self.__dev.freq_correction

    @freq_correction.setter
    def freq_correction(self, value):
        self.__dev.freq_correction = value

    @property
    def direct_sampling_mode(self) -> int:
        return self.__dev.direct_sampling_mode

    @direct_sampling_mode.setter
    def direct_sampling_mode(self, value):
        self.__dev.direct_sampling_mode = value

    @property
    def emit_data_received_signal(self):
        return self.__dev.emit_data_received_signal

    @emit_data_received_signal.setter
    def emit_data_received_signal(self, value):
        self.__dev.emit_data_received_signal = value

    @property
    def samples_to_send(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.samples_to_send
        else:
            raise ValueError("Unsupported Backend")

    @samples_to_send.setter
    def samples_to_send(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            self.__dev.init_send_parameters(value, self.num_sending_repeats)
        elif self.backend == Backends.network:
            self.__dev.samples_to_send = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def ip(self):
        if self.backend == Backends.grc:
            return self.__dev.device_ip
        elif self.backend == Backends.native:
            return self.__dev.device_ip
        else:
            raise ValueError("Unsupported Backend")

    @ip.setter
    def ip(self, value):
        if self.backend == Backends.grc:
            self.__dev.device_ip = value
        elif self.backend == Backends.native:
            self.__dev.device_ip = value
        elif self.backend in (Backends.none, Backends.network):
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def port(self):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            return self.__dev.port
        else:
            raise ValueError("Unsupported Backend")

    @port.setter
    def port(self, value):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            self.__dev.port = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def data(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.samples_to_send
            else:
                return self.__dev.receive_buffer
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                raise NotImplementedError("Todo")
            else:
                if self.__dev.raw_mode:
                    return self.__dev.receive_buffer
                else:
                    return self.__dev.received_bits
        else:
            raise ValueError("Unsupported Backend")

    @data.setter
    def data(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.samples_to_send = value
            else:
                self.__dev.receive_buffer = value
        else:
            logger.warning("{}:{} has no data".format(self.__class__.__name__, self.backend.name))

    def free_data(self):
        if self.backend == Backends.grc:
            self.__dev.data = None
        elif self.backend == Backends.native:
            self.__dev.samples_to_send = None
            self.__dev.receive_buffer = None
        elif self.backend == Backends.network:
            self.__dev.free_data()
        elif self.backend == Backends.none:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def resume_on_full_receive_buffer(self) -> bool:
        return self.__dev.resume_on_full_receive_buffer

    @resume_on_full_receive_buffer.setter
    def resume_on_full_receive_buffer(self, value: bool):
        if value != self.__dev.resume_on_full_receive_buffer:
            self.__dev.resume_on_full_receive_buffer = value
            if self.backend == Backends.native:
                self.__dev.receive_buffer = None
            elif self.backend == Backends.grc:
                self.__dev.data = None

    @property
    def num_sending_repeats(self):
        return self.__dev.sending_repeats

    @num_sending_repeats.setter
    def num_sending_repeats(self, value):
        self.__dev.sending_repeats = value

    @property
    def current_index(self):
        if self.backend == Backends.grc:
            return self.__dev.current_index
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_recv_index
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_receive_index
        else:
            raise ValueError("Unsupported Backend")

    @current_index.setter
    def current_index(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_index = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_recv_index = value
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_receive_index = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def current_iteration(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.current_sending_repeat
        else:
            raise ValueError("Unsupported Backend")

    @current_iteration.setter
    def current_iteration(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_iteration = value
        elif self.backend in (Backends.native, Backends.network):
            self.__dev.current_sending_repeat = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def sending_finished(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration is None
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.sending_finished
        else:
            raise ValueError("Unsupported Backend")

    @property
    def spectrum(self):
        if self.mode == Mode.spectrum:
            if self.backend == Backends.grc:
                return self.__dev.x, self.__dev.y
            elif self.backend == Backends.native or self.backend == Backends.network:
                w = np.abs(np.fft.fft(self.__dev.receive_buffer))
                freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
                idx = np.argsort(freqs)
                return freqs[idx].astype(np.float32), w[idx].astype(np.float32)
        else:
            raise ValueError("Spectrum x only available in spectrum mode")

    def start(self):
        if self.backend == Backends.grc:
            self.__dev.setTerminationEnabled(True)
            self.__dev.terminate()
            time.sleep(0.1)
            self.__dev.start()  # Already connected to started signal in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.start_tx_mode(resume=True)
            else:
                self.__dev.start_rx_mode()

            self.emit_started_signal()
        elif self.backend == Backends.network:
            if self.mode == Mode.receive or self.mode == Mode.spectrum:
                self.__dev.start_tcp_server_for_receiving()
            else:
                self.__dev.start_raw_sending_thread()

            self.emit_started_signal()
        else:
            raise ValueError("Unsupported Backend")

    def stop(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.stop_tx_mode(msg)
            else:
                self.__dev.stop_rx_mode(msg)
            self.emit_stopped_signal()
        elif self.backend == Backends.network:
            self.__dev.stop_tcp_server()
            self.__dev.stop_sending_thread()
            self.emit_stopped_signal()
        elif self.backend == Backends.none:
            pass
        else:
            logger.error("Stop device: Unsupported backend " + str(self.backend))

    def stop_on_error(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            self.read_messages()  # Clear errors
            self.__dev.stop_rx_mode("Stop on error")
            self.__dev.stop_tx_mode("Stop on error")
            self.emit_stopped_signal()
        else:
            raise ValueError("Unsupported Backend")

    def cleanup(self):
        if self.backend == Backends.grc:
            if self.mode == Mode.send:
                self.__dev.socket.close()
                time.sleep(0.1)
            self.__dev.quit()
            self.data = None

        elif self.backend == Backends.native:
            self.data = None

        elif self.backend == Backends.none:
            pass

        else:
            raise ValueError("Unsupported Backend")

    def emit_stopped_signal(self):
        self.stopped.emit()

    def emit_started_signal(self):
        self.started.emit()

    def emit_sender_needs_restart(self):
        self.sender_needs_restart.emit()

    def read_messages(self) -> str:
        """
        returns a string of new device messages separated by newlines

        :return:
        """
        if self.backend == Backends.grc:
            errors = self.__dev.read_errors()

            if "FATAL: " in errors:
                self.fatal_error_occurred.emit(errors[errors.index("FATAL: "):])

            return errors
        elif self.backend == Backends.native:
            messages = "\n".join(self.__dev.device_messages)
            self.__dev.device_messages.clear()

            if messages and not messages.endswith("\n"):
                messages += "\n"

            if "successfully started" in messages:
                self.ready_for_action.emit()
            elif "failed to start" in messages:
                self.fatal_error_occurred.emit(messages[messages.index("failed to start"):])

            return messages
        elif self.backend == Backends.network:
            return ""
        else:
            raise ValueError("Unsupported Backend")

    def set_server_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.server_port = port
        else:
            raise ValueError("Setting port only supported for NetworkSDR Plugin")

    def set_client_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.client_port = port
        else:
            raise ValueError("Setting port only supported for NetworkSDR Plugin")

    def get_device_list(self):
        if hasattr(self.__dev, "get_device_list"):
            return self.__dev.get_device_list()
        else:
            return []

    def increase_gr_port(self):
        if self.backend == Backends.grc:
            self.__dev.gr_port += 1
            logger.info("Retry with port " + str(self.__dev.gr_port))
        else:
            raise ValueError("Only for GR backend")

    def emit_ready_for_action(self):
        """
        Notify observers that device is successfully initialized
        :return:
        """
        self.ready_for_action.emit()

    def emit_fatal_error_occurred(self, msg: str):
        self.fatal_error_occurred.emit(msg)
Esempio n. 3
0
class VirtualDevice(QObject):
    """
    Wrapper class for providing sending methods for grc and native devices

    """
    started = pyqtSignal()
    stopped = pyqtSignal()
    index_changed = pyqtSignal(int, int)
    sender_needs_restart = pyqtSignal()

    def __init__(self,
                 backend_handler,
                 name: str,
                 mode: Mode,
                 bw,
                 freq,
                 gain,
                 samp_rate,
                 samples_to_send=None,
                 device_ip=None,
                 sending_repeats=1,
                 parent=None,
                 is_ringbuffer=False,
                 raw_mode=True,
                 portnumber=1234):
        super().__init__(parent)
        self.name = name
        self.mode = mode
        self.backend_handler = backend_handler

        if self.name == NetworkSDRInterfacePlugin.NETWORK_SDR_NAME:
            self.backend = Backends.network
        else:
            try:
                self.backend = self.backend_handler.device_backends[
                    name.lower()].selected_backend
            except KeyError:
                logger.warning("Invalid device name: {0}".format(name))
                self.backend = Backends.none
                self.__dev = None
                return

        if self.backend == Backends.grc:
            if mode == Mode.receive:
                self.__dev = ReceiverThread(samp_rate,
                                            freq,
                                            gain,
                                            bw,
                                            parent=parent,
                                            is_ringbuffer=is_ringbuffer)
                self.__dev.index_changed.connect(self.emit_index_changed)
            elif mode == Mode.send:
                self.__dev = SenderThread(samp_rate,
                                          freq,
                                          gain,
                                          bw,
                                          parent=parent)
                self.__dev.data = samples_to_send
                self.__dev.samples_per_transmission = len(samples_to_send)
            elif mode == Mode.spectrum:
                self.__dev = SpectrumThread(samp_rate,
                                            freq,
                                            gain,
                                            bw,
                                            parent=parent)
            else:
                raise ValueError("Unknown mode")
            self.__dev.usrp_ip = device_ip
            self.__dev.device = name
            self.__dev.started.connect(self.emit_started_signal)
            self.__dev.stopped.connect(self.emit_stopped_signal)
            self.__dev.sender_needs_restart.connect(
                self.emit_sender_needs_restart)
        elif self.backend == Backends.native:
            name = self.name.lower()
            if name in map(str.lower, BackendHandler.DEVICE_NAMES):
                is_ringbuffer = self.mode == Mode.spectrum or is_ringbuffer

                if name == "hackrf":
                    from urh.dev.native.HackRF import HackRF
                    self.__dev = HackRF(bw,
                                        freq,
                                        gain,
                                        samp_rate,
                                        is_ringbuffer=is_ringbuffer)
                elif name.replace("-", "") == "rtlsdr":
                    from urh.dev.native.RTLSDR import RTLSDR
                    self.__dev = RTLSDR(freq,
                                        gain,
                                        samp_rate,
                                        device_number=0,
                                        is_ringbuffer=is_ringbuffer)
                elif name.replace("-", "") == "rtltcp":
                    from urh.dev.native.RTLSDRTCP import RTLSDRTCP
                    self.__dev = RTLSDRTCP(freq,
                                           gain,
                                           samp_rate,
                                           device_number=0,
                                           is_ringbuffer=is_ringbuffer)
                else:
                    raise NotImplementedError(
                        "Native Backend for {0} not yet implemented".format(
                            name))
            else:
                raise ValueError("Unknown device name {0}".format(name))
            self.__dev.portnumber = portnumber
            self.__dev.device_ip = device_ip
            self.__dev.rcv_index_changed.connect(self.emit_index_changed)
            if mode == Mode.send:
                self.__dev.init_send_parameters(samples_to_send,
                                                sending_repeats,
                                                skip_device_parameters=True)
        elif self.backend == Backends.network:
            self.__dev = NetworkSDRInterfacePlugin(raw_mode=raw_mode)
            self.__dev.rcv_index_changed.connect(self.emit_index_changed)
            self.__dev.samples_to_send = samples_to_send
        elif self.backend == Backends.none:
            self.__dev = None
        else:
            raise ValueError("Unsupported Backend")

    @property
    def bandwidth(self):
        return self.__dev.bandwidth

    @bandwidth.setter
    def bandwidth(self, value):
        self.__dev.bandwidth = value

    @property
    def bandwidth_is_adjustable(self):
        if self.backend == Backends.grc:
            return True
        elif self.backend == Backends.native:
            return self.__dev.bandwidth_is_adjustable
        elif self.backend == Backends.network:
            return True
        else:
            raise ValueError("Unsupported Backend")

    @property
    def frequency(self):
        if self.backend == Backends.grc:
            return self.__dev.freq
        elif self.backend == Backends.native:
            return self.__dev.frequency
        else:
            raise ValueError("Unsupported Backend")

    @frequency.setter
    def frequency(self, value):
        if self.backend == Backends.grc:
            self.__dev.freq = value
        elif self.backend == Backends.native:
            self.__dev.frequency = value
        elif self.backend == Backends.network:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def gain(self):
        return self.__dev.gain

    @gain.setter
    def gain(self, value):
        self.__dev.gain = value

    @property
    def sample_rate(self):
        return self.__dev.sample_rate

    @sample_rate.setter
    def sample_rate(self, value):
        self.__dev.sample_rate = value

    @property
    def samples_to_send(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.samples_to_send
        else:
            raise ValueError("Unsupported Backend")

    @samples_to_send.setter
    def samples_to_send(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            self.__dev.init_send_parameters(value,
                                            self.num_sending_repeats,
                                            skip_device_parameters=True)
        elif self.backend == Backends.network:
            self.__dev.samples_to_send = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def ip(self):
        if self.backend == Backends.grc:
            return self.__dev.usrp_ip
        elif self.backend == Backends.native:
            return self.__dev.device_ip
        else:
            raise ValueError("Unsupported Backend")

    @ip.setter
    def ip(self, value):
        if self.backend == Backends.grc:
            self.__dev.usrp_ip = value
        elif self.backend == Backends.native:
            self.__dev.device_ip = value
        elif self.backend in (Backends.none, Backends.network):
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def port(self):
        if self.backend in (Backends.grc, Backends.native):
            return self.__dev.port
        else:
            raise ValueError(
                "Port only for gnuradio socket (grc backend) and native backend"
            )

    @port.setter
    def port(self, value):
        if self.backend in (Backends.grc, Backends.native):
            self.__dev.port = value
        else:
            raise ValueError(
                "Port only for gnuradio socket (grc backend) and native backend"
            )

    @property
    def data(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.samples_to_send
            else:
                return self.__dev.receive_buffer
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                raise NotImplementedError("Todo")
            else:
                if self.__dev.raw_mode:
                    return self.__dev.receive_buffer
                else:
                    return self.__dev.received_bits
        else:
            raise ValueError("Unsupported Backend")

    @data.setter
    def data(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.samples_to_send = value
            else:
                self.__dev.receive_buffer = value
        else:
            raise ValueError("Unsupported Backend")

    def free_data(self):
        if self.backend == Backends.grc:
            del self.__dev.data
        elif self.backend == Backends.native:
            del self.__dev.samples_to_send
            del self.__dev.receive_buffer
        elif self.backend == Backends.network:
            self.__dev.free_data()
        elif self.backend == Backends.none:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def num_sending_repeats(self):
        if self.mode == Mode.send:
            if self.backend == Backends.grc:
                return self.__dev.max_repeats
            elif self.backend == Backends.native:
                return self.__dev.sending_repeats
            else:
                raise ValueError("Unsupported Backend")

    @num_sending_repeats.setter
    def num_sending_repeats(self, value):
        if self.mode == Mode.send:
            if self.backend == Backends.grc:
                if value != self.__dev.max_repeats:
                    self.__dev.max_repeats = value
                    self.__dev.current_iteration = 0
            elif self.backend in (Backends.native, Backends.network):
                self.__dev.sending_repeats = value
            else:
                raise ValueError("Unsupported Backend")

    @property
    def current_index(self):
        if self.backend == Backends.grc:
            return self.__dev.current_index
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_recv_index
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_receive_index
        else:
            raise ValueError("Unsupported Backend")

    @current_index.setter
    def current_index(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_index = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_recv_index = value
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_receive_index = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def current_iteration(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.current_sending_repeat
        else:
            raise ValueError("Unsupported Backend")

    @current_iteration.setter
    def current_iteration(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_iteration = value
        elif self.backend in (Backends.native, Backends.network):
            self.__dev.current_sending_repeat = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def sending_finished(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration is None
        elif self.backend == Backends.native:
            return self.__dev.sending_finished
        elif self.backend == Backends.network:
            return self.__dev.current_sent_sample == len(self.samples_to_send)
        else:
            raise ValueError("Unsupported Backend")

    @property
    def spectrum(self):
        if self.mode == Mode.spectrum:
            if self.backend == Backends.grc:
                return self.__dev.x, self.__dev.y
            elif self.backend == Backends.native:
                w = np.abs(np.fft.fft(self.__dev.receive_buffer))
                freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
                idx = np.argsort(freqs)
                return freqs[idx].astype(np.float32), w[idx].astype(np.float32)
        else:
            raise ValueError("Spectrum x only available in spectrum mode")

    def start(self):
        if self.backend == Backends.grc:
            self.__dev.setTerminationEnabled(True)
            self.__dev.terminate()
            time.sleep(0.1)
            self.__dev.start(
            )  # Already connected to started signal in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.start_tx_mode(resume=True)
            else:
                self.__dev.start_rx_mode()

            self.emit_started_signal()
        elif self.backend == Backends.network:
            if self.mode == Mode.receive:
                self.__dev.start_tcp_server_for_receiving()
            else:
                self.__dev.start_raw_sending_thread()

            self.emit_started_signal()
        else:
            raise ValueError("Unsupported Backend")

    def stop(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.stop_tx_mode(msg)
            else:
                self.__dev.stop_rx_mode(msg)
            self.emit_stopped_signal()
        elif self.backend == Backends.network:
            self.__dev.stop_tcp_server()
            self.emit_stopped_signal()
        elif self.backend == Backends.none:
            pass
        else:
            logger.error("Stop device: Unsupported backend " +
                         str(self.backend))

    def stop_on_error(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            self.read_errors()  # Clear errors
            self.__dev.stop_rx_mode("Stop on error")
            self.__dev.stop_tx_mode("Stop on error")
            self.emit_stopped_signal()
        else:
            raise ValueError("Unsupported Backend")

    def cleanup(self):
        if self.backend == Backends.grc:
            if self.mode == Mode.send:
                self.__dev.socket.close()
                time.sleep(0.1)
            self.__dev.quit()
            self.data = None

        elif self.backend == Backends.native:
            self.data = None

        elif self.backend == Backends.none:
            pass

        else:
            raise ValueError("Unsupported Backend")

    def emit_stopped_signal(self):
        self.stopped.emit()

    def emit_started_signal(self):
        self.started.emit()

    def emit_sender_needs_restart(self):
        self.sender_needs_restart.emit()

    def emit_index_changed(self, old, new):
        self.index_changed.emit(old, new)

    def read_errors(self):
        if self.backend == Backends.grc:
            return self.__dev.read_errors()
        elif self.backend == Backends.native:
            errors = "\n\n".join(self.__dev.errors)
            self.__dev.errors.clear()
            return errors
        elif self.backend == Backends.network:
            return ""
        else:
            raise ValueError("Unsupported Backend")

    def set_server_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.server_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")

    def set_client_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.client_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")
Esempio n. 4
0
class VirtualDevice(QObject):
    """
    Wrapper class for providing sending methods for grc and native devices

    """
    started = pyqtSignal()
    stopped = pyqtSignal()
    index_changed = pyqtSignal(int, int)
    sender_needs_restart = pyqtSignal()

    def __init__(self,
                 backend_handler,
                 name: str,
                 mode: Mode,
                 freq=None,
                 sample_rate=None,
                 bandwidth=None,
                 gain=None,
                 if_gain=None,
                 baseband_gain=None,
                 samples_to_send=None,
                 device_ip=None,
                 sending_repeats=1,
                 parent=None,
                 is_ringbuffer=False,
                 raw_mode=True,
                 portnumber=1234):
        super().__init__(parent)
        self.name = name
        self.mode = mode
        self.backend_handler = backend_handler

        freq = config.DEFAULT_FREQUENCY if freq is None else freq
        sample_rate = config.DEFAULT_SAMPLE_RATE if sample_rate is None else sample_rate
        bandwidth = config.DEFAULT_BANDWIDTH if bandwidth is None else bandwidth
        gain = config.DEFAULT_GAIN if gain is None else gain
        if_gain = config.DEFAULT_IF_GAIN if if_gain is None else if_gain
        baseband_gain = config.DEFAULT_BB_GAIN if baseband_gain is None else baseband_gain

        if self.name == NetworkSDRInterfacePlugin.NETWORK_SDR_NAME:
            self.backend = Backends.network
        else:
            try:
                self.backend = self.backend_handler.device_backends[
                    name.lower()].selected_backend
            except KeyError:
                logger.warning("Invalid device name: {0}".format(name))
                self.backend = Backends.none
                self.__dev = None
                return

        if self.backend == Backends.grc:
            if mode == Mode.receive:
                from urh.dev.gr.ReceiverThread import ReceiverThread
                self.__dev = ReceiverThread(freq,
                                            sample_rate,
                                            bandwidth,
                                            gain,
                                            if_gain,
                                            baseband_gain,
                                            parent=parent,
                                            is_ringbuffer=is_ringbuffer)
                self.__dev.index_changed.connect(self.emit_index_changed)
            elif mode == Mode.send:
                from urh.dev.gr.SenderThread import SenderThread
                self.__dev = SenderThread(freq,
                                          sample_rate,
                                          bandwidth,
                                          gain,
                                          if_gain,
                                          baseband_gain,
                                          parent=parent)
                self.__dev.data = samples_to_send
                self.__dev.samples_per_transmission = len(samples_to_send)
            elif mode == Mode.spectrum:
                from urh.dev.gr.SpectrumThread import SpectrumThread
                self.__dev = SpectrumThread(freq,
                                            sample_rate,
                                            bandwidth,
                                            gain,
                                            if_gain,
                                            baseband_gain,
                                            parent=parent)
            else:
                raise ValueError("Unknown mode")
            self.__dev.device = name
            self.__dev.started.connect(self.emit_started_signal)
            self.__dev.stopped.connect(self.emit_stopped_signal)
            self.__dev.sender_needs_restart.connect(
                self.emit_sender_needs_restart)
        elif self.backend == Backends.native:
            name = self.name.lower()
            if name in map(str.lower, BackendHandler.DEVICE_NAMES):
                is_ringbuffer = self.mode == Mode.spectrum or is_ringbuffer

                if name == "hackrf":
                    from urh.dev.native.HackRF import HackRF
                    self.__dev = HackRF(freq, sample_rate, bandwidth, gain,
                                        if_gain, baseband_gain, is_ringbuffer)
                elif name.replace("-", "") == "rtlsdr":
                    from urh.dev.native.RTLSDR import RTLSDR
                    self.__dev = RTLSDR(freq,
                                        gain,
                                        sample_rate,
                                        device_number=0,
                                        is_ringbuffer=is_ringbuffer)
                elif name.replace("-", "") == "rtltcp":
                    from urh.dev.native.RTLSDRTCP import RTLSDRTCP
                    self.__dev = RTLSDRTCP(freq,
                                           gain,
                                           sample_rate,
                                           bandwidth,
                                           device_number=0,
                                           is_ringbuffer=is_ringbuffer)
                elif name == "limesdr":
                    from urh.dev.native.LimeSDR import LimeSDR
                    self.__dev = LimeSDR(freq,
                                         gain,
                                         sample_rate,
                                         bandwidth,
                                         gain,
                                         is_ringbuffer=is_ringbuffer)
                elif name.startswith("airspy"):
                    from urh.dev.native.AirSpy import AirSpy
                    self.__dev = AirSpy(freq,
                                        sample_rate,
                                        bandwidth,
                                        gain,
                                        if_gain,
                                        baseband_gain,
                                        is_ringbuffer=is_ringbuffer)
                else:
                    raise NotImplementedError(
                        "Native Backend for {0} not yet implemented".format(
                            name))

            elif name == "test":
                # For Unittests Only
                self.__dev = Device(freq, sample_rate, bandwidth, gain,
                                    if_gain, baseband_gain, is_ringbuffer)
                self.__dev.BYTES_PER_SAMPLE = 4
            else:
                raise ValueError("Unknown device name {0}".format(name))
            self.__dev.portnumber = portnumber
            self.__dev.device_ip = device_ip
            self.__dev.rcv_index_changed.connect(self.emit_index_changed)
            if mode == Mode.send:
                self.__dev.init_send_parameters(samples_to_send,
                                                sending_repeats)
        elif self.backend == Backends.network:
            self.__dev = NetworkSDRInterfacePlugin(
                raw_mode=raw_mode, spectrum=self.mode == Mode.spectrum)
            self.__dev.rcv_index_changed.connect(self.emit_index_changed)
            self.__dev.samples_to_send = samples_to_send
        elif self.backend == Backends.none:
            self.__dev = None
        else:
            raise ValueError("Unsupported Backend")

    @property
    def bandwidth(self):
        return self.__dev.bandwidth

    @bandwidth.setter
    def bandwidth(self, value):
        self.__dev.bandwidth = value

    @property
    def bandwidth_is_adjustable(self):
        if self.backend == Backends.grc:
            return True
        elif self.backend == Backends.native:
            return self.__dev.bandwidth_is_adjustable
        elif self.backend == Backends.network:
            return True
        else:
            raise ValueError("Unsupported Backend")

    @property
    def frequency(self):
        if self.backend == Backends.grc:
            return self.__dev.freq
        elif self.backend == Backends.native:
            return self.__dev.frequency
        else:
            raise ValueError("Unsupported Backend")

    @frequency.setter
    def frequency(self, value):
        if self.backend == Backends.grc:
            self.__dev.freq = value
        elif self.backend == Backends.native:
            self.__dev.frequency = value
        elif self.backend == Backends.network:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def gain(self):
        return self.__dev.gain

    @gain.setter
    def gain(self, value):
        self.__dev.gain = value

    @property
    def if_gain(self):
        return self.__dev.if_gain

    @if_gain.setter
    def if_gain(self, value):
        self.__dev.if_gain = value

    @property
    def baseband_gain(self):
        return self.__dev.baseband_gain

    @baseband_gain.setter
    def baseband_gain(self, value):
        self.__dev.baseband_gain = value

    @property
    def sample_rate(self):
        return self.__dev.sample_rate

    @sample_rate.setter
    def sample_rate(self, value):
        self.__dev.sample_rate = value

    @property
    def channel_index(self) -> int:
        return self.__dev.channel_index

    @channel_index.setter
    def channel_index(self, value: int):
        self.__dev.channel_index = value

    @property
    def antenna_index(self) -> int:
        return self.__dev.antenna_index

    @antenna_index.setter
    def antenna_index(self, value: int):
        self.__dev.antenna_index = value

    @property
    def freq_correction(self):
        return self.__dev.freq_correction

    @freq_correction.setter
    def freq_correction(self, value):
        self.__dev.freq_correction = value

    @property
    def direct_sampling_mode(self) -> int:
        return self.__dev.direct_sampling_mode

    @direct_sampling_mode.setter
    def direct_sampling_mode(self, value):
        self.__dev.direct_sampling_mode = value

    @property
    def samples_to_send(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.samples_to_send
        else:
            raise ValueError("Unsupported Backend")

    @samples_to_send.setter
    def samples_to_send(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            self.__dev.init_send_parameters(value, self.num_sending_repeats)
        elif self.backend == Backends.network:
            self.__dev.samples_to_send = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def device_args(self):
        return self.__dev.device_args

    @device_args.setter
    def device_args(self, value):
        self.__dev.device_args = value

    @property
    def ip(self):
        if self.backend == Backends.grc:
            return self.__dev.device_ip
        elif self.backend == Backends.native:
            return self.__dev.device_ip
        else:
            raise ValueError("Unsupported Backend")

    @ip.setter
    def ip(self, value):
        if self.backend == Backends.grc:
            self.__dev.device_ip = value
        elif self.backend == Backends.native:
            self.__dev.device_ip = value
        elif self.backend in (Backends.none, Backends.network):
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def port(self):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            return self.__dev.port
        else:
            raise ValueError("Unsupported Backend")

    @port.setter
    def port(self, value):
        if self.backend in (Backends.grc, Backends.native, Backends.network):
            self.__dev.port = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def data(self):
        if self.backend == Backends.grc:
            return self.__dev.data
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.samples_to_send
            else:
                return self.__dev.receive_buffer
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                raise NotImplementedError("Todo")
            else:
                if self.__dev.raw_mode:
                    return self.__dev.receive_buffer
                else:
                    return self.__dev.received_bits
        else:
            raise ValueError("Unsupported Backend")

    @data.setter
    def data(self, value):
        if self.backend == Backends.grc:
            self.__dev.data = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.samples_to_send = value
            else:
                self.__dev.receive_buffer = value
        else:
            logger.warning("{}:{} has no data".format(self.__class__.__name__,
                                                      self.backend.name))

    def free_data(self):
        if self.backend == Backends.grc:
            self.__dev.data = None
        elif self.backend == Backends.native:
            self.__dev.samples_to_send = None
            self.__dev.receive_buffer = None
        elif self.backend == Backends.network:
            self.__dev.free_data()
        elif self.backend == Backends.none:
            pass
        else:
            raise ValueError("Unsupported Backend")

    @property
    def num_sending_repeats(self):
        if self.mode == Mode.send:
            if self.backend == Backends.grc:
                return self.__dev.max_repeats
            elif self.backend == Backends.native:
                return self.__dev.sending_repeats
            else:
                raise ValueError("Unsupported Backend")

    @num_sending_repeats.setter
    def num_sending_repeats(self, value):
        if self.mode == Mode.send:
            if self.backend == Backends.grc:
                if value != self.__dev.max_repeats:
                    self.__dev.max_repeats = value
                    self.__dev.current_iteration = 0
            elif self.backend in (Backends.native, Backends.network):
                self.__dev.sending_repeats = value
            else:
                raise ValueError("Unsupported Backend")

    @property
    def current_index(self):
        if self.backend == Backends.grc:
            return self.__dev.current_index
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_recv_index
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                return self.__dev.current_sent_sample
            else:
                return self.__dev.current_receive_index
        else:
            raise ValueError("Unsupported Backend")

    @current_index.setter
    def current_index(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_index = value
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_recv_index = value
        elif self.backend == Backends.network:
            if self.mode == Mode.send:
                self.__dev.current_sent_sample = value
            else:
                self.__dev.current_receive_index = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def current_iteration(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration
        elif self.backend in (Backends.native, Backends.network):
            return self.__dev.current_sending_repeat
        else:
            raise ValueError("Unsupported Backend")

    @current_iteration.setter
    def current_iteration(self, value):
        if self.backend == Backends.grc:
            self.__dev.current_iteration = value
        elif self.backend in (Backends.native, Backends.network):
            self.__dev.current_sending_repeat = value
        else:
            raise ValueError("Unsupported Backend")

    @property
    def sending_finished(self):
        if self.backend == Backends.grc:
            return self.__dev.current_iteration is None
        elif self.backend == Backends.native:
            return self.__dev.sending_finished
        elif self.backend == Backends.network:
            return self.__dev.current_sent_sample == len(self.samples_to_send)
        else:
            raise ValueError("Unsupported Backend")

    @property
    def spectrum(self):
        if self.mode == Mode.spectrum:
            if self.backend == Backends.grc:
                return self.__dev.x, self.__dev.y
            elif self.backend == Backends.native or self.backend == Backends.network:
                w = np.abs(np.fft.fft(self.__dev.receive_buffer))
                freqs = np.fft.fftfreq(len(w), 1 / self.sample_rate)
                idx = np.argsort(freqs)
                return freqs[idx].astype(np.float32), w[idx].astype(np.float32)
        else:
            raise ValueError("Spectrum x only available in spectrum mode")

    def start(self):
        if self.backend == Backends.grc:
            self.__dev.setTerminationEnabled(True)
            self.__dev.terminate()
            time.sleep(0.1)
            self.__dev.start(
            )  # Already connected to started signal in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.start_tx_mode(resume=True)
            else:
                self.__dev.start_rx_mode()

            self.emit_started_signal()
        elif self.backend == Backends.network:
            if self.mode == Mode.receive or self.mode == Mode.spectrum:
                self.__dev.start_tcp_server_for_receiving()
            else:
                self.__dev.start_raw_sending_thread()

            self.emit_started_signal()
        else:
            raise ValueError("Unsupported Backend")

    def stop(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            if self.mode == Mode.send:
                self.__dev.stop_tx_mode(msg)
            else:
                self.__dev.stop_rx_mode(msg)
            self.emit_stopped_signal()
        elif self.backend == Backends.network:
            self.__dev.stop_tcp_server()
            self.emit_stopped_signal()
        elif self.backend == Backends.none:
            pass
        else:
            logger.error("Stop device: Unsupported backend " +
                         str(self.backend))

    def stop_on_error(self, msg: str):
        if self.backend == Backends.grc:
            self.__dev.stop(msg)  # Already connected to stopped in constructor
        elif self.backend == Backends.native:
            self.read_messages()  # Clear errors
            self.__dev.stop_rx_mode("Stop on error")
            self.__dev.stop_tx_mode("Stop on error")
            self.emit_stopped_signal()
        else:
            raise ValueError("Unsupported Backend")

    def cleanup(self):
        if self.backend == Backends.grc:
            if self.mode == Mode.send:
                self.__dev.socket.close()
                time.sleep(0.1)
            self.__dev.quit()
            self.data = None

        elif self.backend == Backends.native:
            self.data = None

        elif self.backend == Backends.none:
            pass

        else:
            raise ValueError("Unsupported Backend")

    def emit_stopped_signal(self):
        self.stopped.emit()

    def emit_started_signal(self):
        self.started.emit()

    def emit_sender_needs_restart(self):
        self.sender_needs_restart.emit()

    def emit_index_changed(self, old, new):
        self.index_changed.emit(old, new)

    def read_messages(self):
        if self.backend == Backends.grc:
            return self.__dev.read_errors()
        elif self.backend == Backends.native:
            messages = "\n".join(self.__dev.device_messages)
            if messages and not messages.endswith("\n"):
                messages += "\n"
            self.__dev.device_messages.clear()
            return messages
        elif self.backend == Backends.network:
            return ""
        else:
            raise ValueError("Unsupported Backend")

    def set_server_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.server_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")

    def set_client_port(self, port: int):
        if self.backend == Backends.network:
            self.__dev.client_port = port
        else:
            raise ValueError(
                "Setting port only supported for NetworkSDR Plugin")

    def increase_gr_port(self):
        if self.backend == Backends.grc:
            self.__dev.gr_port += 1
            logger.info("Retry with port " + str(self.__dev.gr_port))
        else:
            raise ValueError("Only for GR backend")