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;
using namespace logid::backend; 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()); 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) void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
{ {
try { 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) if(!event.linkEstablished)
return; // Device is probably asleep, wait until it wakes up return;
hidpp::Device hidpp_device(receiver(), event); 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>( std::shared_ptr<Device> device = std::make_shared<Device>(
receiver()->rawDevice(), event.index); receiver()->rawDevice(), event.index);
assert(_devices.find(event.index) == _devices.end());
_devices.emplace(event.index, device); _devices.emplace(event.index, device);
} catch(hidpp10::Error &e) { } catch(hidpp10::Error &e) {
log_printf(ERROR, "Caught HID++ 1.0 error while trying to initialize " log_printf(ERROR,
"%s:%d: %s", _path.c_str(), event.index, e.what()); "Caught HID++ 1.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what());
} catch(hidpp20::Error &e) { } catch(hidpp20::Error &e) {
log_printf(ERROR, "Caught HID++ 2.0 error while trying to initialize " log_printf(ERROR, "Caught HID++ 2.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what()); "%s:%d: %s", _path.c_str(), event.index, e.what());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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