Monitor wake up/sleep events with Receiver

This commit is contained in:
pixl 2020-06-24 00:53:04 -04:00
parent 22455af615
commit 1d001237ba
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
7 changed files with 55 additions and 28 deletions

View File

@ -25,7 +25,7 @@
using namespace logid;
using namespace logid::backend;
Receiver::Receiver(std::string path) : dj::ReceiverMonitor(path)
Receiver::Receiver(std::string path) : dj::ReceiverMonitor(path), _path (path)
{
log_printf(DEBUG, "logid::Receiver created on %s", path.c_str());
}
@ -33,8 +33,17 @@ Receiver::Receiver(std::string path) : dj::ReceiverMonitor(path)
void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
{
try {
auto dev = _devices.find(event.index);
if(dev != _devices.end()) {
if(event.linkEstablished)
dev->second->wakeup();
else
dev->second->sleep();
return;
}
if(!event.linkEstablished)
return; // Device is probably asleep, wait until it wakes up
return;
hidpp::Device hidpp_device(receiver(), event);
@ -49,13 +58,12 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
std::shared_ptr<Device> device = std::make_shared<Device>(
receiver()->rawDevice(), event.index);
assert(_devices.find(event.index) == _devices.end());
_devices.emplace(event.index, device);
} catch(hidpp10::Error &e) {
log_printf(ERROR, "Caught HID++ 1.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what());
log_printf(ERROR,
"Caught HID++ 1.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what());
} catch(hidpp20::Error &e) {
log_printf(ERROR, "Caught HID++ 2.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what());

View File

@ -31,8 +31,8 @@ namespace logid
Receiver(std::string path);
protected:
virtual void addDevice(backend::hidpp::DeviceConnectionEvent event);
virtual void removeDevice(backend::hidpp::DeviceIndex index);
void addDevice(backend::hidpp::DeviceConnectionEvent event) override;
void removeDevice(backend::hidpp::DeviceIndex index) override;
private:
std::map<backend::hidpp::DeviceIndex, std::shared_ptr<Device>> _devices;
std::string _path;

View File

@ -53,7 +53,7 @@ Receiver::Receiver(std::string path) :
void Receiver::enumerateDj()
{
sendDjRequest(hidpp::DefaultDevice, GetPairedDevices,{});
_sendDjRequest(hidpp::DefaultDevice, GetPairedDevices,{});
}
Receiver::NotificationFlags Receiver::getHidppNotifications()
@ -228,29 +228,29 @@ hidpp::DeviceConnectionEvent Receiver::deviceConnectionEvent(
hidpp::DeviceConnectionEvent event{};
event.index = report.deviceIndex();
event.unifying = ((report.paramBegin()[0] & 0b111) == 0x04);
event.unifying = ((report.address() & 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);
report.paramBegin()[0] & 0x0f);
event.softwarePresent = report.paramBegin()[0] & (1<<4);
event.encrypted = report.paramBegin()[0] & (1<<5);
event.linkEstablished = !(report.paramBegin()[0] & (1<<6));
event.withPayload = report.paramBegin()[0] & (1<<7);
event.pid = report.paramBegin()[3];
event.pid |= (report.paramBegin()[2] << 8);
event.pid =(report.paramBegin()[2] << 8);
event.pid |= report.paramBegin()[1];
return event;
}
void Receiver::handleDjEvent(Report& report)
void Receiver::_handleDjEvent(Report& report)
{
for(auto& handler : _dj_event_handlers)
if(handler.second->condition(report))
handler.second->callback(report);
}
void Receiver::handleHidppEvent(hidpp::Report &report)
void Receiver::_handleHidppEvent(hidpp::Report &report)
{
for(auto& handler : _hidpp_event_handlers)
if(handler.second->condition(report))
@ -295,7 +295,7 @@ Receiver::hidppEventHandlers()
return _hidpp_event_handlers;
}
void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
void Receiver::_sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
const std::vector<uint8_t>&& params)
{
assert(params.size() <= LongParamLength);
@ -310,10 +310,19 @@ void Receiver::sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
_raw_device->sendReportNoResponse(request.rawData());
}
Receiver::ConnectionStatusEvent Receiver::connectionStatusEvent(Report& report)
{
assert(report.feature() == ConnectionStatus);
ConnectionStatusEvent event{};
event.index = report.index();
event.linkLost = report.paramBegin()[0];
return event;
}
void Receiver::listen()
{
if(!_raw_device->isListening())
std::thread{[=]() { _raw_device->listen(); }}.detach();
std::thread{[this]() { this->_raw_device->listen(); }}.detach();
if(_raw_device->eventHandlers().find("RECV_HIDPP") ==
_raw_device->eventHandlers().end()) {
@ -328,7 +337,7 @@ void Receiver::listen()
hidpp_handler->callback = [this](std::vector<uint8_t>& report)
->void {
hidpp::Report _report(report);
this->handleHidppEvent(_report);
this->_handleHidppEvent(_report);
};
_raw_device->addEventHandler("RECV_HIDPP", hidpp_handler);
}
@ -346,7 +355,7 @@ void Receiver::listen()
dj_handler->callback = [this](std::vector<uint8_t>& report)->void
{
Report _report(report);
this->handleDjEvent(_report);
this->_handleDjEvent(_report);
};
_raw_device->addEventHandler("RECV_DJ", dj_handler);
}

View File

@ -69,6 +69,14 @@ namespace dj
void enumerateDj();
struct ConnectionStatusEvent
{
hidpp::DeviceIndex index;
bool linkLost;
};
ConnectionStatusEvent connectionStatusEvent(dj::Report& report);
/* The following functions deal with HID++ 1.0 features.
* While these are not technically DJ functions, it is redundant
* to have a separate hidpp10::Receiver class for these functions.
@ -153,11 +161,11 @@ namespace dj
std::shared_ptr<raw::RawDevice> rawDevice() const;
private:
void sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
void _sendDjRequest(hidpp::DeviceIndex index, uint8_t function,
const std::vector<uint8_t>&& params);
void handleDjEvent(dj::Report& report);
void handleHidppEvent(hidpp::Report& report);
void _handleDjEvent(dj::Report& report);
void _handleHidppEvent(hidpp::Report& report);
std::map<std::string, std::shared_ptr<EventHandler>>
_dj_event_handlers;

View File

@ -73,6 +73,8 @@ void ReceiverMonitor::run()
void ReceiverMonitor::stop()
{
_receiver->removeHidppEventHandler("RECVMON");
_receiver->stopListening();
}

View File

@ -32,7 +32,7 @@ namespace dj
class ReceiverMonitor
{
public:
ReceiverMonitor(std::string path);
explicit ReceiverMonitor(std::string path);
void enumerate();
void run();

View File

@ -149,7 +149,7 @@ void DeviceMonitor::enumerate()
std::string devnode = udev_device_get_devnode(device);
udev_device_unref(device);
std::thread([this](const std::string name) {
std::thread([this](const std::string& name) {
this->addDevice(name);
}, devnode).detach();
}