Implement raw DeviceMonitor
Multiple things have been done in this commit; the base of the new backend has effectively been created. This branch currently has many vital parts commented out. Therefore, this branch is currently only intended for debugging.
This commit is contained in:
30
src/logid/backend/hidpp/Device.cpp
Normal file
30
src/logid/backend/hidpp/Device.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "Device.h"
|
||||
#include "Report.h"
|
||||
|
||||
using namespace logid::backend;
|
||||
using namespace logid::backend::hidpp;
|
||||
|
||||
const char* Device::InvalidDevice::what() const noexcept
|
||||
{
|
||||
switch(_reason)
|
||||
{
|
||||
case NoHIDPPReport:
|
||||
return "Invalid HID++ device";
|
||||
case InvalidRawDevice:
|
||||
return "Invalid raw device";
|
||||
}
|
||||
}
|
||||
|
||||
Device::InvalidDevice::Reason Device::InvalidDevice::code() const noexcept
|
||||
{
|
||||
return _reason;
|
||||
}
|
||||
|
||||
/// TODO: Initialize a single RawDevice for each path.
|
||||
Device::Device(std::string path, DeviceIndex index):
|
||||
raw_device (std::make_shared<raw::RawDevice>(path)), path (path), index (index)
|
||||
{
|
||||
supported_reports = getSupportedReports(raw_device->reportDescriptor());
|
||||
if(!supported_reports)
|
||||
throw InvalidDevice(InvalidDevice::NoHIDPPReport);
|
||||
}
|
51
src/logid/backend/hidpp/Device.h
Normal file
51
src/logid/backend/hidpp/Device.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef LOGID_HIDPP_DEVICE_H
|
||||
#define LOGID_HIDPP_DEVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "../raw/RawDevice.h"
|
||||
|
||||
namespace logid::backend::hidpp
|
||||
{
|
||||
enum DeviceIndex: uint8_t
|
||||
{
|
||||
DefaultDevice = 0,
|
||||
WirelessDevice1 = 1,
|
||||
WirelessDevice2 = 2,
|
||||
WirelessDevice3 = 3,
|
||||
WirelessDevice4 = 4,
|
||||
WirelessDevice5 = 5,
|
||||
WirelessDevice6 = 6,
|
||||
CordedDevice = 0xff
|
||||
};
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
class InvalidDevice : std::exception
|
||||
{
|
||||
public:
|
||||
enum Reason
|
||||
{
|
||||
NoHIDPPReport,
|
||||
InvalidRawDevice
|
||||
};
|
||||
InvalidDevice(Reason reason) : _reason (reason) {}
|
||||
virtual const char *what() const noexcept;
|
||||
virtual Reason code() const noexcept;
|
||||
private:
|
||||
Reason _reason;
|
||||
|
||||
};
|
||||
Device(std::string path, DeviceIndex index);
|
||||
std::string devicePath() const { return path; }
|
||||
DeviceIndex deviceIndex() const { return index; }
|
||||
private:
|
||||
std::shared_ptr<logid::backend::raw::RawDevice> raw_device;
|
||||
std::string path;
|
||||
DeviceIndex index;
|
||||
uint8_t supported_reports;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //LOGID_HIDPP_DEVICE_H
|
0
src/logid/backend/hidpp/Error.cpp
Normal file
0
src/logid/backend/hidpp/Error.cpp
Normal file
0
src/logid/backend/hidpp/Error.h
Normal file
0
src/logid/backend/hidpp/Error.h
Normal file
83
src/logid/backend/hidpp/Report.cpp
Normal file
83
src/logid/backend/hidpp/Report.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include "Report.h"
|
||||
|
||||
using namespace logid::backend::hidpp;
|
||||
using namespace logid::backend;
|
||||
|
||||
/* Report descriptors were sourced from cvuchener/hidpp */
|
||||
static const std::array<uint8_t, 22> ShortReportDesc = {
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x10, // Report ID (16)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x01, // Usage (0001 - Vendor)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0x09, 0x01, // Usage (0001 - Vendor)
|
||||
0x91, 0x00, // Output (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
|
||||
static const std::array<uint8_t, 22> LongReportDesc = {
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x11, // Report ID (17)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x13, // Report Count (19)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x02, // Usage (0002 - Vendor)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0x09, 0x02, // Usage (0002 - Vendor)
|
||||
0x91, 0x00, // Output (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
|
||||
/* Alternative versions from the G602 */
|
||||
static const std::array<uint8_t, 22> ShortReportDesc2 = {
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x10, // Report ID (16)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x01, // Usage (0001 - Vendor)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0x09, 0x01, // Usage (0001 - Vendor)
|
||||
0x91, 0x00, // Output (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
|
||||
static const std::array<uint8_t, 22> LongReportDesc2 = {
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x11, // Report ID (17)
|
||||
0x95, 0x13, // Report Count (19)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x02, // Usage (0002 - Vendor)
|
||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||
0x09, 0x02, // Usage (0002 - Vendor)
|
||||
0x91, 0x00, // Output (Data, Array, Absolute)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
|
||||
uint8_t hidpp::getSupportedReports(std::vector<uint8_t>&& rdesc)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
|
||||
auto it = std::search(rdesc.begin(), rdesc.end(), ShortReportDesc.begin(), ShortReportDesc.end());
|
||||
if(it == rdesc.end())
|
||||
it = std::search(rdesc.begin(), rdesc.end(), ShortReportDesc2.begin(), ShortReportDesc2.end());
|
||||
if(it != rdesc.end())
|
||||
ret |= HIDPP_REPORT_SHORT_SUPPORTED;
|
||||
|
||||
it = std::search(rdesc.begin(), rdesc.end(), LongReportDesc.begin(), LongReportDesc2.end());
|
||||
if(it == rdesc.end())
|
||||
it = std::search(rdesc.begin(), rdesc.end(), LongReportDesc2.begin(), LongReportDesc2.end());
|
||||
if(it != rdesc.end())
|
||||
ret |= HIDPP_REPORT_LONG_SUPPORTED;
|
||||
|
||||
return ret;
|
||||
}
|
57
src/logid/backend/hidpp/Report.h
Normal file
57
src/logid/backend/hidpp/Report.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef LOGID_BACKEND_HIDPP_REPORT_H
|
||||
#define LOGID_BACKEND_HIDPP_REPORT_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "../raw/RawDevice.h"
|
||||
#include "Device.h"
|
||||
|
||||
#define LOGID_HIDPP_SW_ID 0x0f
|
||||
|
||||
/* Some devices only support a subset of these reports */
|
||||
#define HIDPP_REPORT_SHORT_SUPPORTED 1U
|
||||
#define HIDPP_REPORT_LONG_SUPPORTED 1U<<1U
|
||||
/* Very long reports exist, however they have not been encountered so far */
|
||||
|
||||
namespace logid::backend::hidpp
|
||||
{
|
||||
uint8_t getSupportedReports(std::vector<uint8_t>&& rdesc);
|
||||
class Report
|
||||
{
|
||||
public:
|
||||
enum Type: uint8_t
|
||||
{
|
||||
Short = 0x10,
|
||||
Long = 0x11
|
||||
};
|
||||
|
||||
class InvalidReportID: std::exception
|
||||
{
|
||||
InvalidReportID();
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
|
||||
class InvalidReportLength: std::exception
|
||||
{
|
||||
InvalidReportLength();
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
|
||||
static constexpr std::size_t MaxDataLength = 32;
|
||||
|
||||
Report(uint8_t report_id, const uint8_t* data, std::size_t length);
|
||||
Report(std::vector<uint8_t> data);
|
||||
|
||||
Type type() const;
|
||||
void setType(Report::Type type);
|
||||
|
||||
logid::backend::hidpp::DeviceIndex deviceIndex();
|
||||
|
||||
std::vector<uint8_t> rawReport () const { return _data; }
|
||||
|
||||
private:
|
||||
static constexpr std::size_t HeaderLength = 4;
|
||||
std::vector<uint8_t> _data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //LOGID_BACKEND_HIDPP_REPORT_H
|
Reference in New Issue
Block a user