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.
This commit is contained in:
Heikki Hannikainen
2015-02-24 00:33:26 +02:00
committed by Heikki Hannikainen
parent 33e20bda0c
commit 856d9a6354
3 changed files with 183 additions and 69 deletions

View File

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

View File

@ -263,6 +263,66 @@ int ADDCALL hackrf_exit(void)
#include <stdio.h>
#include <string.h>
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; i<list->usb_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;

View File

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