Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
a58f946edThis file is pinned to the selected release. Download the original to open it in your design tool.
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (c) 2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <libusb.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "cable.hpp"
#include "display.hpp"
#include "libusb_ll.hpp"
using namespace std;
libusb_ll::libusb_ll(int vid, int pid):_verbose(true)
{
(void)vid;
(void)pid;
if (libusb_init(&_usb_ctx) < 0)
throw std::runtime_error("libusb_init_failed");
}
libusb_ll::~libusb_ll()
{
libusb_exit(_usb_ctx);
}
bool libusb_ll::scan()
{
int i = 0;
libusb_device **dev_list;
libusb_device *usb_dev;
libusb_device_handle *handle;
/* iteration */
ssize_t list_size = libusb_get_device_list(_usb_ctx, &dev_list);
if (_verbose)
printInfo("found " + std::to_string(list_size) + " USB device");
char *mess = (char *)malloc(1024);
snprintf(mess, 1024, "%3s %3s %-13s %-15s %-12s %-20s %s",
"Bus", "device", "vid:pid", "probe type", "manufacturer",
"serial", "product");
printSuccess(mess);
while ((usb_dev = dev_list[i++]) != NULL) {
bool found = false;
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(usb_dev, &desc) != 0) {
printError("Unable to get device descriptor");
return false;
}
char probe_type[256];
/* Linux host controller */
if (desc.idVendor == 0x1d6b)
continue;
/* ftdi devices */
// FIXME: missing iProduct in cable_list
if (desc.idVendor == 0x403) {
if (desc.idProduct == 0x6010)
snprintf(probe_type, 256, "FTDI2232");
else if (desc.idProduct == 0x6011)
snprintf(probe_type, 256, "ft4232");
else if (desc.idProduct == 0x6001)
snprintf(probe_type, 256, "ft232RL");
else if (desc.idProduct == 0x6014)
snprintf(probe_type, 256, "ft232H");
else if (desc.idProduct == 0x6015)
snprintf(probe_type, 256, "ft231X");
else if (desc.idProduct == 0x6043)
snprintf(probe_type, 256, "FT4232HP");
else
snprintf(probe_type, 256, "unknown FTDI");
found = true;
} else {
// FIXME: DFU device can't be detected here
for (auto b = cable_list.begin(); b != cable_list.end(); b++) {
cable_t *c = &(*b).second;
if (c->vid == desc.idVendor && c->pid == desc.idProduct) {
snprintf(probe_type, 256, "%s", (*b).first.c_str());
found = true;
}
}
}
if (!found)
continue;
int ret = libusb_open(usb_dev, &handle);
if (ret != 0) {
snprintf(mess, 1024,
"Error: can't open device with vid:vid = 0x%04x:0x%04x. "
"Error code %d %s",
desc.idVendor, desc.idProduct,
ret, libusb_strerror(static_cast<libusb_error>(ret)));
printError(mess);
continue;
}
uint8_t iproduct[200];
uint8_t iserial[200];
uint8_t imanufacturer[200];
ret = libusb_get_string_descriptor_ascii(handle,
desc.iProduct, iproduct, 200);
if (ret < 0)
snprintf((char*)iproduct, 200, "none");
ret = libusb_get_string_descriptor_ascii(handle,
desc.iManufacturer, imanufacturer, 200);
if (ret < 0)
snprintf((char*)imanufacturer, 200, "none");
ret = libusb_get_string_descriptor_ascii(handle,
desc.iSerialNumber, iserial, 200);
if (ret < 0)
snprintf((char*)iserial, 200, "none");
uint8_t bus_addr = libusb_get_bus_number(usb_dev);
uint8_t dev_addr = libusb_get_device_address(usb_dev);
snprintf(mess, 1024, "%03d %03d 0x%04x:0x%04x %-15s %-12s %-20s %s",
bus_addr, dev_addr,
desc.idVendor, desc.idProduct,
probe_type, imanufacturer, iserial, iproduct);
printInfo(mess);
libusb_close(handle);
}
libusb_free_device_list(dev_list, 1);
free(mess);
return true;
}