mirror of
https://github.com/greatscottgadgets/hackrf.git
synced 2026-03-09 08:48:30 +01:00
Merge branch 'master' of https://github.com/mossmann/hackrf
This commit is contained in:
@@ -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,72 @@ static int prepare_transfers(
|
||||
}
|
||||
}
|
||||
|
||||
static int detach_kernel_drivers(libusb_device_handle* usb_device_handle)
|
||||
{
|
||||
int i, num_interfaces, 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;
|
||||
}
|
||||
|
||||
num_interfaces = config->bNumInterfaces;
|
||||
libusb_free_config_descriptor(config);
|
||||
for(i=0; i<num_interfaces; 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 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
if(curr_config != config)
|
||||
{
|
||||
result = detach_kernel_drivers(usb_device);
|
||||
if( result != 0 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = libusb_set_configuration(usb_device, config);
|
||||
if( result != 0 )
|
||||
{
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
}
|
||||
|
||||
result = detach_kernel_drivers(usb_device);
|
||||
if( result != 0 )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return LIBUSB_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@@ -240,6 +311,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 )
|
||||
{
|
||||
@@ -260,41 +335,162 @@ int ADDCALL hackrf_exit(void)
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open(hackrf_device** device)
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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 )
|
||||
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->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 (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->usb_board_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->usb_board_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;
|
||||
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);
|
||||
|
||||
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 (i=0; i<list_length; i++) {
|
||||
struct libusb_device_descriptor device_descriptor;
|
||||
libusb_get_device_descriptor(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) ) {
|
||||
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;
|
||||
if( serial_descriptor_index > 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 + 32-match_len, desired_serial_number, match_len) == 0 ) {
|
||||
printf(" match\n");
|
||||
break;
|
||||
} else {
|
||||
printf(" skip\n");
|
||||
libusb_close(usb_device);
|
||||
usb_device = NULL;
|
||||
}
|
||||
} else {
|
||||
printf(" wrong length of serial number: %d\n", serial_number_length);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
//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;
|
||||
@@ -336,6 +532,73 @@ int ADDCALL hackrf_open(hackrf_device** device)
|
||||
return HACKRF_SUCCESS;
|
||||
}
|
||||
|
||||
int ADDCALL hackrf_open(hackrf_device** device)
|
||||
{
|
||||
libusb_device_handle* usb_device;
|
||||
|
||||
if( device == NULL )
|
||||
{
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
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_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;
|
||||
|
||||
if( device == NULL || list == NULL || idx < 0 || idx >= list->devicecount )
|
||||
{
|
||||
return HACKRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
int i = list->usb_device_index[idx];
|
||||
|
||||
if( libusb_open(list->usb_devices[i], &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;
|
||||
@@ -644,22 +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 = libusb_set_configuration(device->usb_device, 2);
|
||||
if (result != LIBUSB_SUCCESS) {
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
result = libusb_claim_interface(device->usb_device, 0);
|
||||
if (result != LIBUSB_SUCCESS) {
|
||||
return HACKRF_ERROR_LIBUSB;
|
||||
}
|
||||
|
||||
int result, transferred = 0;
|
||||
|
||||
result = hackrf_set_transceiver_mode(device, TRANSCEIVER_MODE_CPLD_UPDATE);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
for (i = 0; i < total_length; i += chunk_size)
|
||||
{
|
||||
result = libusb_bulk_transfer(
|
||||
@@ -1343,6 +1596,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) {
|
||||
|
||||
Reference in New Issue
Block a user