From 4b9b3d02c9e749d4e9ed99ee47ebcd7fc1b27d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 30 Sep 2015 13:08:05 +0200 Subject: [PATCH] supplicant: fix BSSs property type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BSSs property is an array of object paths, not strings. Signed-off-by: Jiří Klimeš --- src/supplicant-manager/nm-supplicant-interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 08b850a..7d33db4 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -556,7 +556,7 @@ props_changed_cb (GDBusProxy *proxy, set_state_from_string (self, s); } - if (g_variant_lookup (changed_properties, "BSSs", "^a&s", &array)) { + if (g_variant_lookup (changed_properties, "BSSs", "^a&o", &array)) { iter = array; while (*iter) handle_new_bss (self, *iter++); -- 2.1.0 From 1649fb2928cedb7512888e3856d8a742ea40916b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 30 Sep 2015 17:05:40 +0200 Subject: [PATCH] wifi: emit NEW_BSS on ScanDone to update APs in Wi-Fi device (rh #1267327) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a Wi-Fi is switched to AP mode, NMDeviceWifi forgets the AP scan list. Later, when the device goes back to normal managed mode, the device was not able to acquire the AP list again (for a long time), because the list is only populated when a new BSS is signalled. And that could take very long or never happen as the supplicant would have to lost the BSS and announce it later. Fix the problem by announcing known BSSs as a response to ScanDone signal. Testcase: $ nmcli con add type wifi ifname wlan0 con-name my-wifi-ap autoconnect off ssid MYSSID $ nmcli con modify my-wifi-ap wifi.mode ap ipv4.method shared $ nmcli con up my-wifi-ap $ nmcli con down my-wifi-ap $ nmcli device wifi list https://bugzilla.redhat.com/show_bug.cgi?id=1267327 Signed-off-by: Jiří Klimeš --- src/supplicant-manager/nm-supplicant-interface.c | 62 ++++++++++++++++++------ 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 7d33db4..30be23a 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -128,16 +128,36 @@ bss_props_changed_cb (GDBusProxy *proxy, changed_properties); } +static GVariant * +_get_bss_proxy_properties (NMSupplicantInterface *self, GDBusProxy *proxy) +{ + gs_strfreev char **properties = NULL; + GVariantBuilder builder; + char **iter; + + iter = properties = g_dbus_proxy_get_cached_property_names (proxy); + if (!iter) + return NULL; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + while (*iter) { + GVariant *copy = g_dbus_proxy_get_cached_property (proxy, *iter); + + g_variant_builder_add (&builder, "{sv}", *iter++, copy); + g_variant_unref (copy); + } + + return g_variant_builder_end (&builder); +} + +#define BSS_PROXY_INITED "bss-proxy-inited" + static void on_bss_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) { NMSupplicantInterface *self; - NMSupplicantInterfacePrivate *priv; gs_free_error GError *error = NULL; - gs_strfreev char **properties = NULL; gs_unref_variant GVariant *props = NULL; - GVariantBuilder builder; - char **iter; if (!g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error)) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { @@ -149,19 +169,12 @@ on_bss_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_da } self = NM_SUPPLICANT_INTERFACE (user_data); - priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - - iter = properties = g_dbus_proxy_get_cached_property_names (proxy); - while (iter && *iter) { - GVariant *copy = g_dbus_proxy_get_cached_property (proxy, *iter); + props = _get_bss_proxy_properties (self, proxy); + if (!props) + return; - g_variant_builder_add (&builder, "{sv}", *iter++, copy); - g_variant_unref (copy); - } + g_object_set_data (G_OBJECT (proxy), BSS_PROXY_INITED, GUINT_TO_POINTER (TRUE)); - props = g_variant_builder_end (&builder); g_signal_emit (self, signals[NEW_BSS], 0, g_dbus_proxy_get_object_path (proxy), g_variant_ref_sink (props)); @@ -508,11 +521,30 @@ signal_cb (GDBusProxy *proxy, gboolean success; if (MATCH_SIGNAL (signal, "ScanDone", args, G_VARIANT_TYPE ("(b)"))) { + GVariant *props; + GHashTableIter iter; + char *bss_path; + GDBusProxy *bss_proxy; + /* Cache last scan completed time */ priv->last_scan = nm_utils_get_monotonic_timestamp_s (); g_variant_get (args, "(b)", &success); g_signal_emit (self, signals[SCAN_DONE], 0, success); + + /* Emit NEW_BSS so that wifi device has the APs (in case it removed them) */ + g_hash_table_iter_init (&iter, priv->bss_proxies); + while (g_hash_table_iter_next (&iter, (gpointer) &bss_path, (gpointer) &bss_proxy)) { + if (g_object_get_data (G_OBJECT (bss_proxy), BSS_PROXY_INITED)) { + props = _get_bss_proxy_properties (self, bss_proxy); + if (props) { + g_signal_emit (self, signals[NEW_BSS], 0, + bss_path, + g_variant_ref_sink (props)); + g_variant_unref (props); + } + } + } } else if (MATCH_SIGNAL (signal, "BSSAdded", args, G_VARIANT_TYPE ("(oa{sv})"))) { if (priv->scanning) priv->last_scan = nm_utils_get_monotonic_timestamp_s (); -- 2.1.0