Support getting version of HID++ 1.0 devices
This commit is contained in:
		@@ -17,6 +17,7 @@ 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/hidpp10/Error.cpp
 | 
				
			||||||
        backend/hidpp20/Device.cpp
 | 
					        backend/hidpp20/Device.cpp
 | 
				
			||||||
        backend/hidpp20/Error.cpp
 | 
					        backend/hidpp20/Error.cpp
 | 
				
			||||||
        backend/hidpp20/Feature.cpp
 | 
					        backend/hidpp20/Feature.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "DeviceMonitor.h"
 | 
					#include "DeviceMonitor.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					#include "backend/hidpp10/Error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NON_WIRELESS_DEV(index) (index) == HIDPP::DefaultDevice ? "default" : "corded"
 | 
					#define NON_WIRELESS_DEV(index) (index) == HIDPP::DefaultDevice ? "default" : "corded"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,7 +129,13 @@ void DeviceMonitor::addDevice(std::string path)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        std::thread([device]() { device->listen(); }).detach();
 | 
					        std::thread([device]() { device->listen(); }).detach();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    catch(backend::hidpp::Device::InvalidDevice &e)
 | 
					    catch(hidpp10::Error &e)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if(e.code() == hidpp10::Error::UnknownDevice) {}
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            throw;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch(hidpp::Device::InvalidDevice &e)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        log_printf(DEBUG, "Detected device at %s but %s", path.c_str(), e.what());
 | 
					        log_printf(DEBUG, "Detected device at %s but %s", path.c_str(), e.what());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@
 | 
				
			|||||||
#include "Device.h"
 | 
					#include "Device.h"
 | 
				
			||||||
#include "Report.h"
 | 
					#include "Report.h"
 | 
				
			||||||
#include "../hidpp20/features/Root.h"
 | 
					#include "../hidpp20/features/Root.h"
 | 
				
			||||||
 | 
					#include "../hidpp20/Error.h"
 | 
				
			||||||
 | 
					#include "../hidpp10/Error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace logid::backend;
 | 
					using namespace logid::backend;
 | 
				
			||||||
using namespace logid::backend::hidpp;
 | 
					using namespace logid::backend::hidpp;
 | 
				
			||||||
