f4exb / sdrangel

SDR Rx/Tx software for Airspy, Airspy HF+, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay and FunCube
GNU General Public License v3.0
2.84k stars 431 forks source link

BUG: Crash if missing Soapy device string #1441

Closed gvimlag closed 1 year ago

gvimlag commented 1 year ago

PROBLEM: SDRangel crashes if the user attempts to add a Soapy device which is missing a soapy device string.

This problem is similar to: "SoapySDR: RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server #731" https://github.com/f4exb/sdrangel/issues/731 This issue was automatically closed on Sep. 2, 2021 without resolution. Since it is closed, I'm unable to post there. Hence, I'm posting here.

EXAMPLE:

  rm -rf ~/.config/f4exb                      #start with clean configuration
  SoapySDRUtil --probe &> /dev/null           #make soapy device visible to SDRangel (avoids needing multiple restarts of SDRangel to see soapy device)
  /opt/install/sdrangel/bin/sdrangel --soapy  #start SDRangel with soapy
  Add Rx device                               #add remote soapy SDR device
    SoapySDR[1:0] remote: Generic RTL2832U OEM :: 00000001
    OK
  start/stop acquisition
  <SDRangel crashes>

CRASH TEXT:

  <click "start/stop acquisition" above>
2022-09-20 22:36:43.477 (D) SoapySDRInput::handleMessage: MsgStartStop:  start
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::initAcquisition
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::handleSynchronousMessages:  DSPAcquisitionInit
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::gotoIdle
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::gotoInit:   m_deviceDescription:  SoapySDRInput  sampleRate:  8000  centerFrequency:  435000000
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::gotoInit: initializing  SpectrumVis
2022-09-20 22:36:43.477 (D) DSPDeviceSourceEngine::startAcquisition
2022-09-20 22:36:43.478 (D) DSPDeviceSourceEngine::handleSynchronousMessages:  DSPAcquisitionStart
2022-09-20 22:36:43.478 (D) DSPDeviceSourceEngine::gotoRunning
2022-09-20 22:36:43.478 (D) DSPDeviceSourceEngine::gotoRunning:  SoapySDRInput  started
2022-09-20 22:36:43.478 (D) SoapySDRInput::start: allocate thread and take ownership
2022-09-20 22:36:43.478 (D) SoapySDRInputThread::SoapySDRInputThread
2022-09-20 22:36:43.478 (D) SoapySDRInput::start: (re)sart buddy thread
2022-09-20 22:36:43.479 (D) SoapySDRInput::start: started
2022-09-20 22:36:43.479 (D) DSPDeviceSourceEngine::gotoRunning: starting  SpectrumVis
2022-09-20 22:36:43.479 (D) DSPDeviceSourceEngine::gotoRunning:input message queue pending:  0
2022-09-20 22:36:43.480 (D) SoapySDRInputThread::run: format: CS16 fullScale: 65536.000000
[INFO] SoapyRemote::setupRxStream(remoteFormat=CS16, localFormat=CF32, scaleFactor=65536, mtu=1500, window=44040192)
[INFO] Client side stream bound to 192.168.1.229:54597
[INFO] Client side status bound to 192.168.1.229:38291
[INFO] Using format CS16.
[INFO] Server side stream bound to [::ffff:192.168.1.222]:36250
[INFO] Server side stream connected to [::ffff:192.168.1.229]:54597
[INFO] Server side status connected to [::ffff:192.168.1.229]:38291
[WARNING] StreamEndpoint resize socket buffer: set 43008 KiB, got 1024 KiB
[INFO] Configured sender endpoint: dgram=1452 bytes, 357 elements @ 4 bytes, window=1024 KiB
[INFO] Client side stream connected to 192.168.1.222:36250
[INFO] Configured receiver endpoint: dgram=1452 bytes, 357 elements @ 4 bytes, window=43008 KiB
2022-09-20 22:36:43.483 (D) SpectrumVis::handleMessage: DSPSignalNotification:  centerFrequency:  435000000  sampleRate:  8000
2022-09-20 22:36:43.483 (D) SoapySDRInputGui::handleInputMessages: message: DSPSignalNotification
2022-09-20 22:36:43.483 (D) SoapySDRInputGui::handleInputMessages: DSPSignalNotification: SampleRate:8000, CenterFrequency:435000000
2022-09-20 22:36:43.484 (D) GLSpectrumGUI::handleInputMessages: message: SpectrumVis::MsgStartStop
2022-09-20 22:36:43.484 (D) GLSpectrumGUI::handleInputMessages: message: GLSpectrum::MsgReportSampleRate
terminate called after throwing an instance of 'std::runtime_error'
  what():  RemoteError: RtAudio init error 'RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server.
