From 9dbe967bf224436dfe049021cf2d78b5a67fe9c2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 15 May 2014 10:08:07 -0700 Subject: [PATCH 01/16] Serial number firmware and host-side changes. Very hacky at this point. Among the TODOs: * Refactor obtaining LPC serial number and chip ID into separate API and header/source files. Remove from main(). * Create a usb_set_serial_number_descriptor() or similar function to be called before USB stack is started. * Ensure USB serial number descriptor is valid even if code forgets to initialize the serial number before the USB stack is started. May be as simple as providing default initializer for usb_descriptor_string_serial_number[]. * Create a #define/constant for the usb_descriptor_string_serial_number length. * Identify what's causing intermittent crashes in hackrf_transfer when no serial number is specified. I'm probably misusing getopt. * Permit serial number without leading zeros so you don't have to type as much. * Add support for serial number argument in other hackrf_* tools. * Provide libhackrf support for enumerating multiple HackRFs, so that hackrf_info can list all devices. May require an additional libhackrf function, outside of hackrf_open(). ...and anything else that makes this less of a hack. --- firmware/hackrf_usb/hackrf_usb.c | 24 +++++++++++ firmware/hackrf_usb/usb_descriptor.c | 6 ++- host/hackrf-tools/src/hackrf_cpldjtag.c | 2 +- host/hackrf-tools/src/hackrf_info.c | 2 +- host/hackrf-tools/src/hackrf_max2837.c | 2 +- host/hackrf-tools/src/hackrf_rffc5071.c | 2 +- host/hackrf-tools/src/hackrf_si5351c.c | 2 +- host/hackrf-tools/src/hackrf_spiflash.c | 2 +- host/hackrf-tools/src/hackrf_transfer.c | 10 ++++- host/libhackrf/src/hackrf.c | 53 ++++++++++++++++++++++++- host/libhackrf/src/hackrf.h | 2 +- 11 files changed, 95 insertions(+), 12 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 42fc4482..4ceba12e 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -32,6 +32,9 @@ #include "usb.h" #include "usb_standard_request.h" +#include +#include "usb_descriptor.h" + #include "usb_device.h" #include "usb_endpoint.h" #include "usb_api_board_info.h" @@ -191,6 +194,27 @@ int main(void) { #endif cpu_clock_init(); + +/* HACK! +*/ + iap_cmd_res_t iap_cmd_res; + /* Read IAP Serial Number Identification */ + iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_SERIAL_NO; + iap_cmd_call(&iap_cmd_res); + if(iap_cmd_res.status_res.status_ret == CMD_SUCCESS) { + usb_descriptor_string_serial_number[0] = 66; + usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; + for(size_t i=0; i<32; i++) { + const uint_fast8_t nibble = (iap_cmd_res.status_res.iap_result[i >> 3] >> (28 - (i & 7) * 4)) & 0xf; + const char c = (nibble > 9) ? ('a' + nibble - 10) : ('0' + nibble); + usb_descriptor_string_serial_number[2 + i * 2] = c; + usb_descriptor_string_serial_number[3 + i * 2] = 0x00; + } + } else { + usb_descriptor_string_serial_number[0] = 2; + usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; + } + usb_set_configuration_changed_cb(usb_configuration_changed); usb_peripheral_reset(); diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index 88818529..bc07c6e4 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -57,7 +57,7 @@ uint8_t usb_descriptor_device[] = { USB_WORD(0x0100), // bcdDevice 0x01, // iManufacturer 0x02, // iProduct - 0x00, // iSerialNumber + 0x05, // iSerialNumber 0x02 // bNumConfigurations }; @@ -329,12 +329,14 @@ uint8_t usb_descriptor_string_config2_description[] = { 'e', 0x00, }; +uint8_t usb_descriptor_string_serial_number[66]; + uint8_t* const usb_descriptor_strings[] = { usb_descriptor_string_languages, usb_descriptor_string_manufacturer, usb_descriptor_string_product, usb_descriptor_string_config1_description, usb_descriptor_string_config2_description, - + usb_descriptor_string_serial_number, 0, // TERMINATOR }; diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index b4fb5d26..4fac03a5 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -158,7 +158,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index d83b9696..47ab9264 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -41,7 +41,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c index d8fb75f5..81ebea65 100644 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -130,7 +130,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c index c9630dd4..00e48d85 100644 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -131,7 +131,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index 41146f2c..0db251e2 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -195,7 +195,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index ba2c224e..00113bdf 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -213,7 +213,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open(NULL, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 6c7b0441..780b2d47 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -422,6 +422,7 @@ int tx_callback(hackrf_transfer* transfer) { static void usage() { printf("Usage:\n"); + printf("\t[-d serial_number] # Serial number of desired HackRF.\n"); printf("\t-r # Receive data into file.\n"); printf("\t-t # Transmit data from file.\n"); printf("\t-w # Receive data into file with WAV header and automatic name.\n"); @@ -477,6 +478,7 @@ int main(int argc, char** argv) { char path_file[PATH_FILE_MAX_LEN]; char date_time[DATE_TIME_MAX_LEN]; const char* path = NULL; + const char* serial_number = NULL; int result; time_t rawtime; struct tm * timeinfo; @@ -486,7 +488,7 @@ int main(int argc, char** argv) { float time_diff; unsigned int lna_gain=8, vga_gain=20, txvga_gain=0; - while( (opt = getopt(argc, argv, "wr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:")) != EOF ) + while( (opt = getopt(argc, argv, "wr:t:f:i:o:m:a:p:s:n:b:l:g:x:c:d:")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) @@ -505,6 +507,10 @@ int main(int argc, char** argv) { path = optarg; break; + case 'd': + serial_number = optarg; + break; + case 'f': automatic_tuning = true; result = parse_u64(optarg, &freq_hz); @@ -776,7 +782,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - result = hackrf_open(&device); + result = hackrf_open(serial_number, &device); if( result != HACKRF_SUCCESS ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index c4a21091..6e2bd30d 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -260,7 +260,10 @@ int ADDCALL hackrf_exit(void) return HACKRF_SUCCESS; } -int ADDCALL hackrf_open(hackrf_device** device) +#include +#include + +int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device) { int result; libusb_device_handle* usb_device; @@ -271,13 +274,61 @@ int ADDCALL hackrf_open(hackrf_device** device) return HACKRF_ERROR_INVALID_PARAM; } + +libusb_device** devices = NULL; +const ssize_t list_length = libusb_get_device_list(g_libusb_context, &devices); +printf("All devices: %ld\n", list_length); +for(ssize_t i=0; i 0 ) { + if( libusb_open(devices[i], &usb_device) != 0 ) { + usb_device = NULL; + continue; + } + char serial_number[64]; + const int serial_number_length = libusb_get_string_descriptor_ascii(usb_device, serial_descriptor_index, (unsigned char*)serial_number, sizeof(serial_number)); + if( serial_number_length == 32 ) { + serial_number[32] = 0; + printf(" %s", serial_number); + if( strncmp(serial_number, desired_serial_number, 32) == 0 ) { + printf(" match\n"); + break; + } else { + printf(" skip\n"); + libusb_close(usb_device); + usb_device = NULL; + } + } else { + printf(" error\n"); + libusb_close(usb_device); + usb_device = NULL; + } + } + } else { + printf(" default\n"); + libusb_open(devices[i], &usb_device); + break; + } + } + } +} +libusb_free_device_list(devices, 1); + // TODO: Do proper scanning of available devices, searching for // unit serial number (if specified?). +/* usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); if( usb_device == NULL ) { usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); } +*/ if( usb_device == NULL ) { return HACKRF_ERROR_NOT_FOUND; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 130f33e9..6b615647 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -101,7 +101,7 @@ extern "C" extern ADDAPI int ADDCALL hackrf_init(); extern ADDAPI int ADDCALL hackrf_exit(); -extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device); +extern ADDAPI int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device); extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx); From 9e92adda79ec610659986cf609b41c90a1292445 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 20:14:20 +0200 Subject: [PATCH 02/16] Refactor obtaining LPC serial number and chip ID into separate API and header/source files. Remove from main(). Create a usb_set_descriptor_by_serial_number(), called before USB stack is started. --- firmware/hackrf_usb/hackrf_usb.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4ceba12e..4eddcae9 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -186,25 +186,19 @@ void usb_configuration_changed( } } -int main(void) { - pin_setup(); - enable_1v8_power(); -#ifdef HACKRF_ONE - enable_rf_power(); -#endif - cpu_clock_init(); - - -/* HACK! -*/ +void usb_set_descriptor_by_serial_number(void) +{ iap_cmd_res_t iap_cmd_res; + /* Read IAP Serial Number Identification */ iap_cmd_res.cmd_param.command_code = IAP_CMD_READ_SERIAL_NO; iap_cmd_call(&iap_cmd_res); - if(iap_cmd_res.status_res.status_ret == CMD_SUCCESS) { + + if (iap_cmd_res.status_res.status_ret == CMD_SUCCESS) { usb_descriptor_string_serial_number[0] = 66; usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; - for(size_t i=0; i<32; i++) { + + for (size_t i=0; i<32; i++) { const uint_fast8_t nibble = (iap_cmd_res.status_res.iap_result[i >> 3] >> (28 - (i & 7) * 4)) & 0xf; const char c = (nibble > 9) ? ('a' + nibble - 10) : ('0' + nibble); usb_descriptor_string_serial_number[2 + i * 2] = c; @@ -214,6 +208,17 @@ int main(void) { usb_descriptor_string_serial_number[0] = 2; usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; } +} + +int main(void) { + pin_setup(); + enable_1v8_power(); +#ifdef HACKRF_ONE + enable_rf_power(); +#endif + cpu_clock_init(); + + usb_set_descriptor_by_serial_number(); usb_set_configuration_changed_cb(usb_configuration_changed); usb_peripheral_reset(); From 35b9e0bea0fa75cbf6ad61d1e922baf072d26631 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 20:29:22 +0200 Subject: [PATCH 03/16] Create a #define/constant for the usb_descriptor_string_serial_number length. Clean up a compilation warning, libusb headers do not like the 'const'. --- firmware/hackrf_usb/hackrf_usb.c | 5 +++-- firmware/hackrf_usb/usb_descriptor.c | 5 +++-- firmware/hackrf_usb/usb_descriptor.h | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 4eddcae9..e842d82b 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -195,10 +195,11 @@ void usb_set_descriptor_by_serial_number(void) iap_cmd_call(&iap_cmd_res); if (iap_cmd_res.status_res.status_ret == CMD_SUCCESS) { - usb_descriptor_string_serial_number[0] = 66; + usb_descriptor_string_serial_number[0] = USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN; usb_descriptor_string_serial_number[1] = USB_DESCRIPTOR_TYPE_STRING; - for (size_t i=0; i<32; i++) { + /* 32 characters of serial number, convert to UTF-16LE */ + for (size_t i=0; i> 3] >> (28 - (i & 7) * 4)) & 0xf; const char c = (nibble > 9) ? ('a' + nibble - 10) : ('0' + nibble); usb_descriptor_string_serial_number[2 + i * 2] = c; diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index bc07c6e4..ff770b24 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -22,6 +22,7 @@ #include #include "usb_type.h" +#include "usb_descriptor.h" #define USB_VENDOR_ID (0x1D50) @@ -329,9 +330,9 @@ uint8_t usb_descriptor_string_config2_description[] = { 'e', 0x00, }; -uint8_t usb_descriptor_string_serial_number[66]; +uint8_t usb_descriptor_string_serial_number[USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN]; -uint8_t* const usb_descriptor_strings[] = { +uint8_t* usb_descriptor_strings[] = { usb_descriptor_string_languages, usb_descriptor_string_manufacturer, usb_descriptor_string_product, diff --git a/firmware/hackrf_usb/usb_descriptor.h b/firmware/hackrf_usb/usb_descriptor.h index 11e274a7..bffa9bf7 100644 --- a/firmware/hackrf_usb/usb_descriptor.h +++ b/firmware/hackrf_usb/usb_descriptor.h @@ -30,6 +30,9 @@ extern uint8_t usb_descriptor_configuration_cpld_update_high_speed[]; extern uint8_t usb_descriptor_string_languages[]; extern uint8_t usb_descriptor_string_manufacturer[]; extern uint8_t usb_descriptor_string_product[]; + +#define USB_DESCRIPTOR_STRING_SERIAL_LEN 32 +#define USB_DESCRIPTOR_STRING_SERIAL_BUF_LEN (USB_DESCRIPTOR_STRING_SERIAL_LEN*2 + 2) /* UTF-16LE */ extern uint8_t usb_descriptor_string_serial_number[]; extern uint8_t* usb_descriptor_strings[]; From c9f8bb2a05aa89f348835a927e62f86e31398ab1 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 21:31:31 +0200 Subject: [PATCH 04/16] libhackrf: refactor serial number searching to hackrf_open_usb() --- host/libhackrf/src/hackrf.c | 113 ++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 6e2bd30d..4bf5fd7b 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -263,6 +263,60 @@ int ADDCALL hackrf_exit(void) #include #include +libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) +{ + libusb_device_handle* usb_device = NULL; + libusb_device** devices = NULL; + const ssize_t list_length = libusb_get_device_list(g_libusb_context, &devices); + + printf("Number of USB devices: %ld\n", list_length); + + for (ssize_t i=0; i 0 ) { + if( libusb_open(devices[i], &usb_device) != 0 ) { + usb_device = NULL; + continue; + } + char serial_number[64]; + const int serial_number_length = libusb_get_string_descriptor_ascii(usb_device, serial_descriptor_index, (unsigned char*)serial_number, sizeof(serial_number)); + if( serial_number_length == 32 ) { + serial_number[32] = 0; + printf(" %s", serial_number); + if( strncmp(serial_number, desired_serial_number, 32) == 0 ) { + printf(" match\n"); + break; + } else { + printf(" skip\n"); + libusb_close(usb_device); + usb_device = NULL; + } + } else { + printf(" error\n"); + libusb_close(usb_device); + usb_device = NULL; + } + } + } else { + printf(" default\n"); + libusb_open(devices[i], &usb_device); + break; + } + } + } + } + + libusb_free_device_list(devices, 1); + + return usb_device; +} + int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device) { int result; @@ -273,62 +327,19 @@ int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** { return HACKRF_ERROR_INVALID_PARAM; } - - -libusb_device** devices = NULL; -const ssize_t list_length = libusb_get_device_list(g_libusb_context, &devices); -printf("All devices: %ld\n", list_length); -for(ssize_t i=0; i 0 ) { - if( libusb_open(devices[i], &usb_device) != 0 ) { - usb_device = NULL; - continue; - } - char serial_number[64]; - const int serial_number_length = libusb_get_string_descriptor_ascii(usb_device, serial_descriptor_index, (unsigned char*)serial_number, sizeof(serial_number)); - if( serial_number_length == 32 ) { - serial_number[32] = 0; - printf(" %s", serial_number); - if( strncmp(serial_number, desired_serial_number, 32) == 0 ) { - printf(" match\n"); - break; - } else { - printf(" skip\n"); - libusb_close(usb_device); - usb_device = NULL; - } - } else { - printf(" error\n"); - libusb_close(usb_device); - usb_device = NULL; - } - } - } else { - printf(" default\n"); - libusb_open(devices[i], &usb_device); - break; - } - } + + if( desired_serial_number ) + { + usb_device = hackrf_open_usb(desired_serial_number); + } else { + usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); } -} -libusb_free_device_list(devices, 1); - - // TODO: Do proper scanning of available devices, searching for - // unit serial number (if specified?). -/* - usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); + if( usb_device == NULL ) { usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); } -*/ + if( usb_device == NULL ) { return HACKRF_ERROR_NOT_FOUND; From 8e21b9882fd51a912e8141c095b483f056cbd147 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 21:44:22 +0200 Subject: [PATCH 05/16] Permit serial number without leading zeros so you don't have to type as much. In fact, permit any suffix of the serial number. --- host/libhackrf/src/hackrf.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 4bf5fd7b..2030f3d4 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -268,15 +268,27 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) libusb_device_handle* usb_device = NULL; libusb_device** devices = NULL; const ssize_t list_length = libusb_get_device_list(g_libusb_context, &devices); + int match_len = 0; printf("Number of USB devices: %ld\n", list_length); + if( desired_serial_number ) { + /* If a shorter serial number is specified, only match against the suffix. + * Should probably complain if the match is not unique, currently doesn't. + */ + match_len = strlen(desired_serial_number); + if ( match_len > 32 ) + return NULL; + } + for (ssize_t i=0; i 0 ) { @@ -289,7 +301,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) if( serial_number_length == 32 ) { serial_number[32] = 0; printf(" %s", serial_number); - if( strncmp(serial_number, desired_serial_number, 32) == 0 ) { + if( strncmp(serial_number + 32-match_len, desired_serial_number, match_len) == 0 ) { printf(" match\n"); break; } else { From b14d77a173562a68d3f2cfc9c851dac04cbda1bb Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 22:35:11 +0200 Subject: [PATCH 06/16] Adjust debug printf's a bit --- host/libhackrf/src/hackrf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 2030f3d4..a61b54f8 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -287,7 +287,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) if( device_descriptor.idVendor == hackrf_usb_vid ) { if( (device_descriptor.idProduct == hackrf_one_usb_pid) || (device_descriptor.idProduct == hackrf_jawbreaker_usb_pid) ) { - printf("%4x:%4x", device_descriptor.idVendor, device_descriptor.idProduct); + printf("USB device %4x:%4x:", device_descriptor.idVendor, device_descriptor.idProduct); if( desired_serial_number != NULL ) { const uint_fast8_t serial_descriptor_index = device_descriptor.iSerialNumber; @@ -310,7 +310,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) usb_device = NULL; } } else { - printf(" error\n"); + printf(" wrong length of serial number: %d\n", serial_number_length); libusb_close(usb_device); usb_device = NULL; } From 6aa5f00186121e5436822af77f4d74edea832652 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 22:40:59 +0200 Subject: [PATCH 07/16] hackrf_spiflash: added -d for device serial number --- host/hackrf-tools/src/hackrf_spiflash.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 00113bdf..d58c41ee 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -89,6 +89,7 @@ static void usage() printf("\t-l, --length : number of bytes to read (default: 0)\n"); printf("\t-r : Read data into file.\n"); printf("\t-w : Write data from file.\n"); + printf("\t-d : Serial number of device, if multiple devices\n"); } int main(int argc, char** argv) @@ -99,6 +100,7 @@ int main(int argc, char** argv) uint32_t tmp_length; uint16_t xfer_len = 0; const char* path = NULL; + const char* serial_number = NULL; hackrf_device* device = NULL; int result = HACKRF_SUCCESS; int option_index = 0; @@ -108,7 +110,7 @@ int main(int argc, char** argv) bool read = false; bool write = false; - while ((opt = getopt_long(argc, argv, "a:l:r:w:", long_options, + while ((opt = getopt_long(argc, argv, "a:l:r:w:d:", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -128,6 +130,10 @@ int main(int argc, char** argv) write = true; path = optarg; break; + + case 'd': + serial_number = optarg; + break; default: fprintf(stderr, "opt error: %d\n", opt); @@ -213,7 +219,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(NULL, &device); + result = hackrf_open(serial_number, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); From 33e20bda0cd69b90a8c9507f6bcc32ef681e8254 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 23 Feb 2015 22:44:18 +0200 Subject: [PATCH 08/16] hackrf_cpldjtag: added -d for device serial number --- host/hackrf-tools/src/hackrf_cpldjtag.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index 4fac03a5..c2120990 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -80,6 +80,7 @@ static void usage() { printf("Usage:\n"); printf("\t-x : XSVF file to be written to CPLD.\n"); + printf("\t-d : Serial number of device, if multiple devices\n"); } int main(int argc, char** argv) @@ -88,6 +89,7 @@ int main(int argc, char** argv) uint32_t length = 0; uint32_t total_length = 0; const char* path = NULL; + const char* serial_number = NULL; hackrf_device* device = NULL; int result = HACKRF_SUCCESS; int option_index = 0; @@ -95,13 +97,17 @@ int main(int argc, char** argv) ssize_t bytes_read; uint8_t* pdata = &data[0]; - while ((opt = getopt_long(argc, argv, "x:", long_options, + while ((opt = getopt_long(argc, argv, "x:d:", long_options, &option_index)) != EOF) { switch (opt) { case 'x': path = optarg; break; + case 'd': + serial_number = optarg; + break; + default: usage(); return EXIT_FAILURE; @@ -158,7 +164,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(NULL, &device); + result = hackrf_open(serial_number, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); From 856d9a635453cd9a391df8b0c231824f4d4a4d9b Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 00:33:26 +0200 Subject: [PATCH 09/16] libhackrf: hackrf_device_list() API for device enumeration and opening of any device (with or without serial numbers). hackrf_info uses hackrf_device_list to list devices, with or without serial number API support. --- host/hackrf-tools/src/hackrf_info.c | 105 ++++++++++++---------- host/libhackrf/src/hackrf.c | 131 +++++++++++++++++++++++----- host/libhackrf/src/hackrf.h | 16 ++++ 3 files changed, 183 insertions(+), 69 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index 47ab9264..571c546b 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -33,6 +33,8 @@ int main(int argc, char** argv) uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; read_partid_serialno_t read_partid_serialno; + hackrf_device_list_t *list; + int i; result = hackrf_init(); if (result != HACKRF_SUCCESS) { @@ -40,55 +42,68 @@ int main(int argc, char** argv) hackrf_error_name(result), result); return EXIT_FAILURE; } - - result = hackrf_open(NULL, &device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_open() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - - printf("Found HackRF board.\n"); - - result = hackrf_board_id_read(device, &board_id); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Board ID Number: %d (%s)\n", board_id, - hackrf_board_id_name(board_id)); - - result = hackrf_version_string_read(device, &version[0], 255); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Firmware Version: %s\n", version); - - result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_board_partid_serialno_read() failed: %s (%d)\n", - hackrf_error_name(result), result); - return EXIT_FAILURE; - } - printf("Part ID Number: 0x%08x 0x%08x\n", - read_partid_serialno.part_id[0], - read_partid_serialno.part_id[1]); - printf("Serial Number: 0x%08x 0x%08x 0x%08x 0x%08x\n", - read_partid_serialno.serial_no[0], - read_partid_serialno.serial_no[1], - read_partid_serialno.serial_no[2], - read_partid_serialno.serial_no[3]); - result = hackrf_close(device); - if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_close() failed: %s (%d)\n", - hackrf_error_name(result), result); + list = hackrf_device_list(); + + if (list->devicecount < 1 ) { + printf("No HackRF boards found.\n"); return EXIT_FAILURE; } + + for (i = 0; i < list->devicecount; i++) { + + if (i > 0) + printf("\n"); + + result = hackrf_device_list_open(list, i, &device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_open() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Found HackRF board %d:\n", i); + + result = hackrf_board_id_read(device, &board_id); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Board ID Number: %d (%s)\n", board_id, + hackrf_board_id_name(board_id)); + + result = hackrf_version_string_read(device, &version[0], 255); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_version_string_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Firmware Version: %s\n", version); + + result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_board_partid_serialno_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Part ID Number: 0x%08x 0x%08x\n", + read_partid_serialno.part_id[0], + read_partid_serialno.part_id[1]); + printf("Serial Number: 0x%08x 0x%08x 0x%08x 0x%08x\n", + read_partid_serialno.serial_no[0], + read_partid_serialno.serial_no[1], + read_partid_serialno.serial_no[2], + read_partid_serialno.serial_no[3]); + + result = hackrf_close(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_close() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + } + hackrf_exit(); return EXIT_SUCCESS; diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index a61b54f8..8c83298a 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -263,6 +263,66 @@ int ADDCALL hackrf_exit(void) #include #include +hackrf_device_list_t* ADDCALL hackrf_device_list() +{ + libusb_device_handle* usb_device = NULL; + hackrf_device_list_t* list = calloc(1, sizeof(*list)); + list->usb_devicecount = libusb_get_device_list(g_libusb_context, (libusb_device ***)&list->usb_devices); + + list->serial_numbers = calloc(list->usb_devicecount, sizeof(void *)); + list->product_ids = calloc(list->usb_devicecount, sizeof(int)); + list->usb_device_index = calloc(list->usb_devicecount, sizeof(int)); + + for (ssize_t i=0; iusb_devicecount; i++) { + struct libusb_device_descriptor device_descriptor; + libusb_get_device_descriptor(list->usb_devices[i], &device_descriptor); + + if( device_descriptor.idVendor == hackrf_usb_vid ) { + if( (device_descriptor.idProduct == hackrf_one_usb_pid) || (device_descriptor.idProduct == hackrf_jawbreaker_usb_pid) ) { + int idx = list->devicecount++; + list->product_ids[idx] = device_descriptor.idProduct; + list->usb_device_index[idx] = i; + + const uint_fast8_t serial_descriptor_index = device_descriptor.iSerialNumber; + if( serial_descriptor_index > 0 ) { + if( libusb_open(list->usb_devices[i], &usb_device) != 0 ) { + usb_device = NULL; + continue; + } + char serial_number[64]; + const int serial_number_length = libusb_get_string_descriptor_ascii(usb_device, serial_descriptor_index, (unsigned char*)serial_number, sizeof(serial_number)); + if( serial_number_length == 32 ) { + serial_number[32] = 0; + list->serial_numbers[idx] = strdup(serial_number); + } + + libusb_close(usb_device); + usb_device = NULL; + } + } + } + } + + return list; +} + +void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list) +{ + int i; + + libusb_free_device_list((libusb_device **)list->usb_devices, 1); + + for (i = 0; i < list->devicecount; i++) { + if (list->serial_numbers[i]) + free(list->serial_numbers[i]); + } + + free(list->serial_numbers); + free(list->product_ids); + free(list->usb_device_index); + free(list); +} + libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) { libusb_device_handle* usb_device = NULL; @@ -329,33 +389,10 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) return usb_device; } -int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device) +static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** device) { int result; - libusb_device_handle* usb_device; hackrf_device* lib_device; - - if( device == NULL ) - { - return HACKRF_ERROR_INVALID_PARAM; - } - - if( desired_serial_number ) - { - usb_device = hackrf_open_usb(desired_serial_number); - } else { - usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); - } - - if( usb_device == NULL ) - { - usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); - } - - if( usb_device == NULL ) - { - return HACKRF_ERROR_NOT_FOUND; - } //int speed = libusb_get_device_speed(usb_device); // TODO: Error or warning if not high speed USB? @@ -410,6 +447,52 @@ int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** return HACKRF_SUCCESS; } +int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device) +{ + libusb_device_handle* usb_device; + + if( device == NULL ) + { + return HACKRF_ERROR_INVALID_PARAM; + } + + if( desired_serial_number ) + { + usb_device = hackrf_open_usb(desired_serial_number); + } else { + usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); + + if( usb_device == NULL ) + { + usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); + } + } + + if( usb_device == NULL ) + { + return HACKRF_ERROR_NOT_FOUND; + } + + return hackrf_open_setup(usb_device, device); +} + +int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device) +{ + libusb_device_handle* usb_device; + + if( device == NULL || list == NULL || idx < 0 || idx >= list->devicecount ) + { + return HACKRF_ERROR_INVALID_PARAM; + } + + if( libusb_open(list->usb_devices[idx], &usb_device) != 0 ) { + usb_device = NULL; + return HACKRF_ERROR_LIBUSB; + } + + return hackrf_open_setup(usb_device, device); +} + int ADDCALL hackrf_set_transceiver_mode(hackrf_device* device, hackrf_transceiver_mode value) { int result; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 6b615647..08afe3c9 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -91,6 +91,18 @@ typedef struct { uint32_t serial_no[4]; } read_partid_serialno_t; + +struct hackrf_device_list { + char **serial_numbers; + int *product_ids; + int *usb_device_index; + int devicecount; + + void **usb_devices; + int usb_devicecount; +}; +typedef struct hackrf_device_list hackrf_device_list_t; + typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer); #ifdef __cplusplus @@ -100,6 +112,10 @@ extern "C" extern ADDAPI int ADDCALL hackrf_init(); extern ADDAPI int ADDCALL hackrf_exit(); + +extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list(); +extern ADDAPI int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device); +extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list); extern ADDAPI int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device); extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device); From d10dd1945c468060c8bc0331cb1c58beac4ae4d9 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 00:45:57 +0200 Subject: [PATCH 10/16] hackrf_info: Adjust output to print USB device identification string and device index number, before trying to open. --- host/hackrf-tools/src/hackrf_info.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index 571c546b..99b86d3b 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -28,7 +28,6 @@ int main(int argc, char** argv) { - hackrf_device* device = NULL; int result = HACKRF_SUCCESS; uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; @@ -51,10 +50,15 @@ int main(int argc, char** argv) } for (i = 0; i < list->devicecount; i++) { - if (i > 0) printf("\n"); + printf("Found HackRF board %d:\n", i); + + if (list->serial_numbers[i]) + printf("USB descriptor string: %s\n", list->serial_numbers[i]); + + hackrf_device* device = NULL; result = hackrf_device_list_open(list, i, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", @@ -62,8 +66,6 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - printf("Found HackRF board %d:\n", i); - result = hackrf_board_id_read(device, &board_id); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_board_id_read() failed: %s (%d)\n", @@ -100,10 +102,10 @@ int main(int argc, char** argv) if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; } } + hackrf_device_list_free(list); hackrf_exit(); return EXIT_SUCCESS; From 893fef3fcfec12a9ac3750243637e5eac1332303 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 01:25:58 +0200 Subject: [PATCH 11/16] Bug fix, open the correct device in hackrf_device_list_open --- host/libhackrf/src/hackrf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 8c83298a..42d69c83 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -485,7 +485,9 @@ int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_ return HACKRF_ERROR_INVALID_PARAM; } - if( libusb_open(list->usb_devices[idx], &usb_device) != 0 ) { + int i = list->usb_device_index[idx]; + + if( libusb_open(list->usb_devices[i], &usb_device) != 0 ) { usb_device = NULL; return HACKRF_ERROR_LIBUSB; } From c0b3638ccee1afb1fc8d7b96cb3b1bd1b0eda686 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 07:15:46 +0200 Subject: [PATCH 12/16] Do not break hackrf_open() API, provide a hackrf_open_by_serial() instead for the new functionality. --- host/hackrf-tools/src/hackrf_cpldjtag.c | 2 +- host/hackrf-tools/src/hackrf_max2837.c | 2 +- host/hackrf-tools/src/hackrf_rffc5071.c | 2 +- host/hackrf-tools/src/hackrf_si5351c.c | 2 +- host/hackrf-tools/src/hackrf_spiflash.c | 2 +- host/hackrf-tools/src/hackrf_transfer.c | 2 +- host/libhackrf/src/hackrf.c | 39 ++++++++++++++++++------- host/libhackrf/src/hackrf.h | 3 +- 8 files changed, 37 insertions(+), 17 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_cpldjtag.c b/host/hackrf-tools/src/hackrf_cpldjtag.c index c2120990..b76c9349 100644 --- a/host/hackrf-tools/src/hackrf_cpldjtag.c +++ b/host/hackrf-tools/src/hackrf_cpldjtag.c @@ -164,7 +164,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(serial_number, &device); + result = hackrf_open_by_serial(serial_number, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_max2837.c b/host/hackrf-tools/src/hackrf_max2837.c index 81ebea65..d8fb75f5 100644 --- a/host/hackrf-tools/src/hackrf_max2837.c +++ b/host/hackrf-tools/src/hackrf_max2837.c @@ -130,7 +130,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(NULL, &device); + result = hackrf_open(&device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_rffc5071.c b/host/hackrf-tools/src/hackrf_rffc5071.c index 00e48d85..c9630dd4 100644 --- a/host/hackrf-tools/src/hackrf_rffc5071.c +++ b/host/hackrf-tools/src/hackrf_rffc5071.c @@ -131,7 +131,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(NULL, &device); + result = hackrf_open(&device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index 0db251e2..41146f2c 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -195,7 +195,7 @@ int main(int argc, char** argv) { return -1; } - result = hackrf_open(NULL, &device); + result = hackrf_open(&device); if( result ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index d58c41ee..f210f370 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -219,7 +219,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - result = hackrf_open(serial_number, &device); + result = hackrf_open_by_serial(serial_number, &device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 780b2d47..b76ae631 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -782,7 +782,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - result = hackrf_open(serial_number, &device); + result = hackrf_open_by_serial(serial_number, &device); if( result != HACKRF_SUCCESS ) { printf("hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 42d69c83..063ad11f 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -447,7 +447,7 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d return HACKRF_SUCCESS; } -int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device) +int ADDCALL hackrf_open(hackrf_device** device) { libusb_device_handle* usb_device; @@ -456,16 +456,11 @@ int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** return HACKRF_ERROR_INVALID_PARAM; } - if( desired_serial_number ) + usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); + + if( usb_device == NULL ) { - usb_device = hackrf_open_usb(desired_serial_number); - } else { - usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_one_usb_pid); - - if( usb_device == NULL ) - { - usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); - } + usb_device = libusb_open_device_with_vid_pid(g_libusb_context, hackrf_usb_vid, hackrf_jawbreaker_usb_pid); } if( usb_device == NULL ) @@ -476,6 +471,30 @@ int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** return hackrf_open_setup(usb_device, device); } +int ADDCALL hackrf_open_by_serial(const char* const desired_serial_number, hackrf_device** device) +{ + libusb_device_handle* usb_device; + + if( desired_serial_number == NULL ) + { + return hackrf_open(device); + } + + if( device == NULL ) + { + return HACKRF_ERROR_INVALID_PARAM; + } + + usb_device = hackrf_open_usb(desired_serial_number); + + if( usb_device == NULL ) + { + return HACKRF_ERROR_NOT_FOUND; + } + + return hackrf_open_setup(usb_device, device); +} + int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device) { libusb_device_handle* usb_device; diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 08afe3c9..d75ee24b 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -117,7 +117,8 @@ extern ADDAPI hackrf_device_list_t* ADDCALL hackrf_device_list(); extern ADDAPI int ADDCALL hackrf_device_list_open(hackrf_device_list_t *list, int idx, hackrf_device** device); extern ADDAPI void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list); -extern ADDAPI int ADDCALL hackrf_open(const char* const desired_serial_number, hackrf_device** device); +extern ADDAPI int ADDCALL hackrf_open(hackrf_device** device); +extern ADDAPI int ADDCALL hackrf_open_by_serial(const char* const desired_serial_number, hackrf_device** device); extern ADDAPI int ADDCALL hackrf_close(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn callback, void* rx_ctx); From 9b9466f02a3bba8a69b9310c8636a44ab2010c2f Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 12:15:05 +0200 Subject: [PATCH 13/16] libhackrf: The usb firmware reports board type as USB product id. Provide hackrf_usb_board_id_name() to decode that. --- host/libhackrf/src/hackrf.c | 18 ++++++++++++++++++ host/libhackrf/src/hackrf.h | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 063ad11f..4987d329 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1519,6 +1519,24 @@ const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id) } } +extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id) +{ + switch(usb_board_id) + { + case USB_BOARD_ID_JAWBREAKER: + return "Jawbreaker"; + + case USB_BOARD_ID_HACKRF_ONE: + return "HackRF One"; + + case USB_BOARD_ID_INVALID: + return "Invalid Board ID"; + + default: + return "Unknown Board ID"; + } +} + const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path) { switch(path) { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index d75ee24b..8a8f16ec 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -69,6 +69,12 @@ enum hackrf_board_id { BOARD_ID_INVALID = 0xFF, }; +enum hackrf_usb_board_id { + USB_BOARD_ID_JAWBREAKER = 0x604B, + USB_BOARD_ID_HACKRF_ONE = 0x6089, + USB_BOARD_ID_INVALID = 0xFFFF, +}; + enum rf_path_filter { RF_PATH_FILTER_BYPASS = 0, RF_PATH_FILTER_LOW_PASS = 1, @@ -181,6 +187,7 @@ extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode); extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id); +extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(enum hackrf_usb_board_id usb_board_id); extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_filter path); /* Compute nearest freq for bw filter (manual filter) */ From 1fae679af3784b38acd412bb3a1d63134f55bdd5 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 12:28:07 +0200 Subject: [PATCH 14/16] device enumeration: Return usb_board_ids as an enum --- host/libhackrf/src/hackrf.c | 14 +++++++++++--- host/libhackrf/src/hackrf.h | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 4987d329..d46f91a5 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -267,12 +267,20 @@ hackrf_device_list_t* ADDCALL hackrf_device_list() { libusb_device_handle* usb_device = NULL; hackrf_device_list_t* list = calloc(1, sizeof(*list)); + if ( list == NULL ) + return NULL; + list->usb_devicecount = libusb_get_device_list(g_libusb_context, (libusb_device ***)&list->usb_devices); list->serial_numbers = calloc(list->usb_devicecount, sizeof(void *)); - list->product_ids = calloc(list->usb_devicecount, sizeof(int)); + list->usb_board_ids = calloc(list->usb_devicecount, sizeof(enum hackrf_usb_board_id)); list->usb_device_index = calloc(list->usb_devicecount, sizeof(int)); + if ( list->serial_numbers == NULL || list->usb_board_ids == NULL || list->usb_device_index == NULL) { + hackrf_device_list_free(list); + return NULL; + } + for (ssize_t i=0; iusb_devicecount; i++) { struct libusb_device_descriptor device_descriptor; libusb_get_device_descriptor(list->usb_devices[i], &device_descriptor); @@ -280,7 +288,7 @@ hackrf_device_list_t* ADDCALL hackrf_device_list() if( device_descriptor.idVendor == hackrf_usb_vid ) { if( (device_descriptor.idProduct == hackrf_one_usb_pid) || (device_descriptor.idProduct == hackrf_jawbreaker_usb_pid) ) { int idx = list->devicecount++; - list->product_ids[idx] = device_descriptor.idProduct; + list->usb_board_ids[idx] = device_descriptor.idProduct; list->usb_device_index[idx] = i; const uint_fast8_t serial_descriptor_index = device_descriptor.iSerialNumber; @@ -318,7 +326,7 @@ void ADDCALL hackrf_device_list_free(hackrf_device_list_t *list) } free(list->serial_numbers); - free(list->product_ids); + free(list->usb_board_ids); free(list->usb_device_index); free(list); } diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 8a8f16ec..dfcf06d3 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -100,7 +100,7 @@ typedef struct { struct hackrf_device_list { char **serial_numbers; - int *product_ids; + enum hackrf_usb_board_id *usb_board_ids; int *usb_device_index; int devicecount; From 7c95f8bb5fdb0c242e4d39a8b5291b9fa0544fe6 Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Tue, 24 Feb 2015 14:56:19 +0200 Subject: [PATCH 15/16] hackrf_init: only call libusb_init() once --- host/libhackrf/src/hackrf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index d46f91a5..256948e9 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -240,6 +240,10 @@ extern "C" int ADDCALL hackrf_init(void) { + if (g_libusb_context != NULL) { + return HACKRF_SUCCESS; + } + const int libusb_error = libusb_init(&g_libusb_context); if( libusb_error != 0 ) { From 3f523326fd640e138e48e87011beeeb4e841515d Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 25 May 2015 09:58:40 +0300 Subject: [PATCH 16/16] Fix compiling on GCC 4.9 ('for' loop initial declarations not allowed with -std=gnu90) --- host/libhackrf/src/hackrf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 256948e9..cb1dafc0 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -269,6 +269,7 @@ int ADDCALL hackrf_exit(void) hackrf_device_list_t* ADDCALL hackrf_device_list() { + ssize_t i; libusb_device_handle* usb_device = NULL; hackrf_device_list_t* list = calloc(1, sizeof(*list)); if ( list == NULL ) @@ -285,7 +286,7 @@ hackrf_device_list_t* ADDCALL hackrf_device_list() return NULL; } - for (ssize_t i=0; iusb_devicecount; i++) { + for (i=0; iusb_devicecount; i++) { struct libusb_device_descriptor device_descriptor; libusb_get_device_descriptor(list->usb_devices[i], &device_descriptor); @@ -341,6 +342,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) libusb_device** devices = NULL; const ssize_t list_length = libusb_get_device_list(g_libusb_context, &devices); int match_len = 0; + ssize_t i; printf("Number of USB devices: %ld\n", list_length); @@ -353,7 +355,7 @@ libusb_device_handle* hackrf_open_usb(const char* const desired_serial_number) return NULL; } - for (ssize_t i=0; i