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:
		@@ -17,6 +17,10 @@ add_executable(logid
 | 
				
			|||||||
        backend/raw/RawDevice.cpp
 | 
					        backend/raw/RawDevice.cpp
 | 
				
			||||||
        backend/hidpp/Device.cpp
 | 
					        backend/hidpp/Device.cpp
 | 
				
			||||||
        backend/hidpp/Report.cpp
 | 
					        backend/hidpp/Report.cpp
 | 
				
			||||||
 | 
					        backend/hidpp20/Device.cpp
 | 
				
			||||||
 | 
					        backend/hidpp20/Error.cpp
 | 
				
			||||||
 | 
					        backend/hidpp20/Feature.cpp
 | 
				
			||||||
 | 
					        backend/hidpp20/features/Root.cpp
 | 
				
			||||||
        backend/dj/Report.cpp
 | 
					        backend/dj/Report.cpp
 | 
				
			||||||
        util/mutex_queue.h)
 | 
					        util/mutex_queue.h)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,6 +105,9 @@ void DeviceMonitor::addDevice(std::string path)
 | 
				
			|||||||
        auto device = std::make_shared<backend::hidpp::Device>(path, hidpp::DeviceIndex::WirelessDevice1);
 | 
					        auto device = std::make_shared<backend::hidpp::Device>(path, hidpp::DeviceIndex::WirelessDevice1);
 | 
				
			||||||
        log_printf(DEBUG, "Detected HID++ device at %s", path.c_str());
 | 
					        log_printf(DEBUG, "Detected HID++ device at %s", path.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto version = device->version();
 | 
				
			||||||
 | 
					        log_printf(DEBUG, "HID++ version: %d.%d", std::get<0>(version), std::get<1>(version));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto eventHandler = std::make_shared<backend::hidpp::EventHandler>();
 | 
					        auto eventHandler = std::make_shared<backend::hidpp::EventHandler>();
 | 
				
			||||||
        eventHandler->condition = [device](backend::hidpp::Report& report)->bool
 | 
					        eventHandler->condition = [device](backend::hidpp::Report& report)->bool
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								src/logid/backend/dj/defs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/logid/backend/dj/defs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					#ifndef LOGID_BACKEND_DJ_DEFS_H
 | 
				
			||||||
 | 
					#define LOGID_BACKEND_DJ_DEFS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace logid {
 | 
				
			||||||
 | 
					namespace backend {
 | 
				
			||||||
 | 
					namespace dj
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    namespace ReportType
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        enum ReportType : uint8_t
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Short = 0x20,
 | 
				
			||||||
 | 
					            Long = 0x21
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //LOGID_BACKEND_DJ_DEFS_H
 | 
				
			||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include "Device.h"
 | 
					#include "Device.h"
 | 
				
			||||||
#include "Report.h"
 | 
					#include "Report.h"
 | 
				
			||||||
 | 
					#include "../hidpp20/features/Root.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace logid::backend;
 | 
					using namespace logid::backend;
 | 
				
			||||||
using namespace logid::backend::hidpp;
 | 
					using namespace logid::backend::hidpp;
 | 
				
			||||||
@@ -29,12 +30,20 @@ Device::Device(const std::string& path, DeviceIndex index):
 | 
				
			|||||||
    if(!supported_reports)
 | 
					    if(!supported_reports)
 | 
				
			||||||
        throw InvalidDevice(InvalidDevice::NoHIDPPReport);
 | 
					        throw InvalidDevice(InvalidDevice::NoHIDPPReport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Report versionRequest(Report::Type::Short, index, hidpp20::FeatureID::ROOT,
 | 
				
			||||||
 | 
					            hidpp20::Root::Ping, LOGID_HIDPP_SOFTWARE_ID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///TODO: Catch error
 | 
				
			||||||
 | 
					    auto versionResponse = sendReport(versionRequest);
 | 
				
			||||||
 | 
					    auto versionResponse_params = versionResponse.paramBegin();
 | 
				
			||||||
 | 
					    _version = std::make_tuple(versionResponse_params[0], versionResponse_params[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Pass all HID++ events with device index to this device.
 | 
					    // Pass all HID++ events with device index to this device.
 | 
				
			||||||
    RawEventHandler rawEventHandler;
 | 
					    RawEventHandler rawEventHandler;
 | 
				
			||||||
    rawEventHandler.condition = [index](std::vector<uint8_t>& report)->bool
 | 
					    rawEventHandler.condition = [index](std::vector<uint8_t>& report)->bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return (report[Offset::Type] == Report::Short ||
 | 
					        return (report[Offset::Type] == Report::Type::Short ||
 | 
				
			||||||
            report[Offset::Type] == Report::Long) && (report[Offset::DeviceIndex] == index);
 | 
					            report[Offset::Type] == Report::Type::Long) && (report[Offset::DeviceIndex] == index);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    rawEventHandler.callback = [this](std::vector<uint8_t>& report)->void
 | 
					    rawEventHandler.callback = [this](std::vector<uint8_t>& report)->void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -69,11 +78,11 @@ Report Device::sendReport(Report& report)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    switch(report.type())
 | 
					    switch(report.type())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Report::Short:
 | 
					        case Report::Type::Short:
 | 
				
			||||||
            if(!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED))
 | 
					            if(!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED))
 | 
				
			||||||
                report.setType(Report::Long);
 | 
					                report.setType(Report::Type::Long);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case Report::Long:
 | 
					        case Report::Type::Long:
 | 
				
			||||||
            /* Report can be truncated, but that isn't a good idea. */
 | 
					            /* Report can be truncated, but that isn't a good idea. */
 | 
				
			||||||
            assert(supported_reports & HIDPP_REPORT_LONG_SUPPORTED);
 | 
					            assert(supported_reports & HIDPP_REPORT_LONG_SUPPORTED);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@ namespace hidpp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::string devicePath() const { return path; }
 | 
					        std::string devicePath() const { return path; }
 | 
				
			||||||
        DeviceIndex deviceIndex() const { return index; }
 | 
					        DeviceIndex deviceIndex() const { return index; }
 | 
				
			||||||
 | 
					        std::tuple<uint8_t, uint8_t> version() const { return _version; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void listen(); // Runs asynchronously
 | 
					        void listen(); // Runs asynchronously
 | 
				
			||||||
        void stopListening();
 | 
					        void stopListening();
 | 
				
			||||||
@@ -56,6 +57,8 @@ namespace hidpp
 | 
				
			|||||||
        DeviceIndex index;
 | 
					        DeviceIndex index;
 | 
				
			||||||
        uint8_t supported_reports;
 | 
					        uint8_t supported_reports;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::tuple<uint8_t, uint8_t> _version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::map<std::string, std::shared_ptr<EventHandler>> event_handlers;
 | 
					        std::map<std::string, std::shared_ptr<EventHandler>> event_handlers;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
} } }
 | 
					} } }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,15 +96,15 @@ const char *Report::InvalidReportLength::what() const noexcept
 | 
				
			|||||||
