Implement logid::backend::dj::ReceiverMonitor

This commit is contained in:
pixl 2020-06-20 03:16:16 -04:00
parent 6bfa52e5c1
commit c04408c2dd
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
6 changed files with 155 additions and 31 deletions

View File

@ -18,6 +18,7 @@ add_executable(logid
backend/raw/DeviceMonitor.cpp backend/raw/DeviceMonitor.cpp
backend/raw/RawDevice.cpp backend/raw/RawDevice.cpp
backend/dj/Receiver.cpp backend/dj/Receiver.cpp
backend/dj/ReceiverMonitor.cpp
backend/dj/Error.cpp backend/dj/Error.cpp
backend/hidpp/Device.cpp backend/hidpp/Device.cpp
backend/hidpp/Report.cpp backend/hidpp/Report.cpp

View File

@ -12,7 +12,13 @@ InvalidReceiver::InvalidReceiver(Reason reason) : _reason (reason)
const char* InvalidReceiver::what() const noexcept 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 InvalidReceiver::Reason InvalidReceiver::code() const noexcept
@ -69,10 +75,11 @@ Receiver::notification_flags Receiver::getHidppNotifications()
auto response = _hidpp10_device.getRegister(EnableHidppNotifications, {}); auto response = _hidpp10_device.getRegister(EnableHidppNotifications, {});
notification_flags flags{}; notification_flags flags{};
flags.device_battery_status = response[0] & (1 << 4); flags.device_battery_status = response[0] & (1 << 4);
flags.receiver_wireless_notifications = response[1] & (1 << 0); flags.receiver_wireless_notifications = response[1] & (1 << 0);
flags.receiver_software_present = response[1] & (1 << 3); flags.receiver_software_present = response[1] & (1 << 3);
return flags;
} }
void Receiver::enableHidppNotifications(notification_flags flags) void Receiver::enableHidppNotifications(notification_flags flags)
@ -142,7 +149,8 @@ std::map<hidpp::DeviceIndex, uint8_t> Receiver::getDeviceActivity()
return device_activity; return device_activity;
} }
Receiver::pairing_info Receiver::getPairingInfo(hidpp::DeviceIndex index) struct Receiver::PairingInfo
Receiver::getPairingInfo(hidpp::DeviceIndex index)
{ {
std::vector<uint8_t> request(1); std::vector<uint8_t> request(1);
request[0] = index; request[0] = index;
@ -150,17 +158,17 @@ Receiver::pairing_info Receiver::getPairingInfo(hidpp::DeviceIndex index)
auto response = _hidpp10_device.getRegister(PairingInfo, request); auto response = _hidpp10_device.getRegister(PairingInfo, request);
pairing_info info{}; struct PairingInfo info{};
info.destination_id = response[0]; info.destinationId = response[0];
info.report_interval = response[1]; info.reportInterval = response[1];
info.pid = response[2]; info.pid = response[2];
info.pid |= (response[3] << 8); info.pid |= (response[3] << 8);
info.device_type = response[6]; info.deviceType = static_cast<DeviceType::DeviceType>(response[6]);
return info; return info;
} }
Receiver::extended_pairing_info struct Receiver::ExtendedPairingInfo
Receiver::getExtendedPairingInfo(hidpp::DeviceIndex index) Receiver::getExtendedPairingInfo(hidpp::DeviceIndex index)
{ {
std::vector<uint8_t> request(1); std::vector<uint8_t> request(1);
@ -169,16 +177,16 @@ Receiver::extended_pairing_info
auto response = _hidpp10_device.getRegister(PairingInfo, request); 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++) 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++) 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; return info;
} }
@ -201,18 +209,35 @@ std::string Receiver::getDeviceName(hidpp::DeviceIndex index)
return name; return name;
} }
hidpp::DeviceIndex Receiver::deviceConnectionEvent(hidpp::Report &report)
{
assert(report.subId() == DeviceConnection);
return report.deviceIndex();
}
hidpp::DeviceIndex Receiver::deviceDisconnectionEvent(hidpp::Report& report) hidpp::DeviceIndex Receiver::deviceDisconnectionEvent(hidpp::Report& report)
{ {
assert(report.subId() == DeviceDisconnection); assert(report.subId() == DeviceDisconnection);
return report.deviceIndex(); 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<DeviceType::DeviceType>(
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) void Receiver::handleDjEvent(Report& report)
{ {
if(report.feature() == DeviceConnection || if(report.feature() == DeviceConnection ||
@ -253,3 +278,8 @@ void Receiver::listen()
{ {
std::thread{[=]() { raw_device->listen(); }}.detach(); std::thread{[=]() { raw_device->listen(); }}.detach();
} }
void Receiver::stopListening()
{
raw_device->stopListener();
}

View File

@ -86,33 +86,49 @@ namespace dj
std::map<hidpp::DeviceIndex, uint8_t> getDeviceActivity(); std::map<hidpp::DeviceIndex, uint8_t> getDeviceActivity();
struct pairing_info struct PairingInfo
{ {
uint8_t destination_id; uint8_t destinationId;
uint8_t report_interval; uint8_t reportInterval;
uint16_t pid; 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; uint32_t serialNumber;
uint8_t report_types[4]; uint8_t reportTypes[4];
uint8_t power_switch_location; ///TODO: Create enum uint8_t powerSwitchLocation; ///TODO: Make enum
}; };
pairing_info getPairingInfo(hidpp::DeviceIndex index); struct PairingInfo getPairingInfo(hidpp::DeviceIndex index);
extended_pairing_info getExtendedPairingInfo(hidpp::DeviceIndex index); struct ExtendedPairingInfo getExtendedPairingInfo(hidpp::DeviceIndex
index);
std::string getDeviceName(hidpp::DeviceIndex index); std::string getDeviceName(hidpp::DeviceIndex index);
hidpp::DeviceIndex deviceConnectionEvent(hidpp::Report& report); struct DeviceConnectionEvent
hidpp::DeviceIndex deviceDisconnectionEvent(hidpp::Report& report); {
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 handleDjEvent(dj::Report& report);
void handleHidppEvent(hidpp::Report& report); void handleHidppEvent(hidpp::Report& report);
void listen(); void listen();
void stopListening();
private: private:
void sendDjRequest(hidpp::DeviceIndex index, uint8_t function, void sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
const std::vector<uint8_t>&& params); const std::vector<uint8_t>&& params);

View File

@ -0,0 +1,30 @@
#include "ReceiverMonitor.h"
#include <utility>
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();
}

View File

@ -1,6 +1,38 @@
#ifndef LOGID_BACKEND_DJ_RECEIVERMONITOR_H #ifndef LOGID_BACKEND_DJ_RECEIVERMONITOR_H
#define LOGID_BACKEND_DJ_RECEIVERMONITOR_H #define LOGID_BACKEND_DJ_RECEIVERMONITOR_H
#include <cstdint>
#include <string>
#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 #endif //LOGID_BACKEND_DJ_RECEIVERMONITOR_H

View File

@ -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 uint8_t ErrorFeature = 0x7f;
static constexpr std::size_t HeaderLength = 3; static constexpr std::size_t HeaderLength = 3;