diff --git a/tuhi.py b/tuhi.py index 5f41da7..a8b320e 100755 --- a/tuhi.py +++ b/tuhi.py @@ -142,6 +142,7 @@ class Tuhi(GObject.Object): self.server.connect('pairing-stop-requested', self._on_stop_pairing_requested) self.bluez = BlueZDeviceManager() self.bluez.connect('device-added', self._on_bluez_device_added) + self.bluez.connect('device-updated', self._on_bluez_device_updated) self.devices = {} @@ -149,10 +150,12 @@ class Tuhi(GObject.Object): self.bluez.connect_to_bluez() def _on_start_pairing_requested(self, dbus_server, stop_handler, device_handler): + self._pairable_device_handler = device_handler self.bluez.start_discovery(stop_handler=stop_handler, timeout=30) def _on_stop_pairing_requested(self, dbus_server): self.bluez.stop_discovery() + self._pairable_device_handler = None @classmethod def _is_pairing_device(cls, bluez_device): @@ -173,6 +176,14 @@ class Tuhi(GObject.Object): d = TuhiDevice(bluez_device, tuhi_dbus_device) self.devices[bluez_device.address] = d + def _on_bluez_device_updated(self, manager, bluez_device): + if bluez_device.vendor_id != WACOM_COMPANY_ID: + return + + if (Tuhi._is_pairing_device(bluez_device) and + self._pairable_device_handler is not None): + self._pairable_device_handler(bluez_device) + def main(args): desc = "Daemon to extract the pen stroke data from Wacom SmartPad devices" diff --git a/tuhi/ble.py b/tuhi/ble.py index 1f0e01d..4d26e3d 100755 --- a/tuhi/ble.py +++ b/tuhi/ble.py @@ -95,6 +95,8 @@ class BlueZDevice(GObject.Object): (GObject.SIGNAL_RUN_FIRST, None, ()), "disconnected": (GObject.SIGNAL_RUN_FIRST, None, ()), + "updated": + (GObject.SIGNAL_RUN_FIRST, None, ()), } def __init__(self, om, obj): @@ -237,6 +239,8 @@ class BlueZDevice(GObject.Object): elif 'ServicesResolved' in properties: if properties['ServicesResolved']: self.emit('connected') + elif 'RSSI' in properties: + self.emit('updated') def connect_gatt_value(self, uuid, callback): """ @@ -262,6 +266,8 @@ class BlueZDeviceManager(GObject.Object): __gsignals__ = { "device-added": (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), + "device-updated": + (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), } def __init__(self, **kwargs): @@ -333,6 +339,12 @@ class BlueZDeviceManager(GObject.Object): except GLib.Error as e: logger.debug('{}: Failed to stop discovery ({})'.format(objpath, e)) + def _on_device_updated(self, device): + """Callback for Device's properties-changed""" + logger.debug('Object updated: {}'.format(device.name)) + + self.emit("device-updated", device) + def _on_om_object_added(self, om, obj): """Callback for ObjectManager's object-added""" objpath = obj.get_object_path() @@ -366,11 +378,11 @@ class BlueZDeviceManager(GObject.Object): def _process_adapter(self, obj): objpath = obj.get_object_path() logger.debug('Adapter: {}'.format(objpath)) - # FIXME: call StartDiscovery if we want to pair def _process_device(self, obj): dev = BlueZDevice(self._om, obj) self.devices.append(dev) + dev.connect("updated", self._on_device_updated) self.emit("device-added", dev) def _process_characteristic(self, obj): diff --git a/tuhi/dbusserver.py b/tuhi/dbusserver.py index 09b89ba..cc30836 100755 --- a/tuhi/dbusserver.py +++ b/tuhi/dbusserver.py @@ -36,6 +36,10 @@ INTROSPECTION_XML = """ + + + + @@ -163,6 +167,7 @@ class TuhiDBusServer(GObject.Object): def __init__(self): GObject.Object.__init__(self) self._devices = [] + self._pairable_devices = {} self._dbus = Gio.bus_own_name(Gio.BusType.SESSION, BUS_NAME, Gio.BusNameOwnerFlags.NONE, @@ -228,11 +233,36 @@ class TuhiDBusServer(GObject.Object): self._connection.emit_signal(None, BASE_PATH, INTF_MANAGER, "PairingStopped", status) + self._pairable_devices = {} + def _on_pairable_device(self, device): """ Called by whoever handles the pairing-start-requested signal """ - logger.DEBUG("Pairable device: {}".format(device)) + logger.debug("Pairable device: {}".format(device)) + + address = device.address + if address in self._pairable_devices: + return + + self._pairable_devices[address] = device + + b = GLib.VariantBuilder(GLib.VariantType.new('a{sv}')) + + key = GLib.Variant.new_string('name') + value = GLib.Variant.new_variant(GLib.Variant.new_string(device.name)) + de = GLib.Variant.new_dict_entry(key, value) + b.add_value(de) + + key = GLib.Variant.new_string('address') + value = GLib.Variant.new_variant(GLib.Variant.new_string(device.address)) + de = GLib.Variant.new_dict_entry(key, value) + b.add_value(de) + + array = b.end() + self._connection.emit_signal(None, BASE_PATH, INTF_MANAGER, + "PairableDevice", + GLib.Variant.new_tuple(array)) def cleanup(self): Gio.bus_unown_name(self._dbus)