From 255b7b4705046891aca4d983a50664ffc21ce19c Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 30 Jan 2017 18:30:17 -0700 Subject: [PATCH 1/2] Add USB API versioning --- firmware/hackrf_usb/usb_descriptor.c | 2 +- host/hackrf-tools/src/hackrf_info.c | 31 +++++++---- host/hackrf-tools/src/hackrf_operacake.c | 54 ++++++++++++------ host/hackrf-tools/src/hackrf_spiflash.c | 25 +++++---- host/hackrf-tools/src/hackrf_sweep.c | 3 +- host/hackrf-tools/src/hackrf_transfer.c | 4 +- host/libhackrf/src/hackrf.c | 71 +++++++++++++++++------- host/libhackrf/src/hackrf.h | 11 +++- 8 files changed, 133 insertions(+), 68 deletions(-) diff --git a/firmware/hackrf_usb/usb_descriptor.c b/firmware/hackrf_usb/usb_descriptor.c index 5a9eeb45..6f6560b1 100644 --- a/firmware/hackrf_usb/usb_descriptor.c +++ b/firmware/hackrf_usb/usb_descriptor.c @@ -55,7 +55,7 @@ uint8_t usb_descriptor_device[] = { USB_MAX_PACKET0, // bMaxPacketSize0 USB_WORD(USB_VENDOR_ID), // idVendor USB_WORD(USB_PRODUCT_ID), // idProduct - USB_WORD(0x0101), // bcdDevice + USB_WORD(0x0102), // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x04, // iSerialNumber diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index def5371d..bd487eb7 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -31,6 +31,7 @@ int main(void) int result = HACKRF_SUCCESS; uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; + uint16_t usb_version; read_partid_serialno_t read_partid_serialno; uint8_t operacakes[8]; hackrf_device_list_t *list; @@ -55,10 +56,11 @@ int main(void) if (i > 0) printf("\n"); - printf("Found HackRF board %d:\n", i); + printf("Found HackRF\n"); + printf("Index: %d\n", i); if (list->serial_numbers[i]) - printf("USB descriptor string: %s\n", list->serial_numbers[i]); + printf("Serial number: %s\n", list->serial_numbers[i]); device = NULL; result = hackrf_device_list_open(list, i, &device); @@ -83,7 +85,15 @@ int main(void) hackrf_error_name(result), result); return EXIT_FAILURE; } - printf("Firmware Version: %s\n", version); + + result = hackrf_usb_api_version_read(device, &usb_version); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_usb_api_version_read() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + printf("Firmware Version: %s (API:%x.%02x)\n", version, + (usb_version>>8)&0xFF, usb_version&0xFF); result = hackrf_board_partid_serialno_read(device, &read_partid_serialno); if (result != HACKRF_SUCCESS) { @@ -101,16 +111,17 @@ int main(void) read_partid_serialno.serial_no[3]); result = hackrf_get_operacake_boards(device, &operacakes[0]); - if (result != HACKRF_SUCCESS) { + if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) { fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", hackrf_error_name(result), result); - return EXIT_FAILURE; + return EXIT_FAILURE; } - for(j=0; j<8; j++) { - if(operacakes[j] == 0) - break; - printf("Operacake found, address: 0x%02x\n", operacakes[j]); - + if(result == HACKRF_SUCCESS) { + for(j=0; j<8; j++) { + if(operacakes[j] == 0) + break; + printf("Operacake found, address: 0x%02x\n", operacakes[j]); + } } result = hackrf_close(device); diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index def90690..91e1e0d2 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -39,14 +39,14 @@ static void usage() { printf("\t-o, --address : specify a particular operacake by address [default: 0x00]\n"); printf("\t-a : set port A connection\n"); printf("\t-b : set port B connection\n"); - printf("\t-v, --verbose: verbose, list available operacake boards\n"); + printf("\t-l, --list: list available operacake boards\n"); } static struct option long_options[] = { { "device", no_argument, 0, 'd' }, { "serial", no_argument, 0, 's' }, { "address", no_argument, 0, 'o' }, - { "verbose", no_argument, 0, 'v' }, + { "list", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, }; @@ -69,8 +69,10 @@ int main(int argc, char** argv) { int operacake_address = 0; int port_a = 0; int port_b = 0; - int verbose = 0; + bool set_ports = false; + bool list = false; uint8_t operacakes[8]; + uint8_t operacake_count = 0; int i = 0; hackrf_device* device = NULL; int option_index = 0; @@ -81,7 +83,7 @@ int main(int argc, char** argv) { return -1; } - while( (opt = getopt_long(argc, argv, "d:s:o:a:b:vh?", long_options, &option_index)) != EOF ) { + while( (opt = getopt_long(argc, argv, "d:s:o:a:b:lh?", long_options, &option_index)) != EOF ) { switch( opt ) { case 'd': device_index = atoi(optarg); @@ -93,6 +95,7 @@ int main(int argc, char** argv) { case 'o': operacake_address = atoi(optarg); + set_ports = true; break; case 'a': @@ -103,8 +106,8 @@ int main(int argc, char** argv) { port_b = atoi(optarg); break; - case 'v': - verbose = 1; + case 'l': + list = true; break; case 'h': case '?': @@ -123,6 +126,12 @@ int main(int argc, char** argv) { } } + if(!(list || set_ports)) { + fprintf(stderr, "Specify either list or address option.\n"); + usage(); + return EXIT_FAILURE; + } + if(serial_number != NULL) { result = hackrf_open_by_serial(serial_number, &device); } else { @@ -139,20 +148,31 @@ int main(int argc, char** argv) { return -1; } - if(verbose) { - hackrf_get_operacake_boards(device, operacakes); - printf("Operacakes found:\n"); - for(i=0; i<8; i++) { - if(operacakes[i] !=0) - printf("%d\n", operacakes[i]); + if(list) { + result = hackrf_get_operacake_boards(device, operacakes); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; } + printf("Operacakes found: "); + for(i=0; i<8; i++) { + if(operacakes[i] !=0) { + printf("\n%d", operacakes[i]); + operacake_count++; + } + } + if(!operacake_count) + printf("None"); printf("\n"); } - result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b); - if( result ) { - printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result); - return -1; + if(set_ports) { + result = hackrf_set_operacake_ports(device, operacake_address, port_a, port_b); + if( result ) { + printf("hackrf_set_operacake_ports() failed: %s (%d)\n", hackrf_error_name(result), result); + return -1; + } } result = hackrf_close(device); @@ -160,8 +180,6 @@ int main(int argc, char** argv) { printf("hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); return -1; } - hackrf_exit(); - return 0; } diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index d230a6b6..fabdb382 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -118,6 +118,7 @@ int main(int argc, char** argv) bool write = false; bool verbose = false; bool reset = false; + uint16_t usb_api; while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vRh?", long_options, &option_index)) != EOF) { @@ -309,13 +310,22 @@ int main(int argc, char** argv) } } + if (fd != NULL) { + fclose(fd); + fd = NULL; + } + if(reset) { result = hackrf_reset(device); if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", - hackrf_error_name(result), result); - fclose(fd); - fd = NULL; + if (result == HACKRF_ERROR_USB_API_VERSION) { + hackrf_usb_api_version_read(device, &usb_api); + fprintf(stderr, "Reset is not supported by firmware API %x.%02x\n", + (usb_api>>8)&0xFF, usb_api&0xFF); + } else { + fprintf(stderr, "hackrf_reset() failed: %s (%d)\n", + hackrf_error_name(result), result); + } return EXIT_FAILURE; } } @@ -324,16 +334,9 @@ int main(int argc, char** argv) if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); - fclose(fd); - fd = NULL; return EXIT_FAILURE; } hackrf_exit(); - - if (fd != NULL) { - fclose(fd); - } - return EXIT_SUCCESS; } diff --git a/host/hackrf-tools/src/hackrf_sweep.c b/host/hackrf-tools/src/hackrf_sweep.c index c907a390..6c044203 100644 --- a/host/hackrf-tools/src/hackrf_sweep.c +++ b/host/hackrf-tools/src/hackrf_sweep.c @@ -448,7 +448,7 @@ int main(int argc, char** argv) { result |= hackrf_set_lna_gain(device, lna_gain); result |= hackrf_start_rx(device, rx_callback, NULL); if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_start_?x() failed: %s (%d)\n", hackrf_error_name(result), result); + fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } @@ -457,7 +457,6 @@ int main(int argc, char** argv) { if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_init_sweep() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); return EXIT_FAILURE; } diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index 5a812c13..ab211993 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -961,12 +961,10 @@ int main(int argc, char** argv) { } } - fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", - hw_sync); + fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync); result = hackrf_set_hw_sync_mode(device, hw_sync ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_set_hw_sync_mode() failed: %s (%d)\n", hackrf_error_name(result), result); - usage(); return EXIT_FAILURE; } diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 30c604f2..5d0025ab 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -1012,6 +1012,27 @@ int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, } } +extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, + uint16_t* version) +{ + int result; + libusb_device* dev; + struct libusb_device_descriptor desc; + dev = libusb_get_device(device->usb_device); + result = libusb_get_device_descriptor(dev, &desc); + if (result < 0) + return HACKRF_ERROR_LIBUSB; + + *version = desc.bcdDevice; + return HACKRF_SUCCESS; +} + +#define USB_API_REQUIRED(device, version) \ +uint16_t usb_version = 0; \ +hackrf_usb_api_version_read(device, &usb_version); \ +if(usb_version < version) \ + return HACKRF_ERROR_USB_API_VERSION; + typedef struct { uint32_t freq_mhz; /* From 0 to 6000+MHz */ uint32_t freq_hz; /* From 0 to 999999Hz */ @@ -1577,26 +1598,6 @@ int ADDCALL hackrf_close(hackrf_device* device) return result1; } -int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) { - int result = libusb_control_transfer( - device->usb_device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE, - value, - 0, - NULL, - 0, - 0 - ); - - if( result != 0 ) - { - return HACKRF_ERROR_LIBUSB; - } else { - return HACKRF_SUCCESS; - } -} - const char* ADDCALL hackrf_error_name(enum hackrf_error errcode) { switch(errcode) @@ -1634,6 +1635,9 @@ const char* ADDCALL hackrf_error_name(enum hackrf_error errcode) case HACKRF_ERROR_STREAMING_EXIT_CALLED: return "HACKRF_ERROR_STREAMING_EXIT_CALLED"; + case HACKRF_ERROR_USB_API_VERSION: + return "feature not supported by installed firmware"; + case HACKRF_ERROR_OTHER: return "HACKRF_ERROR_OTHER"; @@ -1744,9 +1748,33 @@ uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz) return p->bandwidth_hz; } +/* All features below require USB API version 0x1002 or higher) */ + +int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value) { + USB_API_REQUIRED(device, 0x0102) + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE, + value, + 0, + NULL, + 0, + 0 + ); + + if( result != 0 ) + { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + /* Initialise sweep mode with alist of frequencies and dwell time in samples */ int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, int length, uint32_t dwell_time) { + USB_API_REQUIRED(device, 0x0102) int result, i; int size = length * sizeof(frequency_list[0]); @@ -1776,6 +1804,7 @@ int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, i */ int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards) { + USB_API_REQUIRED(device, 0x0102) int result; result = libusb_control_transfer( device->usb_device, @@ -1802,6 +1831,7 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, uint8_t port_a, uint8_t port_b) { + USB_API_REQUIRED(device, 0x0102) int result; /* Error checking */ if((port_a > OPERACAKE_PB4) || (port_b > OPERACAKE_PB4)) { @@ -1831,6 +1861,7 @@ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, } int ADDCALL hackrf_reset(hackrf_device* device) { + USB_API_REQUIRED(device, 0x0102) int result = libusb_control_transfer( device->usb_device, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 06826aad..d1a57c4d 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -59,6 +59,7 @@ enum hackrf_error { HACKRF_ERROR_STREAMING_THREAD_ERR = -1002, HACKRF_ERROR_STREAMING_STOPPED = -1003, HACKRF_ERROR_STREAMING_EXIT_CALLED = -1004, + HACKRF_ERROR_USB_API_VERSION = -1005, HACKRF_ERROR_OTHER = -9999, }; @@ -170,6 +171,7 @@ extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, extern ADDAPI int ADDCALL hackrf_board_id_read(hackrf_device* device, uint8_t* value); extern ADDAPI int ADDCALL hackrf_version_string_read(hackrf_device* device, char* version, uint8_t length); +extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, uint16_t* version); extern ADDAPI int ADDCALL hackrf_set_freq(hackrf_device* device, const uint64_t freq_hz); extern ADDAPI int ADDCALL hackrf_set_freq_explicit(hackrf_device* device, @@ -198,9 +200,6 @@ extern ADDAPI int ADDCALL hackrf_set_txvga_gain(hackrf_device* device, uint32_t /* antenna port power control */ extern ADDAPI int ADDCALL hackrf_set_antenna_enable(hackrf_device* device, const uint8_t value); -/* set hardware sync mode */ -extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); - 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); @@ -210,6 +209,12 @@ extern ADDAPI const char* ADDCALL hackrf_filter_path_name(const enum rf_path_fil extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(const uint32_t bandwidth_hz); /* Compute best default value depending on sample rate (auto filter) */ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz); + +/* All features below require USB API version 0x1002 or higher) */ + +/* set hardware sync mode */ +extern ADDAPI int ADDCALL hackrf_set_hw_sync_mode(hackrf_device* device, const uint8_t value); + /* Start scan mode */ extern ADDAPI int ADDCALL hackrf_init_sweep(hackrf_device* device, uint16_t* frequency_list, From ec432b9d288cd26116746646a9f1611c99b09d82 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 30 Jan 2017 18:33:44 -0700 Subject: [PATCH 2/2] Remove duplicate serial number from hackrf_info --- host/hackrf-tools/src/hackrf_info.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index bd487eb7..0049a3e7 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -104,11 +104,6 @@ int main(void) 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_get_operacake_boards(device, &operacakes[0]); if ((result != HACKRF_SUCCESS) && (result != HACKRF_ERROR_USB_API_VERSION)) {