From 9dbe967bf224436dfe049021cf2d78b5a67fe9c2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 15 May 2014 10:08:07 -0700 Subject: [PATCH] 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);