libusb_ll: rework. Splitted scan method -> help futur dev with a common code to detect/select usb devices
This commit is contained in:
parent
37a0f9c03e
commit
7e90d071d9
|
|
@ -4,11 +4,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "cable.hpp"
|
#include "cable.hpp"
|
||||||
#include "display.hpp"
|
#include "display.hpp"
|
||||||
|
|
@ -16,38 +19,104 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
libusb_ll::libusb_ll(int vid, int pid):_verbose(true)
|
libusb_ll::libusb_ll(int vid, int pid, int8_t _verbose):
|
||||||
|
_usb_ctx(nullptr), _verbose(_verbose >= 2)
|
||||||
{
|
{
|
||||||
(void)vid;
|
(void)vid;
|
||||||
(void)pid;
|
(void)pid;
|
||||||
if (libusb_init(&_usb_ctx) < 0)
|
if (libusb_init(&_usb_ctx) < 0)
|
||||||
throw std::runtime_error("libusb_init_failed");
|
throw std::runtime_error("libusb_init_failed");
|
||||||
|
ssize_t list_size = libusb_get_device_list(_usb_ctx, &_dev_list);
|
||||||
|
if (list_size < 0)
|
||||||
|
throw std::runtime_error("libusb_get_device_list_failed");
|
||||||
|
if (list_size == 0)
|
||||||
|
printError("No USB devices found");
|
||||||
|
if (_verbose)
|
||||||
|
printf("found %zd\n", list_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_ll::~libusb_ll()
|
libusb_ll::~libusb_ll()
|
||||||
{
|
{
|
||||||
|
libusb_free_device_list(_dev_list, 1);
|
||||||
libusb_exit(_usb_ctx);
|
libusb_exit(_usb_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int libusb_ll::get_devices_list(const cable_t *cable)
|
||||||
|
{
|
||||||
|
int vid = 0, pid = 0;
|
||||||
|
uint8_t bus_addr = 0, device_addr = 0;
|
||||||
|
bool vid_pid_filter = false; // if vid/pid only keep matching nodes
|
||||||
|
bool bus_dev_filter = false; // if bus/dev only keep matching nodes
|
||||||
|
|
||||||
|
if (cable != nullptr) {
|
||||||
|
vid = cable->vid;
|
||||||
|
pid = cable->pid;
|
||||||
|
bus_addr = cable->bus_addr;
|
||||||
|
device_addr = cable->device_addr;
|
||||||
|
vid_pid_filter = (vid != 0) && (pid != 0);
|
||||||
|
bus_dev_filter = (bus_addr != 0) && (device_addr != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
libusb_device *usb_dev;
|
||||||
|
|
||||||
|
_usb_dev_list.clear();
|
||||||
|
|
||||||
|
while ((usb_dev = _dev_list[i++]) != nullptr) {
|
||||||
|
if (_verbose) {
|
||||||
|
printf("%x %x %x %x\n", bus_addr, device_addr,
|
||||||
|
libusb_get_device_address(usb_dev),
|
||||||
|
libusb_get_bus_number(usb_dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bus addr and device addr provided: check */
|
||||||
|
if (bus_dev_filter && (
|
||||||
|
bus_addr != libusb_get_device_address(usb_dev) ||
|
||||||
|
device_addr != libusb_get_bus_number(usb_dev)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct libusb_device_descriptor desc;
|
||||||
|
if (libusb_get_device_descriptor(usb_dev, &desc) != 0) {
|
||||||
|
printError("Unable to get device descriptor");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_verbose) {
|
||||||
|
printf("%x %x %x %x\n", vid, pid,
|
||||||
|
desc.idVendor, desc.idProduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linux host controller */
|
||||||
|
if (desc.idVendor == 0x1d6b)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check for VID/PID */
|
||||||
|
if (vid_pid_filter && (
|
||||||
|
vid != desc.idVendor || pid != desc.idProduct))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_usb_dev_list.push_back(usb_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<int>(_usb_dev_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
bool libusb_ll::scan()
|
bool libusb_ll::scan()
|
||||||
{
|
{
|
||||||
int i = 0;
|
char *mess = reinterpret_cast<char *>(malloc(1024));
|
||||||
libusb_device **dev_list;
|
if (!mess) {
|
||||||
libusb_device *usb_dev;
|
printError("Error: failed to allocate buffer");
|
||||||
libusb_device_handle *handle;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* iteration */
|
get_devices_list(nullptr);
|
||||||
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",
|
snprintf(mess, 1024, "%3s %3s %-13s %-15s %-12s %-20s %s",
|
||||||
"Bus", "device", "vid:pid", "probe type", "manufacturer",
|
"Bus", "device", "vid:pid", "probe type", "manufacturer",
|
||||||
"serial", "product");
|
"serial", "product");
|
||||||
printSuccess(mess);
|
printSuccess(mess);
|
||||||
|
|
||||||
while ((usb_dev = dev_list[i++]) != NULL) {
|
for (libusb_device *usb_dev : _usb_dev_list) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
struct libusb_device_descriptor desc;
|
struct libusb_device_descriptor desc;
|
||||||
if (libusb_get_device_descriptor(usb_dev, &desc) != 0) {
|
if (libusb_get_device_descriptor(usb_dev, &desc) != 0) {
|
||||||
|
|
@ -57,35 +126,41 @@ bool libusb_ll::scan()
|
||||||
|
|
||||||
char probe_type[256];
|
char probe_type[256];
|
||||||
|
|
||||||
/* Linux host controller */
|
|
||||||
if (desc.idVendor == 0x1d6b)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ftdi devices */
|
/* ftdi devices */
|
||||||
// FIXME: missing iProduct in cable_list
|
// FIXME: missing iProduct in cable_list
|
||||||
if (desc.idVendor == 0x403) {
|
if (desc.idVendor == 0x403) {
|
||||||
if (desc.idProduct == 0x6010)
|
switch (desc.idProduct) {
|
||||||
|
case 0x6010:
|
||||||
snprintf(probe_type, 256, "FTDI2232");
|
snprintf(probe_type, 256, "FTDI2232");
|
||||||
else if (desc.idProduct == 0x6011)
|
break;
|
||||||
|
case 0x6011:
|
||||||
snprintf(probe_type, 256, "ft4232");
|
snprintf(probe_type, 256, "ft4232");
|
||||||
else if (desc.idProduct == 0x6001)
|
break;
|
||||||
|
case 0x6001:
|
||||||
snprintf(probe_type, 256, "ft232RL");
|
snprintf(probe_type, 256, "ft232RL");
|
||||||
else if (desc.idProduct == 0x6014)
|
break;
|
||||||
|
case 0x6014:
|
||||||
snprintf(probe_type, 256, "ft232H");
|
snprintf(probe_type, 256, "ft232H");
|
||||||
else if (desc.idProduct == 0x6015)
|
break;
|
||||||
|
case 0x6015:
|
||||||
snprintf(probe_type, 256, "ft231X");
|
snprintf(probe_type, 256, "ft231X");
|
||||||
else if (desc.idProduct == 0x6043)
|
break;
|
||||||
|
case 0x6043:
|
||||||
snprintf(probe_type, 256, "FT4232HP");
|
snprintf(probe_type, 256, "FT4232HP");
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
snprintf(probe_type, 256, "unknown FTDI");
|
snprintf(probe_type, 256, "unknown FTDI");
|
||||||
|
break;
|
||||||
|
}
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: DFU device can't be detected here
|
// FIXME: DFU device can't be detected here
|
||||||
for (auto b = cable_list.begin(); b != cable_list.end(); b++) {
|
for (const auto& b : cable_list) {
|
||||||
cable_t *c = &(*b).second;
|
const cable_t *c = &b.second;
|
||||||
if (c->vid == desc.idVendor && c->pid == desc.idProduct) {
|
if (c->vid == desc.idVendor && c->pid == desc.idProduct) {
|
||||||
snprintf(probe_type, 256, "%s", (*b).first.c_str());
|
snprintf(probe_type, 256, "%s", b.first.c_str());
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +168,7 @@ bool libusb_ll::scan()
|
||||||
if (!found)
|
if (!found)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
libusb_device_handle *handle;
|
||||||
int ret = libusb_open(usb_dev, &handle);
|
int ret = libusb_open(usb_dev, &handle);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
snprintf(mess, 1024,
|
snprintf(mess, 1024,
|
||||||
|
|
@ -110,15 +186,15 @@ bool libusb_ll::scan()
|
||||||
ret = libusb_get_string_descriptor_ascii(handle,
|
ret = libusb_get_string_descriptor_ascii(handle,
|
||||||
desc.iProduct, iproduct, 200);
|
desc.iProduct, iproduct, 200);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
snprintf((char*)iproduct, 200, "none");
|
snprintf(reinterpret_cast<char*>(iproduct), 200, "none");
|
||||||
ret = libusb_get_string_descriptor_ascii(handle,
|
ret = libusb_get_string_descriptor_ascii(handle,
|
||||||
desc.iManufacturer, imanufacturer, 200);
|
desc.iManufacturer, imanufacturer, 200);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
snprintf((char*)imanufacturer, 200, "none");
|
snprintf(reinterpret_cast<char*>(imanufacturer), 200, "none");
|
||||||
ret = libusb_get_string_descriptor_ascii(handle,
|
ret = libusb_get_string_descriptor_ascii(handle,
|
||||||
desc.iSerialNumber, iserial, 200);
|
desc.iSerialNumber, iserial, 200);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
snprintf((char*)iserial, 200, "none");
|
snprintf(reinterpret_cast<char*>(iserial), 200, "none");
|
||||||
uint8_t bus_addr = libusb_get_bus_number(usb_dev);
|
uint8_t bus_addr = libusb_get_bus_number(usb_dev);
|
||||||
uint8_t dev_addr = libusb_get_device_address(usb_dev);
|
uint8_t dev_addr = libusb_get_device_address(usb_dev);
|
||||||
|
|
||||||
|
|
@ -132,7 +208,6 @@ bool libusb_ll::scan()
|
||||||
libusb_close(handle);
|
libusb_close(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
free(mess);
|
free(mess);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,25 @@
|
||||||
|
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cable.hpp"
|
||||||
|
|
||||||
class libusb_ll {
|
class libusb_ll {
|
||||||
public:
|
public:
|
||||||
explicit libusb_ll(int vid = -1, int pid = -1);
|
explicit libusb_ll(int vid, int pid, int8_t verbose);
|
||||||
~libusb_ll();
|
~libusb_ll();
|
||||||
|
|
||||||
bool scan();
|
bool scan();
|
||||||
|
const std::vector<struct libusb_device *>usb_dev_list() { return _usb_dev_list; }
|
||||||
|
int get_devices_list(const cable_t *cable);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
struct libusb_context *_usb_ctx;
|
struct libusb_context *_usb_ctx;
|
||||||
bool _verbose;
|
bool _verbose;
|
||||||
|
private:
|
||||||
|
libusb_device **_dev_list;
|
||||||
|
std::vector<struct libusb_device *> _usb_dev_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRC_LIBUSB_LL_HPP_
|
#endif // SRC_LIBUSB_LL_HPP_
|
||||||
|
|
|
||||||
|
|
@ -1107,7 +1107,7 @@ void displaySupported(const struct arguments &args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.scan_usb) {
|
if (args.scan_usb) {
|
||||||
libusb_ll usb(0, 0);
|
libusb_ll usb(0, 0, args.verbose);
|
||||||
usb.scan();
|
usb.scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue