Print version number of device 1 on each raw dev.
Only works on HID++ >=2.0 so far. Also solves a race condition where the wrong response can be sent to a request.
This commit is contained in:
25
src/logid/backend/hidpp20/Device.cpp
Normal file
25
src/logid/backend/hidpp20/Device.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "Device.h"
|
||||
#include "../hidpp/defs.h"
|
||||
|
||||
using namespace logid::backend::hidpp20;
|
||||
|
||||
std::vector<uint8_t> Device::callFunction(uint8_t feature_index,
|
||||
uint8_t function, std::vector<uint8_t>& params)
|
||||
{
|
||||
hidpp::Report::Type type;
|
||||
|
||||
assert(params.size() <= hidpp::LongParamLength);
|
||||
if(params.size() <= hidpp::ShortParamLength)
|
||||
type = hidpp::Report::Type::Short;
|
||||
else if(params.size() <= hidpp::LongParamLength)
|
||||
type = hidpp::Report::Type::Long;
|
||||
|
||||
hidpp::Report request(type, deviceIndex(), feature_index, function,
|
||||
LOGID_HIDPP_SOFTWARE_ID);
|
||||
std::copy(params.begin(), params.end(), request.paramBegin());
|
||||
|
||||
auto response = this->sendReport(request);
|
||||
return std::vector<uint8_t>(response.paramBegin(), response.paramEnd());
|
||||
}
|
19
src/logid/backend/hidpp20/Device.h
Normal file
19
src/logid/backend/hidpp20/Device.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef LOGID_HIDPP20_DEVICE_H
|
||||
#define LOGID_HIDPP20_DEVICE_H
|
||||
|
||||
#include "../hidpp/Device.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp20 {
|
||||
class Device : public hidpp::Device
|
||||
{
|
||||
public:
|
||||
std::vector<uint8_t> callFunction(uint8_t feature_index,
|
||||
uint8_t function,
|
||||
std::vector<uint8_t>& params);
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif //LOGID_HIDPP20_DEVICE_H
|
46
src/logid/backend/hidpp20/Error.cpp
Normal file
46
src/logid/backend/hidpp20/Error.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include "Error.h"
|
||||
|
||||
using namespace logid::backend::hidpp20;
|
||||
|
||||
Error::Error(uint8_t code) : _code (code)
|
||||
{
|
||||
assert(_code != NoError);
|
||||
}
|
||||
|
||||
const char* Error::what() const noexcept
|
||||
{
|
||||
switch(_code)
|
||||
{
|
||||
case NoError:
|
||||
return "No error";
|
||||
case Unknown:
|
||||
return "Unknown";
|
||||
case InvalidArgument:
|
||||
return "Invalid argument";
|
||||
case OutOfRange:
|
||||
return "Out of range";
|
||||
case HardwareError:
|
||||
return "Hardware error";
|
||||
case LogitechInternal:
|
||||
return "Logitech internal feature";
|
||||
case InvalidFeatureIndex:
|
||||
return "Invalid feature index";
|
||||
case InvalidFunctionID:
|
||||
return "Invalid function ID";
|
||||
case Busy:
|
||||
return "Busy";
|
||||
case Unsupported:
|
||||
return "Unsupported";
|
||||
case UnknownDevice:
|
||||
return "Unknown device";
|
||||
default:
|
||||
return std::string("Unknown error code " + std::to_string(_code)).c_str();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Error::code() const noexcept
|
||||
{
|
||||
return _code;
|
||||
}
|
39
src/logid/backend/hidpp20/Error.h
Normal file
39
src/logid/backend/hidpp20/Error.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef LOGID_BACKEND_HIDPP20_ERROR_H
|
||||
#define LOGID_BACKEND_HIDPP20_ERROR_H
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstdint>
|
||||
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp20 {
|
||||
static constexpr uint8_t ErrorID = 0xFF;
|
||||
|
||||
class Error: public std::exception
|
||||
{
|
||||
public:
|
||||
enum ErrorCode: uint8_t {
|
||||
NoError = 0,
|
||||
Unknown = 1,
|
||||
InvalidArgument = 2,
|
||||
OutOfRange = 3,
|
||||
HardwareError = 4,
|
||||
LogitechInternal = 5,
|
||||
InvalidFeatureIndex = 6,
|
||||
InvalidFunctionID = 7,
|
||||
Busy = 8,
|
||||
Unsupported = 9,
|
||||
UnknownDevice = 10
|
||||
};
|
||||
|
||||
Error(uint8_t code);
|
||||
|
||||
virtual const char* what() const noexcept;
|
||||
uint8_t code() const noexcept;
|
||||
|
||||
private:
|
||||
uint8_t _code;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif //LOGID_BACKEND_HIDPP20_ERROR_H
|
28
src/logid/backend/hidpp20/Feature.cpp
Normal file
28
src/logid/backend/hidpp20/Feature.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "Feature.h"
|
||||
|
||||
using namespace logid::backend::hidpp20;
|
||||
|
||||
const char* Feature::UnsupportedFeature::what() const noexcept
|
||||
{
|
||||
return "Unsupported feature";
|
||||
}
|
||||
|
||||
uint16_t Feature::UnsupportedFeature::code() const noexcept
|
||||
{
|
||||
return _f_id;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Feature::callFunction(uint8_t function_id, std::vector<uint8_t>& params)
|
||||
{
|
||||
return _device->callFunction(_index, function_id, params);
|
||||
}
|
||||
|
||||
Feature::Feature(Device* dev, uint16_t _id) : _device (dev), _index (0xff)
|
||||
{
|
||||
///TODO: Set index
|
||||
}
|
||||
|
||||
Feature::Feature(Device* dev, uint8_t _index) : _device (dev), _index (_index)
|
||||
{
|
||||
|
||||
}
|
37
src/logid/backend/hidpp20/Feature.h
Normal file
37
src/logid/backend/hidpp20/Feature.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef LOGID_HIDPP20_FEATURE_H
|
||||
#define LOGID_HIDPP20_FEATURE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "Device.h"
|
||||
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp20 {
|
||||
class Feature
|
||||
{
|
||||
class UnsupportedFeature : public std::exception
|
||||
{
|
||||
public:
|
||||
explicit UnsupportedFeature(uint16_t ID) : _f_id (ID) {}
|
||||
virtual const char* what() const noexcept;
|
||||
uint16_t code() const noexcept;
|
||||
private:
|
||||
uint16_t _f_id;
|
||||
};
|
||||
|
||||
public:
|
||||
static const uint16_t ID;
|
||||
virtual uint16_t getID() = 0;
|
||||
|
||||
protected:
|
||||
explicit Feature(Device* dev, uint16_t _id);
|
||||
explicit Feature(Device* dev, uint8_t _index);
|
||||
std::vector<uint8_t> callFunction(uint8_t function_id,
|
||||
std::vector<uint8_t>& params);
|
||||
private:
|
||||
Device* _device;
|
||||
uint8_t _index;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif //LOGID_HIDPP20_FEATURE_H
|
@@ -6,97 +6,108 @@
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp20 {
|
||||
enum FeatureID : uint16_t
|
||||
{
|
||||
ROOT = 0x0000,
|
||||
FEATURE_SET = 0x0001,
|
||||
FEATURE_INFO = 0x0002,
|
||||
FW_VERSION = 0x0003,
|
||||
DEVICE_NAME = 0x0005,
|
||||
DEVICE_GROUPS = 0x0006,
|
||||
DEVICE_FRIENDLY_NAME = 0x0007,
|
||||
RESET = 0x0020,
|
||||
CRYPTO_IDENTIFIER = 0x0021,
|
||||
DFUCONTROL = 0x00c0,
|
||||
DFUCONTROL_V2 = 0x00c1,
|
||||
DFUCONTROL_V3 = 0x00c2,
|
||||
DFU = 0xd000,
|
||||
BATTERY_STATUS = 0x1000,
|
||||
BATTERY_VOLTAGE = 0x1001,
|
||||
CHARGING_CONTROL = 0x1010,
|
||||
LED_CONTROL = 0x1300,
|
||||
GENERIC_TEST = 0x1800,
|
||||
DEVICE_RESET = 0x1802,
|
||||
OOB_STATE = 0x1805,
|
||||
CONFIGURABLE_DEVICE_PROPERTIES = 0x1806,
|
||||
CHANGE_HOST = 0x1814,
|
||||
HOSTS_INFO = 0x1815,
|
||||
BACKLIGHT = 0x1981,
|
||||
BACKLIGHT_V2 = 0x1982,
|
||||
BACKLIGHT_V3 = 0x1983,
|
||||
PRESENTER_CONTROL = 0x1a00,
|
||||
SENSOR_3D = 0x1a01,
|
||||
REPROG_CONTROLS = 0x1b00,
|
||||
REPROG_CONTROLS_V2 = 0x1b01,
|
||||
REPROG_CONTROLS_V2_2 = 0x1b02,
|
||||
REPROG_CONTROLS_V3 = 0x1b03,
|
||||
REPROG_CONTROLS_V4 = 0x1b04,
|
||||
PERSISTENT_REMAPPABLE_ACTION = 0x1bc0,
|
||||
WIRELESS_DEVICE_STATUS = 0x1d4b,
|
||||
ENABLE_HIDDEN_FEATURE = 0x1e00,
|
||||
FIRMWARE_PROPERTIES = 0x1f1f,
|
||||
ADC_MEASUREMENT = 0x1f20,
|
||||
LEFT_RIGHT_SWAP = 0x2001,
|
||||
SWAP_BUTTON = 0x2005,
|
||||
POINTER_AXES_ORIENTATION = 0x2006,
|
||||
VERTICAL_SCROLLING = 0x2100,
|
||||
SMART_SHIFT = 0x2110,
|
||||
HIRES_SCROLLING = 0x2120,
|
||||
HIRES_SCROLLING_V2 = 0x2121, // Referred to as Hi-res wheel in cvuchener/hidpp, seems to be V2?
|
||||
LORES_SCROLLING = 0x2130,
|
||||
MOUSE_POINTER = 0x2200, // Possibly predecessor to 0x2201?
|
||||
ADJUSTABLE_DPI = 0x2201,
|
||||
ANGLE_SNAPPING = 0x2230,
|
||||
SURFACE_TUNING = 0x2240,
|
||||
HYBRID_TRACKING = 0x2400,
|
||||
FN_INVERSION = 0x40a0,
|
||||
FN_INVERSION_V2 = 0x40a2, // Is 0x40a1 skipped?
|
||||
FN_INVERSION_V3 = 0x40a3,
|
||||
ENCRYPTION = 0x4100,
|
||||
LOCK_KEY_STATE = 0x4220,
|
||||
SOLAR_DASHBOARD = 0x4301,
|
||||
KEYBOARD_LAYOUT = 0x4520,
|
||||
KEYBOARD_DISABLE = 0x4521,
|
||||
DISABLE_KEYS = 0x4522,
|
||||
MULTIPLATFORM = 0x4530, // Dual platform only?
|
||||
MULTIPLATFORM_V2 = 0x4531,
|
||||
KEYBOARD_LAYOUT_V2 = 0x4540,
|
||||
CROWN = 0x4600,
|
||||
TOUCHPAD_FW = 0x6010,
|
||||
TOUCHPAD_SW = 0x6011,
|
||||
TOUCHPAD_FW_WIN8 = 0x6012,
|
||||
TOUCHMOUSE_RAW = 0x6100,
|
||||
// TOUCHMOUSE_6120 = 0x6120, (Keeping this commented out until a better name is found)
|
||||
GESTURE = 0x6500,
|
||||
GESTURE_V2 = 0x6501,
|
||||
G_KEY = 0x8010,
|
||||
M_KEY = 0x8020,
|
||||
// MR = 0x8030, (Keeping this commented out until a better name is found)
|
||||
BRIGHTNESS_CONTROL = 0x8040,
|
||||
REPORT_RATE = 0x8060,
|
||||
RGB_EFFECTS = 0x8070,
|
||||
RGB_EFFECTS_V2 = 0x8071,
|
||||
PER_KEY_LIGHTING = 0x8080,
|
||||
PER_KEY_LIGHTING_V2 = 0x8081,
|
||||
MODE_STATUS = 0x8100,
|
||||
MOUSE_BUTTON_SPY = 0x8110,
|
||||
LATENCY_MONITORING = 0x8111,
|
||||
GAMING_ATTACHMENTS = 0x8120,
|
||||
FORCE_FEEDBACK = 0x8123,
|
||||
SIDETONE = 0x8300,
|
||||
EQUALIZER = 0x8310,
|
||||
HEADSET_OUT = 0x8320
|
||||
struct feature_info {
|
||||
uint16_t feature_id;
|
||||
bool obsolete;
|
||||
bool internal;
|
||||
bool hidden;
|
||||
};
|
||||
|
||||
namespace FeatureID
|
||||
{
|
||||
enum FeatureID : uint16_t
|
||||
{
|
||||
ROOT = 0x0000,
|
||||
FEATURE_SET = 0x0001,
|
||||
FEATURE_INFO = 0x0002,
|
||||
FW_VERSION = 0x0003,
|
||||
DEVICE_NAME = 0x0005,
|
||||
DEVICE_GROUPS = 0x0006,
|
||||
DEVICE_FRIENDLY_NAME = 0x0007,
|
||||
RESET = 0x0020,
|
||||
CRYPTO_IDENTIFIER = 0x0021,
|
||||
DFUCONTROL = 0x00c0,
|
||||
DFUCONTROL_V2 = 0x00c1,
|
||||
DFUCONTROL_V3 = 0x00c2,
|
||||
DFU = 0xd000,
|
||||
BATTERY_STATUS = 0x1000,
|
||||
BATTERY_VOLTAGE = 0x1001,
|
||||
CHARGING_CONTROL = 0x1010,
|
||||
LED_CONTROL = 0x1300,
|
||||
GENERIC_TEST = 0x1800,
|
||||
DEVICE_RESET = 0x1802,
|
||||
OOB_STATE = 0x1805,
|
||||
CONFIGURABLE_DEVICE_PROPERTIES = 0x1806,
|
||||
CHANGE_HOST = 0x1814,
|
||||
HOSTS_INFO = 0x1815,
|
||||
BACKLIGHT = 0x1981,
|
||||
BACKLIGHT_V2 = 0x1982,
|
||||
BACKLIGHT_V3 = 0x1983,
|
||||
PRESENTER_CONTROL = 0x1a00,
|
||||
SENSOR_3D = 0x1a01,
|
||||
REPROG_CONTROLS = 0x1b00,
|
||||
REPROG_CONTROLS_V2 = 0x1b01,
|
||||
REPROG_CONTROLS_V2_2 = 0x1b02,
|
||||
REPROG_CONTROLS_V3 = 0x1b03,
|
||||
REPROG_CONTROLS_V4 = 0x1b04,
|
||||
PERSISTENT_REMAPPABLE_ACTION = 0x1bc0,
|
||||
WIRELESS_DEVICE_STATUS = 0x1d4b,
|
||||
ENABLE_HIDDEN_FEATURE = 0x1e00,
|
||||
FIRMWARE_PROPERTIES = 0x1f1f,
|
||||
ADC_MEASUREMENT = 0x1f20,
|
||||
LEFT_RIGHT_SWAP = 0x2001,
|
||||
SWAP_BUTTON = 0x2005,
|
||||
POINTER_AXES_ORIENTATION = 0x2006,
|
||||
VERTICAL_SCROLLING = 0x2100,
|
||||
SMART_SHIFT = 0x2110,
|
||||
HIRES_SCROLLING = 0x2120,
|
||||
HIRES_SCROLLING_V2 = 0x2121, // Referred to as Hi-res wheel in cvuchener/hidpp, seems to be V2?
|
||||
LORES_SCROLLING = 0x2130,
|
||||
MOUSE_POINTER = 0x2200, // Possibly predecessor to 0x2201?
|
||||
ADJUSTABLE_DPI = 0x2201,
|
||||
ANGLE_SNAPPING = 0x2230,
|
||||
SURFACE_TUNING = 0x2240,
|
||||
HYBRID_TRACKING = 0x2400,
|
||||
FN_INVERSION = 0x40a0,
|
||||
FN_INVERSION_V2 = 0x40a2, // Is 0x40a1 skipped?
|
||||
FN_INVERSION_V3 = 0x40a3,
|
||||
ENCRYPTION = 0x4100,
|
||||
LOCK_KEY_STATE = 0x4220,
|
||||
SOLAR_DASHBOARD = 0x4301,
|
||||
KEYBOARD_LAYOUT = 0x4520,
|
||||
KEYBOARD_DISABLE = 0x4521,
|
||||
DISABLE_KEYS = 0x4522,
|
||||
MULTIPLATFORM = 0x4530, // Dual platform only?
|
||||
MULTIPLATFORM_V2 = 0x4531,
|
||||
KEYBOARD_LAYOUT_V2 = 0x4540,
|
||||
CROWN = 0x4600,
|
||||
TOUCHPAD_FW = 0x6010,
|
||||
TOUCHPAD_SW = 0x6011,
|
||||
TOUCHPAD_FW_WIN8 = 0x6012,
|
||||
TOUCHMOUSE_RAW = 0x6100,
|
||||
// TOUCHMOUSE_6120 = 0x6120, (Keeping this commented out until a better name is found)
|
||||
GESTURE = 0x6500,
|
||||
GESTURE_V2 = 0x6501,
|
||||
G_KEY = 0x8010,
|
||||
M_KEY = 0x8020,
|
||||
// MR = 0x8030, (Keeping this commented out until a better name is found)
|
||||
BRIGHTNESS_CONTROL = 0x8040,
|
||||
REPORT_RATE = 0x8060,
|
||||
RGB_EFFECTS = 0x8070,
|
||||
RGB_EFFECTS_V2 = 0x8071,
|
||||
PER_KEY_LIGHTING = 0x8080,
|
||||
PER_KEY_LIGHTING_V2 = 0x8081,
|
||||
MODE_STATUS = 0x8100,
|
||||
MOUSE_BUTTON_SPY = 0x8110,
|
||||
LATENCY_MONITORING = 0x8111,
|
||||
GAMING_ATTACHMENTS = 0x8120,
|
||||
FORCE_FEEDBACK = 0x8123,
|
||||
SIDETONE = 0x8300,
|
||||
EQUALIZER = 0x8310,
|
||||
HEADSET_OUT = 0x8320
|
||||
};
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif //LOGID_BACKEND_HIDPP20_FEATUREDEFS
|
25
src/logid/backend/hidpp20/features/Root.cpp
Normal file
25
src/logid/backend/hidpp20/features/Root.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "Root.h"
|
||||
|
||||
using namespace logid::backend::hidpp20;
|
||||
|
||||
Root::Root(Device* dev) : Feature(dev, ID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
feature_info Root::getFeature(uint16_t feature_id)
|
||||
{
|
||||
feature_info info;
|
||||
std::vector<uint8_t> params(2);
|
||||
params[0] = feature_id & 0xff;
|
||||
params[1] = (feature_id >> 8) & 0xff;
|
||||
|
||||
auto response = this->callFunction(Function::Ping, params);
|
||||
|
||||
info.feature_id = response[0];
|
||||
info.hidden = response[1] & FeatureFlag::Hidden;
|
||||
info.obsolete = response[1] & FeatureFlag::Obsolete;
|
||||
info.internal = response[1] & FeatureFlag::Internal;
|
||||
|
||||
return info;
|
||||
}
|
37
src/logid/backend/hidpp20/features/Root.h
Normal file
37
src/logid/backend/hidpp20/features/Root.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef LOGID_BACKEND_HIDPP20_FEATURE_ROOT_H
|
||||
#define LOGID_BACKEND_HIDPP20_FEATURE_ROOT_H
|
||||
|
||||
#include "../Feature.h"
|
||||
#include "../feature_defs.h"
|
||||
|
||||
namespace logid {
|
||||
namespace backend {
|
||||
namespace hidpp20
|
||||
{
|
||||
class Root : public Feature
|
||||
{
|
||||
public:
|
||||
static const uint16_t ID = FeatureID::ROOT;
|
||||
virtual uint16_t getID() { return ID; }
|
||||
|
||||
enum Function : uint8_t
|
||||
{
|
||||
GetFeature = 0,
|
||||
Ping = 1
|
||||
};
|
||||
|
||||
Root(Device* device);
|
||||
|
||||
feature_info getFeature (uint16_t feature_id);
|
||||
void ping();
|
||||
private:
|
||||
enum FeatureFlag : uint8_t
|
||||
{
|
||||
Obsolete = 1<<7,
|
||||
Hidden = 1<<6,
|
||||
Internal = 1<<5
|
||||
};
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif //LOGID_BACKEND_HIDPP20_FEATURE_ROOT_H
|
Reference in New Issue
Block a user