diff --git a/src/logid/CMakeLists.txt b/src/logid/CMakeLists.txt index 8488eb7..5be8549 100644 --- a/src/logid/CMakeLists.txt +++ b/src/logid/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(logid backend/raw/DeviceMonitor.cpp backend/raw/RawDevice.cpp backend/dj/Receiver.cpp + backend/dj/ReceiverMonitor.cpp backend/dj/Error.cpp backend/hidpp/Device.cpp backend/hidpp/Report.cpp diff --git a/src/logid/backend/dj/Receiver.cpp b/src/logid/backend/dj/Receiver.cpp index 7d5aef4..d579a32 100644 --- a/src/logid/backend/dj/Receiver.cpp +++ b/src/logid/backend/dj/Receiver.cpp @@ -12,7 +12,13 @@ InvalidReceiver::InvalidReceiver(Reason reason) : _reason (reason) const char* InvalidReceiver::what() const noexcept { - return "Invalid receiver"; + switch(_reason) + { + case NoDJReports: + return "No DJ reports"; + default: + return "Invalid receiver"; + } } InvalidReceiver::Reason InvalidReceiver::code() const noexcept @@ -69,10 +75,11 @@ Receiver::notification_flags Receiver::getHidppNotifications() auto response = _hidpp10_device.getRegister(EnableHidppNotifications, {}); 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); + + return flags; } void Receiver::enableHidppNotifications(notification_flags flags) @@ -142,7 +149,8 @@ std::map Receiver::getDeviceActivity() return device_activity; } -Receiver::pairing_info Receiver::getPairingInfo(hidpp::DeviceIndex index) +struct Receiver::PairingInfo + Receiver::getPairingInfo(hidpp::DeviceIndex index) { std::vector request(1); request[0] = index; @@ -150,17 +158,17 @@ Receiver::pairing_info Receiver::getPairingInfo(hidpp::DeviceIndex index) auto response = _hidpp10_device.getRegister(PairingInfo, request); - pairing_info info{}; - info.destination_id = response[0]; - info.report_interval = response[1]; + struct PairingInfo info{}; + info.destinationId = response[0]; + info.reportInterval = response[1]; info.pid = response[2]; info.pid |= (response[3] << 8); - info.device_type = response[6]; + info.deviceType = static_cast(response[6]); return info; } -Receiver::extended_pairing_info +struct Receiver::ExtendedPairingInfo Receiver::getExtendedPairingInfo(hidpp::DeviceIndex index) { std::vector request(1); @@ -169,16 +177,16 @@ Receiver::extended_pairing_info auto response = _hidpp10_device.getRegister(PairingInfo, request); - extended_pairing_info info{}; + ExtendedPairingInfo info{}; - info.serial_number = 0; + info.serialNumber = 0; for(uint8_t i = 0; i < 4; i++) - info.serial_number |= (response[i] << 8*i); + info.serialNumber |= (response[i] << 8*i); for(uint8_t i = 0; i < 4; i++) - info.report_types[i] = response[i + 4]; + info.reportTypes[i] = response[i + 4]; - info.power_switch_location = response[8] & 0xf; + info.powerSwitchLocation = response[8] & 0xf; return info; } @@ -201,18 +209,35 @@ std::string Receiver::getDeviceName(hidpp::DeviceIndex index) return name; } -hidpp::DeviceIndex Receiver::deviceConnectionEvent(hidpp::Report &report) -{ - assert(report.subId() == DeviceConnection); - return report.deviceIndex(); -} - hidpp::DeviceIndex Receiver::deviceDisconnectionEvent(hidpp::Report& report) { assert(report.subId() == DeviceDisconnection); return report.deviceIndex(); } +Receiver::DeviceConnectionEvent Receiver::deviceConnectionEvent( + hidpp::Report &report) +{ + assert(report.subId() == DeviceConnection); + + DeviceConnectionEvent event{}; + + event.index = report.deviceIndex(); + event.unifying = ((report.paramBegin()[0] & 0b111) == 0x04); + + event.deviceType = static_cast( + report.paramBegin()[1] & 0x0f); + event.softwarePresent = report.paramBegin()[1] & (1<<4); + event.encrypted = report.paramBegin()[1] & (1<<5); + event.linkEstablished = report.paramBegin()[1] & (1<<6); + event.withPayload = report.paramBegin()[1] & (1<<7); + + event.pid = report.paramBegin()[3]; + event.pid |= (report.paramBegin()[2] << 8); + + return event; +} + void Receiver::handleDjEvent(Report& report) { if(report.feature() == DeviceConnection || @@ -252,4 +277,9 @@ void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function, void Receiver::listen() { std::thread{[=]() { raw_device->listen(); }}.detach(); +} + +void Receiver::stopListening() +{ + raw_device->stopListener(); } \ No newline at end of file diff --git a/src/logid/backend/dj/Receiver.h b/src/logid/backend/dj/Receiver.h index 24ffa19..3954a20 100644 --- a/src/logid/backend/dj/Receiver.h +++ b/src/logid/backend/dj/Receiver.h @@ -86,33 +86,49 @@ namespace dj std::map getDeviceActivity(); - struct pairing_info + struct PairingInfo { - uint8_t destination_id; - uint8_t report_interval; + uint8_t destinationId; + uint8_t reportInterval; uint16_t pid; - uint8_t device_type; ///TODO: Create enum for DeviceType + DeviceType::DeviceType deviceType; }; - struct extended_pairing_info + struct ExtendedPairingInfo { - uint32_t serial_number; - uint8_t report_types[4]; - uint8_t power_switch_location; ///TODO: Create enum + uint32_t serialNumber; + uint8_t reportTypes[4]; + uint8_t powerSwitchLocation; ///TODO: Make enum }; - pairing_info getPairingInfo(hidpp::DeviceIndex index); - extended_pairing_info getExtendedPairingInfo(hidpp::DeviceIndex index); + struct PairingInfo getPairingInfo(hidpp::DeviceIndex index); + struct ExtendedPairingInfo getExtendedPairingInfo(hidpp::DeviceIndex + index); std::string getDeviceName(hidpp::DeviceIndex index); - hidpp::DeviceIndex deviceConnectionEvent(hidpp::Report& report); - hidpp::DeviceIndex deviceDisconnectionEvent(hidpp::Report& report); + struct DeviceConnectionEvent + { + hidpp::DeviceIndex index; + uint16_t pid; + DeviceType::DeviceType deviceType; + bool unifying; + bool softwarePresent; + bool encrypted; + bool linkEstablished; + bool withPayload; + }; + + static hidpp::DeviceIndex deviceDisconnectionEvent( + hidpp::Report& report); + static DeviceConnectionEvent deviceConnectionEvent( + hidpp::Report& report); void handleDjEvent(dj::Report& report); void handleHidppEvent(hidpp::Report& report); void listen(); + void stopListening(); private: void sendDjRequest(hidpp::DeviceIndex index, uint8_t function, const std::vector&& params); diff --git a/src/logid/backend/dj/ReceiverMonitor.cpp b/src/logid/backend/dj/ReceiverMonitor.cpp index e69de29..f7302b2 100644 --- a/src/logid/backend/dj/ReceiverMonitor.cpp +++ b/src/logid/backend/dj/ReceiverMonitor.cpp @@ -0,0 +1,30 @@ +#include "ReceiverMonitor.h" + +#include + +using namespace logid::backend::dj; + +ReceiverMonitor::ReceiverMonitor(std::string path) : _reciever (std::move(path)) +{ + Receiver::notification_flags notification_flags{ + true, + true, + true}; + _reciever.enableHidppNotifications(notification_flags); +} + +void ReceiverMonitor::run() +{ + _reciever.listen(); + enumerate(); +} + +void ReceiverMonitor::stop() +{ + _reciever.stopListening(); +} + +void ReceiverMonitor::enumerate() +{ + _reciever.enumerate(); +} \ No newline at end of file diff --git a/src/logid/backend/dj/ReceiverMonitor.h b/src/logid/backend/dj/ReceiverMonitor.h index f717da0..5625294 100644 --- a/src/logid/backend/dj/ReceiverMonitor.h +++ b/src/logid/backend/dj/ReceiverMonitor.h @@ -1,6 +1,38 @@ #ifndef LOGID_BACKEND_DJ_RECEIVERMONITOR_H #define LOGID_BACKEND_DJ_RECEIVERMONITOR_H +#include +#include +#include "Receiver.h" +#include "../hidpp/defs.h" +namespace logid { +namespace backend { +namespace dj +{ + // This class will run on the RawDevice thread, + class ReceiverMonitor + { + public: + ReceiverMonitor(std::string path); + + void enumerate(); + void run(); + void stop(); + + protected: + virtual void addDevice(hidpp::DeviceIndex index, uint16_t pid) = 0; + virtual void removeDevice(hidpp::DeviceIndex index) = 0; + + // Internal methods for derived class + void _pair(uint8_t timeout = 0); + void _stopPairing(); + + void _unpair(); + private: + Receiver _reciever; + }; + +}}} #endif //LOGID_BACKEND_DJ_RECEIVERMONITOR_H \ No newline at end of file diff --git a/src/logid/backend/dj/defs.h b/src/logid/backend/dj/defs.h index 5c0124e..0040432 100644 --- a/src/logid/backend/dj/defs.h +++ b/src/logid/backend/dj/defs.h @@ -16,6 +16,21 @@ namespace dj }; } + namespace DeviceType + { + enum DeviceType : uint8_t + { + Unknown = 0x00, + Keyboard = 0x01, + Mouse = 0x02, + Numpad = 0x03, + Presenter = 0x04, + /* 0x05-0x07 is reserved */ + Trackball = 0x08, + Touchpad = 0x09 + }; + } + static constexpr uint8_t ErrorFeature = 0x7f; static constexpr std::size_t HeaderLength = 3;