pothosware / SoapyAirspy

Soapy SDR plugin for the Airspy
https://github.com/pothosware/SoapyAirspy/wiki
MIT License
25 stars 13 forks source link

Implement open by serial #26

Closed billvoss closed 3 years ago

billvoss commented 3 years ago

Hello,

I'm working on an application where I need to connect multiple SDRs of the same type (AirSpy R2). Each one has a different antenna so I need to be able to distinguish between them.

We can display connected devices with:

device_list = SoapySDR.Device.enumerate()
for device in device_list:
    print(device)

With two AirSpys connected this gives:

{device_id=0, driver=airspy, label=AIRSPY [260868c8:2673939b], serial=260868c8:2673939b}
{device_id=1, driver=airspy, label=AIRSPY [260868c8:266b479b], serial=260868c8:266b479b}

As in the C++ API, I want to be able to connect to a specific device i with:

sdr = SoapySDR.Device(device_list[i]) This works for the first SDR with device_id=0. However, the next device crashes! As per:

Traceback (most recent call last):
  File "./multi_connect_test.py", line 36, in <module>
    sdr2 = SoapySDR.Device(args)
  File "/home/bill/miniforge3/envs/cusignal-dev/lib/python3.6/site-packages/SoapySDR.py", line 1926, in __new__
    return cls.make(*args, **kwargs)
RuntimeError: Airspy device_id out of range [0 .. 1].

I believe this is a bug in the Python binding. Something to do with the device_id being a string, but somewhere it is being checked again an int range?

Any advice on workarounds would be appreciated, or I'm happy to work together to fix the bug.

Thanks, Bill

