From 9dbe967bf224436dfe049021cf2d78b5a67fe9c2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 15 May 2014 10:08:07 -0700 Subject: [PATCH 01/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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/22] 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 d8ae5e37b091a7bcf5b4bdb112aaa2d0e206653d Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Thu, 26 Feb 2015 14:23:32 +0000 Subject: [PATCH 16/22] Attempt to detect correct group for udev rule --- host/CMakeLists.txt | 1 + host/libhackrf/CMakeLists.txt | 18 --------- host/misc/CMakeLists.txt | 2 + host/misc/udev/53-hackrf.rules.in | 6 +++ host/misc/udev/CMakeLists.txt | 61 +++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 host/misc/CMakeLists.txt create mode 100644 host/misc/udev/53-hackrf.rules.in create mode 100644 host/misc/udev/CMakeLists.txt diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 874163f8..52350c32 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -5,6 +5,7 @@ project (hackrf_all) add_subdirectory(libhackrf) add_subdirectory(hackrf-tools) +add_subdirectory(misc) ######################################################################## # Create uninstall target diff --git a/host/libhackrf/CMakeLists.txt b/host/libhackrf/CMakeLists.txt index 4f1ec642..8b003941 100644 --- a/host/libhackrf/CMakeLists.txt +++ b/host/libhackrf/CMakeLists.txt @@ -94,21 +94,3 @@ add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake ) endif() - -######################################################################## -# Install udev rules -######################################################################## -option(INSTALL_UDEV_RULES "Install udev rules for HackRF" OFF) -if (INSTALL_UDEV_RULES) - if (NOT UDEV_INSTALL_DIR) - set (UDEV_INSTALL_DIR "/etc/udev/rules.d") - endif (NOT UDEV_INSTALL_DIR) - - install ( - FILES 53-hackrf.rules - DESTINATION ${UDEV_INSTALL_DIR} - COMPONENT "udev" - ) -else (INSTALL_UDEV_RULES) - message (STATUS "Udev rules not being installed, install them with -DINSTALL_UDEV_RULES=ON") -endif (INSTALL_UDEV_RULES) diff --git a/host/misc/CMakeLists.txt b/host/misc/CMakeLists.txt new file mode 100644 index 00000000..f728056f --- /dev/null +++ b/host/misc/CMakeLists.txt @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 2.8) +add_subdirectory(udev) diff --git a/host/misc/udev/53-hackrf.rules.in b/host/misc/udev/53-hackrf.rules.in new file mode 100644 index 00000000..951c424d --- /dev/null +++ b/host/misc/udev/53-hackrf.rules.in @@ -0,0 +1,6 @@ +# HackRF Jawbreaker +ATTR{idVendor}=="1d50", ATTR{idProduct}=="604b", SYMLINK+="hackrf-jawbreaker-%k", MODE="660", GROUP="@HACKRF_GROUP@" +# HackRF One +ATTR{idVendor}=="1d50", ATTR{idProduct}=="6089", SYMLINK+="hackrf-one-%k", MODE="660", GROUP="@HACKRF_GROUP@" +# HackRF DFU +ATTR{idVendor}=="1fc9", ATTR{idProduct}=="000c", SYMLINK+="nxp-dfu-%k", MODE="660", GROUP="@HACKRF_GROUP@" diff --git a/host/misc/udev/CMakeLists.txt b/host/misc/udev/CMakeLists.txt new file mode 100644 index 00000000..1d65e63f --- /dev/null +++ b/host/misc/udev/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 2.8) + +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + SET(SYSTEM_IS_LINUX TRUE) + SET(UDEV_OPTION_DEFAULT ON) +else() + SET(SYSTEM_IS_LINUX FALSE) + SET(UDEV_OPTION_DEFAULT OFF) +endif() + +option(INSTALL_UDEV_RULES + "Install udev rules for the HackRF" + ${UDEV_OPTION_DEFAULT} +) + +set(UDEV_RULES_PATH + "/etc/udev/rules.d" + CACHE STRING + "Target directory for udev rule installation. Ensure you have permissions to write to this directory." +) + +if(SYSTEM_IS_LINUX) + if(INSTALL_UDEV_RULES) + if(NOT DEFINED UDEV_RULES_GROUP) + foreach(group usb plugdev) + execute_process(COMMAND "getent" group "${group}" + RESULT_VARIABLE _GETENT_RESULT + OUTPUT_QUIET + ERROR_QUIET) + if(NOT _GETENT_RESULT) + message(STATUS "Setting udev rule group to - ${group}") + set(UDEV_RULES_GROUP ${group}) + break() + endif(NOT _GETENT_RESULT) + endforeach(group) + endif(NOT DEFINED UDEV_RULES_GROUP) + if(DEFINED UDEV_RULES_GROUP) + set(HACKRF_GROUP "${UDEV_RULES_GROUP}" + CACHE STRING "Group to associate HackRF devices with in udev rules") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/53-hackrf.rules.in + ${CMAKE_CURRENT_BINARY_DIR}/53-hackrf.rules + @ONLY + ) + message(STATUS "HackRF udev rules will be installed to '${UDEV_RULES_PATH}' upon running 'make install'") + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/53-hackrf.rules + DESTINATION ${UDEV_RULES_PATH} + COMPONENT "udev_rules") + else(UDEV_RULES_GROUP) + message(STATUS "HackRF udev rules will not be installed because no suitable group was found") + message(STATUS "A group can be specified with -DUDEV_RULES_GROUP=") + endif(DEFINED UDEV_RULES_GROUP) + else(INSTALL_UDEV_RULES) + message(STATUS + "HackRF udev rules will not be installed because INSTALL_UDEV_RULES=OFF" + ) + endif(INSTALL_UDEV_RULES) +else(SYSTEM_IS_LINUX) + if(INSTALL_UDEV_RULES) + message(STATUS "udev rules not supported on this platform. Hide this message via -DINSTALL_UDEV_RULES=Off") + endif(INSTALL_UDEV_RULES) +endif(SYSTEM_IS_LINUX) From 3f523326fd640e138e48e87011beeeb4e841515d Mon Sep 17 00:00:00 2001 From: Heikki Hannikainen Date: Mon, 25 May 2015 09:58:40 +0300 Subject: [PATCH 17/22] 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 Date: Fri, 26 Jun 2015 17:50:27 +0100 Subject: [PATCH 18/22] Fix GitHub issue #163 - Detach the kernel driver automatically --- host/libhackrf/src/hackrf.c | 93 +++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 2902a800..2619ac49 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -69,6 +69,11 @@ typedef enum { HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24, } hackrf_vendor_request; +typedef enum { + USB_CONFIG_STANDARD = 0x1, + USB_CONFIG_CPLD_UPDATE = 0x2, +} hackrf_usb_configurations; + typedef enum { HACKRF_TRANSCEIVER_MODE_OFF = 0, HACKRF_TRANSCEIVER_MODE_RECEIVE = 1, @@ -233,6 +238,74 @@ static int prepare_transfers( } } +static int detach_kernel_drivers(libusb_device_handle* usb_device_handle) +{ + int i, result; + libusb_device* dev; + struct libusb_config_descriptor* config; + + dev = libusb_get_device(usb_device_handle); + result = libusb_get_active_config_descriptor(dev, &config); + if( result < 0 ) + { + return HACKRF_ERROR_LIBUSB; + } + + for(i=0; ibNumInterfaces; i++) + { + result = libusb_kernel_driver_active(usb_device_handle, i); + if( result < 0 ) + { + if( result == LIBUSB_ERROR_NOT_SUPPORTED ) { + return 0; + } + return HACKRF_ERROR_LIBUSB; + } else if( result == 1 ) { + result = libusb_detach_kernel_driver(usb_device_handle, i); + if( result != 0 ) + { + return HACKRF_ERROR_LIBUSB; + } + } + } + return HACKRF_SUCCESS; +} + +static int set_hackrf_configuration(libusb_device_handle* usb_device, int config) +{ + int result, curr_config; + result = libusb_get_configuration(usb_device, &curr_config); + if( result != 0 ) + { + libusb_close(usb_device); + return HACKRF_ERROR_LIBUSB; + } + + if(curr_config != config) + { + result = detach_kernel_drivers(usb_device); + if( result != 0 ) + { + libusb_close(usb_device); + return result; + } + result = libusb_set_configuration(usb_device, config); + if( result != 0 ) + { + libusb_close(usb_device); + return HACKRF_ERROR_LIBUSB; + } + } + + result = detach_kernel_drivers(usb_device); + if( result != 0 ) + { + libusb_close(usb_device); + return result; + } + return LIBUSB_SUCCESS; +} + #ifdef __cplusplus extern "C" { @@ -410,16 +483,15 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d //int speed = libusb_get_device_speed(usb_device); // TODO: Error or warning if not high speed USB? - - result = libusb_set_configuration(usb_device, 1); - if( result != 0 ) + + result = set_hackrf_configuration(usb_device, USB_CONFIG_STANDARD); + if( result != LIBUSB_SUCCESS ) { - libusb_close(usb_device); - return HACKRF_ERROR_LIBUSB; + return result; } result = libusb_claim_interface(usb_device, 0); - if( result != 0 ) + if( result != LIBUSB_SUCCESS ) { libusb_close(usb_device); return HACKRF_ERROR_LIBUSB; @@ -842,10 +914,13 @@ int ADDCALL hackrf_cpld_write(hackrf_device* device, return HACKRF_ERROR_LIBUSB; } - result = libusb_set_configuration(device->usb_device, 2); - if (result != LIBUSB_SUCCESS) { - return HACKRF_ERROR_LIBUSB; + result = set_hackrf_configuration(device->usb_device, USB_CONFIG_CPLD_UPDATE); + if( result != LIBUSB_SUCCESS ) + { + return result; } + result = libusb_set_configuration(device->usb_device, 2); + result = libusb_claim_interface(device->usb_device, 0); if (result != LIBUSB_SUCCESS) { From f3a9e6692460c2c97e6329a6677d5c9921f36786 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 29 Jun 2015 13:08:41 +0100 Subject: [PATCH 19/22] Remove duplicate call to set configuration + tidy calls to libusb_close() --- host/libhackrf/src/hackrf.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 2619ac49..2c061f21 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -277,7 +277,6 @@ static int set_hackrf_configuration(libusb_device_handle* usb_device, int config result = libusb_get_configuration(usb_device, &curr_config); if( result != 0 ) { - libusb_close(usb_device); return HACKRF_ERROR_LIBUSB; } @@ -286,13 +285,11 @@ static int set_hackrf_configuration(libusb_device_handle* usb_device, int config result = detach_kernel_drivers(usb_device); if( result != 0 ) { - libusb_close(usb_device); return result; } result = libusb_set_configuration(usb_device, config); if( result != 0 ) { - libusb_close(usb_device); return HACKRF_ERROR_LIBUSB; } } @@ -300,7 +297,6 @@ static int set_hackrf_configuration(libusb_device_handle* usb_device, int config result = detach_kernel_drivers(usb_device); if( result != 0 ) { - libusb_close(usb_device); return result; } return LIBUSB_SUCCESS; @@ -487,6 +483,7 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d result = set_hackrf_configuration(usb_device, USB_CONFIG_STANDARD); if( result != LIBUSB_SUCCESS ) { + libusb_close(usb_device); return result; } @@ -919,8 +916,6 @@ int ADDCALL hackrf_cpld_write(hackrf_device* device, { return result; } - result = libusb_set_configuration(device->usb_device, 2); - result = libusb_claim_interface(device->usb_device, 0); if (result != LIBUSB_SUCCESS) { From 9cfa4048e9abbe9a62bd794a9e2c1d0269b15fb2 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 29 Jun 2015 13:41:45 +0100 Subject: [PATCH 20/22] Free config descriptor once we have the number of interfaces --- 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 2c061f21..6632fb41 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -240,7 +240,7 @@ static int prepare_transfers( static int detach_kernel_drivers(libusb_device_handle* usb_device_handle) { - int i, result; + int i, num_interfaces, result; libusb_device* dev; struct libusb_config_descriptor* config; @@ -251,7 +251,9 @@ static int detach_kernel_drivers(libusb_device_handle* usb_device_handle) return HACKRF_ERROR_LIBUSB; } - for(i=0; ibNumInterfaces; i++) + num_interfaces = config->bNumInterfaces; + libusb_free_config_descriptor(config); + for(i=0; i Date: Mon, 6 Jul 2015 21:25:01 +0100 Subject: [PATCH 21/22] Fix issue #113 - CPLD update fails on Windows Using the patch from @supersat --- firmware/common/hackrf_core.h | 4 +++- firmware/hackrf_usb/hackrf_usb.c | 5 +++++ host/hackrf-tools/src/hackrf_transfer.c | 7 ------- host/libhackrf/src/hackrf.c | 21 +++++---------------- host/libhackrf/src/hackrf.h | 8 ++++++++ 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 8ce6c943..e19829d6 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -345,7 +345,9 @@ extern "C" typedef enum { TRANSCEIVER_MODE_OFF = 0, TRANSCEIVER_MODE_RX = 1, - TRANSCEIVER_MODE_TX = 2 + TRANSCEIVER_MODE_TX = 2, + TRANSCEIVER_MODE_SS = 3, + TRANSCEIVER_MODE_CPLD_UPDATE = 4 } transceiver_mode_t; void delay(uint32_t duration); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index e842d82b..c5ccb6ad 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -99,6 +99,11 @@ usb_request_status_t usb_vendor_request_set_transceiver_mode( set_transceiver_mode(endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); return USB_REQUEST_STATUS_OK; + case TRANSCEIVER_MODE_CPLD_UPDATE: + usb_endpoint_init(&usb_endpoint_bulk_out); + start_cpld_update = true; + usb_transfer_schedule_ack(endpoint->in); + return USB_REQUEST_STATUS_OK; default: return USB_REQUEST_STATUS_STALL; } diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index b76ae631..16e5456c 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -168,13 +168,6 @@ t_wav_file_hdr wave_file_hdr = } }; -typedef enum { - TRANSCEIVER_MODE_OFF = 0, - TRANSCEIVER_MODE_RX = 1, - TRANSCEIVER_MODE_TX = 2, - TRANSCEIVER_MODE_SS = 3 - -} transceiver_mode_t; static transceiver_mode_t transceiver_mode = TRANSCEIVER_MODE_RX; #define U64TOA_MAX_DIGIT (31) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 6632fb41..e68c7195 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -907,23 +907,12 @@ int ADDCALL hackrf_cpld_write(hackrf_device* device, { const unsigned int chunk_size = 512; unsigned int i; - int transferred = 0; - int result = libusb_release_interface(device->usb_device, 0); - if (result != LIBUSB_SUCCESS) { - return HACKRF_ERROR_LIBUSB; - } - - result = set_hackrf_configuration(device->usb_device, USB_CONFIG_CPLD_UPDATE); - if( result != LIBUSB_SUCCESS ) - { + int result, transferred = 0; + + result = hackrf_set_transceiver_mode(device, TRANSCEIVER_MODE_CPLD_UPDATE); + if (result != 0) return result; - } - - result = libusb_claim_interface(device->usb_device, 0); - if (result != LIBUSB_SUCCESS) { - return HACKRF_ERROR_LIBUSB; - } - + for (i = 0; i < total_length; i += chunk_size) { result = libusb_bulk_transfer( diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 6f043444..503e4ec3 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -81,6 +81,14 @@ enum rf_path_filter { RF_PATH_FILTER_HIGH_PASS = 2, }; +typedef enum { + TRANSCEIVER_MODE_OFF = 0, + TRANSCEIVER_MODE_RX = 1, + TRANSCEIVER_MODE_TX = 2, + TRANSCEIVER_MODE_SS = 3, + TRANSCEIVER_MODE_CPLD_UPDATE = 4 +} transceiver_mode_t; + typedef struct hackrf_device hackrf_device; typedef struct { From d3ce4779e90ecca6f340532323b546489c325c6f Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 7 Jul 2015 07:23:48 +0100 Subject: [PATCH 22/22] Fix inconsistent indentation --- firmware/common/hackrf_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index e19829d6..bad03a40 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -347,7 +347,7 @@ typedef enum { TRANSCEIVER_MODE_RX = 1, TRANSCEIVER_MODE_TX = 2, TRANSCEIVER_MODE_SS = 3, - TRANSCEIVER_MODE_CPLD_UPDATE = 4 + TRANSCEIVER_MODE_CPLD_UPDATE = 4 } transceiver_mode_t; void delay(uint32_t duration);