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:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user