receiver: move pairing status to new dataclass attached to receiver
This commit is contained in:
parent
0d225f6cb1
commit
87285faf7f
|
@ -91,6 +91,7 @@ class Device:
|
||||||
self._persister = None # persister holds settings
|
self._persister = None # persister holds settings
|
||||||
self._led_effects = self._firmware = self._keys = self._remap_keys = self._gestures = None
|
self._led_effects = self._firmware = self._keys = self._remap_keys = self._gestures = None
|
||||||
self._profiles = self._backlight = self._registers = self._settings = None
|
self._profiles = self._backlight = self._registers = self._settings = None
|
||||||
|
self.notification_flags = None
|
||||||
|
|
||||||
self._feature_settings_checked = False
|
self._feature_settings_checked = False
|
||||||
self._gestures_lock = _threading.Lock()
|
self._gestures_lock = _threading.Lock()
|
||||||
|
|
|
@ -64,34 +64,35 @@ def _process_receiver_notification(receiver, status, n):
|
||||||
assert n.sub_id & 0x40 == 0x40
|
assert n.sub_id & 0x40 == 0x40
|
||||||
|
|
||||||
if n.sub_id == 0x4A: # pairing lock notification
|
if n.sub_id == 0x4A: # pairing lock notification
|
||||||
status.lock_open = bool(n.address & 0x01)
|
receiver.pairing.lock_open = bool(n.address & 0x01)
|
||||||
reason = _("pairing lock is open") if status.lock_open else _("pairing lock is closed")
|
reason = _("pairing lock is open") if receiver.pairing.lock_open else _("pairing lock is closed")
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("%s: %s", receiver, reason)
|
logger.info("%s: %s", receiver, reason)
|
||||||
status.error = None
|
receiver.pairing.error = None
|
||||||
if status.lock_open:
|
if receiver.pairing.lock_open:
|
||||||
status.new_device = None
|
receiver.pairing.new_device = None
|
||||||
pair_error = ord(n.data[:1])
|
pair_error = ord(n.data[:1])
|
||||||
if pair_error:
|
if pair_error:
|
||||||
status.error = error_string = _hidpp10_constants.PAIRING_ERRORS[pair_error]
|
receiver.pairing.error = error_string = _hidpp10_constants.PAIRING_ERRORS[pair_error]
|
||||||
status.new_device = None
|
receiver.pairing.new_device = None
|
||||||
logger.warning("pairing error %d: %s", pair_error, error_string)
|
logger.warning("pairing error %d: %s", pair_error, error_string)
|
||||||
status.changed(reason=reason)
|
status.changed(reason=reason)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
elif n.sub_id == _R.discovery_status_notification: # Bolt pairing
|
elif n.sub_id == _R.discovery_status_notification: # Bolt pairing
|
||||||
with notification_lock:
|
with notification_lock:
|
||||||
status.discovering = n.address == 0x00
|
receiver.pairing.discovering = n.address == 0x00
|
||||||
reason = _("discovery lock is open") if status.discovering else _("discovery lock is closed")
|
reason = _("discovery lock is open") if receiver.pairing.discovering else _("discovery lock is closed")
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("%s: %s", receiver, reason)
|
logger.info("%s: %s", receiver, reason)
|
||||||
status.error = None
|
receiver.pairing.error = None
|
||||||
if status.discovering:
|
if receiver.pairing.discovering:
|
||||||
status.counter = status.device_address = status.device_authentication = status.device_name = None
|
receiver.pairing.counter = receiver.pairing.device_address = None
|
||||||
status.device_passkey = None
|
receiver.pairing.device_authentication = receiver.pairing.device_name = None
|
||||||
|
receiver.pairing.device_passkey = None
|
||||||
discover_error = ord(n.data[:1])
|
discover_error = ord(n.data[:1])
|
||||||
if discover_error:
|
if discover_error:
|
||||||
status.error = discover_string = _hidpp10_constants.BOLT_PAIRING_ERRORS[discover_error]
|
receiver.pairing.error = discover_string = _hidpp10_constants.BOLT_PAIRING_ERRORS[discover_error]
|
||||||
logger.warning("bolt discovering error %d: %s", discover_error, discover_string)
|
logger.warning("bolt discovering error %d: %s", discover_error, discover_string)
|
||||||
status.changed(reason=reason)
|
status.changed(reason=reason)
|
||||||
return True
|
return True
|
||||||
|
@ -99,44 +100,46 @@ def _process_receiver_notification(receiver, status, n):
|
||||||
elif n.sub_id == _R.device_discovery_notification: # Bolt pairing
|
elif n.sub_id == _R.device_discovery_notification: # Bolt pairing
|
||||||
with notification_lock:
|
with notification_lock:
|
||||||
counter = n.address + n.data[0] * 256 # notification counter
|
counter = n.address + n.data[0] * 256 # notification counter
|
||||||
if status.counter is None:
|
if receiver.pairing.counter is None:
|
||||||
status.counter = counter
|
receiver.pairing.counter = counter
|
||||||
else:
|
else:
|
||||||
if not status.counter == counter:
|
if not receiver.pairing.counter == counter:
|
||||||
return None
|
return None
|
||||||
if n.data[1] == 0:
|
if n.data[1] == 0:
|
||||||
status.device_kind = n.data[3]
|
receiver.pairing.device_kind = n.data[3]
|
||||||
status.device_address = n.data[6:12]
|
receiver.pairing.device_address = n.data[6:12]
|
||||||
status.device_authentication = n.data[14]
|
receiver.pairing.device_authentication = n.data[14]
|
||||||
elif n.data[1] == 1:
|
elif n.data[1] == 1:
|
||||||
status.device_name = n.data[3 : 3 + n.data[2]].decode("utf-8")
|
receiver.pairing.device_name = n.data[3 : 3 + n.data[2]].decode("utf-8")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
elif n.sub_id == _R.pairing_status_notification: # Bolt pairing
|
elif n.sub_id == _R.pairing_status_notification: # Bolt pairing
|
||||||
with notification_lock:
|
with notification_lock:
|
||||||
status.device_passkey = None
|
receiver.pairing.device_passkey = None
|
||||||
status.lock_open = n.address == 0x00
|
receiver.pairing.lock_open = n.address == 0x00
|
||||||
reason = _("pairing lock is open") if status.lock_open else _("pairing lock is closed")
|
reason = _("pairing lock is open") if receiver.pairing.lock_open else _("pairing lock is closed")
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("%s: %s", receiver, reason)
|
logger.info("%s: %s", receiver, reason)
|
||||||
status.error = None
|
receiver.pairing.error = None
|
||||||
if not status.lock_open:
|
if not receiver.pairing.lock_open:
|
||||||
status.counter = status.device_address = status.device_authentication = status.device_name = None
|
receiver.pairing.counter = (
|
||||||
|
receiver.pairing.device_address
|
||||||
|
) = receiver.pairing.device_authentication = receiver.pairing.device_name = None
|
||||||
pair_error = n.data[0]
|
pair_error = n.data[0]
|
||||||
if status.lock_open:
|
if receiver.pairing.lock_open:
|
||||||
status.new_device = None
|
receiver.pairing.new_device = None
|
||||||
elif n.address == 0x02 and not pair_error:
|
elif n.address == 0x02 and not pair_error:
|
||||||
status.new_device = receiver.register_new_device(n.data[7])
|
receiver.pairing.new_device = receiver.register_new_device(n.data[7])
|
||||||
if pair_error:
|
if pair_error:
|
||||||
status.error = error_string = _hidpp10_constants.BOLT_PAIRING_ERRORS[pair_error]
|
receiver.pairing.error = error_string = _hidpp10_constants.BOLT_PAIRING_ERRORS[pair_error]
|
||||||
status.new_device = None
|
receiver.pairing.new_device = None
|
||||||
logger.warning("pairing error %d: %s", pair_error, error_string)
|
logger.warning("pairing error %d: %s", pair_error, error_string)
|
||||||
status.changed(reason=reason)
|
status.changed(reason=reason)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
elif n.sub_id == _R.passkey_request_notification: # Bolt pairing
|
elif n.sub_id == _R.passkey_request_notification: # Bolt pairing
|
||||||
with notification_lock:
|
with notification_lock:
|
||||||
status.device_passkey = n.data[0:6].decode("utf-8")
|
receiver.pairing.device_passkey = n.data[0:6].decode("utf-8")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
elif n.sub_id == _R.passkey_pressed_notification: # Bolt pairing
|
elif n.sub_id == _R.passkey_pressed_notification: # Bolt pairing
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
import errno as _errno
|
import errno as _errno
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import hidapi as _hid
|
import hidapi as _hid
|
||||||
|
@ -33,6 +34,22 @@ _R = hidpp10_constants.REGISTERS
|
||||||
_IR = hidpp10_constants.INFO_SUBREGISTERS
|
_IR = hidpp10_constants.INFO_SUBREGISTERS
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Pairing:
|
||||||
|
"""Information about the current or most recent pairing"""
|
||||||
|
|
||||||
|
lock_open: bool = False
|
||||||
|
discovering: bool = False
|
||||||
|
counter: Optional[int] = None
|
||||||
|
device_address: Optional[bytes] = None
|
||||||
|
device_authentication: Optional[int] = None
|
||||||
|
device_kind: Optional[int] = None
|
||||||
|
device_name: Optional[str] = None
|
||||||
|
device_passkey: Optional[str] = None
|
||||||
|
new_device: Optional[Device] = None
|
||||||
|
error: Optional[any] = None
|
||||||
|
|
||||||
|
|
||||||
class Receiver:
|
class Receiver:
|
||||||
"""A generic Receiver instance, mostly implementing the interface used on Unifying, Nano, and LightSpeed receivers"
|
"""A generic Receiver instance, mostly implementing the interface used on Unifying, Nano, and LightSpeed receivers"
|
||||||
The paired devices are available through the sequence interface.
|
The paired devices are available through the sequence interface.
|
||||||
|
@ -57,6 +74,8 @@ class Receiver:
|
||||||
self.name = product_info.get("name", "Receiver")
|
self.name = product_info.get("name", "Receiver")
|
||||||
self.may_unpair = product_info.get("may_unpair", False)
|
self.may_unpair = product_info.get("may_unpair", False)
|
||||||
self.re_pairs = product_info.get("re_pairs", False)
|
self.re_pairs = product_info.get("re_pairs", False)
|
||||||
|
self.notification_flags = None
|
||||||
|
self.pairing = Pairing()
|
||||||
self.initialize(product_info)
|
self.initialize(product_info)
|
||||||
|
|
||||||
def initialize(self, product_info: dict):
|
def initialize(self, product_info: dict):
|
||||||
|
|
|
@ -45,27 +45,26 @@ def attach_to(device, changed_callback):
|
||||||
|
|
||||||
|
|
||||||
class ReceiverStatus:
|
class ReceiverStatus:
|
||||||
"""The 'runtime' status of a receiver, mostly about the pairing process --
|
"""The 'runtime' status of a receiver, currently vestigial."""
|
||||||
is the pairing lock open or closed, any pairing errors, etc.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, receiver, changed_callback):
|
def __init__(self, receiver, changed_callback):
|
||||||
assert receiver
|
assert receiver
|
||||||
self._receiver = receiver
|
self._receiver = receiver
|
||||||
assert changed_callback
|
assert changed_callback
|
||||||
self._changed_callback = changed_callback
|
self._changed_callback = changed_callback
|
||||||
self.notification_flags = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
self.lock_open = False
|
# self.notification_flags = None
|
||||||
self.discovering = False
|
# self.error = None
|
||||||
self.counter = None
|
|
||||||
self.device_address = None
|
# self.lock_open = False
|
||||||
self.device_authentication = None
|
# self.discovering = False
|
||||||
self.device_kind = None
|
# self.counter = None
|
||||||
self.device_name = None
|
# self.device_address = None
|
||||||
self.device_passkey = None
|
# self.device_authentication = None
|
||||||
self.new_device = None
|
# self.device_kind = None
|
||||||
|
# self.device_name = None
|
||||||
|
# self.device_passkey = None
|
||||||
|
# self.new_device = None
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
count = len(self._receiver)
|
count = len(self._receiver)
|
||||||
|
@ -96,8 +95,8 @@ class DeviceStatus:
|
||||||
self._active = None # is the device active?
|
self._active = None # is the device active?
|
||||||
self.battery = None
|
self.battery = None
|
||||||
self.link_encrypted = None
|
self.link_encrypted = None
|
||||||
self.notification_flags = None
|
# self.notification_flags = None
|
||||||
self.error = None
|
self.battery_error = None
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return self.battery.to_str() if self.battery is not None else ""
|
return self.battery.to_str() if self.battery is not None else ""
|
||||||
|
@ -118,11 +117,11 @@ class DeviceStatus:
|
||||||
|
|
||||||
alert, reason = ALERT.NONE, None
|
alert, reason = ALERT.NONE, None
|
||||||
if info.ok():
|
if info.ok():
|
||||||
self.error = None
|
self.battery_error = None
|
||||||
else:
|
else:
|
||||||
logger.warning("%s: battery %d%%, ALERT %s", self._device, info.level, info.status)
|
logger.warning("%s: battery %d%%, ALERT %s", self._device, info.level, info.status)
|
||||||
if self.error != info.status:
|
if self.battery_error != info.status:
|
||||||
self.error = info.status
|
self.battery_error = info.status
|
||||||
alert = ALERT.NOTIFICATION | ALERT.ATTENTION
|
alert = ALERT.NOTIFICATION | ALERT.ATTENTION
|
||||||
reason = info.to_str()
|
reason = info.to_str()
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ class DeviceStatus:
|
||||||
# get cleared when the device is turned off (but not when the device
|
# get cleared when the device is turned off (but not when the device
|
||||||
# goes idle, and we can't tell the difference right now).
|
# goes idle, and we can't tell the difference right now).
|
||||||
if d.protocol < 2.0:
|
if d.protocol < 2.0:
|
||||||
self.notification_flags = d.enable_connection_notifications()
|
self._device.notification_flags = d.enable_connection_notifications()
|
||||||
# battery information may have changed so try to read it now
|
# battery information may have changed so try to read it now
|
||||||
self.read_battery()
|
self.read_battery()
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,10 @@ def run(receivers, args, find_receiver, _ignore):
|
||||||
kd, known_devices = known_devices, None # only process one connection notification
|
kd, known_devices = known_devices, None # only process one connection notification
|
||||||
if kd is not None:
|
if kd is not None:
|
||||||
if n.devnumber not in kd:
|
if n.devnumber not in kd:
|
||||||
receiver.status.new_device = receiver.register_new_device(n.devnumber, n)
|
receiver.pairing.new_device = receiver.register_new_device(n.devnumber, n)
|
||||||
elif receiver.re_pairs:
|
elif receiver.re_pairs:
|
||||||
del receiver[n.devnumber] # get rid of information on device re-paired away
|
del receiver[n.devnumber] # get rid of information on device re-paired away
|
||||||
receiver.status.new_device = receiver.register_new_device(n.devnumber, n)
|
receiver.pairing.new_device = receiver.register_new_device(n.devnumber, n)
|
||||||
|
|
||||||
timeout = 30 # seconds
|
timeout = 30 # seconds
|
||||||
receiver.handle = _HandleWithNotificationHook(receiver.handle)
|
receiver.handle = _HandleWithNotificationHook(receiver.handle)
|
||||||
|
@ -71,17 +71,17 @@ def run(receivers, args, find_receiver, _ignore):
|
||||||
print("Bolt Pairing: long-press the pairing key or button on your device (timing out in", timeout, "seconds).")
|
print("Bolt Pairing: long-press the pairing key or button on your device (timing out in", timeout, "seconds).")
|
||||||
pairing_start = _timestamp()
|
pairing_start = _timestamp()
|
||||||
patience = 5 # the discovering notification may come slightly later, so be patient
|
patience = 5 # the discovering notification may come slightly later, so be patient
|
||||||
while receiver.status.discovering or _timestamp() - pairing_start < patience:
|
while receiver.pairing.discovering or _timestamp() - pairing_start < patience:
|
||||||
if receiver.status.device_address and receiver.status.device_authentication and receiver.status.device_name:
|
if receiver.pairing.device_address and receiver.pairing.device_authentication and receiver.pairing.device_name:
|
||||||
break
|
break
|
||||||
n = _base.read(receiver.handle)
|
n = _base.read(receiver.handle)
|
||||||
n = _base.make_notification(*n) if n else None
|
n = _base.make_notification(*n) if n else None
|
||||||
if n:
|
if n:
|
||||||
receiver.handle.notifications_hook(n)
|
receiver.handle.notifications_hook(n)
|
||||||
address = receiver.status.device_address
|
address = receiver.pairing.device_address
|
||||||
name = receiver.status.device_name
|
name = receiver.pairing.device_name
|
||||||
authentication = receiver.status.device_authentication
|
authentication = receiver.pairing.device_authentication
|
||||||
kind = receiver.status.device_kind
|
kind = receiver.pairing.device_kind
|
||||||
print(f"Bolt Pairing: discovered {name}")
|
print(f"Bolt Pairing: discovered {name}")
|
||||||
receiver.pair_device(
|
receiver.pair_device(
|
||||||
address=address,
|
address=address,
|
||||||
|
@ -90,21 +90,21 @@ def run(receivers, args, find_receiver, _ignore):
|
||||||
)
|
)
|
||||||
pairing_start = _timestamp()
|
pairing_start = _timestamp()
|
||||||
patience = 5 # the discovering notification may come slightly later, so be patient
|
patience = 5 # the discovering notification may come slightly later, so be patient
|
||||||
while receiver.status.lock_open or _timestamp() - pairing_start < patience:
|
while receiver.pairing.lock_open or _timestamp() - pairing_start < patience:
|
||||||
if receiver.status.device_passkey:
|
if receiver.pairing.device_passkey:
|
||||||
break
|
break
|
||||||
n = _base.read(receiver.handle)
|
n = _base.read(receiver.handle)
|
||||||
n = _base.make_notification(*n) if n else None
|
n = _base.make_notification(*n) if n else None
|
||||||
if n:
|
if n:
|
||||||
receiver.handle.notifications_hook(n)
|
receiver.handle.notifications_hook(n)
|
||||||
if authentication & 0x01:
|
if authentication & 0x01:
|
||||||
print(f"Bolt Pairing: type passkey {receiver.status.device_passkey} and then press the enter key")
|
print(f"Bolt Pairing: type passkey {receiver.pairing.device_passkey} and then press the enter key")
|
||||||
else:
|
else:
|
||||||
passkey = f"{int(receiver.status.device_passkey):010b}"
|
passkey = f"{int(receiver.pairing.device_passkey):010b}"
|
||||||
passkey = ", ".join(["right" if bit == "1" else "left" for bit in passkey])
|
passkey = ", ".join(["right" if bit == "1" else "left" for bit in passkey])
|
||||||
print(f"Bolt Pairing: press {passkey}")
|
print(f"Bolt Pairing: press {passkey}")
|
||||||
print("and then press left and right buttons simultaneously")
|
print("and then press left and right buttons simultaneously")
|
||||||
while receiver.status.lock_open:
|
while receiver.pairing.lock_open:
|
||||||
n = _base.read(receiver.handle)
|
n = _base.read(receiver.handle)
|
||||||
n = _base.make_notification(*n) if n else None
|
n = _base.make_notification(*n) if n else None
|
||||||
if n:
|
if n:
|
||||||
|
@ -115,7 +115,7 @@ def run(receivers, args, find_receiver, _ignore):
|
||||||
print("Pairing: turn your new device on (timing out in", timeout, "seconds).")
|
print("Pairing: turn your new device on (timing out in", timeout, "seconds).")
|
||||||
pairing_start = _timestamp()
|
pairing_start = _timestamp()
|
||||||
patience = 5 # the lock-open notification may come slightly later, wait for it a bit
|
patience = 5 # the lock-open notification may come slightly later, wait for it a bit
|
||||||
while receiver.status.lock_open or _timestamp() - pairing_start < patience:
|
while receiver.pairing.lock_open or _timestamp() - pairing_start < patience:
|
||||||
n = _base.read(receiver.handle)
|
n = _base.read(receiver.handle)
|
||||||
if n:
|
if n:
|
||||||
n = _base.make_notification(*n)
|
n = _base.make_notification(*n)
|
||||||
|
@ -127,11 +127,11 @@ def run(receivers, args, find_receiver, _ignore):
|
||||||
# concurrently running Solaar app might stop working properly
|
# concurrently running Solaar app might stop working properly
|
||||||
_hidpp10.set_notification_flags(receiver, old_notification_flags)
|
_hidpp10.set_notification_flags(receiver, old_notification_flags)
|
||||||
|
|
||||||
if receiver.status.new_device:
|
if receiver.pairing.new_device:
|
||||||
dev = receiver.status.new_device
|
dev = receiver.pairing.new_device
|
||||||
print("Paired device %d: %s (%s) [%s:%s]" % (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
|
print("Paired device %d: %s (%s) [%s:%s]" % (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
|
||||||
else:
|
else:
|
||||||
error = receiver.status.get(_status.error)
|
error = receiver.pairing.error
|
||||||
if error:
|
if error:
|
||||||
raise Exception("pairing failed: %s" % error)
|
raise Exception("pairing failed: %s" % error)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -188,12 +188,12 @@ class ReceiverListener(_listener.EventsListener):
|
||||||
if self.receiver.read_register(_R.receiver_info, _IR.pairing_information + n.devnumber - 1) is None:
|
if self.receiver.read_register(_R.receiver_info, _IR.pairing_information + n.devnumber - 1) is None:
|
||||||
return
|
return
|
||||||
dev = self.receiver.register_new_device(n.devnumber, n)
|
dev = self.receiver.register_new_device(n.devnumber, n)
|
||||||
elif self.receiver.status.lock_open and self.receiver.re_pairs and not ord(n.data[0:1]) & 0x40:
|
elif self.receiver.pairing.lock_open and self.receiver.re_pairs and not ord(n.data[0:1]) & 0x40:
|
||||||
dev = self.receiver[n.devnumber]
|
dev = self.receiver[n.devnumber]
|
||||||
del self.receiver[n.devnumber] # get rid of information on device re-paired away
|
del self.receiver[n.devnumber] # get rid of information on device re-paired away
|
||||||
self._status_changed(dev) # signal that this device has changed
|
self._status_changed(dev) # signal that this device has changed
|
||||||
dev = self.receiver.register_new_device(n.devnumber, n)
|
dev = self.receiver.register_new_device(n.devnumber, n)
|
||||||
self.receiver.status.new_device = self.receiver[n.devnumber]
|
self.receiver.pairing.new_device = self.receiver[n.devnumber]
|
||||||
else:
|
else:
|
||||||
dev = self.receiver[n.devnumber]
|
dev = self.receiver[n.devnumber]
|
||||||
else:
|
else:
|
||||||
|
@ -224,12 +224,13 @@ class ReceiverListener(_listener.EventsListener):
|
||||||
else:
|
else:
|
||||||
_notifications.process(dev, n)
|
_notifications.process(dev, n)
|
||||||
|
|
||||||
if self.receiver.status.lock_open and not already_known:
|
if self.receiver.pairing.lock_open and not already_known:
|
||||||
# this should be the first notification after a device was paired
|
# this should be the first notification after a device was paired
|
||||||
assert n.sub_id == 0x41, "first notification was not a connection notification"
|
if logger.isEnabledFor(logging.WARNING):
|
||||||
|
logger.warning("first notification was not a connection notification")
|
||||||
if logger.isEnabledFor(logging.INFO):
|
if logger.isEnabledFor(logging.INFO):
|
||||||
logger.info("%s: pairing detected new device", self.receiver)
|
logger.info("%s: pairing detected new device", self.receiver)
|
||||||
self.receiver.status.new_device = dev
|
self.receiver.pairing.new_device = dev
|
||||||
elif dev.online is None:
|
elif dev.online is None:
|
||||||
dev.ping()
|
dev.ping()
|
||||||
|
|
||||||
|
|
|
@ -71,23 +71,23 @@ def _check_lock_state(assistant, receiver, count=2):
|
||||||
logger.debug("assistant %s destroyed, bailing out", assistant)
|
logger.debug("assistant %s destroyed, bailing out", assistant)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiver.status.error:
|
if receiver.pairing.error:
|
||||||
# receiver.status.new_device = _fake_device(receiver)
|
# receiver.pairing.new_device = _fake_device(receiver)
|
||||||
_pairing_failed(assistant, receiver, receiver.status.error)
|
_pairing_failed(assistant, receiver, receiver.pairing.error)
|
||||||
receiver.status.error = None
|
receiver.pairing.error = None
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiver.status.new_device:
|
if receiver.pairing.new_device:
|
||||||
receiver.remaining_pairings(False) # Update remaining pairings
|
receiver.remaining_pairings(False) # Update remaining pairings
|
||||||
device, receiver.status.new_device = receiver.status.new_device, None
|
device, receiver.pairing.new_device = receiver.pairing.new_device, None
|
||||||
_pairing_succeeded(assistant, receiver, device)
|
_pairing_succeeded(assistant, receiver, device)
|
||||||
return False
|
return False
|
||||||
elif receiver.status.device_address and receiver.status.device_name and not address:
|
elif receiver.pairing.device_address and receiver.pairing.device_name and not address:
|
||||||
address = receiver.status.device_address
|
address = receiver.pairing.device_address
|
||||||
name = receiver.status.device_name
|
name = receiver.pairing.device_name
|
||||||
kind = receiver.status.device_kind
|
kind = receiver.pairing.device_kind
|
||||||
authentication = receiver.status.device_authentication
|
authentication = receiver.pairing.device_authentication
|
||||||
name = receiver.status.device_name
|
name = receiver.pairing.device_name
|
||||||
entropy = 10
|
entropy = 10
|
||||||
if kind == _hidpp10_constants.DEVICE_KIND.keyboard:
|
if kind == _hidpp10_constants.DEVICE_KIND.keyboard:
|
||||||
entropy = 20
|
entropy = 20
|
||||||
|
@ -100,12 +100,12 @@ def _check_lock_state(assistant, receiver, count=2):
|
||||||
else:
|
else:
|
||||||
_pairing_failed(assistant, receiver, "failed to open pairing lock")
|
_pairing_failed(assistant, receiver, "failed to open pairing lock")
|
||||||
return False
|
return False
|
||||||
elif address and receiver.status.device_passkey and not passcode:
|
elif address and receiver.pairing.device_passkey and not passcode:
|
||||||
passcode = receiver.status.device_passkey
|
passcode = receiver.pairing.device_passkey
|
||||||
_show_passcode(assistant, receiver, passcode)
|
_show_passcode(assistant, receiver, passcode)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not receiver.status.lock_open and not receiver.status.discovering:
|
if not receiver.pairing.lock_open and not receiver.pairing.discovering:
|
||||||
if count > 0:
|
if count > 0:
|
||||||
# the actual device notification may arrive later so have a little patience
|
# the actual device notification may arrive later so have a little patience
|
||||||
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver, count - 1)
|
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver, count - 1)
|
||||||
|
@ -119,16 +119,16 @@ def _check_lock_state(assistant, receiver, count=2):
|
||||||
def _show_passcode(assistant, receiver, passkey):
|
def _show_passcode(assistant, receiver, passkey):
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("%s show passkey: %s", receiver, passkey)
|
logger.debug("%s show passkey: %s", receiver, passkey)
|
||||||
name = receiver.status.device_name
|
name = receiver.pairing.device_name
|
||||||
authentication = receiver.status.device_authentication
|
authentication = receiver.pairing.device_authentication
|
||||||
intro_text = _("%(receiver_name)s: pair new device") % {"receiver_name": receiver.name}
|
intro_text = _("%(receiver_name)s: pair new device") % {"receiver_name": receiver.name}
|
||||||
page_text = _("Enter passcode on %(name)s.") % {"name": name}
|
page_text = _("Enter passcode on %(name)s.") % {"name": name}
|
||||||
page_text += "\n"
|
page_text += "\n"
|
||||||
if authentication & 0x01:
|
if authentication & 0x01:
|
||||||
page_text += _("Type %(passcode)s and then press the enter key.") % {"passcode": receiver.status.device_passkey}
|
page_text += _("Type %(passcode)s and then press the enter key.") % {"passcode": receiver.pairing.device_passkey}
|
||||||
else:
|
else:
|
||||||
passcode = ", ".join(
|
passcode = ", ".join(
|
||||||
[_("right") if bit == "1" else _("left") for bit in f"{int(receiver.status.device_passkey):010b}"]
|
[_("right") if bit == "1" else _("left") for bit in f"{int(receiver.pairing.device_passkey):010b}"]
|
||||||
)
|
)
|
||||||
page_text += _("Press %(code)s\nand then press left and right buttons simultaneously.") % {"code": passcode}
|
page_text += _("Press %(code)s\nand then press left and right buttons simultaneously.") % {"code": passcode}
|
||||||
page = _create_page(assistant, Gtk.AssistantPageType.PROGRESS, intro_text, "preferences-desktop-peripherals", page_text)
|
page = _create_page(assistant, Gtk.AssistantPageType.PROGRESS, intro_text, "preferences-desktop-peripherals", page_text)
|
||||||
|
@ -144,8 +144,8 @@ def _prepare(assistant, page, receiver):
|
||||||
if index == 0:
|
if index == 0:
|
||||||
if receiver.receiver_kind == "bolt":
|
if receiver.receiver_kind == "bolt":
|
||||||
if receiver.discover(timeout=_PAIRING_TIMEOUT):
|
if receiver.discover(timeout=_PAIRING_TIMEOUT):
|
||||||
assert receiver.status.new_device is None
|
assert receiver.pairing.new_device is None
|
||||||
assert receiver.status.error is None
|
assert receiver.pairing.error is None
|
||||||
spinner = page.get_children()[-1]
|
spinner = page.get_children()[-1]
|
||||||
spinner.start()
|
spinner.start()
|
||||||
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver)
|
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver)
|
||||||
|
@ -153,8 +153,8 @@ def _prepare(assistant, page, receiver):
|
||||||
else:
|
else:
|
||||||
GLib.idle_add(_pairing_failed, assistant, receiver, "discovery did not start")
|
GLib.idle_add(_pairing_failed, assistant, receiver, "discovery did not start")
|
||||||
elif receiver.set_lock(False, timeout=_PAIRING_TIMEOUT):
|
elif receiver.set_lock(False, timeout=_PAIRING_TIMEOUT):
|
||||||
assert receiver.status.new_device is None
|
assert receiver.pairing.new_device is None
|
||||||
assert receiver.status.error is None
|
assert receiver.pairing.error is None
|
||||||
spinner = page.get_children()[-1]
|
spinner = page.get_children()[-1]
|
||||||
spinner.start()
|
spinner.start()
|
||||||
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver)
|
GLib.timeout_add(_STATUS_CHECK, _check_lock_state, assistant, receiver)
|
||||||
|
@ -169,16 +169,16 @@ def _finish(assistant, receiver):
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("finish %s", assistant)
|
logger.debug("finish %s", assistant)
|
||||||
assistant.destroy()
|
assistant.destroy()
|
||||||
receiver.status.new_device = None
|
receiver.pairing.new_device = None
|
||||||
if receiver.status.lock_open:
|
if receiver.pairing.lock_open:
|
||||||
if receiver.receiver_kind == "bolt":
|
if receiver.receiver_kind == "bolt":
|
||||||
receiver.pair_device("cancel")
|
receiver.pair_device("cancel")
|
||||||
else:
|
else:
|
||||||
receiver.set_lock()
|
receiver.set_lock()
|
||||||
if receiver.status.discovering:
|
if receiver.pairing.discovering:
|
||||||
receiver.discover(True)
|
receiver.discover(True)
|
||||||
if not receiver.status.lock_open and not receiver.status.discovering:
|
if not receiver.pairing.lock_open and not receiver.pairing.discovering:
|
||||||
receiver.status.error = None
|
receiver.pairing.error = None
|
||||||
|
|
||||||
|
|
||||||
def _pairing_failed(assistant, receiver, error):
|
def _pairing_failed(assistant, receiver, error):
|
||||||
|
|
|
@ -573,7 +573,7 @@ def _update_details(button):
|
||||||
elif device.kind is None or device.online:
|
elif device.kind is None or device.online:
|
||||||
yield (" %s" % _("Firmware"), "...")
|
yield (" %s" % _("Firmware"), "...")
|
||||||
|
|
||||||
flag_bits = device.status.notification_flags
|
flag_bits = device.notification_flags
|
||||||
if flag_bits is not None:
|
if flag_bits is not None:
|
||||||
flag_names = (
|
flag_names = (
|
||||||
("(%s)" % _("none"),) if flag_bits == 0 else _hidpp10_constants.NOTIFICATION_FLAG.flag_names(flag_bits)
|
("(%s)" % _("none"),) if flag_bits == 0 else _hidpp10_constants.NOTIFICATION_FLAG.flag_names(flag_bits)
|
||||||
|
@ -648,7 +648,7 @@ def _update_receiver_panel(receiver, panel, buttons, full=False):
|
||||||
|
|
||||||
panel._count.set_markup(paired_text)
|
panel._count.set_markup(paired_text)
|
||||||
|
|
||||||
is_pairing = receiver.status.lock_open
|
is_pairing = receiver.pairing.lock_open
|
||||||
if is_pairing:
|
if is_pairing:
|
||||||
panel._scanning.set_visible(True)
|
panel._scanning.set_visible(True)
|
||||||
if not panel._spinner.get_visible():
|
if not panel._spinner.get_visible():
|
||||||
|
@ -872,7 +872,7 @@ def update(device, need_popup=False, refresh=False):
|
||||||
|
|
||||||
if is_alive and item:
|
if is_alive and item:
|
||||||
was_pairing = bool(_model.get_value(item, _COLUMN.STATUS_ICON))
|
was_pairing = bool(_model.get_value(item, _COLUMN.STATUS_ICON))
|
||||||
is_pairing = (not device.isDevice) and bool(device.status.lock_open)
|
is_pairing = (not device.isDevice) and bool(device.pairing.lock_open)
|
||||||
_model.set_value(item, _COLUMN.STATUS_ICON, "network-wireless" if is_pairing else _CAN_SET_ROW_NONE)
|
_model.set_value(item, _COLUMN.STATUS_ICON, "network-wireless" if is_pairing else _CAN_SET_ROW_NONE)
|
||||||
|
|
||||||
if selected_device_id == (device.path, 0):
|
if selected_device_id == (device.path, 0):
|
||||||
|
|
Loading…
Reference in New Issue