2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2016-12-21 00:14:55 -08:00
|
|
|
|
|
|
|
|
#include "UsbUtil.h"
|
|
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
2016-12-22 22:08:08 -08:00
|
|
|
#include <libgen.h>
|
|
|
|
|
#include <sys/ioctl.h>
|
2016-12-21 00:14:55 -08:00
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
#include <fmt/format.h>
|
2018-04-29 23:33:19 -07:00
|
|
|
#include <wpi/SmallString.h>
|
2021-06-06 16:13:58 -07:00
|
|
|
#include <wpi/StringExtras.h>
|
|
|
|
|
#include <wpi/fs.h>
|
2018-04-29 23:33:19 -07:00
|
|
|
#include <wpi/raw_istream.h>
|
|
|
|
|
#include <wpi/raw_ostream.h>
|
2016-12-21 00:14:55 -08:00
|
|
|
|
2018-10-31 20:22:58 -07:00
|
|
|
#include "Instance.h"
|
2016-12-22 22:08:08 -08:00
|
|
|
#include "Log.h"
|
2016-12-21 00:14:55 -08:00
|
|
|
|
|
|
|
|
namespace cs {
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
static std::string GetUsbNameFromFile(int vendor, int product) {
|
2016-12-21 00:14:55 -08:00
|
|
|
int fd = open("/var/lib/usbutils/usb.ids", O_RDONLY);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (fd < 0) {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
2016-12-21 00:14:55 -08:00
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
wpi::SmallString<128> buf;
|
2016-12-21 00:14:55 -08:00
|
|
|
wpi::raw_fd_istream is{fd, true};
|
|
|
|
|
|
|
|
|
|
// build vendor and product 4-char hex strings
|
2021-06-06 16:13:58 -07:00
|
|
|
auto vendorStr = fmt::format("{:04x}", vendor);
|
|
|
|
|
auto productStr = fmt::format("{:04x}", product);
|
2016-12-21 00:14:55 -08:00
|
|
|
|
|
|
|
|
// scan file
|
2018-04-29 23:33:19 -07:00
|
|
|
wpi::SmallString<128> lineBuf;
|
2016-12-21 00:14:55 -08:00
|
|
|
bool foundVendor = false;
|
|
|
|
|
for (;;) {
|
2017-08-25 18:10:47 -07:00
|
|
|
auto line = is.getline(lineBuf, 4096);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (is.has_error()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-12-21 00:14:55 -08:00
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
if (line.empty()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2016-12-21 00:14:55 -08:00
|
|
|
|
|
|
|
|
// look for vendor at start of line
|
2021-06-06 16:13:58 -07:00
|
|
|
if (wpi::starts_with(line, vendorStr)) {
|
2016-12-21 00:14:55 -08:00
|
|
|
foundVendor = true;
|
2021-11-27 21:31:40 -08:00
|
|
|
buf += wpi::trim(wpi::substr(line, 5));
|
2021-06-06 16:13:58 -07:00
|
|
|
buf += ' ';
|
2016-12-21 00:14:55 -08:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (foundVendor) {
|
|
|
|
|
// next vendor, but didn't match product?
|
|
|
|
|
if (line[0] != '\t') {
|
2021-06-06 16:13:58 -07:00
|
|
|
buf += "Unknown";
|
2022-08-15 05:38:15 -07:00
|
|
|
return std::string{buf};
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// look for product
|
2021-11-27 21:31:40 -08:00
|
|
|
if (wpi::starts_with(wpi::substr(line, 1), productStr)) {
|
|
|
|
|
buf += wpi::trim(wpi::substr(line, 6));
|
2022-08-15 05:38:15 -07:00
|
|
|
return std::string{buf};
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
return {};
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
std::string GetUsbNameFromId(int vendor, int product) {
|
2016-12-21 00:14:55 -08:00
|
|
|
// try reading usb.ids
|
2021-06-06 16:13:58 -07:00
|
|
|
std::string rv = GetUsbNameFromFile(vendor, product);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (!rv.empty()) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
2016-12-21 00:14:55 -08:00
|
|
|
|
|
|
|
|
// Fall back to internal database
|
|
|
|
|
switch (vendor) {
|
2021-06-06 16:13:58 -07:00
|
|
|
case 0x046d: {
|
|
|
|
|
std::string_view productStr;
|
2016-12-21 00:14:55 -08:00
|
|
|
switch (product) {
|
2017-08-25 17:48:06 -07:00
|
|
|
case 0x0802:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C200";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0804:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C250";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0805:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C300";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0807:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam B500";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0808:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C600";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0809:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam Pro 9000";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x080a:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Portable Webcam C905";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x080f:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C120";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0819:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C210";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x081b:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C310";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x081d:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "HD Webcam C510";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0821:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "HD Webcam C910";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0825:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C270";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0826:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "HD Webcam C525";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0828:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "HD Webcam B990";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x082b:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C170";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x082d:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "HD Pro Webcam C920";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0836:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "B525 HD Webcam";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
|
|
|
|
case 0x0843:
|
2021-06-06 16:13:58 -07:00
|
|
|
productStr = "Webcam C930e";
|
2017-08-25 17:48:06 -07:00
|
|
|
break;
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
2021-06-06 16:13:58 -07:00
|
|
|
return fmt::format("Logitech, Inc. {}", productStr);
|
|
|
|
|
}
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
return {};
|
2016-12-21 00:14:55 -08:00
|
|
|
}
|
|
|
|
|
|
2017-08-25 17:48:06 -07:00
|
|
|
int CheckedIoctl(int fd, unsigned long req, void* data, // NOLINT(runtime/int)
|
|
|
|
|
const char* name, const char* file, int line, bool quiet) {
|
2016-12-22 22:08:08 -08:00
|
|
|
int retval = ioctl(fd, req, data);
|
|
|
|
|
if (!quiet && retval < 0) {
|
2021-06-06 16:13:58 -07:00
|
|
|
WPI_ERROR(Instance::GetInstance().logger, "ioctl {} failed at {}:{}: {}",
|
|
|
|
|
name, fs::path{file}.filename().string(), line,
|
|
|
|
|
std::strerror(errno));
|
2016-12-22 22:08:08 -08:00
|
|
|
}
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-21 00:14:55 -08:00
|
|
|
} // namespace cs
|