diff options
author | Dan Williams <dcbw@redhat.com> | 2014-07-03 18:12:13 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2014-07-03 18:50:41 -0500 |
commit | a949c38d8e247d16ec99f14c53b2781e71de6dcf (patch) | |
tree | 6a4a8e9fe5290c827f13090475f6afd5297e4a52 | |
parent | 3ee9c3be57610e613a57f585f15a9afd2a2b4999 (diff) | |
download | NetworkManager-a949c38d8e247d16ec99f14c53b2781e71de6dcf.tar.gz |
bluez: handle Bluez4 PropertyChanged events
The addition of Bluez5 support mistakenly broke support for Bluez4 property
change events. Bluez4 uses a custom D-Bus interface that we must explicitly
handle.
This caused NM to ignore BT devices immediately after pairing, since the UUIDs
only show up through a custom Bluez4 PropertyChanged even when pairing is
complete. Only then do we finally know priv->capabilities, and only then is
the NMBluezDevice usable.
-rw-r--r-- | src/devices/bluetooth/nm-bluez-device.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 5630727b7e..f493b77bcb 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -761,6 +761,23 @@ adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) } static void +_take_one_variant_property (NMBluezDevice *self, const char *property, GVariant *v) +{ + if (v) { + if (!g_strcmp0 (property, "Address")) + _take_variant_property_address (self, v); + else if (!g_strcmp0 (property, "Connected")) + _take_variant_property_connected (self, v); + else if (!g_strcmp0 (property, "Name")) + _take_variant_property_name (self, v); + else if (!g_strcmp0 (property, "UUIDs")) + _take_variant_property_uuids (self, v); + else + g_variant_unref (v); + } +} + +static void _set_properties (NMBluezDevice *self, GVariant *properties) { GVariantIter i; @@ -769,20 +786,8 @@ _set_properties (NMBluezDevice *self, GVariant *properties) g_object_freeze_notify (G_OBJECT (self)); g_variant_iter_init (&i, properties); - while (g_variant_iter_next (&i, "{&sv}", &property, &v)) { - if (!property) { - g_variant_unref (v); - } else if (!strcmp (property, "Address")) { - _take_variant_property_address (self, v); - } else if (!strcmp (property, "Connected")) { - _take_variant_property_connected (self, v); - } else if (!strcmp (property, "Name")) { - _take_variant_property_name (self, v); - } else if (!strcmp (property, "UUIDs")) { - _take_variant_property_uuids (self, v); - } else - g_variant_unref (v); - } + while (g_variant_iter_next (&i, "{&sv}", &property, &v)) + _take_one_variant_property (self, property, v); g_object_thaw_notify (G_OBJECT (self)); } @@ -795,10 +800,27 @@ properties_changed (GDBusProxy *proxy, NMBluezDevice *self = NM_BLUEZ_DEVICE (user_data); _set_properties (self, changed_properties); - check_emit_usable (self); } +static void +bluez4_property_changed (GDBusProxy *proxy, + const char *sender, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMBluezDevice *self = NM_BLUEZ_DEVICE (user_data); + + if (g_strcmp0 (signal_name, "PropertyChanged") == 0) { + const char *property = NULL; + GVariant *v = NULL; + + g_variant_get (parameters, "(&sv)", &property, &v); + _take_one_variant_property (self, property, v); + check_emit_usable (self); + } +} static void get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_data) @@ -843,7 +865,6 @@ END: g_object_unref (self); } - static void query_properties (NMBluezDevice *self) { @@ -903,6 +924,11 @@ on_proxy_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self) } else { g_signal_connect (priv->proxy, "g-properties-changed", G_CALLBACK (properties_changed), self); + if (priv->bluez_version == 4) { + /* Watch for custom Bluez4 PropertyChanged signals */ + g_signal_connect (priv->proxy, "g-signal", + G_CALLBACK (bluez4_property_changed), self); + } query_properties (self); } @@ -1050,6 +1076,8 @@ finalize (GObject *object) g_free (priv->name); g_free (priv->bt_iface); + if (priv->proxy) + g_signal_handlers_disconnect_by_data (priv->proxy, object); g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_bluez_device_parent_class)->finalize (object); |