tuhi: handle cold-plugged devices

When bluez restarts (or the tuhi daemon restarts), the values we have
in the bluez device's field ManufacturerData are quite not accurate.

When bluez restarts they are empty, and if the last time we saw the
device was for the pairing process, the device will still be marked
as in the pairing mode.

So we should mark the cold-plug sequence differently from the hot-plug
one, and we should be more confident in the current configuration we
have stored to export the currently known devices over dbus.

Fixes #13
This commit is contained in:
Benjamin Tissoires 2018-01-22 10:39:23 +01:00 committed by Peter Hutterer
parent ea890958d6
commit ca82af78de
2 changed files with 26 additions and 16 deletions

28
tuhi.py
View File

@ -253,18 +253,28 @@ class Tuhi(GObject.Object):
# restart discovery if some users are already in the listening mode
self._on_listening_updated(None, None)
def _on_bluez_device_updated(self, manager, bluez_device):
if bluez_device.vendor_id != WACOM_COMPANY_ID:
return
pairing_device = Tuhi._is_pairing_device(bluez_device)
def _on_bluez_device_updated(self, manager, bluez_device, event=True):
uuid = None
# check if the device is already known by us
try:
config = self.config.devices[bluez_device.address]
uuid = config['uuid']
except KeyError:
pass
if uuid is None and bluez_device.vendor_id != WACOM_COMPANY_ID:
return
# if event is set, the device has been 'hotplugged' in the bluez stack
# so ManufacturerData is reliable. Else, consider the device not in
# the pairing mode
pairing_device = False
if event:
pairing_device = Tuhi._is_pairing_device(bluez_device)
if not pairing_device:
try:
config = self.config.devices[bluez_device.address]
uuid = config['uuid']
except KeyError:
if uuid is None:
logger.info('{}: device without config, must be paired first'.format(bluez_device.address))
return
logger.debug('{}: UUID {}'.format(bluez_device.address, uuid))

View File

@ -265,7 +265,7 @@ class BlueZDeviceManager(GObject.Object):
"""
__gsignals__ = {
"device-added":
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT, GObject.TYPE_BOOLEAN)),
"device-updated":
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
"discovery-started":
@ -300,7 +300,7 @@ class BlueZDeviceManager(GObject.Object):
# object path length and process them in order, this way we're
# guaranteed that the objects we need already exist.
for obj in self._om.get_objects():
self._process_object(obj)
self._process_object(obj, event=False)
def _discovery_timeout_expired(self):
self.stop_discovery()
@ -382,7 +382,7 @@ class BlueZDeviceManager(GObject.Object):
"""Callback for ObjectManager's object-added"""
objpath = obj.get_object_path()
logger.debug('Object added: {}'.format(objpath))
needs_resolve = self._process_object(obj)
needs_resolve = self._process_object(obj, event=True)
# we had at least one characteristic added, need to resolve the
# devices.
@ -396,13 +396,13 @@ class BlueZDeviceManager(GObject.Object):
objpath = obj.get_object_path()
logger.debug('Object removed: {}'.format(objpath))
def _process_object(self, obj):
def _process_object(self, obj, event=True):
"""Process a single DBusProxyObject"""
if obj.get_interface(ORG_BLUEZ_ADAPTER1) is not None:
self._process_adapter(obj)
elif obj.get_interface(ORG_BLUEZ_DEVICE1) is not None:
self._process_device(obj)
self._process_device(obj, event)
elif obj.get_interface(ORG_BLUEZ_GATTCHARACTERISTIC1) is not None:
return True
@ -412,11 +412,11 @@ class BlueZDeviceManager(GObject.Object):
objpath = obj.get_object_path()
logger.debug('Adapter: {}'.format(objpath))
def _process_device(self, obj):
def _process_device(self, obj, event=True):
dev = BlueZDevice(self._om, obj)
self.devices.append(dev)
dev.connect("updated", self._on_device_updated)
self.emit("device-added", dev)
self.emit("device-added", dev, event)
def _process_characteristic(self, obj):
objpath = obj.get_object_path()