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.
This commit is contained in:
@@ -760,6 +760,23 @@ adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
|
|||||||
g_object_unref (self);
|
g_object_unref (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
|
static void
|
||||||
_set_properties (NMBluezDevice *self, GVariant *properties)
|
_set_properties (NMBluezDevice *self, GVariant *properties)
|
||||||
{
|
{
|
||||||
@@ -769,20 +786,8 @@ _set_properties (NMBluezDevice *self, GVariant *properties)
|
|||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
g_variant_iter_init (&i, properties);
|
g_variant_iter_init (&i, properties);
|
||||||
while (g_variant_iter_next (&i, "{&sv}", &property, &v)) {
|
while (g_variant_iter_next (&i, "{&sv}", &property, &v))
|
||||||
if (!property) {
|
_take_one_variant_property (self, property, v);
|
||||||
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);
|
|
||||||
}
|
|
||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,10 +800,27 @@ properties_changed (GDBusProxy *proxy,
|
|||||||
NMBluezDevice *self = NM_BLUEZ_DEVICE (user_data);
|
NMBluezDevice *self = NM_BLUEZ_DEVICE (user_data);
|
||||||
|
|
||||||
_set_properties (self, changed_properties);
|
_set_properties (self, changed_properties);
|
||||||
|
|
||||||
check_emit_usable (self);
|
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
|
static void
|
||||||
get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
get_properties_cb_4 (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
@@ -843,7 +865,6 @@ END:
|
|||||||
g_object_unref (self);
|
g_object_unref (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
query_properties (NMBluezDevice *self)
|
query_properties (NMBluezDevice *self)
|
||||||
{
|
{
|
||||||
@@ -903,6 +924,11 @@ on_proxy_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
|
|||||||
} else {
|
} else {
|
||||||
g_signal_connect (priv->proxy, "g-properties-changed",
|
g_signal_connect (priv->proxy, "g-properties-changed",
|
||||||
G_CALLBACK (properties_changed), self);
|
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);
|
query_properties (self);
|
||||||
}
|
}
|
||||||
@@ -1050,6 +1076,8 @@ finalize (GObject *object)
|
|||||||
g_free (priv->name);
|
g_free (priv->name);
|
||||||
g_free (priv->bt_iface);
|
g_free (priv->bt_iface);
|
||||||
|
|
||||||
|
if (priv->proxy)
|
||||||
|
g_signal_handlers_disconnect_by_data (priv->proxy, object);
|
||||||
g_clear_object (&priv->proxy);
|
g_clear_object (&priv->proxy);
|
||||||
|
|
||||||
G_OBJECT_CLASS (nm_bluez_device_parent_class)->finalize (object);
|
G_OBJECT_CLASS (nm_bluez_device_parent_class)->finalize (object);
|
||||||
|
Reference in New Issue
Block a user