Report::Report(Report::Type type, DeviceIndex device_index,
 | 
					Report::Report(Report::Type type, DeviceIndex device_index,
 | 
				
			||||||
        uint8_t feature_index, uint8_t function, uint8_t sw_id)
 | 
					        uint8_t feature_index, uint8_t function, uint8_t sw_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(!(function & functionMask));
 | 
					    assert(function <= functionMask);
 | 
				
			||||||
    assert(!(sw_id & swIdMask));
 | 
					    assert(sw_id <= swIdMask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch(type)
 | 
					    switch(type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Short:
 | 
					        case Type::Short:
 | 
				
			||||||
            _data.resize(HeaderLength + ShortParamLength);
 | 
					            _data.resize(HeaderLength + ShortParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case Long:
 | 
					        case Type::Long:
 | 
				
			||||||
            _data.resize(HeaderLength + LongParamLength);
 | 
					            _data.resize(HeaderLength + LongParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
@@ -123,10 +123,10 @@ Report::Report(const std::vector<uint8_t>& data)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    switch(_data[Offset::Type])
 | 
					    switch(_data[Offset::Type])
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Short:
 | 
					        case Type::Short:
 | 
				
			||||||
            _data.resize(HeaderLength + ShortParamLength);
 | 
					            _data.resize(HeaderLength + ShortParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case Long:
 | 
					        case Type::Long:
 | 
				
			||||||
            _data.resize(HeaderLength + LongParamLength);
 | 
					            _data.resize(HeaderLength + LongParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
@@ -138,10 +138,10 @@ void Report::setType(Report::Type type)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    switch(type)
 | 
					    switch(type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        case Short:
 | 
					        case Type::Short:
 | 
				
			||||||
            _data.resize(HeaderLength + ShortParamLength);
 | 
					            _data.resize(HeaderLength + ShortParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case Long:
 | 
					        case Type::Long:
 | 
				
			||||||
            _data.resize(HeaderLength + LongParamLength);
 | 
					            _data.resize(HeaderLength + LongParamLength);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
@@ -158,3 +158,10 @@ void Report::setParams(const std::vector<uint8_t>& _params)
 | 
				
			|||||||
    for(std::size_t i = 0; i < _params.size(); i++)
 | 
					    for(std::size_t i = 0; i < _params.size(); i++)
 | 
				
			||||||
        _data[Offset::Parameters + i] = _params[i];
 | 
					        _data[Offset::Parameters + i] = _params[i];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Report::isError20(Report::hidpp20_error* error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(_data[Offset::Type] != Type::Long ||
 | 
				
			||||||
 | 
					        _data[Offset::Feature] != 0xff)
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -26,11 +26,7 @@ namespace logid::backend::hidpp
 | 
				
			|||||||
    class Report
 | 
					    class Report
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        enum Type: uint8_t
 | 
					        typedef ReportType::ReportType Type;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Short = 0x10,
 | 
					 | 
				
			||||||
            Long = 0x11
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class InvalidReportID: public std::exception
 | 
					        class InvalidReportID: public std::exception
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -50,19 +46,26 @@ namespace logid::backend::hidpp
 | 
				
			|||||||
        static constexpr uint8_t swIdMask = 0x0f;
 | 
					        static constexpr uint8_t swIdMask = 0x0f;
 | 
				
			||||||
        static constexpr uint8_t functionMask = 0x0f;
 | 
					        static constexpr uint8_t functionMask = 0x0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Report(Type type, DeviceIndex device_index,
 | 
					        Report(Report::Type type, DeviceIndex device_index,
 | 
				
			||||||
                uint8_t feature_index,
 | 
					                uint8_t feature_index,
 | 
				
			||||||
                uint8_t function,
 | 
					                uint8_t function,
 | 
				
			||||||
                uint8_t sw_id);
 | 
					                uint8_t sw_id);
 | 
				
			||||||
        explicit Report(const std::vector<uint8_t>& data);
 | 
					        explicit Report(const std::vector<uint8_t>& data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Type type() const { return static_cast<Type>(_data[Offset::Type]); };
 | 
					        Report::Type type() const { return static_cast<Report::Type>(_data[Offset::Type]); };
 | 
				
			||||||
        void setType(Report::Type type);
 | 
					        void setType(Report::Type type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::vector<uint8_t>::const_iterator paramBegin() const { return _data.begin() + Offset::Parameters; }
 | 
					        std::vector<uint8_t>::iterator paramBegin() { return _data.begin() + Offset::Parameters; }
 | 
				
			||||||
        std::vector<uint8_t>::const_iterator paramEnd() const { return _data.end(); }
 | 
					        std::vector<uint8_t>::iterator paramEnd() { return _data.end(); }
 | 
				
			||||||
        void setParams(const std::vector<uint8_t>& _params);
 | 
					        void setParams(const std::vector<uint8_t>& _params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        struct hidpp20_error
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            uint8_t feature_index, function, software_id, error_code;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool isError20(hidpp20_error* error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        logid::backend::hidpp::DeviceIndex deviceIndex()
 | 
					        logid::backend::hidpp::DeviceIndex deviceIndex()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return static_cast<DeviceIndex>(_data[Offset::DeviceIndex]);
 | 
					            return static_cast<DeviceIndex>(_data[Offset::DeviceIndex]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace logid::backend::hidpp
 | 
					namespace logid::backend::hidpp
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    namespace ReportType
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        enum ReportType : uint8_t
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Short = 0x10,
 | 
				
			||||||
 | 
					            Long = 0x11
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum DeviceIndex: uint8_t
 | 
					    enum DeviceIndex: uint8_t
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        DefaultDevice = 0,
 | 
					        DefaultDevice = 0,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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,6 +6,15 @@
 | 
				
			|||||||
namespace logid {
 | 
					namespace logid {
 | 
				
			||||||
namespace backend {
 | 
					namespace backend {
 | 
				
			||||||
namespace hidpp20 {
 | 
					namespace hidpp20 {
 | 
				
			||||||
 | 
					    struct feature_info {
 | 
				
			||||||
 | 
					        uint16_t feature_id;
 | 
				
			||||||
 | 
					        bool obsolete;
 | 
				
			||||||
 | 
					        bool internal;
 | 
				
			||||||
 | 
					        bool hidden;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    namespace FeatureID
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        enum FeatureID : uint16_t
 | 
					        enum FeatureID : uint16_t
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ROOT = 0x0000,
 | 
					            ROOT = 0x0000,
 | 
				
			||||||
@@ -97,6 +106,8 @@ namespace hidpp20 {
 | 
				
			|||||||
            EQUALIZER = 0x8310,
 | 
					            EQUALIZER = 0x8310,
 | 
				
			||||||
            HEADSET_OUT = 0x8320
 | 
					            HEADSET_OUT = 0x8320
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}}
 | 
					}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //LOGID_BACKEND_HIDPP20_FEATUREDEFS
 | 
					#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
 | 
				
			||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
#include "RawDevice.h"
 | 
					#include "RawDevice.h"
 | 
				
			||||||
#include "../Error.h"
 | 
					#include "../Error.h"
 | 
				
			||||||
 | 
					#include "../hidpp/defs.h"
 | 
				
			||||||
 | 
					#include "../dj/defs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <system_error>
 | 
					#include <system_error>
 | 
				
			||||||
@@ -16,9 +18,16 @@ extern "C"
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace logid::backend::raw;
 | 
					using namespace logid::backend::raw;
 | 
				
			||||||
 | 
					using namespace logid::backend;
 | 
				
			||||||
using namespace std::chrono;
 | 
					using namespace std::chrono;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RawDevice::RawDevice(std::string path) : path (path)
 | 
					bool RawDevice::supportedReportID(uint8_t id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (hidpp::ReportType::Short == id) || (hidpp::ReportType::Long == id) ||
 | 
				
			||||||
 | 
					           (dj::ReportType::Short == id) || (dj::ReportType::Long == id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RawDevice::RawDevice(std::string path) : path (path), continue_listen (false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,24 +89,81 @@ RawDevice::~RawDevice()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::vector<uint8_t> RawDevice::sendReport(const std::vector<uint8_t>& report)
 | 
					std::vector<uint8_t> RawDevice::sendReport(const std::vector<uint8_t>& report)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    std::packaged_task<std::vector<uint8_t>()> task(
 | 
					    assert(supportedReportID(report[0]));
 | 
				
			||||||
            [=]() {
 | 
					 | 
				
			||||||
        _sendReport(report);
 | 
					 | 
				
			||||||
        std::vector<uint8_t> response;
 | 
					 | 
				
			||||||
        _readReport(response, MAX_DATA_LENGTH);
 | 
					 | 
				
			||||||
        return response;
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* If the listener will stop, handle I/O manually.
 | 
					        /* If the listener will stop, handle I/O manually.
 | 
				
			||||||
     * Otherwise, push to queue and wait for result. */
 | 
					     * Otherwise, push to queue and wait for result. */
 | 
				
			||||||
    if(continue_listen)
 | 
					    if(continue_listen)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        std::packaged_task<std::vector<uint8_t>()> task( [this, report]() {
 | 
				
			||||||
 | 
					            return this->_respondToReport(report);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        auto f = task.get_future();
 | 
					        auto f = task.get_future();
 | 
				
			||||||
        write_queue.push(&task);
 | 
					        write_queue.push(&task);
 | 
				
			||||||
        return f.get();
 | 
					        return f.get();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        return task.get_future().get();
 | 
					        return _respondToReport(report);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<uint8_t> RawDevice::_respondToReport
 | 
				
			||||||
 | 
					    (const std::vector<uint8_t>& request)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _sendReport(request);
 | 
				
			||||||
 | 
					    while(true)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::vector<uint8_t> response;
 | 
				
			||||||
 | 
					        _readReport(response, MAX_DATA_LENGTH);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // All reports have the device index at byte 2
 | 
				
			||||||
 | 
					        if(response[1] != request[1])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::thread([this](std::vector<uint8_t> report) {
 | 
				
			||||||
 | 
					                this->handleEvent(report);
 | 
				
			||||||
 | 
					            }, request).detach();
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(hidpp::ReportType::Short == request[0] ||
 | 
				
			||||||
 | 
					            hidpp::ReportType::Long == request[0])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if(hidpp::ReportType::Short != response[0] &&
 | 
				
			||||||
 | 
					               hidpp::ReportType::Long != response[0])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::thread([this](std::vector<uint8_t> report) {
 | 
				
			||||||
 | 
					                    this->handleEvent(report);
 | 
				
			||||||
 | 
					                }, request).detach();
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Error; leave to device to handle
 | 
				
			||||||
 | 
					            if(response[2] == 0x8f || response[2] == 0xff)
 | 
				
			||||||
 | 
					                return response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool others_match = true;
 | 
				
			||||||
 | 
					            for(int i = 2; i < 4; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if(response[i] != request[i])
 | 
				
			||||||
 | 
					                    others_match = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(others_match)
 | 
				
			||||||
 | 
					                return response;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if(dj::ReportType::Short == request[0] ||
 | 
				
			||||||
 | 
					            dj::ReportType::Long == request[0])
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //Error; leave to device ot handle
 | 
				
			||||||
 | 
					            if(0x7f == response[2])
 | 
				
			||||||
 | 
					                return response;
 | 
				
			||||||
 | 
					            else if(response[2] == request[2])
 | 
				
			||||||
 | 
					                return response;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::thread([this](std::vector<uint8_t> report) {
 | 
				
			||||||
 | 
					            this->handleEvent(report);
 | 
				
			||||||
 | 
					        }, request).detach();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int RawDevice::_sendReport(const std::vector<uint8_t>& report)
 | 
					int RawDevice::_sendReport(const std::vector<uint8_t>& report)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
#include <future>
 | 
					#include <future>
 | 
				
			||||||
 | 
					#include <set>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../defs.h"
 | 
					#include "../defs.h"
 | 
				
			||||||
#include "../../util/mutex_queue.h"
 | 
					#include "../../util/mutex_queue.h"
 | 
				
			||||||
@@ -20,12 +21,13 @@ namespace raw
 | 
				
			|||||||
    class RawDevice
 | 
					    class RawDevice
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					        static bool supportedReportID(uint8_t id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        RawDevice(std::string path);
 | 
					        RawDevice(std::string path);
 | 
				
			||||||
        ~RawDevice();
 | 
					        ~RawDevice();
 | 
				
			||||||
        std::string hidrawPath() const { return path; }
 | 
					        std::string hidrawPath() const { return path; }
 | 
				
			||||||
        std::vector<uint8_t> reportDescriptor() const { return rdesc; }
 | 
					        std::vector<uint8_t> reportDescriptor() const { return rdesc; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// TODO: Process reports in a queue.
 | 
					 | 
				
			||||||
        std::vector<uint8_t> sendReport(const std::vector<uint8_t>& report);
 | 
					        std::vector<uint8_t> sendReport(const std::vector<uint8_t>& report);
 | 
				
			||||||
        void interruptRead();
 | 
					        void interruptRead();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,6 +57,8 @@ namespace raw
 | 
				
			|||||||
        int _sendReport(const std::vector<uint8_t>& report);
 | 
					        int _sendReport(const std::vector<uint8_t>& report);
 | 
				
			||||||
        int _readReport(std::vector<uint8_t>& report, std::size_t maxDataLength);
 | 
					        int _readReport(std::vector<uint8_t>& report, std::size_t maxDataLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::vector<uint8_t> _respondToReport(const std::vector<uint8_t>& request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mutex_queue<std::packaged_task<std::vector<uint8_t>()>*> write_queue;
 | 
					        mutex_queue<std::packaged_task<std::vector<uint8_t>()>*> write_queue;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}}}
 | 
					}}}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user