diff --git a/src/logid/Device.cpp b/src/logid/Device.cpp index 3550c09..3041542 100644 --- a/src/logid/Device.cpp +++ b/src/logid/Device.cpp @@ -5,7 +5,7 @@ using namespace logid; using namespace logid::backend; Device::Device(std::string path, backend::hidpp::DeviceIndex index) : - _hidpp20 (path, index), _path (path), _index (index) + _hidpp20 (path, index), _path (std::move(path)), _index (index) { log_printf(DEBUG, "logid::Device created on %s:%d", _path.c_str(), _index); } diff --git a/src/logid/DeviceManager.cpp b/src/logid/DeviceManager.cpp index 1ee5854..8c6a35d 100644 --- a/src/logid/DeviceManager.cpp +++ b/src/logid/DeviceManager.cpp @@ -44,14 +44,16 @@ void DeviceManager::addDevice(std::string path) _devices.emplace(path, device); } else { try { - auto device = std::make_shared(path, hidpp::CordedDevice); + auto device = std::make_shared(path, + hidpp::CordedDevice); _devices.emplace(path, device); } catch(hidpp10::Error &e) { if(e.code() != hidpp10::Error::UnknownDevice) throw; else - log_printf(WARN, "HID++ 1.0 error while trying to initialize" - " %s: %s", path.c_str(), e.what()); + log_printf(WARN, + "HID++ 1.0 error while trying to initialize %s:" + "%s", path.c_str(), e.what()); } catch(hidpp::Device::InvalidDevice &e) { // Ignore } catch(std::system_error &e) { // This error should have been thrown previously diff --git a/src/logid/DeviceManager.h b/src/logid/DeviceManager.h index e4134bc..57e9012 100644 --- a/src/logid/DeviceManager.h +++ b/src/logid/DeviceManager.h @@ -1,5 +1,5 @@ -#ifndef LOGID_DEVICEMONITOR_H -#define LOGID_DEVICEMONITOR_H +#ifndef LOGID_DEVICEMANAGER_H +#define LOGID_DEVICEMANAGER_H #include #include @@ -29,4 +29,4 @@ namespace logid extern DeviceManager* finder; } -#endif //LOGID_DEVICEFINDER_H \ No newline at end of file +#endif //LOGID_DEVICEMANAGER_H \ No newline at end of file diff --git a/src/logid/backend/Error.cpp b/src/logid/backend/Error.cpp index c224f76..f7f8d0b 100644 --- a/src/logid/backend/Error.cpp +++ b/src/logid/backend/Error.cpp @@ -1,6 +1,6 @@ #include "Error.h" -const char *logid::backend::TimeoutError::what() noexcept +const char *logid::backend::TimeoutError::what() const noexcept { return "Device timed out"; } diff --git a/src/logid/backend/Error.h b/src/logid/backend/Error.h index 20865cf..3cc515f 100644 --- a/src/logid/backend/Error.h +++ b/src/logid/backend/Error.h @@ -9,7 +9,7 @@ class TimeoutError: public std::exception { public: TimeoutError() = default; - virtual const char* what() noexcept; + const char* what() const noexcept override; }; }} diff --git a/src/logid/backend/dj/Error.cpp b/src/logid/backend/dj/Error.cpp index d3a4dbc..8a7f73f 100644 --- a/src/logid/backend/dj/Error.cpp +++ b/src/logid/backend/dj/Error.cpp @@ -8,14 +8,17 @@ Error::Error(uint8_t code) : _code (code) const char* Error::what() const noexcept { - switch(_code) - { - case Unknown: - return "Unknown"; - case KeepAliveTimeout: - return "Keep-alive timeout"; - default: - return std::string("Reserved error code " + std::to_string(_code)) - .c_str(); + switch(_code) { + case Unknown: + return "Unknown"; + case KeepAliveTimeout: + return "Keep-alive timeout"; + default: + return "Reserved"; } +} + +uint8_t Error::code() const noexcept +{ + return _code; } \ No newline at end of file diff --git a/src/logid/backend/dj/Error.h b/src/logid/backend/dj/Error.h index f462377..6c48f17 100644 --- a/src/logid/backend/dj/Error.h +++ b/src/logid/backend/dj/Error.h @@ -1,5 +1,5 @@ -#ifndef LOGID_HIDPP_BACKEND_DJ_ERROR_H -#define LOGID_HIDPP_BACKEND_DJ_ERROR_H +#ifndef LOGID_BACKEND_DJ_ERROR_H +#define LOGID_BACKEND_DJ_ERROR_H #include #include @@ -17,9 +17,9 @@ namespace dj KeepAliveTimeout = 0x01 }; - Error(uint8_t code); + explicit Error(uint8_t code); - virtual const char* what() const noexcept; + const char* what() const noexcept override; uint8_t code() const noexcept; private: @@ -27,4 +27,4 @@ namespace dj }; }}} -#endif //LOGID_HIDPP_BACKEND_DJ_ERROR_H +#endif //LOGID_BACKEND_DJ_ERROR_H \ No newline at end of file diff --git a/src/logid/backend/dj/Receiver.cpp b/src/logid/backend/dj/Receiver.cpp index 847fe53..14bb4dd 100644 --- a/src/logid/backend/dj/Receiver.cpp +++ b/src/logid/backend/dj/Receiver.cpp @@ -12,12 +12,11 @@ InvalidReceiver::InvalidReceiver(Reason reason) : _reason (reason) const char* InvalidReceiver::what() const noexcept { - switch(_reason) - { - case NoDJReports: - return "No DJ reports"; - default: - return "Invalid receiver"; + switch(_reason) { + case NoDJReports: + return "No DJ reports"; + default: + return "Invalid receiver"; } } @@ -27,10 +26,10 @@ InvalidReceiver::Reason InvalidReceiver::code() const noexcept } Receiver::Receiver(std::string path) : - raw_device (std::make_shared(path)), - _hidpp10_device (raw_device, hidpp::DefaultDevice) + _raw_device (std::make_shared(std::move(path))), + _hidpp10_device (_raw_device, hidpp::DefaultDevice) { - if(!supportsDjReports(raw_device->reportDescriptor())) + if(!supportsDjReports(_raw_device->reportDescriptor())) throw InvalidReceiver(InvalidReceiver::NoDJReports); } @@ -39,28 +38,28 @@ void Receiver::enumerateDj() sendDjRequest(hidpp::DefaultDevice, GetPairedDevices,{}); } -Receiver::notification_flags Receiver::getHidppNotifications() +Receiver::NotificationFlags Receiver::getHidppNotifications() { auto response = _hidpp10_device.getRegister(EnableHidppNotifications, {}, hidpp::ReportType::Short); - notification_flags flags{}; - flags.device_battery_status = response[0] & (1 << 4); - flags.receiver_wireless_notifications = response[1] & (1 << 0); - flags.receiver_software_present = response[1] & (1 << 3); + NotificationFlags flags{}; + flags.deviceBatteryStatus = response[0] & (1 << 4); + flags.receiverWirelessNotifications = response[1] & (1 << 0); + flags.receiverSoftwarePresent = response[1] & (1 << 3); return flags; } -void Receiver::enableHidppNotifications(notification_flags flags) +void Receiver::enableHidppNotifications(NotificationFlags flags) { std::vector request(3); - if(flags.device_battery_status) + if(flags.deviceBatteryStatus) request[0] |= (1 << 4); - if(flags.receiver_wireless_notifications) + if(flags.receiverWirelessNotifications) request[1] |= 1; - if(flags.receiver_software_present) + if(flags.receiverSoftwarePresent) request[1] |= (1 << 3); _hidpp10_device.setRegister(EnableHidppNotifications, request, @@ -228,14 +227,14 @@ hidpp::DeviceConnectionEvent Receiver::deviceConnectionEvent( void Receiver::handleDjEvent(Report& report) { - for(auto& handler : dj_event_handlers) + for(auto& handler : _dj_event_handlers) if(handler.second->condition(report)) handler.second->callback(report); } void Receiver::handleHidppEvent(hidpp::Report &report) { - for(auto& handler : hidpp_event_handlers) + for(auto& handler : _hidpp_event_handlers) if(handler.second->condition(report)) handler.second->callback(report); } @@ -243,39 +242,39 @@ void Receiver::handleHidppEvent(hidpp::Report &report) void Receiver::addDjEventHandler(const std::string& nickname, const std::shared_ptr& handler) { - auto it = dj_event_handlers.find(nickname); - assert(it == dj_event_handlers.end()); - dj_event_handlers.emplace(nickname, handler); + auto it = _dj_event_handlers.find(nickname); + assert(it == _dj_event_handlers.end()); + _dj_event_handlers.emplace(nickname, handler); } void Receiver::removeDjEventHandler(const std::string &nickname) { - dj_event_handlers.erase(nickname); + _dj_event_handlers.erase(nickname); } const std::map>& Receiver::djEventHandlers() { - return dj_event_handlers; + return _dj_event_handlers; } void Receiver::addHidppEventHandler(const std::string& nickname, const std::shared_ptr& handler) { - auto it = hidpp_event_handlers.find(nickname); - assert(it == hidpp_event_handlers.end()); - hidpp_event_handlers.emplace(nickname, handler); + auto it = _hidpp_event_handlers.find(nickname); + assert(it == _hidpp_event_handlers.end()); + _hidpp_event_handlers.emplace(nickname, handler); } void Receiver::removeHidppEventHandler(const std::string &nickname) { - hidpp_event_handlers.erase(nickname); + _hidpp_event_handlers.erase(nickname); } const std::map>& Receiver::hidppEventHandlers() { - return hidpp_event_handlers; + return _hidpp_event_handlers; } void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function, @@ -290,61 +289,61 @@ void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function, std::copy(params.begin(), params.end(), request.paramBegin()); - raw_device->sendReportNoResponse(request.rawData()); + _raw_device->sendReportNoResponse(request.rawData()); } void Receiver::listen() { - if(!raw_device->isListening()) - std::thread{[=]() { raw_device->listen(); }}.detach(); + if(!_raw_device->isListening()) + std::thread{[=]() { _raw_device->listen(); }}.detach(); - if(raw_device->eventHandlers().find("RECV_HIDPP") == - raw_device->eventHandlers().end()) { + if(_raw_device->eventHandlers().find("RECV_HIDPP") == + _raw_device->eventHandlers().end()) { // Pass all HID++ events on DefaultDevice to handleHidppEvent - std::shared_ptr hidppRawEventHandler = - std::make_shared(); - hidppRawEventHandler->condition = [](std::vector& report)->bool + std::shared_ptr hidpp_handler = + std::make_shared(); + hidpp_handler->condition = [](std::vector& report)->bool { return (report[hidpp::Offset::Type] == hidpp::Report::Type::Short || report[hidpp::Offset::Type] == hidpp::Report::Type::Long); }; - hidppRawEventHandler->callback = [this](std::vector& report)->void - { + hidpp_handler->callback = [this](std::vector& report) + ->void { hidpp::Report _report(report); this->handleHidppEvent(_report); }; - raw_device->addEventHandler("RECV_HIDPP", hidppRawEventHandler); + _raw_device->addEventHandler("RECV_HIDPP", hidpp_handler); } - if(raw_device->eventHandlers().find("RECV_DJ") == - raw_device->eventHandlers().end()) { - // Pass all DJ events with device index to handleHidppEvent - std::shared_ptr djRawEventHandler = - std::make_shared(); - djRawEventHandler->condition = [](std::vector& report)->bool + if(_raw_device->eventHandlers().find("RECV_DJ") == + _raw_device->eventHandlers().end()) { + // Pass all DJ events with device index to handleDjEvent + std::shared_ptr dj_handler = + std::make_shared(); + dj_handler->condition = [](std::vector& report)->bool { return (report[Offset::Type] == Report::Type::Short || report[Offset::Type] == Report::Type::Long); }; - djRawEventHandler->callback = [this](std::vector& report)->void + dj_handler->callback = [this](std::vector& report)->void { Report _report(report); this->handleDjEvent(_report); }; - raw_device->addEventHandler("RECV_DJ", djRawEventHandler); + _raw_device->addEventHandler("RECV_DJ", dj_handler); } } void Receiver::stopListening() { - raw_device->removeEventHandler("RECV_HIDPP"); - raw_device->removeEventHandler("RECV_DJ"); + _raw_device->removeEventHandler("RECV_HIDPP"); + _raw_device->removeEventHandler("RECV_DJ"); - if(raw_device->eventHandlers().empty()) - raw_device->stopListener(); + if(_raw_device->eventHandlers().empty()) + _raw_device->stopListener(); } std::shared_ptr Receiver::rawDevice() const { - return raw_device; + return _raw_device; } \ No newline at end of file diff --git a/src/logid/backend/dj/Receiver.h b/src/logid/backend/dj/Receiver.h index 0214e17..40c543e 100644 --- a/src/logid/backend/dj/Receiver.h +++ b/src/logid/backend/dj/Receiver.h @@ -25,7 +25,7 @@ namespace dj NoDJReports }; explicit InvalidReceiver(Reason reason); - virtual const char* what() const noexcept; + const char* what() const noexcept override; Reason code() const noexcept; private: Reason _reason; @@ -73,15 +73,15 @@ namespace dj PairingInfo = 0xb5 }; - struct notification_flags + struct NotificationFlags { - bool device_battery_status; - bool receiver_wireless_notifications; - bool receiver_software_present; + bool deviceBatteryStatus; + bool receiverWirelessNotifications; + bool receiverSoftwarePresent; }; - notification_flags getHidppNotifications(); - void enableHidppNotifications(notification_flags flags); + NotificationFlags getHidppNotifications(); + void enableHidppNotifications(NotificationFlags flags); void enumerateHidpp(); uint8_t getConnectionState(hidpp::DeviceIndex index); @@ -142,11 +142,11 @@ namespace dj void handleHidppEvent(hidpp::Report& report); std::map> - dj_event_handlers; + _dj_event_handlers; std::map> - hidpp_event_handlers; + _hidpp_event_handlers; - std::shared_ptr raw_device; + std::shared_ptr _raw_device; hidpp10::Device _hidpp10_device; }; } diff --git a/src/logid/backend/dj/ReceiverMonitor.cpp b/src/logid/backend/dj/ReceiverMonitor.cpp index bdc8366..8d66397 100644 --- a/src/logid/backend/dj/ReceiverMonitor.cpp +++ b/src/logid/backend/dj/ReceiverMonitor.cpp @@ -13,7 +13,7 @@ ReceiverMonitor::ReceiverMonitor(std::string path) : _receiver ( assert(_receiver->djEventHandlers().find("RECVMON") == _receiver->djEventHandlers().end()); - Receiver::notification_flags notification_flags{ + Receiver::NotificationFlags notification_flags{ true, true, true}; @@ -25,16 +25,15 @@ void ReceiverMonitor::run() _receiver->listen(); if(_receiver->hidppEventHandlers().find("RECVMON") == - _receiver->hidppEventHandlers().end()) - { - std::shared_ptr eventHandler = + _receiver->hidppEventHandlers().end()) { + std::shared_ptr event_handler = std::make_shared(); - eventHandler->condition = [](hidpp::Report &report) -> bool { + event_handler->condition = [](hidpp::Report &report) -> bool { return (report.subId() == Receiver::DeviceConnection || report.subId() == Receiver::DeviceDisconnection); }; - eventHandler->callback = [this](hidpp::Report &report) -> void { + event_handler->callback = [this](hidpp::Report &report) -> void { /* Running in a new thread prevents deadlocks since the * receiver may be enumerating. */ @@ -48,7 +47,7 @@ void ReceiverMonitor::run() }, report}.detach(); }; - _receiver->addHidppEventHandler("RECVMON", eventHandler); + _receiver->addHidppEventHandler("RECVMON", event_handler); } enumerate(); diff --git a/src/logid/backend/dj/Report.cpp b/src/logid/backend/dj/Report.cpp index 0dff2fd..5f7d596 100644 --- a/src/logid/backend/dj/Report.cpp +++ b/src/logid/backend/dj/Report.cpp @@ -28,37 +28,36 @@ static const std::array DJReportDesc = { bool dj::supportsDjReports(std::vector&& rdesc) { - auto it = std::search(rdesc.begin(), rdesc.end(), DJReportDesc.begin(), DJReportDesc.end()); + auto it = std::search(rdesc.begin(), rdesc.end(), + DJReportDesc.begin(), DJReportDesc.end()); return it != rdesc.end(); } Report::Report(std::vector& data) : _data (data) { - switch(data[Offset::Type]) - { - case ReportType::Short: - _data.resize(HeaderLength+ShortParamLength); - break; - case ReportType::Long: - _data.resize(HeaderLength+LongParamLength); - break; - default: - assert(false); + switch(data[Offset::Type]) { + case ReportType::Short: + _data.resize(HeaderLength+ShortParamLength); + break; + case ReportType::Long: + _data.resize(HeaderLength+LongParamLength); + break; + default: + assert(false); } } Report::Report(Report::Type type, hidpp::DeviceIndex index, uint8_t feature) { - switch(type) - { - case ReportType::Short: - _data.resize(HeaderLength+ShortParamLength); - break; - case ReportType::Long: - _data.resize(HeaderLength+LongParamLength); - break; - default: - assert(false); + switch(type) { + case ReportType::Short: + _data.resize(HeaderLength+ShortParamLength); + break; + case ReportType::Long: + _data.resize(HeaderLength+LongParamLength); + break; + default: + assert(false); } _data[Offset::Type] = type; diff --git a/src/logid/backend/dj/Report.h b/src/logid/backend/dj/Report.h index 6f01bb7..36482fc 100644 --- a/src/logid/backend/dj/Report.h +++ b/src/logid/backend/dj/Report.h @@ -6,7 +6,9 @@ #include "defs.h" #include "../hidpp/defs.h" -namespace logid::backend::dj +namespace logid { +namespace backend { +namespace dj { namespace Offset { @@ -33,6 +35,6 @@ namespace logid::backend::dj private: std::vector _data; }; -} +}}} #endif //LOGID_BACKEND_DJ_REPORT_H diff --git a/src/logid/backend/hidpp/Device.cpp b/src/logid/backend/hidpp/Device.cpp index ea2d196..4c0d4cc 100644 --- a/src/logid/backend/hidpp/Device.cpp +++ b/src/logid/backend/hidpp/Device.cpp @@ -13,16 +13,15 @@ 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"; - case Asleep: - return "Device asleep"; - default: - return "Invalid device"; + switch(_reason) { + case NoHIDPPReport: + return "Invalid HID++ device"; + case InvalidRawDevice: + return "Invalid raw device"; + case Asleep: + return "Device asleep"; + default: + return "Invalid device"; } } @@ -58,10 +57,25 @@ Device::Device(std::shared_ptr receiver, _init(); } +std::string Device::devicePath() const +{ + return _path; +} + +DeviceIndex Device::deviceIndex() const +{ + return _index; +} + +std::tuple Device::version() const +{ + return _version; +} + void Device::_init() { - supported_reports = getSupportedReports(_raw_device->reportDescriptor()); - if(!supported_reports) + _supported_reports = getSupportedReports(_raw_device->reportDescriptor()); + if(!_supported_reports) throw InvalidDevice(InvalidDevice::NoHIDPPReport); try { @@ -101,20 +115,20 @@ Device::~Device() void Device::addEventHandler(const std::string& nickname, const std::shared_ptr& handler) { - auto it = event_handlers.find(nickname); - assert(it == event_handlers.end()); + auto it = _event_handlers.find(nickname); + assert(it == _event_handlers.end()); - event_handlers.emplace(nickname, handler); + _event_handlers.emplace(nickname, handler); } void Device::removeEventHandler(const std::string& nickname) { - event_handlers.erase(nickname); + _event_handlers.erase(nickname); } void Device::handleEvent(Report& report) { - for(auto& handler : event_handlers) + for(auto& handler : _event_handlers) if(handler.second->condition(report)) handler.second->callback(report); } @@ -123,26 +137,26 @@ Report Device::sendReport(Report& report) { switch(report.type()) { - case Report::Type::Short: - if(!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED)) - report.setType(Report::Type::Long); - break; - case Report::Type::Long: - /* Report can be truncated, but that isn't a good idea. */ - assert(supported_reports & HIDPP_REPORT_LONG_SUPPORTED); + case Report::Type::Short: + if(!(_supported_reports & HIDPP_REPORT_SHORT_SUPPORTED)) + report.setType(Report::Type::Long); + break; + case Report::Type::Long: + /* Report can be truncated, but that isn't a good idea. */ + assert(_supported_reports & HIDPP_REPORT_LONG_SUPPORTED); } auto raw_response = _raw_device->sendReport(report.rawReport()); Report response(raw_response); - Report::hidpp10_error hidpp10Error{}; - if(response.isError10(&hidpp10Error)) - throw hidpp10::Error(hidpp10Error.error_code); + Report::Hidpp10Error hidpp10_error{}; + if(response.isError10(&hidpp10_error)) + throw hidpp10::Error(hidpp10_error.error_code); - Report::hidpp20_error hidpp20Error{}; - if(response.isError20(&hidpp20Error)) - throw hidpp10::Error(hidpp20Error.error_code); + Report::Hidpp20Error hidpp20_error{}; + if(response.isError20(&hidpp20_error)) + throw hidpp10::Error(hidpp20_error.error_code); return response; } @@ -153,20 +167,20 @@ void Device::listen() std::thread{[=]() { _raw_device->listen(); }}.detach(); // Pass all HID++ events with device index to this device. - std::shared_ptr rawEventHandler; - rawEventHandler->condition = [this](std::vector& report)->bool + std::shared_ptr handler; + handler->condition = [this](std::vector& report)->bool { return (report[Offset::Type] == Report::Type::Short || report[Offset::Type] == Report::Type::Long) && (report[Offset::DeviceIndex] == this->_index); }; - rawEventHandler->callback = [this](std::vector& report)->void + handler->callback = [this](std::vector& report)->void { Report _report(report); this->handleEvent(_report); }; - _raw_device->addEventHandler("DEV_" + std::to_string(_index), rawEventHandler); + _raw_device->addEventHandler("DEV_" + std::to_string(_index), handler); } void Device::stopListening() diff --git a/src/logid/backend/hidpp/Device.h b/src/logid/backend/hidpp/Device.h index 460e65b..1372cfc 100644 --- a/src/logid/backend/hidpp/Device.h +++ b/src/logid/backend/hidpp/Device.h @@ -1,5 +1,5 @@ -#ifndef LOGID_HIDPP_DEVICE_H -#define LOGID_HIDPP_DEVICE_H +#ifndef LOGID_BACKEND_HIDPP_DEVICE_H +#define LOGID_BACKEND_HIDPP_DEVICE_H #include #include @@ -44,14 +44,15 @@ namespace hidpp }; explicit Device(const std::string& path, DeviceIndex index); - explicit Device(std::shared_ptr raw_device, DeviceIndex index); + explicit Device(std::shared_ptr raw_device, + DeviceIndex index); explicit Device(std::shared_ptr receiver, hidpp::DeviceConnectionEvent event); ~Device(); - std::string devicePath() const { return _path; } - DeviceIndex deviceIndex() const { return _index; } - std::tuple version() const { return _version; } + std::string devicePath() const; + DeviceIndex deviceIndex() const; + std::tuple version() const; void listen(); // Runs asynchronously void stopListening(); @@ -70,14 +71,14 @@ namespace hidpp std::shared_ptr _receiver; std::string _path; DeviceIndex _index; - uint8_t supported_reports; + uint8_t _supported_reports; std::tuple _version; uint16_t _pid; std::string _name; - std::map> event_handlers; + std::map> _event_handlers; }; } } } -#endif //LOGID_HIDPP_DEVICE_H \ No newline at end of file +#endif //LOGID_BACKEND_HIDPP_DEVICE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp/Error.cpp b/src/logid/backend/hidpp/Error.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/logid/backend/hidpp/Error.h b/src/logid/backend/hidpp/Error.h deleted file mode 100644 index e69de29..0000000 diff --git a/src/logid/backend/hidpp/Report.cpp b/src/logid/backend/hidpp/Report.cpp index b928bc4..a8c0429 100644 --- a/src/logid/backend/hidpp/Report.cpp +++ b/src/logid/backend/hidpp/Report.cpp @@ -70,15 +70,19 @@ uint8_t hidpp::getSupportedReports(std::vector&& rdesc) { uint8_t ret = 0; - auto it = std::search(rdesc.begin(), rdesc.end(), ShortReportDesc.begin(), ShortReportDesc.end()); + 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()); + 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(), LongReportDesc.end()); + it = std::search(rdesc.begin(), rdesc.end(), + LongReportDesc.begin(), LongReportDesc.end()); if(it == rdesc.end()) - it = std::search(rdesc.begin(), rdesc.end(), LongReportDesc2.begin(), LongReportDesc2.end()); + it = std::search(rdesc.begin(), rdesc.end(), + LongReportDesc2.begin(), LongReportDesc2.end()); if(it != rdesc.end()) ret |= HIDPP_REPORT_LONG_SUPPORTED; @@ -98,16 +102,15 @@ const char *Report::InvalidReportLength::what() const noexcept Report::Report(Report::Type type, DeviceIndex device_index, uint8_t sub_id, uint8_t address) { - switch(type) - { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch(type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; @@ -119,25 +122,25 @@ 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) { - assert(function <= functionMask); - assert(sw_id <= swIdMask); + assert(function <= 0x0f); + assert(sw_id <= 0x0f); - switch(type) - { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch(type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; _data[Offset::DeviceIndex] = device_index; _data[Offset::Feature] = feature_index; - _data[Offset::Function] = (function & functionMask) << 4 | (sw_id & swIdMask); + _data[Offset::Function] = (function & 0x0f) << 4 | + (sw_id & 0x0f); } Report::Report(const std::vector& data) @@ -145,16 +148,15 @@ Report::Report(const std::vector& data) _data = data; // Truncating data is entirely valid here. - switch(_data[Offset::Type]) - { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch(_data[Offset::Type]) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } } @@ -165,16 +167,15 @@ Report::Type Report::type() const void Report::setType(Report::Type type) { - switch(type) - { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch(type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; @@ -218,7 +219,7 @@ uint8_t Report::function() const void Report::setFunction(uint8_t function) { _data[Offset::Function] &= 0x0f; - _data[Offset::Function] |= (function << 4) & 0x0f; + _data[Offset::Function] |= (function & 0x0f) << 4; } uint8_t Report::swId() const @@ -250,7 +251,7 @@ void Report::setParams(const std::vector& _params) _data[Offset::Parameters + i] = _params[i]; } -bool Report::isError10(Report::hidpp10_error *error) +bool Report::isError10(Report::Hidpp10Error *error) { assert(error != nullptr); @@ -265,8 +266,10 @@ bool Report::isError10(Report::hidpp10_error *error) return true; } -bool Report::isError20(Report::hidpp20_error* error) +bool Report::isError20(Report::Hidpp20Error* error) { + assert(error != nullptr); + if(_data[Offset::Type] != Type::Long || _data[Offset::Feature] != hidpp20::ErrorID) return false; diff --git a/src/logid/backend/hidpp/Report.h b/src/logid/backend/hidpp/Report.h index c3ab1d6..c3b6ecd 100644 --- a/src/logid/backend/hidpp/Report.h +++ b/src/logid/backend/hidpp/Report.h @@ -10,7 +10,9 @@ #define HIDPP_REPORT_LONG_SUPPORTED 1U<<1U /* Very long reports exist, however they have not been encountered so far */ -namespace logid::backend::hidpp +namespace logid { +namespace backend { +namespace hidpp { uint8_t getSupportedReports(std::vector&& rdesc); @@ -34,19 +36,17 @@ namespace logid::backend::hidpp { public: InvalidReportID() = default; - virtual const char* what() const noexcept; + const char* what() const noexcept override; }; class InvalidReportLength: public std::exception { public: InvalidReportLength() = default;; - virtual const char* what() const noexcept; + const char* what() const noexcept override; }; static constexpr std::size_t MaxDataLength = 20; - static constexpr uint8_t swIdMask = 0x0f; - static constexpr uint8_t functionMask = 0x0f; Report(Report::Type type, DeviceIndex device_index, uint8_t sub_id, @@ -85,19 +85,17 @@ namespace logid::backend::hidpp std::vector::iterator paramEnd() { return _data.end(); } void setParams(const std::vector& _params); - struct hidpp10_error + struct Hidpp10Error { uint8_t sub_id, address, error_code; }; + bool isError10(Hidpp10Error* error); - bool isError10(hidpp10_error* error); - - struct hidpp20_error + struct Hidpp20Error { uint8_t feature_index, function, software_id, error_code; }; - - bool isError20(hidpp20_error* error); + bool isError20(Hidpp20Error* error); std::vector rawReport () const { return _data; } @@ -105,6 +103,6 @@ namespace logid::backend::hidpp private: std::vector _data; }; -} +}}} #endif //LOGID_BACKEND_HIDPP_REPORT_H \ No newline at end of file diff --git a/src/logid/backend/hidpp/defs.h b/src/logid/backend/hidpp/defs.h index 295af39..d08886d 100644 --- a/src/logid/backend/hidpp/defs.h +++ b/src/logid/backend/hidpp/defs.h @@ -3,7 +3,9 @@ #define LOGID_HIDPP_SOFTWARE_ID 0 -namespace logid::backend::hidpp +namespace logid { +namespace backend { +namespace hidpp { namespace ReportType { @@ -28,6 +30,6 @@ namespace logid::backend::hidpp static constexpr std::size_t ShortParamLength = 3; static constexpr std::size_t LongParamLength = 16; -} +} } } #endif //LOGID_HIDPP_DEFS_H \ No newline at end of file diff --git a/src/logid/backend/hidpp10/Device.cpp b/src/logid/backend/hidpp10/Device.cpp index e1f2d15..12531ee 100644 --- a/src/logid/backend/hidpp10/Device.cpp +++ b/src/logid/backend/hidpp10/Device.cpp @@ -41,10 +41,11 @@ std::vector Device::setRegister(uint8_t address, return accessRegister(sub_id, address, params); } -std::vector Device::accessRegister(uint8_t sub_id, uint8_t address, const std::vector ¶ms) +std::vector Device::accessRegister(uint8_t sub_id, uint8_t address, + const std::vector ¶ms) { hidpp::Report::Type type = params.size() <= hidpp::ShortParamLength ? - hidpp::Report::Type::Short : hidpp::Report::Type::Long; + hidpp::Report::Type::Short : hidpp::Report::Type::Long; hidpp::Report request(type, deviceIndex(), sub_id, address); std::copy(params.begin(), params.end(), request.paramBegin()); diff --git a/src/logid/backend/hidpp10/Error.cpp b/src/logid/backend/hidpp10/Error.cpp index 30f6b3f..2206173 100644 --- a/src/logid/backend/hidpp10/Error.cpp +++ b/src/logid/backend/hidpp10/Error.cpp @@ -11,36 +11,35 @@ Error::Error(uint8_t code): _code(code) 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(); + 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 "Unknown error code"; } } diff --git a/src/logid/backend/hidpp10/Error.h b/src/logid/backend/hidpp10/Error.h index 71488b0..7021839 100644 --- a/src/logid/backend/hidpp10/Error.h +++ b/src/logid/backend/hidpp10/Error.h @@ -28,9 +28,9 @@ namespace hidpp10 { WrongPINCode = 0x0C }; - Error(uint8_t code); + explicit Error(uint8_t code); - virtual const char* what() const noexcept; + const char* what() const noexcept override; uint8_t code() const noexcept; private: diff --git a/src/logid/backend/hidpp20/Error.cpp b/src/logid/backend/hidpp20/Error.cpp index 33fdfe1..7941c9e 100644 --- a/src/logid/backend/hidpp20/Error.cpp +++ b/src/logid/backend/hidpp20/Error.cpp @@ -11,32 +11,31 @@ Error::Error(uint8_t code) : _code (code) 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(); + 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 "Unknown error code"; } } diff --git a/src/logid/backend/hidpp20/Error.h b/src/logid/backend/hidpp20/Error.h index 53fec65..533c4be 100644 --- a/src/logid/backend/hidpp20/Error.h +++ b/src/logid/backend/hidpp20/Error.h @@ -26,9 +26,9 @@ namespace hidpp20 { UnknownDevice = 10 }; - Error(uint8_t code); + explicit Error(uint8_t code); - virtual const char* what() const noexcept; + const char* what() const noexcept override; uint8_t code() const noexcept; private: diff --git a/src/logid/backend/hidpp20/Feature.h b/src/logid/backend/hidpp20/Feature.h index 8a96602..6dba742 100644 --- a/src/logid/backend/hidpp20/Feature.h +++ b/src/logid/backend/hidpp20/Feature.h @@ -11,7 +11,7 @@ namespace hidpp20 { { public: explicit UnsupportedFeature(uint16_t ID) : _f_id (ID) {} - virtual const char* what() const noexcept; + const char* what() const noexcept override; uint16_t code() const noexcept; private: uint16_t _f_id; diff --git a/src/logid/backend/hidpp20/features/DeviceName.h b/src/logid/backend/hidpp20/features/DeviceName.h index 39b7cca..deb6d03 100644 --- a/src/logid/backend/hidpp20/features/DeviceName.h +++ b/src/logid/backend/hidpp20/features/DeviceName.h @@ -21,7 +21,7 @@ namespace hidpp20 GetDeviceName = 1 }; - DeviceName(Device* device); + explicit DeviceName(Device* device); uint8_t getNameLength(); std::string getName(); @@ -33,7 +33,7 @@ namespace hidpp20 static const uint16_t ID = FeatureID::DEVICE_NAME; virtual uint16_t getID() { return ID; } - EssentialDeviceName(hidpp::Device* device); + explicit EssentialDeviceName(hidpp::Device* device); uint8_t getNameLength(); std::string getName(); diff --git a/src/logid/backend/hidpp20/features/Root.cpp b/src/logid/backend/hidpp20/features/Root.cpp index b5a6203..d7462ad 100644 --- a/src/logid/backend/hidpp20/features/Root.cpp +++ b/src/logid/backend/hidpp20/features/Root.cpp @@ -14,7 +14,8 @@ std::vector _genGetFeatureParams(uint16_t feature_id) return params; } -feature_info _genGetFeatureInfo(uint16_t feature_id, std::vector response) +feature_info _genGetFeatureInfo(uint16_t feature_id, + std::vector response) { feature_info info{}; info.feature_id = response[0]; diff --git a/src/logid/backend/hidpp20/features/Root.h b/src/logid/backend/hidpp20/features/Root.h index 9882aa0..295e5bf 100644 --- a/src/logid/backend/hidpp20/features/Root.h +++ b/src/logid/backend/hidpp20/features/Root.h @@ -21,7 +21,7 @@ namespace hidpp20 Ping = 1 }; - Root(Device* device); + explicit Root(Device* device); feature_info getFeature (uint16_t feature_id); std::tuple getVersion(); @@ -40,9 +40,9 @@ namespace hidpp20 static const uint16_t ID = FeatureID::ROOT; virtual uint16_t getID() { return ID; } - EssentialRoot(hidpp::Device* device); + explicit EssentialRoot(hidpp::Device* device); - feature_info getFeature (uint16_t feature_id); + feature_info getFeature(uint16_t feature_id); std::tuple getVersion(); }; }}} diff --git a/src/logid/backend/raw/DeviceMonitor.cpp b/src/logid/backend/raw/DeviceMonitor.cpp index 69eac98..77aa293 100644 --- a/src/logid/backend/raw/DeviceMonitor.cpp +++ b/src/logid/backend/raw/DeviceMonitor.cpp @@ -13,40 +13,39 @@ using namespace logid::backend::raw; DeviceMonitor::DeviceMonitor() { - if(-1 == pipe(monitor_pipe)) - throw std::system_error(errno, std::system_category(), "pipe creation failed"); + if(-1 == pipe(_pipe)) + throw std::system_error(errno, std::system_category(), + "pipe creation failed"); - udev_context = udev_new(); - if(!udev_context) + _udev_context = udev_new(); + if(!_udev_context) throw std::runtime_error("udev_new failed"); } DeviceMonitor::~DeviceMonitor() { - bool is_running = running.try_lock(); - if(is_running) - running.unlock(); - else - this->stop(); + this->stop(); - udev_unref(udev_context); + udev_unref(_udev_context); - for(int i : monitor_pipe) + for(int i : _pipe) close(i); } void DeviceMonitor::run() { int ret; - const std::lock_guard run_lock(running); + std::lock_guard lock(_running); - struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev_context, "udev"); + struct udev_monitor* monitor = udev_monitor_new_from_netlink(_udev_context, + "udev"); if(!monitor) throw std::runtime_error("udev_monitor_new_from_netlink failed"); - ret = udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", nullptr); + ret = udev_monitor_filter_add_match_subsystem_devtype(monitor, "hidraw", + nullptr); if (0 != ret) - throw std::system_error (-ret, std::system_category (), + throw std::system_error (-ret, std::system_category(), "udev_monitor_filter_add_match_subsystem_devtype"); ret = udev_monitor_enable_receiving(monitor); @@ -57,20 +56,27 @@ void DeviceMonitor::run() this->enumerate(); int fd = udev_monitor_get_fd(monitor); - while (true) { + + _run_monitor = true; + while (_run_monitor) { fd_set fds; FD_ZERO(&fds); - FD_SET(monitor_pipe[0], &fds); + FD_SET(_pipe[0], &fds); FD_SET(fd, &fds); - if (-1 == select (std::max (monitor_pipe[0], fd)+1, &fds, nullptr, nullptr, nullptr)) { + + if (-1 == select (std::max (_pipe[0], fd)+1, &fds, nullptr, + nullptr, nullptr)) { if (errno == EINTR) continue; - throw std::system_error (errno, std::system_category(), "udev_monitor select"); + throw std::system_error (errno, std::system_category(), + "udev_monitor select"); } + if (FD_ISSET(fd, &fds)) { struct udev_device *device = udev_monitor_receive_device(monitor); std::string action = udev_device_get_action(device); std::string devnode = udev_device_get_devnode(device); + if (action == "add") std::thread([this](const std::string name) { this->addDevice(name); @@ -79,12 +85,13 @@ void DeviceMonitor::run() std::thread([this](const std::string name) { this->removeDevice(name); }, devnode).detach(); + udev_device_unref (device); } - if (FD_ISSET(monitor_pipe[0], &fds)) { + if (FD_ISSET(_pipe[0], &fds)) { char c; - if (-1 == read(monitor_pipe[0], &c, sizeof (char))) - throw std::system_error (errno, std::system_category (), + if (-1 == read(_pipe[0], &c, sizeof (char))) + throw std::system_error (errno, std::system_category(), "read pipe"); break; } @@ -93,13 +100,14 @@ void DeviceMonitor::run() void DeviceMonitor::stop() { - + _run_monitor = false; + std::lock_guard lock(_running); } void DeviceMonitor::enumerate() { int ret; - struct udev_enumerate* udev_enum = udev_enumerate_new(udev_context); + struct udev_enumerate* udev_enum = udev_enumerate_new(_udev_context); ret = udev_enumerate_add_match_subsystem(udev_enum, "hidraw"); if(0 != ret) throw std::system_error(-ret, std::system_category(), @@ -112,11 +120,10 @@ void DeviceMonitor::enumerate() struct udev_list_entry* udev_enum_entry; udev_list_entry_foreach(udev_enum_entry, - udev_enumerate_get_list_entry(udev_enum)) - { + udev_enumerate_get_list_entry(udev_enum)) { const char* name = udev_list_entry_get_name(udev_enum_entry); - struct udev_device* device = udev_device_new_from_syspath(udev_context, + struct udev_device* device = udev_device_new_from_syspath(_udev_context, name); if(!device) throw std::runtime_error("udev_device_new_from_syspath failed"); diff --git a/src/logid/backend/raw/DeviceMonitor.h b/src/logid/backend/raw/DeviceMonitor.h index af2a0c6..b24ad19 100644 --- a/src/logid/backend/raw/DeviceMonitor.h +++ b/src/logid/backend/raw/DeviceMonitor.h @@ -3,13 +3,16 @@ #include #include +#include extern "C" { #include } -namespace logid::backend::raw +namespace logid { +namespace backend { +namespace raw { class DeviceMonitor { @@ -23,10 +26,11 @@ namespace logid::backend::raw virtual void addDevice(std::string device) = 0; virtual void removeDevice(std::string device) = 0; private: - struct udev* udev_context; - int monitor_pipe[2]; - std::mutex running; + struct udev* _udev_context; + int _pipe[2]; + std::atomic _run_monitor; + std::mutex _running; }; -} +}}} #endif //LOGID_BACKEND_RAW_DEVICEMONITOR_H \ No newline at end of file diff --git a/src/logid/backend/raw/RawDevice.cpp b/src/logid/backend/raw/RawDevice.cpp index 917745e..bae0742 100644 --- a/src/logid/backend/raw/RawDevice.cpp +++ b/src/logid/backend/raw/RawDevice.cpp @@ -7,12 +7,13 @@ #include #include -#include +#include #define MAX_DATA_LENGTH 32 extern "C" { +#include #include #include #include @@ -25,105 +26,116 @@ using namespace std::chrono; bool RawDevice::supportedReport(uint8_t id, uint8_t length) { - switch(id) - { - case hidpp::ReportType::Short: - return length == (hidpp::ShortParamLength + - hidpp::Report::HeaderLength); - case hidpp::ReportType::Long: - return length == (hidpp::LongParamLength + - hidpp::Report::HeaderLength); - case dj::ReportType::Short: - return length == (dj::ShortParamLength + dj::HeaderLength); - case dj::ReportType::Long: - return length == (dj::LongParamLength + dj::HeaderLength); - default: - return false; + switch(id) { + case hidpp::ReportType::Short: + return length == (hidpp::ShortParamLength + + hidpp::Report::HeaderLength); + case hidpp::ReportType::Long: + return length == (hidpp::LongParamLength + + hidpp::Report::HeaderLength); + case dj::ReportType::Short: + return length == (dj::ShortParamLength + dj::HeaderLength); + case dj::ReportType::Long: + return length == (dj::LongParamLength + dj::HeaderLength); + default: + return false; } - - 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) +RawDevice::RawDevice(std::string path) : _path (std::move(path)), + _continue_listen (false) { int ret; - fd = ::open(path.c_str(), O_RDWR); - if (fd == -1) + _fd = ::open(_path.c_str(), O_RDWR); + if (_fd == -1) throw std::system_error(errno, std::system_category(), "RawDevice open failed"); hidraw_devinfo devinfo{}; - if (-1 == ::ioctl(fd, HIDIOCGRAWINFO, &devinfo)) - { + if (-1 == ::ioctl(_fd, HIDIOCGRAWINFO, &devinfo)) { int err = errno; - ::close(fd); + ::close(_fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRAWINFO failed"); } - vid = devinfo.vendor; - pid = devinfo.product; + _vid = devinfo.vendor; + _pid = devinfo.product; char name_buf[256]; - if (-1 == (ret = ::ioctl(fd, HIDIOCGRAWNAME(sizeof(name_buf)), name_buf))) - { + if (-1 == (ret = ::ioctl(_fd, HIDIOCGRAWNAME(sizeof(name_buf)), name_buf) + )) { int err = errno; - ::close(fd); + ::close(_fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRAWNAME failed"); } _name.assign(name_buf, ret - 1); hidraw_report_descriptor _rdesc{}; - if (-1 == ::ioctl(fd, HIDIOCGRDESCSIZE, &_rdesc.size)) - { + if (-1 == ::ioctl(_fd, HIDIOCGRDESCSIZE, &_rdesc.size)) { int err = errno; - ::close(fd); + ::close(_fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRDESCSIZE failed"); } - if (-1 == ::ioctl(fd, HIDIOCGRDESC, &_rdesc)) - { + if (-1 == ::ioctl(_fd, HIDIOCGRDESC, &_rdesc)) { int err = errno; - ::close(fd); + ::close(_fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRDESC failed"); } rdesc = std::vector(_rdesc.value, _rdesc.value + _rdesc.size); - if (-1 == ::pipe(dev_pipe)) - { + if (-1 == ::pipe(_pipe)) { int err = errno; - close(fd); + close(_fd); throw std::system_error(err, std::system_category(), "RawDevice pipe open failed"); } - continue_listen = false; + _continue_listen = false; } RawDevice::~RawDevice() { - if(fd != -1) + if(_fd != -1) { - ::close(fd); - ::close(dev_pipe[0]); - ::close(dev_pipe[1]); + ::close(_fd); + ::close(_pipe[0]); + ::close(_pipe[1]); } } +std::string RawDevice::hidrawPath() const +{ + return _path; +} + +std::string RawDevice::name() const +{ + return _name; +} + +uint16_t RawDevice::vendorId() const +{ + return _vid; +} + +uint16_t RawDevice::productId() const +{ + return _pid; +} std::vector RawDevice::sendReport(const std::vector& report) { /* If the listener will stop, handle I/O manually. * Otherwise, push to queue and wait for result. */ - if(continue_listen) - { + if(_continue_listen) { std::packaged_task()> task( [this, report]() { return this->_respondToReport(report); }); auto f = task.get_future(); - write_queue.push(&task); + _io_queue.push(&task); return f.get(); } else @@ -135,14 +147,13 @@ void RawDevice::sendReportNoResponse(const std::vector& report) { /* If the listener will stop, handle I/O manually. * Otherwise, push to queue and wait for result. */ - if(continue_listen) - { + if(_continue_listen) { std::packaged_task()> task([this, report]() { this->_sendReport(report); return std::vector(); }); auto f = task.get_future(); - write_queue.push(&task); + _io_queue.push(&task); f.get(); } else @@ -153,27 +164,23 @@ std::vector RawDevice::_respondToReport (const std::vector& request) { _sendReport(request); - while(true) - { + while(true) { std::vector response; _readReport(response, MAX_DATA_LENGTH); // All reports have the device index at byte 2 - if(response[1] != request[1]) - { - if(continue_listen) - this->handleEvent(response); + if(response[1] != request[1]) { + if(_continue_listen) + this->_handleEvent(response); continue; } if(hidpp::ReportType::Short == request[0] || - hidpp::ReportType::Long == request[0]) - { + hidpp::ReportType::Long == request[0]) { if(hidpp::ReportType::Short != response[0] && - hidpp::ReportType::Long != response[0]) - { - if(continue_listen) - this->handleEvent(response); + hidpp::ReportType::Long != response[0]) { + if(_continue_listen) + this->_handleEvent(response); continue; } @@ -183,17 +190,13 @@ std::vector RawDevice::_respondToReport 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]) - { + } else if(dj::ReportType::Short == request[0] || + dj::ReportType::Long == request[0]) { //Error; leave to device ot handle if(0x7f == response[2]) return response; @@ -201,16 +204,16 @@ std::vector RawDevice::_respondToReport return response; } - if(continue_listen) - this->handleEvent(response); + if(_continue_listen) + this->_handleEvent(response); } } int RawDevice::_sendReport(const std::vector& report) { - std::lock_guard lock(dev_io); + std::lock_guard lock(_dev_io); if(logid::global_verbosity == LogLevel::RAWREPORT) { - printf("[RAWREPORT] %s OUT: ", path.c_str()); + printf("[RAWREPORT] %s OUT: ", _path.c_str()); for(auto &i : report) printf("%02x ", i); printf("\n"); @@ -218,11 +221,11 @@ int RawDevice::_sendReport(const std::vector& report) assert(supportedReport(report[0], report.size())); - int ret = ::write(fd, report.data(), report.size()); + int ret = ::write(_fd, report.data(), report.size()); if(ret == -1) { ///TODO: This seems like a hacky solution // Try again before failing - ret = ::write(fd, report.data(), report.size()); + ret = ::write(_fd, report.data(), report.size()); if(ret == -1) throw std::system_error(errno, std::system_category(), "_sendReport write failed"); @@ -233,7 +236,7 @@ int RawDevice::_sendReport(const std::vector& report) int RawDevice::_readReport(std::vector& report, std::size_t maxDataLength) { - std::lock_guard lock(dev_io); + std::lock_guard lock(_dev_io); int ret; report.resize(maxDataLength); @@ -243,10 +246,10 @@ int RawDevice::_readReport(std::vector& report, std::size_t maxDataLeng fd_set fds; do { FD_ZERO(&fds); - FD_SET(fd, &fds); - FD_SET(dev_pipe[0], &fds); + FD_SET(_fd, &fds); + FD_SET(_pipe[0], &fds); - ret = select(std::max(fd, dev_pipe[0]) + 1, + ret = select(std::max(_fd, _pipe[0]) + 1, &fds, nullptr, nullptr, (HIDPP_IO_TIMEOUT.count() > 0 ? nullptr : &timeout)); } while(ret == -1 && errno == EINTR); @@ -255,19 +258,17 @@ int RawDevice::_readReport(std::vector& report, std::size_t maxDataLeng throw std::system_error(errno, std::system_category(), "_readReport select failed"); - if(FD_ISSET(fd, &fds)) - { - ret = read(fd, report.data(), report.size()); + if(FD_ISSET(_fd, &fds)) { + ret = read(_fd, report.data(), report.size()); if(ret == -1) throw std::system_error(errno, std::system_category(), "_readReport read failed"); report.resize(ret); } - if(FD_ISSET(dev_pipe[0], &fds)) - { + if(FD_ISSET(_pipe[0], &fds)) { char c; - ret = read(dev_pipe[0], &c, sizeof(char)); + ret = read(_pipe[0], &c, sizeof(char)); if(ret == -1) throw std::system_error(errno, std::system_category(), "_readReport read pipe failed"); @@ -277,7 +278,7 @@ int RawDevice::_readReport(std::vector& report, std::size_t maxDataLeng throw backend::TimeoutError(); if(logid::global_verbosity == LogLevel::RAWREPORT) { - printf("[RAWREPORT] %s IN: ", path.c_str()); + printf("[RAWREPORT] %s IN: ", _path.c_str()); for(auto &i : report) printf("%02x ", i); printf("\n"); @@ -289,82 +290,79 @@ int RawDevice::_readReport(std::vector& report, std::size_t maxDataLeng void RawDevice::interruptRead() { char c = 0; - if(-1 == write(dev_pipe[1], &c, sizeof(char))) + if(-1 == write(_pipe[1], &c, sizeof(char))) throw std::system_error(errno, std::system_category(), "interruptRead write pipe failed"); // Ensure I/O has halted - std::lock_guard lock(dev_io); + std::lock_guard lock(_dev_io); } void RawDevice::listen() { - std::lock_guard lock(listening); + std::lock_guard lock(_listening); - continue_listen = true; - while(continue_listen) - { - while(!write_queue.empty()) - { - auto task = write_queue.front(); + _continue_listen = true; + while(_continue_listen) { + while(!_io_queue.empty()) { + auto task = _io_queue.front(); (*task)(); - write_queue.pop(); + _io_queue.pop(); } std::vector report; _readReport(report, MAX_DATA_LENGTH); - this->handleEvent(report); + this->_handleEvent(report); } // Listener is stopped, handle I/O queue - while(!write_queue.empty()) - { - auto task = write_queue.front(); + while(!_io_queue.empty()) { + auto task = _io_queue.front(); (*task)(); - write_queue.pop(); + _io_queue.pop(); } - continue_listen = false; + _continue_listen = false; } void RawDevice::stopListener() { - continue_listen = false; + _continue_listen = false; interruptRead(); } void RawDevice::addEventHandler(const std::string& nickname, - const std::shared_ptr& handler) + const std::shared_ptr& handler) { - auto it = event_handlers.find(nickname); - assert(it == event_handlers.end()); - event_handlers.emplace(nickname, handler); + auto it = _event_handlers.find(nickname); + assert(it == _event_handlers.end()); + _event_handlers.emplace(nickname, handler); } void RawDevice::removeEventHandler(const std::string &nickname) { - event_handlers.erase(nickname); + _event_handlers.erase(nickname); } -const std::map>& +const std::map>& RawDevice::eventHandlers() { - return event_handlers; + return _event_handlers; } -void RawDevice::handleEvent(std::vector &report) +void RawDevice::_handleEvent(std::vector &report) { - for(auto& handler : event_handlers) + for(auto& handler : _event_handlers) if(handler.second->condition(report)) handler.second->callback(report); } bool RawDevice::isListening() { - bool ret = listening.try_lock(); + bool ret = _listening.try_lock(); if(ret) - listening.unlock(); + _listening.unlock(); return !ret; } diff --git a/src/logid/backend/raw/RawDevice.h b/src/logid/backend/raw/RawDevice.h index 4cb99c1..50e4f55 100644 --- a/src/logid/backend/raw/RawDevice.h +++ b/src/logid/backend/raw/RawDevice.h @@ -9,7 +9,7 @@ #include #include -#include "../defs.h" +#include "defs.h" #include "../../util/mutex_queue.h" #define HIDPP_IO_TIMEOUT std::chrono::seconds(2) @@ -25,11 +25,11 @@ namespace raw explicit RawDevice(std::string path); ~RawDevice(); - std::string hidrawPath() const { return path; } + std::string hidrawPath() const; - std::string name() const { return _name; } - uint16_t vendorId() const { return vid; } - uint16_t productId() const { return pid; } + std::string name() const; + uint16_t vendorId() const; + uint16_t productId() const; std::vector reportDescriptor() const { return rdesc; } @@ -42,34 +42,35 @@ namespace raw bool isListening(); void addEventHandler(const std::string& nickname, - const std::shared_ptr& handler); + const std::shared_ptr& handler); void removeEventHandler(const std::string& nickname); - const std::map>& + const std::map>& eventHandlers(); private: - std::mutex dev_io, listening; - std::string path; - int fd; - int dev_pipe[2]; - uint16_t vid; - uint16_t pid; + std::mutex _dev_io, _listening; + std::string _path; + int _fd; + int _pipe[2]; + uint16_t _vid; + uint16_t _pid; std::string _name; std::vector rdesc; - std::atomic continue_listen; + std::atomic _continue_listen; - std::map> - event_handlers; - void handleEvent(std::vector& report); + std::map> + _event_handlers; + void _handleEvent(std::vector& report); /* These will only be used internally and processed with a queue */ int _sendReport(const std::vector& report); int _readReport(std::vector& report, std::size_t maxDataLength); - std::vector _respondToReport(const std::vector& request); + std::vector _respondToReport(const std::vector& + request); - mutex_queue()>*> write_queue; + mutex_queue()>*> _io_queue; }; }}} diff --git a/src/logid/backend/defs.h b/src/logid/backend/raw/defs.h similarity index 50% rename from src/logid/backend/defs.h rename to src/logid/backend/raw/defs.h index 8ef5af1..0247e0f 100644 --- a/src/logid/backend/defs.h +++ b/src/logid/backend/raw/defs.h @@ -1,15 +1,19 @@ -#ifndef LOGID_BACKEND_DEFS_H -#define LOGID_BACKEND_DEFS_H +#ifndef LOGID_BACKEND_RAW_DEFS_H +#define LOGID_BACKEND_RAW_DEFS_H #include +#include +#include -namespace logid::backend +namespace logid { +namespace backend { +namespace raw { struct RawEventHandler { std::function& )> condition; std::function& )> callback; }; -} +}}} -#endif //LOGID_BACKEND_DEFS_H \ No newline at end of file +#endif //LOGID_BACKEND_RAW_DEFS_H \ No newline at end of file diff --git a/src/logid/logid.cpp b/src/logid/logid.cpp index 8313965..eb53810 100644 --- a/src/logid/logid.cpp +++ b/src/logid/logid.cpp @@ -50,79 +50,71 @@ void logid::reload() } */ -void read_cli_options(int argc, char** argv) +void readCliOptions(int argc, char** argv) { - for(int i = 1; i < argc; i++) - { + for(int i = 1; i < argc; i++) { Option option = Option::None; - if(argv[i][0] == '-') // This argument is an option - { - switch(argv[i][1]) // Set option - { - case '-': // Full option name - { - std::string op_str = argv[i]; - if (op_str == "--verbose") option = Option::Verbose; - if (op_str == "--config") option = Option::Config; - if (op_str == "--help") option = Option::Help; - if (op_str == "--version") option = Option::Version; - break; - } - case 'v': // Verbosity - option = Option::Verbose; - break; - case 'V': //Version + if(argv[i][0] == '-') { + // This argument is an option + switch(argv[i][1]) { + case '-': { + // Full option name + std::string op_str = argv[i]; + if (op_str == "--verbose") option = Option::Verbose; + if (op_str == "--config") option = Option::Config; + if (op_str == "--help") option = Option::Help; + if (op_str == "--version") option = Option::Version; + break; + } + case 'v': // Verbosity + option = Option::Verbose; + break; + case 'V': //Version option = Option::Version; break; - case 'c': // Config file path - option = Option::Config; - break; - case 'h': // Help - option = Option::Help; - break; - default: - log_printf(WARN, "%s is not a valid option, ignoring.", argv[1]); + case 'c': // Config file path + option = Option::Config; + break; + case 'h': // Help + option = Option::Help; + break; + default: + log_printf(WARN, "%s is not a valid option, ignoring.", + argv[i]); } - switch(option) - { - case Option::Verbose: - { - if (++i >= argc) - { - global_verbosity = DEBUG; // Assume debug verbosity - break; - } - std::string loglevel = argv[i]; - try { global_verbosity = stringToLogLevel(argv[i]); } - catch (std::invalid_argument &e) - { - if (argv[i][0] == '-') - { - global_verbosity = DEBUG; // Assume debug verbosity - i--; // Go back to last argument to continue loop. - } - else - { - log_printf(WARN, e.what()); - printf("Valid verbosity levels are: Debug, Info, Warn/Warning, or Error.\n"); - exit(EXIT_FAILURE); - } - } + + switch(option) { + case Option::Verbose: { + if (++i >= argc) { + global_verbosity = DEBUG; // Assume debug verbosity break; } - case Option::Config: - { - if (++i >= argc) - { - log_printf(ERROR, "Config file is not specified."); + std::string loglevel = argv[i]; + try { + global_verbosity = stringToLogLevel(argv[i]); + } catch (std::invalid_argument &e) { + if (argv[i][0] == '-') { + global_verbosity = DEBUG; // Assume debug verbosity + i--; // Go back to last argument to continue loop. + } else { + log_printf(WARN, e.what()); + printf("Valid verbosity levels are: Debug, Info, " + "Warn/Warning, or Error.\n"); exit(EXIT_FAILURE); } - config_file = argv[i]; - break; } - case Option::Help: - { - printf(R"(logid version %s + break; + } + case Option::Config: { + if (++i >= argc) { + log_printf(ERROR, "Config file is not specified."); + exit(EXIT_FAILURE); + } + config_file = argv[i]; + break; + } + case Option::Help: + printf(R"(logid version %s Usage: %s [options] Possible options are: -v,--verbose [level] Set log level to debug/info/warn/error (leave blank for debug) @@ -130,16 +122,12 @@ Possible options are: -c,--config [file path] Change config file from default at %s -h,--help Print this message. )", LOGIOPS_VERSION, argv[0], DEFAULT_CONFIG_FILE); - - exit(EXIT_SUCCESS); - } - case Option::Version: - { - printf("%s\n", LOGIOPS_VERSION); - exit(EXIT_SUCCESS); - } - case Option::None: - break; + exit(EXIT_SUCCESS); + case Option::Version: + printf("%s\n", LOGIOPS_VERSION); + exit(EXIT_SUCCESS); + case Option::None: + break; } } } @@ -147,7 +135,7 @@ Possible options are: int main(int argc, char** argv) { - read_cli_options(argc, argv); + readCliOptions(argc, argv); /* // Read config @@ -168,8 +156,7 @@ int main(int argc, char** argv) // Scan devices, create listeners, handlers, etc. finder = new DeviceManager(); - while(!kill_logid) - { + while(!kill_logid) { finder_reloading.lock(); finder_reloading.unlock(); finder->run();