bool bladerf_devinfo_matches(const struct bladerf_devinfo *a, const struct bladerf_devinfo *b) { return bladerf_instance_matches(a, b) && bladerf_serial_matches(a, b) && bladerf_bus_addr_matches(a ,b); }
static int find_and_open_device(libusb_context *context, const struct bladerf_devinfo *info_in, struct bladerf_lusb **dev_out, struct bladerf_devinfo *info_out) { int status = BLADERF_ERR_NODEV; int i, n; ssize_t count; struct libusb_device **list; struct bladerf_devinfo curr_info; bool printed_access_warning = false; *dev_out = NULL; count = libusb_get_device_list(context, &list); if (count < 0) { if (count < INT_MIN) { /* Ensure we don't have a situation where we accidentally return 0 * due to a narrowing conversion */ return BLADERF_ERR_UNEXPECTED; } else { return error_conv((int) count); } } for (i = 0, n = 0; (i < count) && (*dev_out == NULL); i++) { if (device_is_bladerf(list[i])) { log_verbose("Found a bladeRF (idx=%d)\n", i); /* Open the USB device and get some information */ status = get_devinfo(list[i], &curr_info); if (status < 0) { /* Give the user a helpful hint in case the have forgotten * to update their udev rules */ if (status == LIBUSB_ERROR_ACCESS && !printed_access_warning) { printed_access_warning = true; log_warning("Found a bladeRF via VID/PID, but could not " "open it due to insufficient permissions.\n"); } else { log_debug("Could not open bladeRF device: %s\n", libusb_error_name(status) ); } status = BLADERF_ERR_NODEV; continue; /* Continue trying the next devices */ } else { curr_info.instance = n++; } /* Check to see if this matches the info struct */ if (bladerf_devinfo_matches(&curr_info, info_in)) { status = open_device(&curr_info, context, list[i], dev_out); if (status < 0) { status = BLADERF_ERR_NODEV; continue; /* Continue trying the next matching device */ } else { memcpy(info_out, &curr_info, sizeof(info_out[0])); } } else { status = BLADERF_ERR_NODEV; log_verbose("Devinfo doesn't match - skipping" "(instance=%d, serial=%d, bus/addr=%d\n", bladerf_instance_matches(&curr_info, info_in), bladerf_serial_matches(&curr_info, info_in), bladerf_bus_addr_matches(&curr_info, info_in)); } } } if (status == 0) { /* Returning 0 indicates this function is providing a device */ assert(*dev_out != NULL); } libusb_free_device_list(list, 1); return status; }
static int lusb_open(void **driver, struct bladerf_devinfo *info_in, struct bladerf_devinfo *info_out) { int status, i, n; int fx3_status; ssize_t count; struct bladerf_lusb *lusb = NULL; libusb_device **list = NULL; struct bladerf_devinfo thisinfo; libusb_context *context; /* Initialize libusb for device tree walking */ status = libusb_init(&context); if (status) { log_error("Could not initialize libusb: %s\n", libusb_error_name(status)); status = error_conv(status); goto error; } /* We can only print this out when log output is enabled, or else we'll * get snagged by -Werror=unused-but-set-variable */ # ifdef LOGGING_ENABLED { char buf[64]; get_libusb_version(buf, sizeof(buf)); log_verbose("Using libusb version: %s\n", buf); } # endif /* Iterate through all the USB devices */ count = libusb_get_device_list(context, &list); for (i = 0, n = 0; i < count; i++) { if (device_is_bladerf(list[i])) { log_verbose("Found a bladeRF (based upon VID/PID)\n"); /* Open the USB device and get some information */ status = get_devinfo(list[i], &thisinfo); if(status < 0) { log_debug("Could not open bladeRF device: %s\n", libusb_error_name(status) ); status = error_conv(status); goto error; } thisinfo.instance = n++; /* Check to see if this matches the info struct */ if (bladerf_devinfo_matches(&thisinfo, info_in)) { lusb = (struct bladerf_lusb *)malloc(sizeof(struct bladerf_lusb)); if (lusb == NULL) { log_debug("Skipping instance %d due to failed allocation\n", thisinfo.instance); lusb = NULL; continue; } lusb->context = context; lusb->dev = list[i]; status = libusb_open(list[i], &lusb->handle); if (status < 0) { status = error_conv(status); goto error; } status = libusb_claim_interface(lusb->handle, 0); if(status < 0) { log_debug("Could not claim interface: %s\n", libusb_error_name(status)); status = error_conv(status); goto error; } memcpy(info_out, &thisinfo, sizeof(struct bladerf_devinfo)); *driver = lusb; break; } else { log_verbose("Devinfo doesn't match - skipping" "(instance=%d, serial=%d, bus/addr=%d\n", bladerf_instance_matches(&thisinfo, info_in), bladerf_serial_matches(&thisinfo, info_in), bladerf_bus_addr_matches(&thisinfo, info_in)); } } if (device_is_fx3_bootloader(list[i])) { fx3_status = get_devinfo(list[i], &thisinfo); if (fx3_status != 0) { log_debug("Could not open FX3 bootloader device: %s\n", libusb_error_name(fx3_status)); continue; } log_info("Found FX3 bootloader device on bus=%d addr=%d. " "This may be a bladeRF.\n", thisinfo.usb_bus, thisinfo.usb_addr); log_info("Use bladeRF-cli command \"recover %d %d " "<FX3 firmware>\" to boot the bladeRF firmware.\n", thisinfo.usb_bus, thisinfo.usb_addr); } } error: if (list) { libusb_free_device_list(list, 1); } if (lusb == NULL) { log_debug("No devices available on the libusb backend.\n"); status = BLADERF_ERR_NODEV; } if (status != 0) { if (lusb != NULL) { if (lusb->handle) { libusb_close(lusb->handle); } free(lusb); } libusb_exit(context); } return status; }