From 505f40d9a092ad44c7d3a77477a72e37c955b4ff Mon Sep 17 00:00:00 2001 From: Dimitri Stolnikov Date: Sun, 20 May 2012 16:41:15 +0200 Subject: [PATCH] introduce api function to read usb string descriptors This API allows to read manufacturer and product names as well as the serial number advertized by the device on the bus. --- include/rtl-sdr.h | 30 ++++++++++++++++ src/librtlsdr.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++ src/rtl_sdr.c | 10 +++--- 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index a5b3dfd..804334d 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -33,6 +33,22 @@ RTLSDR_API uint32_t rtlsdr_get_device_count(void); RTLSDR_API const char* rtlsdr_get_device_name(uint32_t index); +/*! + * Get USB device strings. + * + * NOTE: The string arguments must provide space for up to 256 bytes. + * + * \param index the device index + * \param manufact manufacturer name, may be NULL + * \param product product name, may be NULL + * \param serial serial number, may be NULL + * \return 0 on success + */ +RTLSDR_API int rtlsdr_get_device_usb_strings(uint32_t index, + char *manufact, + char *product, + char *serial); + RTLSDR_API int rtlsdr_open(rtlsdr_dev_t **dev, uint32_t index); RTLSDR_API int rtlsdr_close(rtlsdr_dev_t *dev); @@ -69,6 +85,20 @@ RTLSDR_API int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, RTLSDR_API int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_freq); +/*! + * Get USB device strings. + * + * NOTE: The string arguments must provide space for up to 256 bytes. + * + * \param dev the device handle given by rtlsdr_open() + * \param manufact manufacturer name, may be NULL + * \param product product name, may be NULL + * \param serial serial number, may be NULL + * \return 0 on success + */ +RTLSDR_API int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, + char *product, char *serial); + RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq); /*! diff --git a/src/librtlsdr.c b/src/librtlsdr.c index 7721c4a..d961985 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -571,6 +571,47 @@ int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_ return 0; } +int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product, + char *serial) +{ + struct libusb_device_descriptor dd; + libusb_device *device = NULL; + const int buf_max = 256; + int r = 0; + + if (!dev || !dev->devh) + return -1; + + device = libusb_get_device(dev->devh); + + r = libusb_get_device_descriptor(device, &dd); + if (r < 0) + return -1; + + if (manufact) { + memset(manufact, 0, buf_max); + libusb_get_string_descriptor_ascii(dev->devh, dd.iManufacturer, + (unsigned char *)manufact, + buf_max); + } + + if (product) { + memset(product, 0, buf_max); + libusb_get_string_descriptor_ascii(dev->devh, dd.iProduct, + (unsigned char *)product, + buf_max); + } + + if (serial) { + memset(serial, 0, buf_max); + libusb_get_string_descriptor_ascii(dev->devh, dd.iSerialNumber, + (unsigned char *)serial, + buf_max); + } + + return 0; +} + int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq) { int r = -1; @@ -815,6 +856,52 @@ const char *rtlsdr_get_device_name(uint32_t index) return ""; } +int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact, + char *product, char *serial) +{ + int r = -2; + int i; + libusb_context *ctx; + libusb_device **list; + struct libusb_device_descriptor dd; + rtlsdr_dongle_t *device = NULL; + rtlsdr_dev_t devt; + uint32_t device_count = 0; + ssize_t cnt; + + libusb_init(&ctx); + + cnt = libusb_get_device_list(ctx, &list); + + for (i = 0; i < cnt; i++) { + libusb_get_device_descriptor(list[i], &dd); + + device = find_known_device(dd.idVendor, dd.idProduct); + + if (device) { + device_count++; + + if (index == device_count - 1) { + r = libusb_open(list[i], &devt.devh); + if (!r) { + r = rtlsdr_get_usb_strings(&devt, + manufact, + product, + serial); + libusb_close(devt.devh); + } + break; + } + } + } + + libusb_free_device_list(list, 1); + + libusb_exit(ctx); + + return r; +} + int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) { int r; diff --git a/src/rtl_sdr.c b/src/rtl_sdr.c index 98d5fc5..45995c2 100644 --- a/src/rtl_sdr.c +++ b/src/rtl_sdr.c @@ -107,6 +107,7 @@ int main(int argc, char **argv) uint32_t samp_rate = DEFAULT_SAMPLE_RATE; uint32_t out_block_size = DEFAULT_BUF_LENGTH; int device_count; + char vendor[256], product[256], serial[256]; #ifndef _WIN32 while ((opt = getopt(argc, argv, "d:f:g:s:b:S::")) != -1) { switch (opt) { @@ -168,13 +169,14 @@ int main(int argc, char **argv) } fprintf(stderr, "Found %d device(s):\n", device_count); - for (i = 0; i < device_count; i++) - fprintf(stderr, " %d: %s\n", i, rtlsdr_get_device_name(i)); + for (i = 0; i < device_count; i++) { + rtlsdr_get_device_usb_strings(i, vendor, product, serial); + fprintf(stderr, " %d: %s, %s, SN: %s\n", i, vendor, product, serial); + } fprintf(stderr, "\n"); fprintf(stderr, "Using device %d: %s\n", - dev_index, - rtlsdr_get_device_name(dev_index)); + dev_index, rtlsdr_get_device_name(dev_index)); r = rtlsdr_open(&dev, dev_index); if (r < 0) {