Skip to content

Commit

Permalink
Multi device support (#432)
Browse files Browse the repository at this point in the history
* control device extensions with macros remove fallback logic

* wrap hackrf device list method

* add multi device support for hackrf

* fix argument order

* add multi dev support for rtlsdr

* add multi device support for lime sdr

* add multi device support for sdrplay

* multi device support for usrp
  • Loading branch information
jopohl authored May 3, 2018
1 parent a3c0a24 commit 7407c6b
Show file tree
Hide file tree
Showing 38 changed files with 3,238 additions and 8,962 deletions.
78 changes: 41 additions & 37 deletions data/ui/send_recv_device_settings.ui
Original file line number Diff line number Diff line change
Expand Up @@ -108,29 +108,6 @@ QGroupBox::indicator:checked {
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDeviceArgs">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If you only have one USRP connected you may leave this field empty, so your USRP gets detected automatically.&lt;/p&gt;&lt;p&gt;If you have multiple USRPs connected or need better control, enter a device identifier of your USRP here.&lt;/p&gt;&lt;p&gt;You may also enter other device arguments here.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="toolTipDuration">
<number>-1</number>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>Device arguments:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditDeviceArgs">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If you only have one USRP connected you may leave this field empty, so your USRP gets detected automatically.&lt;/p&gt;&lt;p&gt;If you have multiple USRPs connected or need better control, enter a device identifier of your USRP here.&lt;/p&gt;&lt;p&gt;You may also enter other device arguments here.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelChannel">
<property name="text">
Expand Down Expand Up @@ -225,6 +202,13 @@ QGroupBox::indicator:checked {
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="labelBandwidth">
<property name="text">
<string>Bandwidth (Hz):</string>
</property>
</widget>
</item>
<item row="7" column="2" rowspan="2">
<widget class="QToolButton" name="btnLockBWSR">
<property name="sizePolicy">
Expand Down Expand Up @@ -254,10 +238,13 @@ QGroupBox::indicator:checked {
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="labelBandwidth">
<item row="9" column="0">
<widget class="QLabel" name="labelGain">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The gain (more exactly RF gain) is the gain applied to the RF signal. This amplifies the high frequent signal arriving at the antenna of your Software Defined Radio.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Bandwidth (Hz):</string>
<string>Gain:</string>
</property>
</widget>
</item>
Expand All @@ -274,16 +261,6 @@ QGroupBox::indicator:checked {
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="labelGain">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The gain (more exactly RF gain) is the gain applied to the RF signal. This amplifies the high frequent signal arriving at the antenna of your Software Defined Radio.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Gain:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<layout class="QGridLayout" name="gridLayout_5">
<property name="sizeConstraint">
Expand Down Expand Up @@ -478,6 +455,34 @@ QGroupBox::indicator:checked {
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelDeviceIdentifier">
<property name="text">
<string>Device Identifier:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBoxDeviceIdentifier">
<property name="editable">
<bool>false</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="btnRefreshDeviceIdentifier">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset theme="view-refresh">
<normaloff>.</normaloff>.</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand All @@ -496,7 +501,6 @@ QGroupBox::indicator:checked {
<tabstops>
<tabstop>groupBoxDeviceSettings</tabstop>
<tabstop>cbDevice</tabstop>
<tabstop>lineEditDeviceArgs</tabstop>
<tabstop>comboBoxChannel</tabstop>
<tabstop>comboBoxAntenna</tabstop>
<tabstop>lineEditIP</tabstop>
Expand Down
3 changes: 1 addition & 2 deletions src/urh/controller/dialogs/ContinuousSendDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ def __init__(self, project_manager, messages, modulators, total_samples: int, pa
self.setWindowTitle("Send Signal (continuous mode)")
self.ui.lSamplesSentText.setText("Progress:")

self.init_device()

self.create_connects()
self.device_settings_widget.on_cb_device_current_index_changed()

def create_connects(self):
SendRecvDialog.create_connects(self)
Expand Down
14 changes: 6 additions & 8 deletions src/urh/controller/dialogs/ProtocolSniffDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,19 @@ def __init__(self, project_manager, signal=None, signals=None, parent=None, test
self.sniff_settings_widget.ui.btn_sniff_use_signal.setAutoDefault(False)

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

self.ui.txtEd_sniff_Preview.setFont(util.get_monospace_font())

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

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

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

self.ui.txtEd_sniff_Preview.setFont(util.get_monospace_font())

self.create_connects()

@property
def view_type(self) -> int:
Expand Down
12 changes: 3 additions & 9 deletions src/urh/controller/dialogs/ReceiveDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,13 @@ def __init__(self, project_manager, parent=None, testing_mode=False):
self.already_saved = True
self.recorded_files = []

# set really in on_device_started
self.scene_manager = None # type: LiveSceneManager

self.init_device()
self.device_settings_widget.set_bandwidth_status()

self.setWindowTitle("Record Signal")
self.setWindowIcon(QIcon.fromTheme("media-record"))

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

# set really in on_device_started
self.scene_manager = None # type: LiveSceneManager
self.create_connects()
self.device_settings_widget.on_cb_device_current_index_changed()

def create_connects(self):
super().create_connects()
Expand Down
6 changes: 1 addition & 5 deletions src/urh/controller/dialogs/SendDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ def __init__(self, project_manager, modulated_data, modulation_msg_indices=None,
self.graphics_view.set_signal(signal)
self.graphics_view.sample_rate = samp_rate

self.init_device()

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

self.create_connects()
self.device_settings_widget.on_cb_device_current_index_changed()

def create_connects(self):
super().create_connects()
Expand Down
7 changes: 6 additions & 1 deletion src/urh/controller/dialogs/SendRecvDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ def emit_editing_finished_signals(self):

@pyqtSlot()
def on_selected_device_changed(self):
self.scene_manager.plot_data = None
if hasattr(self.scene_manager, "plot_data"):
self.scene_manager.plot_data = None

self.init_device()

Expand All @@ -164,6 +165,8 @@ def on_device_stopped(self):
self.ui.btnStop.setEnabled(False)
self.ui.btnClear.setEnabled(True)
self.ui.btnSave.setEnabled(self.device.current_index > 0)
self.device_settings_widget.ui.comboBoxDeviceIdentifier.setEnabled(True)
self.device_settings_widget.ui.btnRefreshDeviceIdentifier.setEnabled(True)
self.device_settings_widget.set_bandwidth_status()

self.timer.stop()
Expand All @@ -179,6 +182,8 @@ def on_device_started(self):

self.ui.btnClear.setEnabled(False)
self.ui.btnStop.setEnabled(True)
self.device_settings_widget.ui.comboBoxDeviceIdentifier.setEnabled(False)
self.device_settings_widget.ui.btnRefreshDeviceIdentifier.setEnabled(False)

self.timer.start(self.update_interval)

Expand Down
8 changes: 3 additions & 5 deletions src/urh/controller/dialogs/SpectrumDialogController.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ def __init__(self, project_manager, parent=None, testing_mode=False):
self.ui.graphicsViewSpectrogram.setScene(QGraphicsScene())
self.__clear_spectrogram()

self.init_device()
self.device_settings_widget.set_bandwidth_status()

self.gain_timer = QTimer(self)
self.gain_timer.setSingleShot(True)

Expand All @@ -44,6 +41,7 @@ def __init__(self, project_manager, parent=None, testing_mode=False):
self.bb_gain_timer.setSingleShot(True)

self.create_connects()
self.device_settings_widget.on_cb_device_current_index_changed()

def __clear_spectrogram(self):
self.ui.graphicsViewSpectrogram.scene().clear()
Expand All @@ -65,7 +63,6 @@ def __update_spectrogram(self):
scene.setSceneRect(0, 0, Spectrogram.DEFAULT_FFT_WINDOW_SIZE, self.spectrogram_y_pos)
self.ui.graphicsViewSpectrogram.ensureVisible(pixmap_item)


def _eliminate_graphic_view(self):
super()._eliminate_graphic_view()
if self.ui.graphicsViewSpectrogram and self.ui.graphicsViewSpectrogram.scene() is not None:
Expand All @@ -81,7 +78,8 @@ def create_connects(self):
self.graphics_view.wheel_event_triggered.connect(self.on_graphics_view_wheel_event_triggered)

self.device_settings_widget.ui.sliderGain.valueChanged.connect(self.on_slider_gain_value_changed)
self.device_settings_widget.ui.sliderBasebandGain.valueChanged.connect(self.on_slider_baseband_gain_value_changed)
self.device_settings_widget.ui.sliderBasebandGain.valueChanged.connect(
self.on_slider_baseband_gain_value_changed)
self.device_settings_widget.ui.sliderIFGain.valueChanged.connect(self.on_slider_if_gain_value_changed)
self.device_settings_widget.ui.spinBoxFreq.editingFinished.connect(self.on_spinbox_frequency_editing_finished)

Expand Down
40 changes: 28 additions & 12 deletions src/urh/controller/widgets/DeviceSettingsWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler
self.ui = Ui_FormDeviceSettings()
self.ui.setupUi(self)

self.__device = None # type: VirtualDevice

self.is_tx = is_tx
self.is_rx = not is_tx
if backend_handler is None:
Expand All @@ -42,8 +44,6 @@ def __init__(self, project_manager: ProjectManager, is_tx: bool, backend_handler
self.ui.cbDevice.addItems(items)
self.bootstrap(project_manager.device_conf, enforce_default=True)

self.__device = None # type: VirtualDevice

self.ui.btnLockBWSR.setChecked(self.bw_sr_are_locked)
self.on_btn_lock_bw_sr_clicked()

Expand Down Expand Up @@ -134,19 +134,22 @@ def create_connects(self):
self.ui.spinBoxBandwidth.editingFinished.connect(self.on_spinbox_bandwidth_editing_finished)
self.ui.spinBoxPort.editingFinished.connect(self.on_spinbox_port_editing_finished)
self.ui.lineEditIP.editingFinished.connect(self.on_line_edit_ip_editing_finished)
self.ui.lineEditDeviceArgs.editingFinished.connect(self.on_line_edit_device_args_editing_finished)

self.ui.comboBoxAntenna.currentIndexChanged.connect(self.on_combobox_antenna_current_index_changed)
self.ui.comboBoxChannel.currentIndexChanged.connect(self.on_combobox_channel_current_index_changed)

self.ui.spinBoxFreqCorrection.editingFinished.connect(self.on_spinbox_freq_correction_editing_finished)
self.ui.comboBoxDirectSampling.currentIndexChanged.connect(self.on_combobox_direct_sampling_index_changed)

self.ui.cbDevice.currentIndexChanged.connect(self.cb_device_current_index_changed)
self.ui.cbDevice.currentIndexChanged.connect(self.on_cb_device_current_index_changed)

self.ui.spinBoxNRepeat.editingFinished.connect(self.on_num_repeats_changed)
self.ui.btnLockBWSR.clicked.connect(self.on_btn_lock_bw_sr_clicked)

self.ui.btnRefreshDeviceIdentifier.clicked.connect(self.on_btn_refresh_device_identifier_clicked)
self.ui.comboBoxDeviceIdentifier.currentIndexChanged.connect(self.on_combo_box_device_identifier_current_index_changed)


def set_gain_defaults(self):
self.set_default_rf_gain()
self.set_default_if_gain()
Expand Down Expand Up @@ -271,8 +274,10 @@ def set_device_ui_items_visibility(self, device_name: str, adjust_gains=True):
else:
combobox.setVisible(False)

self.ui.lineEditDeviceArgs.setVisible("device_args" in conf)
self.ui.labelDeviceArgs.setVisible("device_args" in conf)
multi_dev_support = hasattr(self.device, "has_multi_device_support") and self.device.has_multi_device_support
self.ui.labelDeviceIdentifier.setVisible(multi_dev_support)
self.ui.btnRefreshDeviceIdentifier.setVisible(multi_dev_support)
self.ui.comboBoxDeviceIdentifier.setVisible(multi_dev_support)
self.ui.lineEditIP.setVisible("ip" in conf)
self.ui.labelIP.setVisible("ip" in conf)
self.ui.spinBoxPort.setVisible("port" in conf)
Expand Down Expand Up @@ -320,7 +325,6 @@ def emit_editing_finished_signals(self):
self.ui.spinBoxFreqCorrection.editingFinished.emit()
self.ui.lineEditIP.editingFinished.emit()
self.ui.spinBoxPort.editingFinished.emit()
self.ui.lineEditDeviceArgs.editingFinished.emit()
self.ui.comboBoxAntenna.currentIndexChanged.emit(self.ui.comboBoxAntenna.currentIndex())
self.ui.comboBoxChannel.currentIndexChanged.emit(self.ui.comboBoxChannel.currentIndex())

Expand Down Expand Up @@ -372,10 +376,6 @@ def on_spinbox_bandwidth_editing_finished(self):
def on_line_edit_ip_editing_finished(self):
self.device.ip = self.ui.lineEditIP.text()

@pyqtSlot()
def on_line_edit_device_args_editing_finished(self):
self.device.device_args = self.ui.lineEditDeviceArgs.text()

@pyqtSlot()
def on_spinbox_port_editing_finished(self):
self.device.port = self.ui.spinBoxPort.value()
Expand Down Expand Up @@ -452,9 +452,11 @@ def on_spinbox_baseband_gain_value_changed(self, value: int):
pass

@pyqtSlot()
def cb_device_current_index_changed(self):
def on_cb_device_current_index_changed(self):
if self.device is not None:
self.device.free_data()

# Here init_device of dialogs gets called
self.selected_device_changed.emit()

dev_name = self.ui.cbDevice.currentText()
Expand All @@ -463,6 +465,20 @@ def cb_device_current_index_changed(self):
self.sync_gain_sliders()
self.set_bandwidth_status()

self.ui.comboBoxDeviceIdentifier.clear()

@pyqtSlot()
def on_btn_refresh_device_identifier_clicked(self):
if self.device is None:
return
self.ui.comboBoxDeviceIdentifier.clear()
self.ui.comboBoxDeviceIdentifier.addItems(self.device.get_device_list())

@pyqtSlot()
def on_combo_box_device_identifier_current_index_changed(self):
if self.device is not None:
self.device.device_serial = self.ui.comboBoxDeviceIdentifier.currentText()
self.device.device_number = self.ui.comboBoxDeviceIdentifier.currentIndex()

if __name__ == '__main__':
from PyQt5.QtWidgets import QApplication
Expand Down
5 changes: 1 addition & 4 deletions src/urh/dev/BackendHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,7 @@ def __lime_native_enabled(self) -> bool:
@property
def __rtlsdr_native_enabled(self) -> bool:
try:
try:
from urh.dev.native.lib import rtlsdr
except ImportError:
from urh.dev.native.lib import rtlsdr_fallback
from urh.dev.native.lib import rtlsdr
return True
except ImportError:
return False
Expand Down
Loading

0 comments on commit 7407c6b

Please sign in to comment.