@@ -30,13 +32,24 @@ 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,
 | 
					    try
 | 
				
			||||||
            hidpp20::Root::Ping, LOGID_HIDPP_SOFTWARE_ID);
 | 
					    {
 | 
				
			||||||
 | 
					        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 = sendReport(versionRequest);
 | 
					        auto versionResponse_params = versionResponse.paramBegin();
 | 
				
			||||||
    auto versionResponse_params = versionResponse.paramBegin();
 | 
					        _version = std::make_tuple(versionResponse_params[0], versionResponse_params[1]);
 | 
				
			||||||
    _version = std::make_tuple(versionResponse_params[0], versionResponse_params[1]);
 | 
					    }
 | 
				
			||||||
 | 
					    catch(hidpp10::Error &e)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Valid HID++ 1.0 devices should send an InvalidSubID error
 | 
				
			||||||
 | 
					        if(e.code() != hidpp10::Error::InvalidSubID)
 | 
				
			||||||
 | 
					            throw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // HID++ 2.0 is not supported, assume HID++ 1.0
 | 
				
			||||||
 | 
					        _version = std::make_tuple(1, 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Pass all HID++ events with device index to this device.
 | 
					    // Pass all HID++ events with device index to this device.
 | 
				
			||||||
    RawEventHandler rawEventHandler;
 | 
					    RawEventHandler rawEventHandler;
 | 
				
			||||||
@@ -88,7 +101,18 @@ Report Device::sendReport(Report& report)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto raw_response = raw_device->sendReport(report.rawReport());
 | 
					    auto raw_response = raw_device->sendReport(report.rawReport());
 | 
				
			||||||
    return Report(raw_response);
 | 
					
 | 
				
			||||||
 | 
					    Report response(raw_response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Report::hidpp10_error hidpp10Error{};
 | 
				
			||||||
 | 
					    if(response.isError10(&hidpp10Error))
 | 
				
			||||||
 | 
					        throw hidpp10::Error(hidpp10Error.error_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Report::hidpp20_error hidpp20Error{};
 | 
				
			||||||
 | 
					    if(response.isError20(&hidpp20Error))
 | 
				
			||||||
 | 
					        throw hidpp10::Error(hidpp20Error.error_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Device::listen()
 | 
					void Device::listen()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@
 | 
				
			|||||||
#include <algorithm>
 | 
					#include <algorithm>
 | 
				
			||||||
#include <cassert>
 | 
					#include <cassert>
 | 
				
			||||||
#include "Report.h"
 | 
					#include "Report.h"
 | 
				
			||||||
 | 
					#include "../hidpp10/Error.h"
 | 
				
			||||||
 | 
					#include "../hidpp20/Error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace logid::backend::hidpp;
 | 
					using namespace logid::backend::hidpp;
 | 
				
			||||||
using namespace logid::backend;
 | 
					using namespace logid::backend;
 | 
				
			||||||
@@ -159,9 +161,31 @@ void Report::setParams(const std::vector<uint8_t>& _params)
 | 
				
			|||||||
        _data[Offset::Parameters + i] = _params[i];
 | 
					        _data[Offset::Parameters + i] = _params[i];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Report::isError10(Report::hidpp10_error *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(error != nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(_data[Offset::Type] != Type::Short ||
 | 
				
			||||||
 | 
					        _data[Offset::SubID] != hidpp10::ErrorID)
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error->sub_id = _data[3];
 | 
				
			||||||
 | 
					    error->address = _data[4];
 | 
				
			||||||
 | 
					    error->error_code = _data[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Report::isError20(Report::hidpp20_error* error)
 | 
					bool Report::isError20(Report::hidpp20_error* error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(_data[Offset::Type] != Type::Long ||
 | 
					    if(_data[Offset::Type] != Type::Long ||
 | 
				
			||||||
        _data[Offset::Feature] != 0xff)
 | 
					        _data[Offset::Feature] != hidpp20::ErrorID)
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error->feature_index= _data[3];
 | 
				
			||||||
 | 
					    error->function = (_data[4] >> 4) & 0x0f;
 | 
				
			||||||
 | 
					    error->software_id = _data[4] & 0x0f;
 | 
				
			||||||
 | 
					    error->error_code = _data[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -18,6 +18,7 @@ namespace logid::backend::hidpp
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        static constexpr uint8_t Type = 0;
 | 
					        static constexpr uint8_t Type = 0;
 | 
				
			||||||
        static constexpr uint8_t DeviceIndex = 1;
 | 
					        static constexpr uint8_t DeviceIndex = 1;
 | 
				
			||||||
 | 
					        static constexpr uint8_t SubID = 2;
 | 
				
			||||||
        static constexpr uint8_t Feature = 2;
 | 
					        static constexpr uint8_t Feature = 2;
 | 
				
			||||||
        static constexpr uint8_t Function = 3;
 | 
					        static constexpr uint8_t Function = 3;
 | 
				
			||||||
        static constexpr uint8_t Parameters = 4;
 | 
					        static constexpr uint8_t Parameters = 4;
 | 
				
			||||||
@@ -59,6 +60,13 @@ namespace logid::backend::hidpp
 | 
				
			|||||||
        std::vector<uint8_t>::iterator paramEnd() { 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 hidpp10_error
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            uint8_t sub_id, address, error_code;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool isError10(hidpp10_error* error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct hidpp20_error
 | 
					        struct hidpp20_error
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            uint8_t feature_index, function, software_id, error_code;
 | 
					            uint8_t feature_index, function, software_id, error_code;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
#ifndef LOGID_HIDPP_DEFS_H
 | 
					#ifndef LOGID_HIDPP_DEFS_H
 | 
				
			||||||
#define LOGID_HIDPP_DEFS_H
 | 
					#define LOGID_HIDPP_DEFS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LOGID_HIDPP_SOFTWARE_ID 1
 | 
					#define LOGID_HIDPP_SOFTWARE_ID 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace logid::backend::hidpp
 | 
					namespace logid::backend::hidpp
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								src/logid/backend/hidpp10/Error.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/logid/backend/hidpp10/Error.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					#include <cassert>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include "Error.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace logid::backend::hidpp10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Error::Error(uint8_t code): _code(code)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    assert(code != Success);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char* Error::what() const noexcept
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch(_code)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case Success:
 | 
				
			||||||
 | 
					            return "Success";
 | 
				
			||||||
 | 
					        case InvalidSubID:
 | 
				
			||||||
 | 
					            return "Invalid sub ID";
 | 
				
			||||||
 | 
					        case InvalidAddress:
 | 
				
			||||||
 | 
					            return "Invalid address";
 | 
				
			||||||
 | 
					        case InvalidValue:
 | 
				
			||||||
 | 
					            return "Invalid value";
 | 
				
			||||||
 | 
					        case ConnectFail:
 | 
				
			||||||
 | 
					            return "Connection failure";
 | 
				
			||||||
 | 
					        case TooManyDevices:
 | 
				
			||||||
 | 
					            return "Too many devices";
 | 
				
			||||||
 | 
					        case AlreadyExists:
 | 
				
			||||||
 | 
					            return "Already exists";
 | 
				
			||||||
 | 
					        case Busy:
 | 
				
			||||||
 | 
					            return "Busy";
 | 
				
			||||||
 | 
					        case UnknownDevice:
 | 
				
			||||||
 | 
					            return "Unknown device";
 | 
				
			||||||
 | 
					        case ResourceError:
 | 
				
			||||||
 | 
					            return "Resource error";
 | 
				
			||||||
 | 
					        case RequestUnavailable:
 | 
				
			||||||
 | 
					            return "Request unavailable";
 | 
				
			||||||
 | 
					        case InvalidParameterValue:
 | 
				
			||||||
 | 
					            return "Invalid parameter value";
 | 
				
			||||||
 | 
					        case WrongPINCode:
 | 
				
			||||||
 | 
					            return "Wrong PIN code";
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            return std::string("Unknown error code " + std::to_string(_code)).c_str();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t Error::code() const noexcept
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								src/logid/backend/hidpp10/Error.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/logid/backend/hidpp10/Error.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					#ifndef LOGID_BACKEND_HIDPP10_ERROR_H
 | 
				
			||||||
 | 
					#define LOGID_BACKEND_HIDPP10_ERROR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace logid {
 | 
				
			||||||
 | 
					namespace backend {
 | 
				
			||||||
 | 
					namespace hidpp10 {
 | 
				
			||||||
 | 
					    static constexpr uint8_t ErrorID = 0x8f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Error: public std::exception
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        enum ErrorCode: uint8_t
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Success = 0x00,
 | 
				
			||||||
 | 
					            InvalidSubID = 0x01,
 | 
				
			||||||
 | 
					            InvalidAddress = 0x02,
 | 
				
			||||||
 | 
					            InvalidValue = 0x03,
 | 
				
			||||||
 | 
					            ConnectFail = 0x04,
 | 
				
			||||||
 | 
					            TooManyDevices = 0x05,
 | 
				
			||||||
 | 
					            AlreadyExists = 0x06,
 | 
				
			||||||
 | 
					            Busy = 0x07,
 | 
				
			||||||
 | 
					            UnknownDevice = 0x08,
 | 
				
			||||||
 | 
					            ResourceError = 0x09,
 | 
				
			||||||
 | 
					            RequestUnavailable = 0x0A,
 | 
				
			||||||
 | 
					            InvalidParameterValue = 0x0B,
 | 
				
			||||||
 | 
					            WrongPINCode = 0x0C
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Error(uint8_t code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual const char* what() const noexcept;
 | 
				
			||||||
 | 
					        uint8_t code() const noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        uint8_t _code;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //LOGID_BACKEND_HIDPP10_ERROR_H
 | 
				
			||||||
		Reference in New Issue
	
	Block a user