This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/osmocom-sdr@lists.osmocom.org/.
Alexander Motzkau a.motzkau at web.deI'm using a Raspberry with two similar devices but different antennas. Specifying the device via index didn't work, because the enumeration of devices changed from time to time. Therefore I implemented functions to give a USB path instead. This path looks the same as the Linux kernel uses (eg. "4-1.2") and contains the USB bus and port numbers. I'll hope you'll find my patch acceptable. Best Regards, Alex Add functions to query devices via path, and path from a device. The path is formatted similar to Linux USB device names (bus number, hyphen, ports separated by dots, eg. "4-1.2"). --- include/rtl-sdr.h | 25 +++++++ src/convenience/convenience.c | 10 +++ src/librtlsdr.c | 121 ++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index d64701e..e6ce33a 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -49,6 +49,31 @@ RTLSDR_API int rtlsdr_get_device_usb_strings(uint32_t index, char *product, char *serial); +/*! + * Get device index by USB path string. + * + * The path string has the format "bus-port.port..." + * (i.e. the bus number, followed by a hyphen, then + * followed by the port numbers separated by dots). + * + * \param path path string of the device + * \return device index of the device with the given path + * \return -1 if no matching device was found. + */ +RTLSDR_API int rtlsdr_get_index_by_path(const char *path); + +/*! + * Get the USB path. + * + * NOTE: The buffer should provide space for at least 32 bytes. + * + * \param index the device index + * \param buf buffer where the path will be written + * \param len size of the buffer + * \return 0 on success + */ +RTLSDR_API int rtlsdr_get_device_path(uint32_t index, char *buf, size_t len); + /*! * Get device index by USB serial string descriptor. * diff --git a/src/convenience/convenience.c b/src/convenience/convenience.c index 00cc2cc..55f82e2 100644 --- a/src/convenience/convenience.c +++ b/src/convenience/convenience.c @@ -268,6 +268,16 @@ int verbose_device_search(char *s) device, rtlsdr_get_device_name((uint32_t)device)); return device; } + /* does string match a path */ + if (s2[0] == '-') { + i = rtlsdr_get_index_by_path(s); + if (i >= 0) { + device = i; + fprintf(stderr, "Using device %d: %s\n", + device, rtlsdr_get_device_name((uint32_t)device)); + return device; + } + } /* does string exact match a serial */ for (i = 0; i < device_count; i++) { rtlsdr_get_device_usb_strings(i, vendor, product, serial); diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 0146298..e3f03d7 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -1414,6 +1414,127 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, return r; } +static void get_device_path(libusb_device *dev, char *buf, size_t len) +{ + uint8_t port_numbers[16]; + int port_entries; + int i, count; + + count = snprintf(buf, len, "%d-", (int)libusb_get_bus_number(dev)); + if (count < 0) { + buf[0] = 0; + return; + } + else if ((size_t)count >= len) { + buf[len-1] = 0; + return; + } + + len -= count; + buf += count; + + port_entries = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers)/sizeof(port_numbers[0])); + if (port_entries < 0) + return; + + for (i = 0; i < port_entries; i++) { + count = snprintf(buf, len, i ? ".%d" : "%d", (int) port_numbers[i]); + + if (count < 0) { + buf[0] = 0; + break; + } + else if ((size_t)count >= len) { + buf[len-1] = 0; + break; + } + + len -= count; + buf += count; + } + + if (!port_entries && len > 1) { + buf[0] = '0'; + buf[1] = 0; + } +} + +int rtlsdr_get_index_by_path(const char *path) +{ + libusb_context *ctx; + libusb_device **list; + struct libusb_device_descriptor dd; + ssize_t cnt; + int i,r,pos; + + r = libusb_init(&ctx); + + if(r < 0) + return -1; + + cnt = libusb_get_device_list(ctx, &list); + + pos = 0; + for (i = 0; i < cnt; i++) { + libusb_get_device_descriptor(list[i], &dd); + + if (find_known_device(dd.idVendor, dd.idProduct)) { + char buf[64]; + get_device_path(list[i], buf, sizeof(buf)); + + if (!strncmp(path, buf, sizeof(buf))) { + libusb_free_device_list(list, 1); + libusb_exit(ctx); + + return pos; + } + + pos++; + } + } + + libusb_free_device_list(list, 1); + libusb_exit(ctx); + + return -1; +} + +int rtlsdr_get_device_path(uint32_t index, char *buf, size_t len) +{ + libusb_context *ctx; + libusb_device **list; + struct libusb_device_descriptor dd; + int i,r; + uint32_t device_count = 0; + ssize_t cnt; + + r = libusb_init(&ctx); + if(r < 0) + return r; + + cnt = libusb_get_device_list(ctx, &list); + + r = LIBUSB_ERROR_NO_DEVICE; + for (i = 0; i < cnt; i++) { + libusb_get_device_descriptor(list[i], &dd); + + if (find_known_device(dd.idVendor, dd.idProduct)) { + device_count++; + + if (index == device_count - 1) { + get_device_path(list[i], buf, len); + r = 0; + break; + } + } + } + + libusb_free_device_list(list, 1); + libusb_exit(ctx); + + return r; +} + int rtlsdr_get_index_by_serial(const char *serial) { int i, cnt, r; -- 2.20.1