Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement device filter and open by serial #23

Closed
guruofquality opened this issue Dec 28, 2020 · 75 comments
Closed

implement device filter and open by serial #23

guruofquality opened this issue Dec 28, 2020 · 75 comments

Comments

@guruofquality
Copy link
Collaborator

As part of standards compliance (just kidding). The find function and open should support the "serial" keyword, filtering on the keyword when specified in the hints, and even using it to open the device in the factory function. But most of the drivers actually support this so you can almost universally pass in a serial number in the args to uniquely specify a device and it should actually simplify the code a bit:

Here are a few notes:

SDRPlay v2 has a good example of this

Implementation changes

  • Dont parse the label string in Settings.cpp, just use the args["serial"] directly to match the device
  • In Registration.cpp, just add dev["serial"] = format(... SDRPLAY_MAX_SER_NO_LEN, rspDevs[i].SerNo)
  • And in Registration.cpp, skip the loop if dev["serial"] != args["serial"] when serial is present in the args

Other notes

  • dev["driver"] = "sdrplay"; is redundant, SoapySDR library will handle that
@fventuri
Copy link
Collaborator

Thanks Josh for the useful feedback.
I'll work on making those changes.

Franco

@fventuri
Copy link
Collaborator

@guruofquality - the reason for the convoluted (and ugly) code in Registration.cpp (and Setting.cpp) is because the RSPduo can have several 'modes of operation' (Single Tuner, Dual Tuner, Master, Slave) as described in the SDRplay API specification (https://www.sdrplay.com/docs/SDRplay_API_Specification_v3.06.pdf). The mode of the operation for the RSPduo must be known (i.e. chosen by the user) before the device is selected with the sdrplay_api_SelectDevice() API call, which happens in the constructor (https://github.com/pothosware/SoapySDRPlay3/blob/master/Settings.cpp#L180).

A while ago Andy (@SDRplay ), Vincent (@vsonnier ) and I had a long discussion about how to best handle these multiple RSPduo modes (see here: pothosware/SoapySDRPlay2#62 and here for a previous discussion: pothosware/SoapySDRPlay2#58), and the solution we adopted was to have multiple 'pseudo-devices' for the same RSPduo, one for each of the possible modes (for instance single tuner with tuner A, single tuner with tuner B, dual tuner, master with tuner A, master with tuner B, or just slave with the available tuner in case another application is running in master mode).
This approach gave us the benefit that at creation time we know which one of the various RSPduo configuration modes the user want to run, but has the drawback that the serial number alone is not enough to know how to the RSPduo should be configured, i.e. we do not have enough information with just the SN to be able to run the constructor.

Since you are more familiar than me on how other SoapySDR drivers work, perhaps you might have already encountered a similar scenario, and therefore know a better option that would still allow the user to choose among the various mode of operation that the RSPduo model offers.

Franco

@guruofquality
Copy link
Collaborator Author

Just for the sake of argument, I think pseudo-devices can be a good solution and its certainly nice for applications like cubicsdr or gqrx that give nice drop downs with the label. With pseudo-devices, I would still do everything the same with the serial number as discussed, but also add a keyword like "mode".

  • If the find function passed in a "mode" string, it would eliminate options that did not match the "mode"
  • And in the constructor, "mode" would be used to sdrplay_api_SelectDevice()
  • And of course if the user passed in a serial, you still get the desired behaviour of only selecting the SDRPlay of interest. Or lets say its an RTLSDR serial, you would eliminate SDRPlays from being discovered, which is one of the ways we can "play nice" with other drivers by supporting the "serial" convention

@fventuri
Copy link
Collaborator

@guruofquality - I just pushed the changes you suggested to the branch 'support_for_serial_keyword' (https://github.com/pothosware/SoapySDRPlay3/tree/support_for_serial_keyword).

I just ran a couple of quick tests here with the RSPduo; I was able to run CubicSDR in Single Tuner mode (and Dual Tuner mode), and two instances of CubicSDR at the same time, one in Master mode, and the other in Slave mode, so the basic functionality should work.

Franco

@guruofquality
Copy link
Collaborator Author

looks good

@fventuri
Copy link
Collaborator

Thanks @guruofquality for checking.
I found (and fixed) another problem with the variable outputSampleRate not being initialized, that was causing gqrx to crash at startup.
I pushed the code change to the support_for_serial_keyword branch a few minutes ago; give it a try again and let me know if you see any other problem.

@nmaster2042 - if you have some time, can you try running the code from this new branch support_for_serial_keyword with gqrx (and possibly CubicSDR) to make sure that everything works as expected?

Thanks,
Franco

@nmaster2042
Copy link

nmaster2042 commented Jan 1, 2021

Happy new year to you all.

@fventuri OK, I'm starting tests with the new support_for_serial_keyword branch.

I'll give results here ASAP.

@nmaster2042
Copy link

nmaster2042 commented Jan 2, 2021

Hi @fventuri

I made test with RSP2, gqrx 2.14.3, gr-osmosdr official and new support_for_serial_keyword branch.

I can't use RSP2, because I get an error, see below.

Gqrx Soapysdrplay1

I didn't get this with master branch you updated some days ago with string args.

Also tried with CubicSDR, no issue here.

EDIT: I tried changing sample rate, it doesn't accept any.

@fventuri
Copy link
Collaborator

fventuri commented Jan 2, 2021

Good catch @nmaster2042 - I had forgotten the initialization of the variable outputSampleRate for the non-RSPduo devices.
I just fixed that problem in the branch support_for_serial_keyword; please try again with the latest code, and let me know how it goes.

I'll also run some more tests here with switching RSPduo modes and tuners/antennas while the RSPduo is streaming to make sure the client application (CubicSDR or gqrx) does not hang, like it used to when I started working on this driver.

Franco

@nmaster2042
Copy link

Hi @fventuri I made tests on your new commit.

It's now working as expected with gqrx, cubic, and sdrplusplus, a new SDR software in Beta I'm testing right now.
On Gqrx, no more crash, we can see now serial number on selected device, for duo, the mode is now a string.
String args still working like the last update you made on mater branch in gqrx.

So it seems to work fine.

Thank you for the great work.

@fventuri
Copy link
Collaborator

fventuri commented Jan 3, 2021

Thanks for your very extensive tests @nmaster2042

Yesterday afternoon/evening I played around a bit with CubicSDR and the RSPduo, and I noticed that trying to change the RSPduo mode from say Single Tuner to Master while it is streaming causes an exception to be thrown.

I also noticed that the code for the cached results for claimed handles (that I copied almost exactly from the SoapySDRPlay2 driver) does not to seem to work correctly for the different RSPduo modes; according to the change log for the SoapySDRPlay2 driver release 0.3.0 (https://github.com/pothosware/SoapySDRPlay2/blob/master/Changelog.txt#L5), this change should make things work with SoapySDR server, so I suspect more tests are needed with SoapySDR server, to make it work as it should with the RSPduo.

Franco

@nmaster2042
Copy link

OK @fventuri.

Until now, I mainly made tests with devices attached to my computer, except for RSP DX that is used remotely with a SoapySDRServer.

I will swap RSP Duo and Dx, to try duo modes remotely.

With Gqrx, I have issues with SoapySDRServer, crash for example when I change demodulator.
I'll chaek with a non RSP device to see if it's a gqrx issue.

With gqrx, it's always more complex to detect the layer causing issues (gqrx, gr-osmosdr, soapy).

I'll post results here ASAP.

@nmaster2042
Copy link

nmaster2042 commented Jan 4, 2021

@fventuri , here is my test results with RSP Duo on SoapySDRServer, for now only single tuner mode.

Single tuner mode seemed to work initially.

Cubic Rdp duo single tuner 1

Start Cubic, select device, start streaming.

Cubic Rdp duo single tuner 2

Then I stopped streaming, refresh device list and select RSP duo single tuner mode, same antenna (Tuner 2) and Bias T.

Cubic Rdp duo single tuner 3

And start streaming again.

Here it seems Tuner 2 is not selected. I had to select Tuner 1 then Tuner 2 to get back to what I listened before.

Cubic Rdp duo single tuner 4

Other issue, Cubic on RSP duo, single tuner mode, I started a second instance of Cubic, to check what will happen in my device list.

Cubic Rdp duo single tuner 5

And I see I have RSP Duo - Single Tuner, I can't get option settings on the right of the window.
I think as I'm runing a first instance in single tuner mode I shouldn't see the RSP Duo in the second Cubic, right ?

I'll continue with other modes.

@nmaster2042
Copy link

nmaster2042 commented Jan 4, 2021

Second test set with RSP duo on SoapySDRServer, Dual Tuner mode.

I don't know really what this mode can be used for (diversity ?).

In First instance of Cubic, selecting RSP duo - Dual Tuner mode and start streaming is OK.

On the second instance of Cubic, like in Single Tuner mode:

Cubic Rdp duo dual tuner

If dual tuner mode is already used, I think it shouldn't be displayed in the device list.

@nmaster2042
Copy link

Now this is the test set for master mode on RSP duo, SoapySDRServer, Cubic SDR.

First, Start of Cubic, select the remote RSP duo - Master, set Tuner 2 + Bias T.

Cubic Rsp duo master mode 1

Then Start Streaming, all is fine.

Cubic Rsp duo master mode 2

Stop stream, open device list, refresh device list, keep same setup (Tuner 2 + Bias T).

Cubic Rsp duo master mode 3

Seems like not the right tuner selected. At this stage I need to close and restart Cubic to get things working as espected.

Cubic Rsp duo master mode 4

Test set for slave mode coming.

@nmaster2042
Copy link

Last test set, Slave mode RSP duo on SoapySDRServer while a Cubic instance is using RSP duo Master mode, Tuner 2 + Bias T.

Start of the second instance of cubic, I get 2 Rsp duo - Slave avaliable

Cubic Rsp duo slave mode 1

On the 2 device I cat see options.

Cubic Rsp duo slave mode 2

Choosing the first one and start streaming, OK.

Cubic Rsp duo slave mode 3

Stop streaming, go to device list, refresh, I get now only one slave device.

Cubic Rsp duo slave mode 4

Start stream again, and it works, master continues to stream on first cubic instance.

Now on the first instance of cubic (master) I stop streaming, slave continues to stream on second instance.

In first instance stopped master, I go to device list, refresh, I get a slave device only.

Cubic Rsp duo slave mode 5

But can't sekect and start because Cubic crashes.

Cubic Rsp duo slave mode 6

Something failed, see SoapySDRServer log screen below:

Cubic Rsp duo slave mode 7

The second instance of cubic (slave) freeze too:

Cubic Rsp duo slave mode 8

I had to kill this instance of cubic by myself.

Cubic Rsp duo slave mode 9

I hope this will help you do identify what is to be modified in the driver.

@fventuri
Copy link
Collaborator

fventuri commented Jan 5, 2021

Thanks for all your extensive tests and screenshots @nmaster2042 !

Tonight I just looked at one of the problems you found with SoapySDRServer - namely the fact that if you run two instances of CubicSDR, and the first one is say in Single Tuner mode, the second instance too sees the RSPduo in Single Tuner mode (going through SoapySDRServer, of course).

At first I thought too it was wrong that the second instance of CubicSDR would also see the RSPduo, then I found out this issue pothosware/SoapySDRPlay2#46 for the old version of the SoapySDRPlay driver (i.e. SoapySDRPlay2); after reading it, I understood that that behavior is by design (see the changes by @guruofquality in this pull request pothosware/SoapySDRPlay2#47), and therefore should be replicated in the new SoapySDRPlay3 driver.

In order to make sure that it works exactly the same way, I ran these two 'SoapySDRUtil' commands in two different terminal windows as suggested by @fmoessbauer (pothosware/SoapySDRPlay2#46 (comment)):

SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=1e6 --direction=RX

and:

SoapySDRUtil --find="driver=remote,remote=127.0.0.1,remote:driver=sdrplay"

Since I noticed that, in the case of the RSPduo, the serial number is not enough to uniquely identify the selected RSPduo mode ('Single Tuner', 'Dual Tuner, 'Master', etc), I made a few changes to the code in the support_for_serial_keyword branch to add the RSPduo mode to the claimed serial cache key.

Tomorrow after work I'll start looking at the problems with the crash and freeze of CubicSDR (which should never happen).

Franco

@nmaster2042
Copy link

OK @fventuri I saw your changes for RSP duo mode to the claimed serial cache key.

On Cubic now if I start a master mode stream, on a second instance device list I can see 2 RSPduo devices: Master and Slave.

@fventuri
Copy link
Collaborator

fventuri commented Jan 5, 2021

@nmaster2042 - that is to be expected on the second instance of CubicSDR when the first instance is running in Master mode:

  • the Slave instance comes from the fact that the RSPduo has its slave "half" available for streaming (as per the Master/Slave architecture in the RSPduo), and if you click on that, you should be able to stream in slave mode, as usual
  • the Master instance comes from the "claimed serial cache" inside SoapySDRServer (as discussed here: issues with multiple consumers SoapySDRPlay2#46); I implemented that logic the same way that @guruofquality did in his commit, however to be very honest, I am not sure what purpose it serves yet (I need to re-read that discussion tonight to understand better).

Franco

@fventuri
Copy link
Collaborator

@nmaster2042 , @pausrn - I just pushed several changes to the support_for_serial_keyword branch (https://github.com/pothosware/SoapySDRPlay3/tree/support_for_serial_keyword), that should hopefully address many problems with multiple clients and SoapyRemote.

These are the tests I ran here with my RSPduo; they all ran without any crash or freezing the client application (in all these tests I started SoapyRemote in a different terminal with the command: SoapySDRServer --bind):

  • First test (Single Tuner mode):
    client 1:
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=1e6 --direction=RX

client 2:

SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=1e6 --direction=RX
  • Second test (Master mode):
    client 1:
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp,remote:mode=MA" --rate=1e6 --direction=RX

client 2:

SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp,remote:mode=MA" --rate=1e6 --direction=RX
  • Third test (Master + Slave mode):
    client 1:
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp,remote:mode=MA" --rate=1e6 --direction=RX

client 2:

SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp,remote:mode=SL" --rate=1e6 --direction=RX

Please run your tests with the new code, and let me know if you experience any problem (crashes, freezes, or others) - if you can reproduce the problem with a CLI command like SoapySDRUtil or rx_tools, please post the exact command, since it makes troubleshooting the problem easier for me.

Franco

@pausrn
Copy link

pausrn commented Jan 10, 2021

Tried with SoapySDRUtil, cubicSDR and rx_tools. Only problem I have seen is that, except for the first , starting a stream with a sample rate greater-than or equal to 3Msps will make the server crash with a segfault :

Ex :
Starting a first stream (at any sample rate)
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=6e6 --direction=RX

Starting another stream (at less than 3Msps)
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=2e6 --direction=RX

Starting another stream (at more than 3Msps)
SoapySDRUtil --args="driver=remote,remote=127.0.0.1,remote:driver=sdrplay,remote:prot=tcp" --rate=3e6 --direction=RX

Here the server will crash with a segfault

This can be replicated with rx_tools and cubicSDR :
Starting iq recording with rx_sdr
./rx_sdr -f 1700M -s 6M -d "driver=remote,remote=tcp://[::]:55132" -I CS16 -F CS16 test_METEOR.raw
then starting CubicSDR with a sample rate higher than 3Msps will crash the server

The same happen with two CubicSDR instances, two rx_tools instances, one rx_tools and one SoapySDRUtil, one SoapySDRUtil and one CubicSDR,...

gdb trace for the server :

(gdb) file /usr/local/bin/SoapySDRServer
Reading symbols from /usr/local/bin/SoapySDRServer...done.
(gdb) run --bind
Starting program: /usr/local/bin/SoapySDRServer --bind
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
######################################################
## Soapy Server -- Use any Soapy SDR remotely
######################################################

Server version: 0.6.0-gc09b2f10
Server UUID: 3803b9fa-e23d-1658-8567-22a9007f0101
Launching the server... tcp://[::]:55132
Server bound to [::]:55132
Launching discovery server... 
[New Thread 0x7ffff7a01700 (LWP 8874)]
Connecting to DNS-SD daemon... 
[WARNING] SoapyRemote compiled without DNS-SD support!
Press Ctrl+C to stop the server
SoapyServerListener::accept([::ffff:127.0.0.1]:42690)
[New Thread 0x7ffff7200700 (LWP 8877)]
SoapyServerListener::accept([::ffff:127.0.0.1]:42692)
[New Thread 0x7ffff69ff700 (LWP 8878)]
[Thread 0x7ffff7200700 (LWP 8877) exited]
[Thread 0x7ffff69ff700 (LWP 8878) exited]
SoapyServerListener::accept([::ffff:127.0.0.1]:42694)
[New Thread 0x7ffff5e3b700 (LWP 8881)]
SoapyServerListener::close()
SoapyServerListener::close()
SoapyServerListener::accept([::ffff:127.0.0.1]:42696)
[New Thread 0x7ffff69ff700 (LWP 8882)]
[New Thread 0x7ffff7200700 (LWP 8887)]
[New Thread 0x7ffff553d700 (LWP 8888)]
[New Thread 0x7ffff4d3c700 (LWP 8889)]
[New Thread 0x7fffdffff700 (LWP 8890)]
[New Thread 0x7fffdf7fe700 (LWP 8891)]
[Thread 0x7fffdf7fe700 (LWP 8891) exited]
SoapyServerListener::accept([::ffff:127.0.0.1]:42702)
[New Thread 0x7fffdeffd700 (LWP 8893)]
SoapyServerListener::accept([::ffff:127.0.0.1]:42704)
[New Thread 0x7fffde7fc700 (LWP 8894)]
[Thread 0x7fffdeffd700 (LWP 8893) exited]
[Thread 0x7fffde7fc700 (LWP 8894) exited]
SoapyServerListener::accept([::ffff:127.0.0.1]:42706)
[New Thread 0x7fffddffb700 (LWP 8896)]
SoapyServerListener::close()
SoapyServerListener::close()
SoapyServerListener::accept([::ffff:127.0.0.1]:42708)
[New Thread 0x7fffde7fc700 (LWP 8897)]
[New Thread 0x7fffdeffd700 (LWP 8899)]
[New Thread 0x7fffdd7fa700 (LWP 8900)]
[Thread 0x7fffdd7fa700 (LWP 8900) exited]
SoapyServerListener::accept([::ffff:127.0.0.1]:42714)
[New Thread 0x7fffdcff9700 (LWP 8903)]
SoapyServerListener::accept([::ffff:127.0.0.1]:42716)
[New Thread 0x7fffc3fff700 (LWP 8904)]
[Thread 0x7fffdcff9700 (LWP 8903) exited]
[Thread 0x7fffc3fff700 (LWP 8904) exited]
SoapyServerListener::accept([::ffff:127.0.0.1]:42718)
[New Thread 0x7fffc37fe700 (LWP 8906)]
SoapyServerListener::close()
SoapyServerListener::close()
SoapyServerListener::accept([::ffff:127.0.0.1]:42720)
[New Thread 0x7fffc3fff700 (LWP 8907)]
[New Thread 0x7fffdcff9700 (LWP 8909)]
[New Thread 0x7fffc2ffd700 (LWP 8910)]
[Thread 0x7fffc2ffd700 (LWP 8910) exited]

Thread 10 "SoapySDRServer" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffdffff700 (LWP 8890)]
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
384     ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Aucun fichier ou dossier de ce type.
(gdb) bt
#0  __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
#1  0x00007ffff609627f in SoapySDRPlay::readStream (this=0x7fffec002970, stream=0x7fffec001c10, buffs=0x7fffd4000b20, numElems=1006, 
    flags=@0x7fffdfffe99c: 0, timeNs=@0x7fffdfffe990: 0, timeoutUs=100000)
    at ~/compile/SoapySDRPlay3/Streaming.cpp:418
#2  0x00005555555bb814 in ServerStreamData::sendEndpointWork (this=0x7fffec002168)
    at ~/compile/SoapyRemote/server/ServerStreamData.cpp:185
#3  0x00005555555bc198 in std::__invoke_impl<void, void (ServerStreamData::*)(), ServerStreamData*> (
    __f=@0x7fffec0055a0: (void (ServerStreamData::*)(ServerStreamData * const)) 0x5555555bb554 <ServerStreamData::sendEndpointWork()>, __t=@0x7fffec005598: 0x7fffec002168) at /usr/include/c++/8/bits/invoke.h:73
#4  0x00005555555bbb3b in std::__invoke<void (ServerStreamData::*)(), ServerStreamData*> (
    __fn=@0x7fffec0055a0: (void (ServerStreamData::*)(ServerStreamData * const)) 0x5555555bb554 <ServerStreamData::sendEndpointWork()>, __args#0=@0x7fffec005598: 0x7fffec002168) at /usr/include/c++/8/bits/invoke.h:95
#5  0x00005555555bcf8b in std::thread::_Invoker<std::tuple<void (ServerStreamData::*)(), ServerStreamData*> >::_M_invoke<0ul, 1ul> (
    this=0x7fffec005598) at /usr/include/c++/8/thread:244
#6  0x00005555555bcf46 in std::thread::_Invoker<std::tuple<void (ServerStreamData::*)(), ServerStreamData*> >::operator() (
    this=0x7fffec005598) at /usr/include/c++/8/thread:253
#7  0x00005555555bcf2a in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (ServerStreamData::*)(), ServerStreamData*> > >::_M_run (this=0x7fffec005590) at /usr/include/c++/8/thread:196
#8  0x00007ffff7e3bb2f in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007ffff7f0bfa3 in start_thread (arg=<optimized out>) at pthread_create.c:486
#10 0x00007ffff7b194cf in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95```

@nmaster2042
Copy link

nmaster2042 commented Jan 10, 2021

I make some test, for now only single tuner mode, soapySDRRemote.

Same test as you @fventuri, no issues.

But, with Cubic, start first one ST mode, Tuner 1, center freq = 7500 khz, ok
Start second cubic, I see RSP duo ST avaliable, select it, same Tuner, frequency, sample rate, ok.
My 2 instances are running, if I stop the stream of one of the two, they crash togather,

On my terminal of instance 1 I see

[ERROR] SoapyLogAcceptor::handlerLoop(tcp://192.168.0.65:55132) FAIL: SoapyRPCUnpacker::recv(header) FAIL: terminate called after throwing an instance of 'std::runtime_error' what(): SoapyRPCUnpacker::recv(header) FAIL: Abandon (core dumped)

And on the second instance terminal

[ERROR] SoapyLogAcceptor::handlerLoop(tcp://192.168.0.65:55132) FAIL: SoapyRPCUnpacker::recv(header) FAIL: Terminating SDR thread.. ERROR: thread '9SDRThread' has not terminated in time ! (> 3000 ms)

Finally my SoapySDRServer crash too.

During my test I made mistake of selecting wrong frequency and tuner for the second instance of Cubic in single tuner mode. That worked, but it changed also the stream of instance 1, witch is logic.

I wasn't aware of the use of a sdr via soapyremote by more than one client at once.

It's probably usefull but for special cases.

@nmaster2042
Copy link

nmaster2042 commented Jan 10, 2021

Humm I tried the same approach with a airspyhf+: opening 2 instances of cubicsdr and stream same frequency.
It works but issues also when I stop one of the two.

So it's possible issues are not only coming from SoapySDRPlay3.

@nmaster2042
Copy link

@fventuri viewing @pausrn's tests, I was wondering if it's ok to start different streams with different sample rates ?
I thought it had to be the same ?

@nmaster2042
Copy link

@pausrn I tried this 2 streams on my system:

SoapySDRUtil --args="driver=remote,remote=192.168.0.65,remote:driver=sdrplay,remote:prot=tcp" --rate=6e6 --direction=RX

and

SoapySDRUtil --args="driver=remote,remote=192.168.0.65,remote:driver=sdrplay,remote:prot=tcp" --rate=4e6 --direction=RX

No crash here.

If I change the second stream with a sample rate >= 5 Mbps it crash

@fventuri
Copy link
Collaborator

fventuri commented Jan 13, 2021

@nmaster2042 , @pausrn - thanks for all your comments and tests.

In the last couple of days I have been running some tests with a very simple RSP2 device, and I was able to reproduce the crashes using any value of the sample rate > 2MHz.
I see that SoapySDRServer calls setSampleRate() every time a new client stream is started, so if I run SoapySDRUtil with the argument --rate=2.1e6, and, while it is running, I start another instance of SoapySDRUtil in another windows with the argument --rate=2.2e6, then the second call to setSampleRate() with 2.2e6 overrides the first call, and I suspect that even the first stream gets a new sample rate of 2.2e6 (unless SoapySDRServer has some resampling code inside; I haven't checked that).

As per the crashes, they seem to be due to incorrect handling of buffer overflows in the SoapySDRPlay3 driver; I am still trying to understand how that is supposed to work in first place; after I have that figured out, I should able to find the problem and fix it.

Franco

@fventuri
Copy link
Collaborator

@SDRplay
You re right, Andy; when CubicSDR stops streaming, it makes two SoapySDR API calls: first deactivateStream(), and then closeStream(), where I do call sdrplay_api_Uninit(), so that would explain the crash.

If I understand correctly then, the function sdrplay_api_SwapRspDuoMode() is designed for the scenario when the user wants to switch RSPduo mode while they are streaming (which honestly is something I never thought one would do based on the abstraction of pseudo-devices that the SoapySDRPlay driver presents to the client application), while in my test above I was trying to go through the steps of someone simply wanting to 'switch' the SDR device they are using in CubicSDR.

At this point I think I need to come up with a comprehensive list of use-case scenarios that the user might reasonably expect to try with say CubicSDR, gqrx, and SoapyRemote, figure out which SoapySDR calls are invoked in each case, and finally try to map those calls to the SDRplay APIs functions like SelectDevice, ReleaseDevice, Init, Uninit, SwapRspDuoMode, etc

Franco

@SDRplay
Copy link
Collaborator

SDRplay commented Feb 11, 2021

@fventuri it really comes down to how you see the devices and it's slightly more complicated in SoapySDR framework case because of not having the control over the end application.

You could take the view that you can't switch these modes without stopping the application and restarting it. Or if you do want to try to use the switch modes function, you will need to do it whilst the device is still initialised.

Andy

@nmaster2042
Copy link

@fventuri I built your last commit of swap_rspduo_mode and tried with my RSP Duo over network SoapySDRServer.

I get same result as you with cubicsdr.

When I run some time on Single Tuner mode, Stop and select master mode, cubic sdr crashes with this error.

[INFO] swapRspDuoMode() - swapRspDuo=0xffff64012570 - args=agc_setpoint=-30, biasT_ctrl=true, dabnotch_ctrl=false, driver=sdrplay, extref_ctrl=false, iqcorr_ctrl=true, label=SDRplay Dev2 RSPduo 1809029C32 - Master, mode=MA, remote=tcp://192.168.0.65:55132, rfgain_sel=4, rfnotch_ctrl=false, serial=1809029C32, soapy_remote_no_deeper=
[INFO] rspDuoMode: 4
[INFO] tuner: 1
[INFO] rspDuoSampleFreq: 6000000.000000
[INFO] swapRspDuoMode() - before SDRplay API call - &device=0xffff4c003200, &deviceParams=0xffff4c003260 rspDuoMode=4 rspDuoSampleFreq=6000000.000000 tuner=1 bwType=1536 ifType=1620 tuner1AmPortSel=0
[ERROR] SoapyLogAcceptor::handlerLoop(tcp://192.168.0.65:55132) FAIL: SoapyRPCUnpacker::recv(header) FAIL: 
Terminating SDR thread..
Terminating SDR post-processing thread..
Terminating All Demodulators..
Terminating Visual Processor threads..
Application termination complete.
Unhandled unknown exception; terminating the application.

@fventuri
Copy link
Collaborator

Thanks for trying it @nmaster2042

Over the weekend I came up with a perhaps cleaner solution that I started coding, and I should be able to debug in the next couple of nights after work.
Once it works reasonably here, I'll push it to the repository so you can give it a try, and see if it works reasonably OK there too.

Franco

@fventuri
Copy link
Collaborator

@nmaster2042
I rewrote a good portion of the RSP device selection code, and in my initial tests here these changes seem to address the problems with crashes and freezes in CubicSDR (and hopefully in gqrx and with SoapySDRRemote), when switching between different RSPduo modes (single tuner to master, and viceversa). These changes however do not prevent CubicSDR to crash when it is streaming from the RSPduo in slave mode, and the user suddenly stops the application that is running in master node (I am not even sure if there is a good way to deal with this scenario).

Anyway, I just pushed all these changes to the usual support_for_serial_keyword branch for you to try out to see if things are better now.

If it looks OK, then we can go ahead and finally merge this branch into master (long due!)

I apologize for making you wait for more than a month for it.

Franco

@vsonnier
Copy link

vsonnier commented Mar 25, 2021

Hi @fventuri, thanks for your hard work !

I give the branch support_for_serial_keyword a try with my RSP2 under Windows and CubicSDR, using the recompiled SoapySDR master as well.

The first run happens correctly, however when I re-launch CubicSDR, I got the following errors:

Second run:

SDR enumerator starting.
SoapySDR init..
        API Version: v0.8.0
        ABI Version: v0.8
        Install root: D:\Projets\GIT_Repositories\CubicSDR\CubicSDR_win64
        Loading modules...
Loading bundled SoapySDR module D:\Projets\GIT_Repositories\CubicSDR\CubicSDR_win64\x64/modules//sdrPlaySupport.dll..
        Available factories...sdrplay
  driver = sdrplay
  label = SDRplay Dev0 RSP2 1702007700
  serial = 1702007700
Make device 0
[INFO] devIdx: 0
[INFO] hwVer: 2
[INFO] rspDuoMode: 0
[INFO] tuner: 1
[INFO] rspDuoSampleFreq: 0,000000
  sdrplay_api_api_version=3,070000
  sdrplay_api_hw_version=2
Initializing WGL swap control extensions..
Loaded font 'Bitstream Vera Sans Mono' from ...
Reporting enumeration complete.
SDR enumerator done.
[INFO] devIdx: 0
[INFO] hwVer: 2
[INFO] rspDuoMode: 0
[INFO] tuner: 1
[INFO] rspDuoSampleFreq: 0,000000
SDR thread starting.
device init()
[INFO] Using format CF32.
[ERROR] error in activateStream() - Init() failed: sdrplay_api_Fail
SDRThread : Device Stream set to MTU: 65536
starting readLoop()
...

The initial Devices dialog presents the usual options, but when I start, nothing shows up on CubicSDR.

No amount of plug-unplug of the device, or restarting the service cures it, I have to reboot the machine to get the RSP2 back.

@vsonnier
Copy link

vsonnier commented Mar 25, 2021

Hold on, my RSP2 may have chosen to die today. I'll investigate on my side first.

@fventuri
Copy link
Collaborator

@vsonnier
This morning I plugged in the RSP2 (I ran last night's initial tests only on the RSPduo), and I was able to stream from it, stop and start it several times without any crashes or freezes.
I should have mentioned that I am using Linux here for all my tests, while I see you are running Windows, so it is very possible that I missed something (and hopefully it is not a problem with the hardware).

Let me know what you find out,
Franco

@vsonnier
Copy link

vsonnier commented Mar 25, 2021

@vsonnier
This morning I plugged in the RSP2 (I ran last night's initial tests only on the RSPduo), and I was able to stream from it, stop and start it several times without any crashes or freezes.
I should have mentioned that I am using Linux here for all my tests, while I see you are running Windows, so it is very possible that I missed something (and hopefully it is not a problem with the hardware).

Let me know what you find out,
Franco

Thanks Franco to have tried on your side. Luckily, I saw quickly after my last message that SDRUno worked perfectly... After a full resinstall of SDRUno 1.40.2 (so including API), Cubic still refused to work....

Until I finally cleared the CubicSDR config.xml manually. Probably since last time I updated the module, the device - id string would have changed enough to confuse the app...

Both Win32 and Win64 versions of CubicSDR (and the corresponding modules) seems to work.

Sorry Franco for the unecessary scare, thanks again for your efforts.

@fventuri
Copy link
Collaborator

@vsonnier
Thanks Vincent for confirming that the new code works with CubicSDR under Windows (and I am really glad it wasn't a hardware problem with the RSP2!)

Tonight I ran several tests using SoapySDRServer (SoapyRemote), connecting to it both with the command line test utility SoapySDRUtil, and with CubicSDR; I streamed from the RSPduo in single tuner, master, and slave modes (and combination of them), and there were no crashes or freezes (except in the case when I accidentally stopped the master before the slave, but that was my own fault, and I should have known better).

In the next few days I plan to keep running more tests (for instance using gqrx); this should also give @SDRplay, @nmaster2042, and other brave early testers the chance to try things out to make sure there are no major bugs before I merge it into the master branch.

Franco

@nmaster2042
Copy link

@fventuri

Sorry, I will make tests this week end.
I'll post update here.

@fventuri
Copy link
Collaborator

@nmaster2042

No rush at all - it took me more than a month to make these changes, so it is perfectly OK if it takes a few days to test them.
Also I just pushed a minor change to the way the code handles switching from one antenna to another for the RSPduo case, so you may want to run another git pull to refresh your copy of the source code there.

Thanks for all you tests and patience,
Franco

@vsonnier
Copy link

(and I am really glad it wasn't a hardware problem with the RSP2!)

So do I Franco, thanks for your concern.

One question : we all the changes you have made, is it now possible to have several RSPs connected to the same PC, each one served by a different instance of CubicSDR, independently ?

I'm not speaking of the Master / Slave Duo black magic here, but merely a use case of say several RSP1 are connected on the same machine for convenience, each one run independently to cover completly different bands for different needs, simultaneously.

@fventuri
Copy link
Collaborator

@vsonnier good point Vincent!

I never tried that before, but that's a good experiment.
I scavenged another of those USB 'printer' cables from a drawer, and I connected both the RSPduo and the old RSP2 to my PC, then started two instances of CubicSDR, in one I selected the RSP2 and in the other I selected the RSPduo, and I was able to stream and listen to two different FM stations from different parts of the FM spectrum (I had use the PulseAudio controls to mute one instance of CubicSDR in my headphones while listening to the other one, otherwise I would hear both of them at the same time, which is not very pleasant).

So, yes, I think it should work in the scenario of multiple RSP devices covering different bands for different purposes (at least based on this quick test this morning).

Franco

@vsonnier
Copy link

@fventuri Great, it means both the service and the modules have no hidden global states that would prevent them to run multiple streams. I may need such a configuration in the future for professional activities.

@nmaster2042
Copy link

@fventuri I ran new test building the last commits of support_for_serial_keyword branch.
For CubicSDR, it's fine now, no more crashes when changing RSP Duo mode.
I tried in local, and remote use cases.

Then I tried with Gqrx, now it crashes with this error:
[ERROR] Invalid sameple rate and/or IF setting

I selected SR of 2 Mhz, BW = 1.536 Mhz, that was my favorite parameters and it worked before.
But I can't confirm this was introduced by the last commits.
So let me know if I should open an other issue for this gqrx error.

Thanks for your help.

@fventuri
Copy link
Collaborator

@nmaster2042
Thanks for trying things out.

The error message you are seeing with gqrx is because I added a consistency check between the selected sample rate and the IF frequency.

I just added a more detailed error message in the latest commit to the support_for_serial_keyword branch; can you try doing a git pull again, building and running the new code, and sending me the new error message with all the details, so I can see where is the problem?

Thanks,
Franco

@nmaster2042
Copy link

@fventuri

I made new test with your latest commit with gqrx.

Here is the SDR selection windows:

GQRX - RSPDUO 1

I press OK and I get:

GQRX - RSPDUO 2

Finally a last OK I get:

GQRX - RSPDUO 3

@fventuri
Copy link
Collaborator

@nmaster2042
Thanks for the screenshots.

From the second and third screenshot, I can see where is the problem with your gqrx configuration: you are trying to run your RSPduo with a sample rate of 2MHz and a zero IF.
According to @SDRplay 's comment from 1/7/2020 here: pothosware/SoapySDRPlay2#62 (comment), output sample rates <= 2MHz (including 2MHz) should use an IF of 1,620kHz or 2,048kHz (depending on the value of the input/hw sample rate), while only output sample rates > 2MHz should use zero IF.
This is the source of the information I used to add that sample rate/IF frequency consistency check that is now causing the error message in gqrx.

Based on that, I see that there is a slightly higher sample rate (2.048MHz) available, which is allowed for zero IF, so I was wondering if it would be possible for you to use that value (2.048Mhz) instead of 2MHz in gqrx with the same zero IF setting, to make sure the quality of the streaming at 2.048MHz is the same of what you were achieving with 2MHz.

Franco

@SDRplay
Copy link
Collaborator

SDRplay commented Mar 31, 2021

Just want to clarify that 2 MHz sample rate with zero IF is a valid state, however if you had the choice between 2 MHz zero IF and Low IF, then you would select Low IF because it doesn't suffer from the DC offset spike.

So for a 2 MHz output sample rate in single tuner mode using Low-IF mode you would ONLY ever use...

Input sample rate = 6 MHz, IF freq = 1.62 MHz, IFBW = 1.536 MHz

The IF freq of 2.048 MHz should ONLY be used in master/slave mode where the 2nd tuner is being used with dump1090. In this case then the input sample rate must be 8 MHz.

Best regards,

Andy

@nmaster2042
Copy link

@fventuri I tried using 2048 as SR but I get same error.

Even with higher SR, always same issue occurs.

Before this change, there was no error messages with gqrx.

And I can't change the Zero-IF / Low-IF state in the UI settings.

@fventuri
Copy link
Collaborator

Thanks @SDRplay and @nmaster2042 for the useful comments.

I think I figured out the problem with gqrx - when the SoapySDRPlay3 driver calls the API function sdrplay_api_GetDeviceParams() without making any changes, the values set in deviceParams are (among others):

  • fs: 2MHz
  • IF: 0kHz (zero IF)

which would violate the consistency check I add added (and that's why gqrx would display that error message).

As @SDRplay said, "2 MHz sample rate with zero IF is a valid state", therefore I relaxed a little bit the consistency check to allow for that combination of settings. I just tested it with gqrx here, and it seems to work (i.e. I don't see the error message here).

Please pull the latest changes I just pushed to the support_for_serial_keyword branch, rebuild it, and let me know if everything works as it should now.

Franco

@nmaster2042
Copy link

@fventuri I tried again with your last commit with both gqrx and cubic.

I confirm it's now working as expected without crash.

Thank you very much for this dev work.

@fventuri
Copy link
Collaborator

fventuri commented Apr 1, 2021

@nmaster2042 - thanks for being so patient during these months and checking everything so thoroughly!

At this point, unless there are objections, this is my plan:

  • in a couple of days, over the weekend, merge the support_for_serial_keyword branch into master
  • after a few more days, if I don't hear any problems posted here, close this issue as resolved

@guruofquality @SDRplay @vsonnier - let me know if you are OK with this.

Franco

@vsonnier
Copy link

vsonnier commented Apr 2, 2021

Still Works for Me. To the Moon !

@fventuri
Copy link
Collaborator

This issue is now resolved (see merge #33)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants