Listen for events on receiver device on timeout

Previously, if a receiver device didn't respond during the initial scan,
logid would not recognize it until it sent a wakeup/connect event.

This makes it so if the device times out, logid will listen for the next
event from the device and try detecting it. (e.g. shaking the mouse will
make it become detected)
master
pixl 4 years ago
parent 1a056a1ecf
commit 4ce76f5927
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
  1. 6
      src/logid/Receiver.cpp
  2. 1
      src/logid/backend/dj/Receiver.cpp
  3. 1
      src/logid/backend/dj/Receiver.h
  4. 31
      src/logid/backend/dj/ReceiverMonitor.cpp
  5. 2
      src/logid/backend/dj/ReceiverMonitor.h
  6. 4
      src/logid/backend/raw/RawDevice.cpp
  7. 1
      src/logid/backend/raw/RawDevice.h

@ -21,6 +21,7 @@
#include "util/log.h"
#include "backend/hidpp10/Error.h"
#include "backend/hidpp20/Error.h"
#include "backend/Error.h"
using namespace logid;
using namespace logid::backend;
@ -67,6 +68,11 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
} catch(hidpp20::Error &e) {
logPrintf(ERROR, "Caught HID++ 2.0 error while trying to initialize "
"%s:%d: %s", _path.c_str(), event.index, e.what());
} catch(TimeoutError &e) {
if(!event.fromTimeoutCheck)
logPrintf(DEBUG, "%s:%d timed out, waiting for input from device to"
" initialize.", _path.c_str(), event.index);
waitForDevice(event.index);
}
}

@ -238,6 +238,7 @@ hidpp::DeviceConnectionEvent Receiver::deviceConnectionEvent(const
event.encrypted = report.paramBegin()[0] & (1<<5);
event.linkEstablished = !(report.paramBegin()[0] & (1<<6));
event.withPayload = report.paramBegin()[0] & (1<<7);
event.fromTimeoutCheck = false;
event.pid =(report.paramBegin()[2] << 8);
event.pid |= report.paramBegin()[1];

@ -189,6 +189,7 @@ namespace hidpp
bool encrypted;
bool linkEstablished;
bool withPayload;
bool fromTimeoutCheck = false; // Fake field
};
}}}

@ -95,6 +95,37 @@ void ReceiverMonitor::enumerate()
_receiver->enumerateHidpp();
}
void ReceiverMonitor::waitForDevice(hidpp::DeviceIndex index)
{
std::string nickname = "WAIT_DEV_" + std::to_string(index);
auto handler = std::make_shared<raw::RawEventHandler>();
handler->condition = [index](std::vector<uint8_t>& report)->bool {
return report[Offset::DeviceIndex] == index;
};
handler->callback = [this, index, nickname](std::vector<uint8_t>& report) {
(void)report; // Suppress unused warning
hidpp::DeviceConnectionEvent event{};
event.withPayload = false;
event.linkEstablished = true;
event.index = index;
event.fromTimeoutCheck = true;
task::spawn({[this, event, nickname]() {
_receiver->rawDevice()->removeEventHandler(nickname);
this->addDevice(event);
}}, {[path=_receiver->rawDevice()->hidrawPath(), event]
(std::exception& e) {
logPrintf(ERROR, "Failed to add device %d to receiver "
"on %s: %s", event.index,
path.c_str(), e.what());
}});
};
_receiver->rawDevice()->addEventHandler(nickname, handler);
}
std::shared_ptr<Receiver> ReceiverMonitor::receiver() const
{
return _receiver;

@ -42,6 +42,8 @@ namespace dj
virtual void addDevice(hidpp::DeviceConnectionEvent event) = 0;
virtual void removeDevice(hidpp::DeviceIndex index) = 0;
void waitForDevice(hidpp::DeviceIndex index);
// Internal methods for derived class
void _pair(uint8_t timeout = 0);
void _stopPairing();

@ -404,6 +404,7 @@ void RawDevice::stopListener()
void RawDevice::addEventHandler(const std::string& nickname,
const std::shared_ptr<raw::RawEventHandler>& handler)
{
std::unique_lock<std::mutex> lock(_event_handler_lock);
auto it = _event_handlers.find(nickname);
assert(it == _event_handlers.end());
assert(handler);
@ -412,17 +413,20 @@ void RawDevice::addEventHandler(const std::string& nickname,
void RawDevice::removeEventHandler(const std::string &nickname)
{
std::unique_lock<std::mutex> lock(_event_handler_lock);
_event_handlers.erase(nickname);
}
const std::map<std::string, std::shared_ptr<raw::RawEventHandler>>&
RawDevice::eventHandlers()
{
std::unique_lock<std::mutex> lock(_event_handler_lock);
return _event_handlers;
}
void RawDevice::_handleEvent(std::vector<uint8_t> &report)
{
std::unique_lock<std::mutex> lock(_event_handler_lock);
for(auto& handler : _event_handlers)
if(handler.second->condition(report))
handler.second->callback(report);

@ -80,6 +80,7 @@ namespace raw
std::map<std::string, std::shared_ptr<RawEventHandler>>
_event_handlers;
std::mutex _event_handler_lock;
void _handleEvent(std::vector<uint8_t>& report);
/* These will only be used internally and processed with a queue */

Loading…
Cancel
Save