From 246c6cc1b2af5072206661a02cd75a0e42dc013c Mon Sep 17 00:00:00 2001 From: effective-light Date: Wed, 12 Aug 2020 16:31:34 -0400 Subject: [PATCH] udev: add a timeout to find_paired_node because the device might not be instantly ready (e.g. after pairing) --- lib/hidapi/udev.py | 15 ++++++++++----- lib/logitech_receiver/device.py | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/hidapi/udev.py b/lib/hidapi/udev.py index c5062e82..be7146bc 100644 --- a/lib/hidapi/udev.py +++ b/lib/hidapi/udev.py @@ -34,6 +34,7 @@ import os as _os from collections import namedtuple from select import select as _select from time import sleep +from time import time as _timestamp from pyudev import Context as _Context from pyudev import Device as _Device @@ -154,7 +155,7 @@ def _match(action, device, filter): return d_info -def find_paired_node(receiver_path, index): +def find_paired_node(receiver_path, index, timeout): """Find the node of a device paired with a receiver""" context = _Context() receiver_phys = _Devices.from_device_file(context, receiver_path).find_parent('hid').get('HID_PHYS') @@ -163,10 +164,14 @@ def find_paired_node(receiver_path, index): return None phys = f'{receiver_phys}:{index}' - for dev in context.list_devices(subsystem='hidraw'): - dev_phys = dev.find_parent('hid').get('HID_PHYS') - if dev_phys and dev_phys == phys: - return dev.device_node + timeout += _timestamp() + delta = _timestamp() + while delta < timeout: + for dev in context.list_devices(subsystem='hidraw'): + dev_phys = dev.find_parent('hid').get('HID_PHYS') + if dev_phys and dev_phys == phys: + return dev.device_node + delta = _timestamp() return None diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py index f6ad0d99..cf53c7ad 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -128,7 +128,7 @@ class Device(object): # device is unpaired assert self.wpid is not None, 'failed to read wpid: device %d of %s' % (number, receiver) - self.path = _hid.find_paired_node(receiver.path, number) + self.path = _hid.find_paired_node(receiver.path, number, _base.DEFAULT_TIMEOUT) self.handle = _hid.open_path(self.path) if self.path else None self.descriptor = _DESCRIPTORS.get(self.wpid) @@ -280,7 +280,7 @@ class Device(object): for s in self.descriptor.settings: try: setting = s(self) - except Exception as e: # Do nothing if the device is offline + except Exception as e: # Do nothing if the device is offline setting = None if self.online: raise e