Aborted

SOLUTION: Manually add an Args string for the remote Soapy device.

  SoapySDRUtil --probe &> /dev/null           #make soapy device visible to SDRangel (avoids needing multiple restarts of SDRangel to see soapy device)
  /opt/install/sdrangel/bin/sdrangel --soapy  #start SDRangel with soapy
  Preferences->Devices->User arguments...
    Select: "SoapySDR 1 SoapySDR[1:0] remote: Generic RTL2832U OEM :: 00000001"
    <down arrow> "Add the selected hardware to the list below"
    Select: "SoapySDR 1"
    Args: soapy=0,driver=remote,remote:driver=rtlsdr,serial=00000001
    OK
  Add Rx device                               #add remote soapy SDR device
    SoapySDR[1:0] remote: Generic RTL2832U OEM :: 00000001
    OK
  start/stop acquisition
  <SDRangel WORKS, no longer crashes>

RECOMMENDATIONS: Since this crash happens when accessing a commonly used hardware combination: RTL-SDR dongle and Raspberry Pi soapy server; I'd recommend adding a check to SDRangel for a device missing a soapy string. If a missing string is detected, then do the following:

  Solution-1: automatically generate and add the missing soapy string.
      or
  Solution-2: popup a warning and show an example of how the user can enter this missing string.
              Example popup:
                # WARNING #
        Missing Args string for Remote Soapy Device: "SoapySDR[1:0] remote: Generic RTL2832U OEM :: 00000001"
        Please add an Args string for your Remote Soapy Device.
        Example for RTL-SDR:
        1) Preferences->Devices->User arguments...
        2) Select: "SoapySDR 1 SoapySDR[1:0] remote: Generic RTL2832U OEM :: 00000001"
        3) <down arrow> "Add the selected hardware to the list below"
        4) Select: "SoapySDR 1"
        5) Args: soapy=0,driver=remote,remote:driver=rtlsdr,serial=00000001
        6) OK

SYSTEM:

  Hardware: x86 64-bit                             (Soapy Client)
  OS:       Debian 11 (bullseye) 64-bit            (Soapy Client)
  Hardware: Raspberry Pi 4B                        (Soapy Server)
  OS:       Raspberry Pi OS Lite (bullseye) 64-bit (Soapy Server)
  Dongle:   RTL-SDR connected to Raspberry Pi
  SDRangel: (compiled from source following "https://github.com/f4exb/sdrangel/wiki/Compile-from-source-in-Linux")
    Version 7.6.4-37-gc97a6a7af
    Build info: Qt 5.15.2 64 bits
    DSP Rx 16 bits    Tx 16 bits
      Included plugins for "Hardware dependencies":
        RTL-SDR
      Included plugins for "Soapy SDR":
        RTL-SDR
        Soapy Remote
f4exb commented 1 year ago

Firstly SoaupySDR should be considered as a last resort. You have many other options to get I/Q stream from a remote RTL-SDR device:

I have hesitated to remove SoapySDR support completely because of the many shortcomings of SoapySDR but finally resorted to making it optional (with the --soapy parameter) as effectively a last resort if nothing else would be available which I think should happen in very rare cases if any. In the particular case of Soapy Remote in its Wiki it pretends to support devices "transparently over the network" but immediately after "However, users will need to specify an additional device argument to engage the remote support module". Sorry guys this is not what I call "transparent" and we are in this case here. At most what you would need to specify is the remote server address (as with the Pluto in remote mode).

The log you posted seems to show that opening the device does not throw any exception nor returns nullptr for the device if anything went wrong. The "[INFO]" messages come from Soapy and could not be there if something wrong was detected at the opening. However presently the boolean returned from the opening device routine is not checked: https://github.com/f4exb/sdrangel/blob/master/plugins/samplesource/soapysdrinput/soapysdrinput.cpp#L50 this can be fixed resulting in the device refusing to start and not crashing but I doubt it will work.

In any case I will not apply what you suggest because firstly what happens if the remote device is not a RTL-SDR and then if the RTL-SDR serial is not 00000001. At best this deserves a note in the Wiki since you made the effort to check the right parameters to give to Soapy Remote.