(For more info, I've had a brief discussion on the forum: https://groups.google.com/g/pothos-users/c/-l1P1NFdfgQ)

guruofquality commented 3 years ago

Honestly, something is probably wrong with the Airspy find and open functions. The device ID just some "internal" index that changes as soon as you open the first device.

Although it could be fixed, in my opinion, this device ID stuff has to go. It should use the open by serial convention. Since you have two airspy devices, I would greatly appreciate a PR that cleans up this stuff.

Just as an example, airspyhf does this:

A plea in SDRPlay for open by serial: https://github.com/pothosware/SoapySDRPlay3/issues/23 (and its almost ready for merge)

billvoss commented 3 years ago

Thanks Josh,

That makes sense.

I'll have a look at the airspyHF code and see what I can do!

What I still don't understand is how I can open two CubicSDR windows and successfully read simultaneously from two Airspys, if the issue is fundamentally with SoapyAirspy.

jketterl commented 3 years ago

I have just reviewed the code since this has come up on our mailing list. To me, it seems like everything is in place and this should work already.

I have given this a quick test on a site that has one Airspy R2 and one Airspy mini (they are easy to distinguish thanks to their different sample rates) and a current "master" build of this repo. Result looks good to me:

$ SoapySDRUtil --find
######################################################
## Soapy SDR -- the SDR abstraction library
######################################################

Found device 0
  driver = airspy
  label = AirSpy One [4a464c836411c0b]
  serial = 4a464c836411c0b

Found device 1
  driver = airspy
  label = AirSpy One [4a464c83496770b]
  serial = 4a464c83496770b

[... additional devices removed ...]

$ SoapySDRUtil --probe=serial=4a464c836411c0b
######################################################
## Soapy SDR -- the SDR abstraction library
######################################################

Probe device serial=4a464c836411c0b

----------------------------------------------------
-- Device identification
----------------------------------------------------
  driver=Airspy
  hardware=Airspy
  serial=4a464c836411c0b
[...]
  Sample rates: 10, 2.5 MSps

$ SoapySDRUtil --probe=serial=4a464c83496770b
######################################################
## Soapy SDR -- the SDR abstraction library
######################################################

Probe device serial=4a464c83496770b

----------------------------------------------------
-- Device identification
----------------------------------------------------
  driver=Airspy
  hardware=Airspy
  serial=4a464c83496770b
[...]
  Sample rates: 6, 3 MSps

Device selection by serial seems to work as expected in OpenWebRX as well.

Any other tests I could perform?

janvgils commented 3 years ago

In my challenge to get two AirSpy models active on a system running two SatNOGS client I experience something similar.

SoapySDRUtil --info

######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Lib Version: v0.7.2-1
API Version: v0.7.1
ABI Version: v0.7

SoapySDRUtil --find

Found device 0
  device_id = 0
  driver = airspy
  label = AIRSPY [4a464c8:3670830b]
  serial = 4a464c8:3670830b

Found device 1
  device_id = 1
  driver = airspy
  label = AIRSPY [466c64c8:306b65c7]
  serial = 466c64c8:306b65c7

I find it strange to see a colon in the serial value and the option to use SoapySDRUtil --probe=serial=466c64c8:306b65c7 isn't working in my setup, it will show only one AirSpy device and isn't using the serial value,

I would prefer that this would work similar to the rtlsdr driver.

This would look something like this SoapySDRUtil --probe="driver=airspy,serial=4a464c8:3670830b"

guruofquality commented 3 years ago

@janvgils can you help debug this, soapy airspy code was recently updated to open by serial but there still may be some minor bugs. The colon in the serial number looks like some unexpected formatting or local issue:

Serial number to string https://github.com/pothosware/SoapyAirspy/blob/master/Registration.cpp#L52

And back to 64-bit number https://github.com/pothosware/SoapyAirspy/blob/master/Settings.cpp#L55

And basically its not converting back nicely to the same 64-bit integer. The string formed by serialstr << std::hex << serials[i]; doesnt look right, can you try replacing it with sprintf(buff, "%llx", serials[i]);

janvgils commented 3 years ago

I will try and see if I can successfully build the latest code with the proposed change

janvgils commented 3 years ago

Here an update on this issue:

I am testing this on a Debian buster x86_64 distribution.

sudo apt-get install libsoapysdr-dev

git clone https://github.com/pothosware/SoapyAirspy.git

cd SoapyAirspy
mkdir build
cmake ../
make

cd /usr/lib/x86_64-linux-gnu/SoapySDR/modules0.7
cp libairspySupport.so libairspySupport.so.deb
cp ${HOME}/source/git/pothosware/SoapyAirspy/build/libairspySupport.so .
sudo ldconfig

SoapySDRUtil --info
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Lib Version: v0.7.2-1
API Version: v0.7.1
ABI Version: v0.7
Install root: /usr
Search path:  /usr/lib/x86_64-linux-gnu/SoapySDR/modules0.7
...
...
...
Module found: /usr/lib/x86_64-linux-gnu/SoapySDR/modules0.7/libairspySupport.so  (0.1.2-10d697b)

SoapySDRUtil --find="driver=airspy"
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Found device 0
  driver = airspy
  label = AirSpy One [466c64c8306b65c7]
  serial = 466c64c8306b65c7

SoapySDRUtil --probe="driver=airspy"
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Probe device driver=airspy

----------------------------------------------------
-- Device identification
----------------------------------------------------
  driver=Airspy
  hardware=Airspy
  serial=466c64c8306b65c7

----------------------------------------------------
-- Peripheral summary
----------------------------------------------------
  Channels: 1 Rx, 0 Tx
  Timestamps: NO
  Other Settings:
     * Bias tee - Enable the 4.5v DC Bias tee to power SpyVerter / LNA / etc. via antenna connection.
       [key=biastee, default=false, type=bool]
     * Bit Pack - Enable packing 4 12-bit samples into 3 16-bit words for 25% less USB trafic.
       [key=bitpack, default=false, type=bool]

----------------------------------------------------
-- RX Channel 0
----------------------------------------------------
  Full-duplex: YES
  Supports AGC: YES
  Stream formats: CS16, CF32
  Native format: CS16 [full-scale=32767]
  Antennas: RX
  Full gain range: [0, 45] dB
    LNA gain range: [0, 15] dB
    MIX gain range: [0, 15] dB
    VGA gain range: [0, 15] dB
  Full freq range: [24, 1800] MHz
    RF freq range: [24, 1800] MHz
  Sample rates: 10, 2.5 MSps

SoapySDRUtil --probe="driver=airspy,serial=466c64c8306b65c7"
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Probe device driver=airspy,serial=466c64c8306b65c7

----------------------------------------------------
-- Device identification
----------------------------------------------------
  driver=Airspy
  hardware=Airspy
  serial=466c64c8306b65c7

----------------------------------------------------
-- Peripheral summary
----------------------------------------------------
  Channels: 1 Rx, 0 Tx
  Timestamps: NO
  Other Settings:
     * Bias tee - Enable the 4.5v DC Bias tee to power SpyVerter / LNA / etc. via antenna connection.
       [key=biastee, default=false, type=bool]
     * Bit Pack - Enable packing 4 12-bit samples into 3 16-bit words for 25% less USB trafic.
       [key=bitpack, default=false, type=bool]

----------------------------------------------------
-- RX Channel 0
----------------------------------------------------
  Full-duplex: YES
  Supports AGC: YES
  Stream formats: CS16, CF32
  Native format: CS16 [full-scale=32767]
  Antennas: RX
  Full gain range: [0, 45] dB
    LNA gain range: [0, 15] dB
    MIX gain range: [0, 15] dB
    VGA gain range: [0, 15] dB
  Full freq range: [24, 1800] MHz
    RF freq range: [24, 1800] MHz
  Sample rates: 10, 2.5 MSps

So this looks promising and to make sure the serial is used I also tried a dummy serial to see what happens.

SoapySDRUtil --probe="driver=airspy,serial=466c64c8306b65c8"
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Probe device driver=airspy,serial=466c64c8306b65c8
Error probing device: Unable to open AirSpy device with serial 466c64c8306b65c8

The final test will be done by me reconnecting all the AirSpy devices and check if the client also works.

janvgils commented 3 years ago

I connected the second AirSpy and this also looks good.

SoapySDRUtil --find="driver=airspy"
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Found device 0
  driver = airspy
  label = AirSpy One [466c64c8306b65c7]
  serial = 466c64c8306b65c7

Found device 1
  driver = airspy
  label = AirSpy One [4a464c83670830b]
  serial = 4a464c83670830b

If others have the same experience I hope this will be make it to stable a release a.s.a.p.

Thanks for the support.

guruofquality commented 3 years ago

I'm happy the fix worked. Can you share the git diff for the exact source change that worked for you? Or better yet a pull request if you are feeling bold. Thanks!

janvgils commented 3 years ago

Hi,

The only thing I did, as descripted in my previous posts, is a git clone, nothing else. So my experience is based on the current master.

cd ${HOME}/source/git/pothosware/SoapyAirspy && git branch

* master
guruofquality commented 3 years ago

Sorry, completely missed that. The code is fine, it just needs a release.

I'm closing the issue, since this actually got resolved a while ago.

And I will tag the repo