Extract HID report size for EDBG debug tools via HID endpoint descriptor.

Removed hidapi bodge (where we were mimicking the hid_device_ struct, to
obtain the report size via `(hid_device_*)->input_ep_max_packet_size`).
This commit is contained in:
Nav
2023-01-14 03:03:10 +00:00
parent e3e37ace4b
commit dfaac9e30f
7 changed files with 84 additions and 82 deletions

View File

@@ -9,9 +9,15 @@ namespace Bloom::Usb
{
using namespace Bloom::Exceptions;
HidInterface::HidInterface(std::uint8_t interfaceNumber, std::uint16_t vendorId, std::uint16_t productId)
HidInterface::HidInterface(
std::uint8_t interfaceNumber,
std::uint16_t inputReportSize,
std::uint16_t vendorId,
std::uint16_t productId
)
: interfaceNumber(interfaceNumber)
, vendorId(vendorId)
, inputReportSize(inputReportSize)
, productId(productId)
{}
@@ -27,15 +33,6 @@ namespace Bloom::Usb
}
this->hidDevice.reset(hidDevice);
if (this->hidDevice->input_ep_max_packet_size < 1) {
throw DeviceInitializationFailure(
"Invalid max packet size for USB endpoint, on interface "
+ std::to_string(this->interfaceNumber)
);
}
this->inputReportSize = static_cast<std::size_t>(this->hidDevice->input_ep_max_packet_size);
}
void HidInterface::close() {

View File

@@ -7,7 +7,8 @@
#include <optional>
#include <chrono>
#include "hidapi.hpp"
#include <hidapi/hidapi.h>
#include <hidapi/hidapi_libusb.h>
namespace Bloom::Usb
{
@@ -21,9 +22,11 @@ namespace Bloom::Usb
{
public:
std::uint8_t interfaceNumber = 0;
std::uint16_t inputReportSize = 64;
HidInterface(
std::uint8_t interfaceNumber,
std::uint16_t inputReportSize,
std::uint16_t vendorId,
std::uint16_t productId
);
@@ -72,12 +75,6 @@ namespace Bloom::Usb
HidDevice hidDevice = HidDevice(nullptr, ::hid_close);
/**
* All HID reports have a fixed report length. This means that every packet we send or receive to/from an HID
* endpoint must be equal (in size) to the report length.
*/
std::size_t inputReportSize = 64;
std::uint16_t vendorId = 0;
std::uint16_t productId = 0;
};

View File

@@ -1,43 +0,0 @@
#pragma once
#include <libusb-1.0/libusb.h>
#include <hidapi/hidapi.h>
/*
* The code below was extracted from the HIDAPI library. Third-party license may apply here.
*
* https://github.com/signal11/hidapi
*/
struct hid_device_
{
// Handle to the actual device.
libusb_device_handle* device_handle;
// Endpoint information
int input_endpoint;
int output_endpoint;
int input_ep_max_packet_size;
// The interface number of the HID
int interface;
// Indexes of Strings
int manufacturer_index;
int product_index;
int serial_index;
// Whether blocking reads are used
int blocking; // boolean
// Read thread objects
pthread_t thread;
pthread_mutex_t mutex; // Protects input_reports
pthread_cond_t condition;
pthread_barrier_t barrier; // Ensures correct start up sequence
int shutdown_thread;
int cancelled;
struct libusb_transfer* transfer;
// List of received input reports.
struct input_report* input_reports;
};

View File

@@ -56,26 +56,9 @@ namespace Bloom::Usb
}
void UsbDevice::setConfiguration(std::uint8_t configurationIndex) {
::libusb_config_descriptor* configDescriptorPtr = {};
auto libusbStatusCode = ::libusb_get_config_descriptor(
this->libusbDevice.get(),
configurationIndex,
&configDescriptorPtr
);
const auto configDescriptor = this->getConfigDescriptor(configurationIndex);
if (libusbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to obtain USB configuration descriptor - error code " + std::to_string(libusbStatusCode)
+ " returned."
);
}
const auto configDescriptor = std::unique_ptr<::libusb_config_descriptor, decltype(&::libusb_free_config_descriptor)>(
configDescriptorPtr,
::libusb_free_config_descriptor
);
libusbStatusCode = ::libusb_set_configuration(
const auto libusbStatusCode = ::libusb_set_configuration(
this->libusbDeviceHandle.get(),
configDescriptor->bConfigurationValue
);
@@ -121,6 +104,26 @@ namespace Bloom::Usb
return matchedDevices;
}
LibusbConfigDescriptor UsbDevice::getConfigDescriptor(std::optional<std::uint8_t> configurationIndex) {
::libusb_config_descriptor* configDescriptor = {};
auto libusbStatusCode = configurationIndex.has_value()
? ::libusb_get_config_descriptor(this->libusbDevice.get(), *configurationIndex, &configDescriptor)
: ::libusb_get_active_config_descriptor(this->libusbDevice.get(), &configDescriptor);
if (libusbStatusCode < 0) {
throw DeviceInitializationFailure(
"Failed to obtain USB configuration descriptor - error code " + std::to_string(libusbStatusCode)
+ " returned."
);
}
return LibusbConfigDescriptor(
configDescriptor,
::libusb_free_config_descriptor
);
}
void UsbDevice::detachKernelDriverFromInterface(std::uint8_t interfaceNumber) {
const auto libusbStatusCode = ::libusb_kernel_driver_active(this->libusbDeviceHandle.get(), interfaceNumber);

View File

@@ -13,6 +13,7 @@ namespace Bloom::Usb
using LibusbContext = std::unique_ptr<::libusb_context, decltype(&::libusb_exit)>;
using LibusbDevice = std::unique_ptr<::libusb_device, decltype(&::libusb_unref_device)>;
using LibusbDeviceHandle = std::unique_ptr<::libusb_device_handle, decltype(&::libusb_close)>;
using LibusbConfigDescriptor = std::unique_ptr<::libusb_config_descriptor, decltype(&::libusb_free_config_descriptor)>;
class UsbDevice
{
@@ -47,6 +48,8 @@ namespace Bloom::Usb
std::vector<LibusbDevice> findMatchingDevices(std::uint16_t vendorId, std::uint16_t productId);
LibusbConfigDescriptor getConfigDescriptor(std::optional<std::uint8_t> configurationIndex = std::nullopt);
void detachKernelDriverFromInterface(std::uint8_t interfaceNumber);
void close();