Fix issues with HID++ >= 2.0 devices (particularly related to sleep).
* Don't assume 0x41 messages only occur when a device is first paired (prevents errors when waking from sleep or turning a device on) * Delay reads/writes when a device is powered on, to prevent broken pipe errors (hacky solution). * Don't clear status when a device connects, preventing settings from being cleared when a device sleeps or is turned off. * Fix typos.
This commit is contained in:
parent
d021d87656
commit
a59368f3e7
|
@ -150,7 +150,7 @@ class EventsListener(_threading.Thread):
|
|||
|
||||
# replace the handle with a threaded one
|
||||
self.receiver.handle = _ThreadedHandle(self, self.receiver.path, self.receiver.handle)
|
||||
# get the right low-level handle for this thead
|
||||
# get the right low-level handle for this thread
|
||||
ihandle = int(self.receiver.handle)
|
||||
if _log.isEnabledFor(_INFO):
|
||||
_log.info("started with %s (%d)", self.receiver, ihandle)
|
||||
|
|
|
@ -164,14 +164,14 @@ def _process_hidpp10_notification(device, status, n):
|
|||
assert wpid == device.wpid, "%s wpid mismatch, got %s" % (device, wpid)
|
||||
|
||||
flags = ord(n.data[:1]) & 0xF0
|
||||
link_encrypyed = bool(flags & 0x20)
|
||||
link_encrypted = bool(flags & 0x20)
|
||||
link_established = not (flags & 0x40)
|
||||
if _log.isEnabledFor(_DEBUG):
|
||||
sw_present = bool(flags & 0x10)
|
||||
has_payload = bool(flags & 0x80)
|
||||
_log.debug("%s: %s connection notification: software=%s, encrypted=%s, link=%s, payload=%s",
|
||||
device, protocol_name, sw_present, link_encrypyed, link_established, has_payload)
|
||||
status[_K.LINK_ENCRYPTED] = link_encrypyed
|
||||
device, protocol_name, sw_present, link_encrypted, link_established, has_payload)
|
||||
status[_K.LINK_ENCRYPTED] = link_encrypted
|
||||
status.changed(active=link_established)
|
||||
else:
|
||||
_log.warn("%s: connection notification with unknown protocol %02X: %s", device.number, n.address, n)
|
||||
|
|
|
@ -67,10 +67,11 @@ def attach_to(device, changed_callback):
|
|||
assert device
|
||||
assert changed_callback
|
||||
|
||||
if device.kind is None:
|
||||
device.status = ReceiverStatus(device, changed_callback)
|
||||
else:
|
||||
device.status = DeviceStatus(device, changed_callback)
|
||||
if not hasattr(device, 'status') or device.status is None:
|
||||
if device.kind is None:
|
||||
device.status = ReceiverStatus(device, changed_callback)
|
||||
else:
|
||||
device.status = DeviceStatus(device, changed_callback)
|
||||
|
||||
#
|
||||
#
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import time
|
||||
|
||||
from logging import getLogger, INFO as _INFO
|
||||
_log = getLogger(__name__)
|
||||
|
@ -181,11 +182,20 @@ class ReceiverListener(_listener.EventsListener):
|
|||
return
|
||||
|
||||
# a device notification
|
||||
assert n.devnumber > 0 and n.devnumber <= self.receiver.max_devices
|
||||
assert 0 < n.devnumber <= self.receiver.max_devices
|
||||
already_known = n.devnumber in self.receiver
|
||||
|
||||
if n.sub_id == 0x41:
|
||||
already_known = False
|
||||
# FIXME: hacky fix for kernel/hardware race condition
|
||||
# If the device was just turned on or woken up from sleep, it may not
|
||||
# be ready to receive commands. The "payload" bit of the wireless
|
||||
# status notification seems to tell us this. If this is the case, we
|
||||
# must wait a short amount of time to avoid causing a broken pipe
|
||||
# error.
|
||||
device_ready = not bool(ord(n.data[0:1]) & 0x80) or n.sub_id != 0x41
|
||||
if not device_ready:
|
||||
time.sleep(0.01)
|
||||
|
||||
if n.sub_id == 0x41 and not already_known:
|
||||
dev = self.receiver.register_new_device(n.devnumber, n)
|
||||
else:
|
||||
dev = self.receiver[n.devnumber]
|
||||
|
@ -194,7 +204,8 @@ class ReceiverListener(_listener.EventsListener):
|
|||
_log.warn("%s: received %s for invalid device %d: %r", self.receiver, n, n.devnumber, dev)
|
||||
return
|
||||
|
||||
if not already_known:
|
||||
# Apply settings every time the device connects
|
||||
if n.sub_id == 0x41:
|
||||
if _log.isEnabledFor(_INFO):
|
||||
_log.info("%s triggered new device %s (%s)", n, dev, dev.kind)
|
||||
# If there are saved configs, bring the device's settings up-to-date.
|
||||
|
@ -213,8 +224,7 @@ class ReceiverListener(_listener.EventsListener):
|
|||
if _log.isEnabledFor(_INFO):
|
||||
_log.info("%s: pairing detected new device", self.receiver)
|
||||
self.receiver.status.new_device = dev
|
||||
elif dev:
|
||||
if dev.online is None:
|
||||
elif dev.online is None:
|
||||
dev.ping()
|
||||
|
||||
def __str__(self):
|
||||
|
|
Loading…
Reference in New Issue