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)
This commit is contained in:
parent
1a056a1ecf
commit
4ce76f5927
|
@ -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…
Reference in New Issue
Block a user