Closed farhan296 closed 4 years ago
Can you confirm the same bug with SoapySDRUtil --find, and SoapySDRUtil --make="the key/value args" and share what arguments are passing to the make option.
The problem is in the SoapySDR::Device* SoapySDR::Device::make(const Kwargs &inputArgs) function. Upon passing the second device in the argument of the function it first checks if it has already been placed in the list at line 135 of Factory.cpp . If it does not find it in the list it goes on to enumerate again at line 142 and then in line 143 it picks the first device from the enumeration result that has already been opened and present in the list. From there on it exits the function.
Thats correct behavior, but the enumerate call should be returning only one device if you passed in arguments that specify a specific device (usually by serial). If not, it could be a bug in the XTRX enumerate code, you may want to let them know.
sudo SoapySDRUtil --find ######################################################
######################################################
14:55:03.477718 DEBUG: xtrxllpciev0_discovery:264 [PCIE] pcie: Found pcie:///dev/xtrx0
14:55:03.477772 DEBUG: xtrxllpciev0_discovery:264 [PCIE] pcie: Found pcie:///dev/xtrx1
Found device 0
addr = pcie:///dev/xtrx0
dev = pcie:///dev/xtrx0
driver = xtrx
label = XTRX: pcie:///dev/xtrx0 (10Gbit)
media = PCIe
module = SoapyXTRX
name = XTRX
serial =
type = xtrx
Found device 1 addr = pcie:///dev/xtrx1 dev = pcie:///dev/xtrx1 driver = xtrx label = XTRX: pcie:///dev/xtrx1 (10Gbit) media = PCIe module = SoapyXTRX name = XTRX serial = type = xtrx In the above we can clearly see two devices are connected to the system now when I pass the Key Value pair of xtrx1 above in make it only opens xtrx0 because of the reason I mentioned above.
sudo SoapySDRUtil --make="addr=pcie:///dev/xtrx1,dev=pcie:///dev/xtrx1,driver=xtrx,label=XTRX: pcie:///dev/xtrx1 (10Gbit),media=PCIe,module=SoapyXTRX,name=XTRX,serial= ,type=xtrx" ######################################################
######################################################
Make device addr=pcie:///dev/xtrx1,dev=pcie:///dev/xtrx1,driver=xtrx,label=XTRX: pcie:///dev/xtrx1 (10Gbit),media=PCIe,module=SoapyXTRX,name=XTRX,serial= ,type=xtrx
14:59:32.889379 DEBUG: xtrxllpciev0_discovery:264 [PCIE] pcie: Found pcie:///dev/xtrx0
14:59:32.889409 DEBUG: xtrxllpciev0_discovery:264 [PCIE] pcie: Found pcie:///dev/xtrx1
[INFO] Make connection: 'pcie:///dev/xtrx0'
14:59:32.891626 INFO: [CTRL] PCI:/dev/xtrx0: XTRX Rev4 (04000113)
14:59:32.891633 INFO: [BPCI] PCI:/dev/xtrx0: RX DMA STOP MIMO (BLK:0 TS:0); TX DMA STOP MIMO @0.0
14:59:32.891637 INFO: [PCIE] PCI:/dev/xtrx0: Device pcie:///dev/xtrx0
was opened
CPU Features: SSE2+ SSE4.1+ AVX+ FMA+
14:59:33.008522 INFO: [CTRL] PCI:/dev/xtrx0: RFIC_GPIO 0x000304
14:59:33.108673 INFO: [CTRL] PCI:/dev/xtrx0: FPGA V_GPIO set to 3280mV
14:59:33.108705 INFO: [CTRL] PCI:/dev/xtrx0: LMS PMIC DCDC out set to VA18=1880mV VA14=1480mV VA12=1340mV
14:59:33.112239 INFO: [CTRL] PCI:/dev/xtrx0: FPGA V_IO set to 1800mV
14:59:33.122385 INFO: [CTRL] PCI:/dev/xtrx0: RFIC_GPIO 0x000306
14:59:33.133446 INFO: [LSM7] PCI:/dev/xtrx0: LMS VER:7 REV:1 MASK:1 (3841)
14:59:33.133480 INFO: [CTRL] PCI:/dev/xtrx0: RFIC_GPIO 0x00031e
14:59:33.133601 INFO: [DBGP] Starting XTRX debug thread
driver=xtrx
hardware=/dev/xtrx0
14:59:33.134370 INFO: [CTRL] PCI:/dev/xtrx0: RFIC_GPIO 0x000300
14:59:33.135506 INFO: [PCIE] PCI:/dev/xtrx0: Device closing
Ideally one should enumerate first and based on the enumeration result, the key value pair must be passed to make function. The make function now always picks the first device identified in the list via results.front() in line 143. What happens in the case when there is more than one device on the system and the user wants to make the second device in the list? Clearly this is not possible in the current implementation.
Ideally one should enumerate first and based on the enumeration result, the key value pair must be passed to make function. The make function now always picks the first device identified in the list via results.front() in line 143
Correct
What happens in the case when there is more than one device on the system and the user wants to make the second device in the list? Clearly this is not possible in the current implementation.
In this case you want it to only yield one result if you pass the args in for a specific device, but you are seeing two. If you run 'sudo SoapySDRUtil --find="addr=pcie:///dev/xtrx1,dev=pcie:///dev/xtrx1,driver=xtrx,label=XTRX: pcie:///dev/xtrx1 (10Gbit),media=PCIe,module=SoapyXTRX,name=XTRX,serial= ,type=xtrx"' you get two devices right?
I regularly use SoapySDR with dozens of devices on the network. What I'm saying is that the implementation is not in this project. Its in Soapy XTRX. There is nothing I can do to address this issue this in this repository as far as I know.
For example somethings that seem like bugs to me:
I think fairwaves needs to know about this so they can fix it.
Correct I see two. The thing is that I would not even know before hand what the Device's key value pairs are until I enumerate right ? After enumeration I should pass on those parameters of that particular device (xtrx0 or xtrx1) to make function for it to make that specific device. In the current implementation it always makes xtrx0 even when I pass the key/value pairs for xtrx1. This is because at first the Devicetable is empty, when make is invoked it searches for the device table in line 135. If it does not find it goes ahead and calls the enumerate function which returns a list with xtrx0 and xtrx1 key/value pair. At line 143 discoveredArgs = results.front(); it can be seen that the first entry is returned only which is xtrx0 key/value pairs. xtrx1 is never referenced. This issue will arise when you connect two or more SDRs of the same vendor using the same underlying drivers. Take two LimeSDR for instance and connect them to the same host system.
Answer to your questions
Generally devices support a unique way to identify them that you can know prior such as serial number (almost universally) and when not that a unique address or index are always possible.
For XTRX, I would strongly prefer the serial be fixed if possible -- that way the driver would match how 90% of the other supported devices work in this reguard. As a close second I think "addr" or "dev" (specifically) would work -- as they are unique, and hopefully can be made persistent on reboot.
As far as factory implementation. I know it only picks the first enumeration result even if there are more. But the intention is to make sure that the enumeration implementation provided by the manufacturer's driver gets to sanitize the input arguments and ensure that only arguments from the manufacturer's enumerate is passed into the manufacturer's factory function.
There is intentionally not a way for factory in this project to use the args to select more than one of the enumeration result. Its the job of the manufacturer's enumeration function to do this. That gives the device manufacturer the flexibility on how to implement it.
This is documented here for driver maintainers: https://github.com/pothosware/SoapySDR/wiki/DriverGuide#filtering-devices
So in this case, the XTRX has a bug in how this enumeration is supposed to work. I opened an issue here: https://github.com/xtrx-sdr/libxtrx/issues/20
Hello,
I am using XTRX pro SDR with SOAPY SDR library. I have two of those connected to my PC. On probing and using SoapySDR::KwargsList SoapySDR::Device::enumerate function I am able to get the result of both the devices.
Now when I try to open the device using SoapySDR::Device* SoapySDR::Device::make(const Kwargs &inputArgs) , only the first device in the list returned from the enumeration is opened.
The problem is in the SoapySDR::Device* SoapySDR::Device::make(const Kwargs &inputArgs) function. Upon passing the second device in the argument of the function it first checks if it has already been placed in the list at line 135 of Factory.cpp . If it does not find it in the list it goes on to enumerate again at line 142 and then in line 143 it picks the first device from the enumeration result that has already been opened and present in the list. From there on it exits the function.