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);