summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2015-03-03 15:00:14 -0600
committerDan Williams <dcbw@redhat.com>2015-03-03 15:00:14 -0600
commit19c0de8b888910a006a092699d835c689bc24132 (patch)
treebfefaa21c99ed9f25129ae7ef8c41a6775a969e3
parent0681b625fbb80879a9c656aa452beae18c950be9 (diff)
parent9adbc05e1b035bdee3cacd66f4861ae4993bfa60 (diff)
downloadNetworkManager-19c0de8b888910a006a092699d835c689bc24132.tar.gz
merge: replace usage of dbus-glib in supplicant code with GDBus (bgo #744598)
-rw-r--r--src/Makefile.am2
-rw-r--r--src/devices/wifi/nm-device-wifi.c4
-rw-r--r--src/devices/wifi/nm-wifi-ap.c229
-rw-r--r--src/devices/wifi/nm-wifi-ap.h2
-rw-r--r--src/supplicant-manager/nm-call-store.c119
-rw-r--r--src/supplicant-manager/nm-call-store.h41
-rw-r--r--src/supplicant-manager/nm-supplicant-config.c85
-rw-r--r--src/supplicant-manager/nm-supplicant-config.h2
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c1497
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.h6
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.c261
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.h9
-rw-r--r--src/supplicant-manager/nm-supplicant-types.h4
-rw-r--r--src/supplicant-manager/tests/test-supplicant-config.c233
14 files changed, 1025 insertions, 1469 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ead105de4a..64aa9dd485 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -275,8 +275,6 @@ nm_sources = \
supplicant-manager/nm-supplicant-settings-verify.c \
supplicant-manager/nm-supplicant-settings-verify.h \
supplicant-manager/nm-supplicant-types.h \
- supplicant-manager/nm-call-store.c \
- supplicant-manager/nm-call-store.h \
\
vpn-manager/nm-vpn-connection.c \
vpn-manager/nm-vpn-connection.h \
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index f694549960..425dadcfd8 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -165,7 +165,7 @@ static void supplicant_iface_state_cb (NMSupplicantInterface *iface,
static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface,
const char *object_path,
- GHashTable *properties,
+ GVariant *properties,
NMDeviceWifi * self);
static void supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface,
@@ -1830,7 +1830,7 @@ schedule_scanlist_cull (NMDeviceWifi *self)
static void
supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
const char *object_path,
- GHashTable *properties,
+ GVariant *properties,
NMDeviceWifi *self)
{
NMDeviceState state;
diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c
index ee07cf40dd..7084bede28 100644
--- a/src/devices/wifi/nm-wifi-ap.c
+++ b/src/devices/wifi/nm-wifi-ap.c
@@ -30,6 +30,7 @@
#include "nm-utils.h"
#include "nm-logging.h"
#include "nm-dbus-manager.h"
+#include "nm-core-internal.h"
#include "nm-setting-wireless.h"
#include "nm-glib-compat.h"
@@ -330,163 +331,131 @@ nm_ap_new (void)
}
static NM80211ApSecurityFlags
-pair_to_flags (const char *str)
+security_from_vardict (GVariant *security)
{
- g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
+ NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
+ const char **array, *tmp;
- if (strcmp (str, "tkip") == 0)
- return NM_802_11_AP_SEC_PAIR_TKIP;
- if (strcmp (str, "ccmp") == 0)
- return NM_802_11_AP_SEC_PAIR_CCMP;
- return NM_802_11_AP_SEC_NONE;
-}
+ g_return_val_if_fail (g_variant_is_of_type (security, G_VARIANT_TYPE_VARDICT), NM_802_11_AP_SEC_NONE);
-static NM80211ApSecurityFlags
-group_to_flags (const char *str)
-{
- g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
-
- if (strcmp (str, "wep40") == 0)
- return NM_802_11_AP_SEC_GROUP_WEP40;
- if (strcmp (str, "wep104") == 0)
- return NM_802_11_AP_SEC_GROUP_WEP104;
- if (strcmp (str, "tkip") == 0)
- return NM_802_11_AP_SEC_GROUP_TKIP;
- if (strcmp (str, "ccmp") == 0)
- return NM_802_11_AP_SEC_GROUP_CCMP;
- return NM_802_11_AP_SEC_NONE;
-}
-
-static NM80211ApSecurityFlags
-security_from_dict (GHashTable *security)
-{
- GValue *value;
- NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
- const char **items, **iter;
-
- value = g_hash_table_lookup (security, "KeyMgmt");
- if (value) {
- items = g_value_get_boxed (value);
- for (iter = items; iter && *iter; iter++) {
- if (strcmp (*iter, "wpa-psk") == 0)
- flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
- else if (strcmp (*iter, "wpa-eap") == 0)
- flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
- }
+ if (g_variant_lookup (security, "KeyMgmt", "^a&s", &array)) {
+ if (_nm_utils_string_in_list ("wpa-psk", array))
+ flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ if (_nm_utils_string_in_list ("wpa-eap", array))
+ flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
+ g_free (array);
}
- value = g_hash_table_lookup (security, "Pairwise");
- if (value) {
- items = g_value_get_boxed (value);
- for (iter = items; iter && *iter; iter++)
- flags |= pair_to_flags (*iter);
+ if (g_variant_lookup (security, "Pairwise", "^a&s", &array)) {
+ if (_nm_utils_string_in_list ("tkip", array))
+ flags |= NM_802_11_AP_SEC_PAIR_TKIP;
+ if (_nm_utils_string_in_list ("ccmp", array))
+ flags |= NM_802_11_AP_SEC_PAIR_CCMP;
+ g_free (array);
}
- value = g_hash_table_lookup (security, "Group");
- if (value)
- flags |= group_to_flags (g_value_get_string (value));
+ if (g_variant_lookup (security, "Group", "&s", &tmp)) {
+ if (strcmp (tmp, "wep40") == 0)
+ flags |= NM_802_11_AP_SEC_GROUP_WEP40;
+ if (strcmp (tmp, "wep104") == 0)
+ flags |= NM_802_11_AP_SEC_GROUP_WEP104;
+ if (strcmp (tmp, "tkip") == 0)
+ flags |= NM_802_11_AP_SEC_GROUP_TKIP;
+ if (strcmp (tmp, "ccmp") == 0)
+ flags |= NM_802_11_AP_SEC_GROUP_CCMP;
+ }
return flags;
}
-static void
-foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
+NMAccessPoint *
+nm_ap_new_from_properties (const char *supplicant_path, GVariant *properties)
{
- GValue *variant = (GValue *) value;
- NMAccessPoint *ap = (NMAccessPoint *) user_data;
+ const char bad_bssid1[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ const char bad_bssid2[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ const char *addr;
+ const guint8 *bytes;
+ NMAccessPoint *ap;
+ GVariant *v;
+ gsize len;
+ gboolean b = FALSE;
+ const char *s;
+ gint16 i16;
+ guint16 u16;
- if (G_VALUE_HOLDS_BOXED (variant)) {
- GArray *array = g_value_get_boxed (variant);
+ g_return_val_if_fail (properties != NULL, NULL);
- if (!strcmp (key, "SSID")) {
- guint32 len = MIN (32, array->len);
+ ap = nm_ap_new ();
- /* Stupid ieee80211 layer uses <hidden> */
- if (((len == 8) || (len == 9))
- && (memcmp (array->data, "<hidden>", 8) == 0))
- return;
+ g_object_freeze_notify (G_OBJECT (ap));
- if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len))
- return;
+ if (g_variant_lookup (properties, "Privacy", "b", &b) && b)
+ nm_ap_set_flags (ap, nm_ap_get_flags (ap) | NM_802_11_AP_FLAGS_PRIVACY);
- nm_ap_set_ssid (ap, (const guint8 *) array->data, len);
- } else if (!strcmp (key, "BSSID")) {
- char *addr;
+ if (g_variant_lookup (properties, "Mode", "&s", &s)) {
+ if (!g_strcmp0 (s, "infrastructure"))
+ nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
+ else if (!g_strcmp0 (s, "ad-hoc"))
+ nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
+ }
- if (array->len != ETH_ALEN)
- return;
- addr = nm_utils_hwaddr_ntoa (array->data, array->len);
- nm_ap_set_address (ap, addr);
- g_free (addr);
- } else if (!strcmp (key, "Rates")) {
- guint32 maxrate = 0;
- int i;
-
- /* Find the max AP rate */
- for (i = 0; i < array->len; i++) {
- guint32 r = g_array_index (array, guint32, i);
-
- if (r > maxrate) {
- maxrate = r;
- nm_ap_set_max_bitrate (ap, r / 1000);
- }
- }
- } else if (!strcmp (key, "WPA")) {
- NM80211ApSecurityFlags flags = nm_ap_get_wpa_flags (ap);
+ if (g_variant_lookup (properties, "Signal", "n", &i16))
+ nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (i16));
- flags |= security_from_dict (g_value_get_boxed (variant));
- nm_ap_set_wpa_flags (ap, flags);
- } else if (!strcmp (key, "RSN")) {
- NM80211ApSecurityFlags flags = nm_ap_get_rsn_flags (ap);
+ if (g_variant_lookup (properties, "Frequency", "q", &u16))
+ nm_ap_set_freq (ap, u16);
- flags |= security_from_dict (g_value_get_boxed (variant));
- nm_ap_set_rsn_flags (ap, flags);
- }
- } else if (G_VALUE_HOLDS_UINT (variant)) {
- guint32 val = g_value_get_uint (variant);
-
- if (!strcmp (key, "Frequency"))
- nm_ap_set_freq (ap, val);
- } else if (G_VALUE_HOLDS_INT (variant)) {
- gint val = g_value_get_int (variant);
-
- if (!strcmp (key, "Signal"))
- nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (val));
- } else if (G_VALUE_HOLDS_STRING (variant)) {
- const char *val = g_value_get_string (variant);
-
- if (val && !strcmp (key, "Mode")) {
- if (strcmp (val, "infrastructure") == 0)
- nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
- else if (strcmp (val, "ad-hoc") == 0)
- nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
+ v = g_variant_lookup_value (properties, "SSID", G_VARIANT_TYPE_BYTESTRING);
+ if (v) {
+ bytes = g_variant_get_fixed_array (v, &len, 1);
+ len = MIN (32, len);
+
+ /* Stupid ieee80211 layer uses <hidden> */
+ if ( bytes && len
+ && !(((len == 8) || (len == 9)) && !memcmp (bytes, "<hidden>", 8))
+ && !nm_utils_is_empty_ssid (bytes, len))
+ nm_ap_set_ssid (ap, bytes, len);
+
+ g_variant_unref (v);
+ }
+
+ v = g_variant_lookup_value (properties, "BSSID", G_VARIANT_TYPE_BYTESTRING);
+ if (v) {
+ bytes = g_variant_get_fixed_array (v, &len, 1);
+ if (len == ETH_ALEN) {
+ addr = nm_utils_hwaddr_ntoa (bytes, len);
+ nm_ap_set_address (ap, addr);
}
- } else if (G_VALUE_HOLDS_BOOLEAN (variant)) {
- gboolean val = g_value_get_boolean (variant);
+ g_variant_unref (v);
+ }
- if (strcmp (key, "Privacy") == 0) {
- if (val) {
- NM80211ApFlags flags = nm_ap_get_flags (ap);
- nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
+ v = g_variant_lookup_value (properties, "Rates", G_VARIANT_TYPE ("au"));
+ if (v) {
+ const guint32 *rates = g_variant_get_fixed_array (v, &len, sizeof (guint32));
+ guint32 maxrate = 0;
+ int i;
+
+ /* Find the max AP rate */
+ for (i = 0; i < len; i++) {
+ if (rates[i] > maxrate) {
+ maxrate = rates[i];
+ nm_ap_set_max_bitrate (ap, rates[i] / 1000);
}
}
+ g_variant_unref (v);
}
-}
-
-NMAccessPoint *
-nm_ap_new_from_properties (const char *supplicant_path, GHashTable *properties)
-{
- NMAccessPoint *ap;
- const char *addr;
- const char bad_bssid1[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- const char bad_bssid2[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- g_return_val_if_fail (properties != NULL, NULL);
-
- ap = nm_ap_new ();
+ v = g_variant_lookup_value (properties, "WPA", G_VARIANT_TYPE_VARDICT);
+ if (v) {
+ nm_ap_set_wpa_flags (ap, nm_ap_get_wpa_flags (ap) | security_from_vardict (v));
+ g_variant_unref (v);
+ }
- g_object_freeze_notify (G_OBJECT (ap));
- g_hash_table_foreach (properties, foreach_property_cb, ap);
+ v = g_variant_lookup_value (properties, "RSN", G_VARIANT_TYPE_VARDICT);
+ if (v) {
+ nm_ap_set_wpa_flags (ap, nm_ap_get_rsn_flags (ap) | security_from_vardict (v));
+ g_variant_unref (v);
+ }
nm_ap_set_supplicant_path (ap, supplicant_path);
diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h
index 0abb28fccd..8ad9acb71b 100644
--- a/src/devices/wifi/nm-wifi-ap.h
+++ b/src/devices/wifi/nm-wifi-ap.h
@@ -56,7 +56,7 @@ typedef struct {
GType nm_ap_get_type (void);
NMAccessPoint * nm_ap_new_from_properties (const char *supplicant_path,
- GHashTable *properties);
+ GVariant *properties);
NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection);
void nm_ap_export_to_dbus (NMAccessPoint *ap);
diff --git a/src/supplicant-manager/nm-call-store.c b/src/supplicant-manager/nm-call-store.c
deleted file mode 100644
index 6e910a96b4..0000000000
--- a/src/supplicant-manager/nm-call-store.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2007 Novell, Inc.
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#include "config.h"
-
-#include "nm-call-store.h"
-#include "nm-logging.h"
-
-NMCallStore *
-nm_call_store_new (void)
-{
- /* Maps { DBusGProxy :: GHashTable { DBusGProxyCall :: NULL } } */
- return g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_hash_table_destroy);
-}
-
-static void
-proxy_destroyed_cb (gpointer data, GObject *proxy)
-{
- g_hash_table_remove ((NMCallStore *) data, proxy);
-}
-
-void
-nm_call_store_add (NMCallStore *store,
- DBusGProxy *proxy,
- DBusGProxyCall *call)
-{
- GHashTable *calls;
-
- g_return_if_fail (store != NULL);
- g_return_if_fail (proxy != NULL);
-
- if (!call) {
- /* Allow calling nm_call_store_add() with NULL @call for convenience.
- * This way you can pass the result of dbus_g_proxy_begin_call() directly
- * to nm_call_store_add() without checking for NULL. */
- return;
- }
-
- calls = g_hash_table_lookup (store, proxy);
- if (!calls) {
- calls = g_hash_table_new (NULL, NULL);
- g_hash_table_insert (store, proxy, calls);
- g_object_weak_ref (G_OBJECT (proxy), proxy_destroyed_cb, store);
- }
-
- g_hash_table_add (calls, call);
-}
-
-void
-nm_call_store_remove (NMCallStore *store,
- DBusGProxy *proxy,
- DBusGProxyCall *call)
-{
- GHashTable *calls;
-
- g_return_if_fail (store != NULL);
- g_return_if_fail (proxy != NULL);
- g_return_if_fail (call != NULL);
-
- calls = g_hash_table_lookup (store, proxy);
- if (!calls)
- return;
-
- g_hash_table_remove (calls, call);
- if (g_hash_table_size (calls) == 0) {
- g_hash_table_remove (store, proxy);
- g_object_weak_unref (G_OBJECT (proxy), proxy_destroyed_cb, store);
- }
-}
-
-void
-nm_call_store_clear (NMCallStore *store)
-{
- DBusGProxy *proxy;
- GHashTable *calls;
- GHashTableIter proxies_iter;
-
- g_return_if_fail (store != NULL);
-
- g_hash_table_iter_init (&proxies_iter, store);
- while (g_hash_table_iter_next (&proxies_iter, (gpointer) &proxy, (gpointer) &calls)) {
- GHashTableIter calls_iter;
- DBusGProxyCall *call;
-
- g_hash_table_iter_init (&calls_iter, calls);
- while (g_hash_table_iter_next (&calls_iter, (gpointer) &call, NULL)) {
- dbus_g_proxy_cancel_call (proxy, call);
- g_hash_table_iter_remove (&calls_iter);
- }
- g_object_weak_unref (G_OBJECT (proxy), proxy_destroyed_cb, store);
- g_hash_table_iter_remove (&proxies_iter);
- }
- g_assert_cmpint (g_hash_table_size (store), ==, 0);
-}
-
-void
-nm_call_store_destroy (NMCallStore *store)
-{
- g_return_if_fail (store);
- g_hash_table_destroy (store);
-}
diff --git a/src/supplicant-manager/nm-call-store.h b/src/supplicant-manager/nm-call-store.h
deleted file mode 100644
index bcee54cfbb..0000000000
--- a/src/supplicant-manager/nm-call-store.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2007 Novell, Inc.
- */
-
-#ifndef __NETWORKMANAGER_CALLBACK_STORE_H__
-#define __NETWORKMANAGER_CALLBACK_STORE_H__
-
-#include <glib-object.h>
-#include <dbus/dbus-glib.h>
-
-typedef GHashTable NMCallStore;
-
-NMCallStore *nm_call_store_new (void);
-void nm_call_store_add (NMCallStore *store,
- DBusGProxy *proxy,
- DBusGProxyCall *call);
-
-void nm_call_store_remove (NMCallStore *store,
- DBusGProxy *proxy,
- DBusGProxyCall *call);
-
-void nm_call_store_clear (NMCallStore *store);
-void nm_call_store_destroy (NMCallStore *store);
-
-#endif /* __NETWORKMANAGER_CALLBACK_STORE_H__ */
diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c
index 9ae8709557..d976bd703f 100644
--- a/src/supplicant-manager/nm-supplicant-config.c
+++ b/src/supplicant-manager/nm-supplicant-config.c
@@ -260,65 +260,44 @@ nm_supplicant_config_fast_required (NMSupplicantConfig *self)
return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->fast_required;
}
-static void
-get_hash_cb (gpointer key, gpointer value, gpointer user_data)
-{
- ConfigOption *opt = (ConfigOption *) value;
- GValue *variant;
- GByteArray *array;
-
- variant = g_slice_new0 (GValue);
-
- switch (opt->type) {
- case TYPE_INT:
- g_value_init (variant, G_TYPE_INT);
- g_value_set_int (variant, atoi (opt->value));
- break;
- case TYPE_BYTES:
- case TYPE_UTF8:
- array = g_byte_array_sized_new (opt->len);
- g_byte_array_append (array, (const guint8 *) opt->value, opt->len);
- g_value_init (variant, DBUS_TYPE_G_UCHAR_ARRAY);
- g_value_set_boxed (variant, array);
- g_byte_array_free (array, TRUE);
- break;
- case TYPE_KEYWORD:
- case TYPE_STRING:
- g_value_init (variant, G_TYPE_STRING);
- g_value_set_string (variant, opt->value);
- break;
- default:
- g_slice_free (GValue, variant);
- return;
- }
-
- g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), variant);
-}
-
-static void
-destroy_hash_value (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-GHashTable *
-nm_supplicant_config_get_hash (NMSupplicantConfig * self)
+GVariant *
+nm_supplicant_config_to_variant (NMSupplicantConfig *self)
{
NMSupplicantConfigPrivate *priv;
- GHashTable *hash;
+ GVariantBuilder builder;
+ GHashTableIter iter;
+ ConfigOption *option;
+ const char *key;
g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
- hash = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- destroy_hash_value);
-
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
- g_hash_table_foreach (priv->config, get_hash_cb, hash);
- return hash;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+
+ g_hash_table_iter_init (&iter, priv->config);
+ while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &option)) {
+ switch (option->type) {
+ case TYPE_INT:
+ g_variant_builder_add (&builder, "{sv}", key, g_variant_new_int32 (atoi (option->value)));
+ break;
+ case TYPE_BYTES:
+ case TYPE_UTF8:
+ g_variant_builder_add (&builder, "{sv}",
+ key,
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ option->value, option->len, 1));
+ break;
+ case TYPE_KEYWORD:
+ case TYPE_STRING:
+ g_variant_builder_add (&builder, "{sv}", key, g_variant_new_string (option->value));
+ break;
+ default:
+ break;
+ }
+ }
+
+ return g_variant_builder_end (&builder);
}
GHashTable *
diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h
index 482e3545b6..3324f637f4 100644
--- a/src/supplicant-manager/nm-supplicant-config.h
+++ b/src/supplicant-manager/nm-supplicant-config.h
@@ -59,7 +59,7 @@ void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self,
gboolean nm_supplicant_config_fast_required (NMSupplicantConfig *self);
-GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig *self);
+GVariant *nm_supplicant_config_to_variant (NMSupplicantConfig *self);
GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self);
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index 02b82b7ee2..77dfd4cabc 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -27,13 +27,11 @@
#include "NetworkManagerUtils.h"
#include "nm-supplicant-interface.h"
-#include "nm-supplicant-manager.h"
#include "nm-logging.h"
#include "nm-supplicant-config.h"
-#include "nm-dbus-manager.h"
-#include "nm-call-store.h"
-#include "nm-dbus-glib-types.h"
#include "nm-glib-compat.h"
+#include "gsystem-local-alloc.h"
+#include "nm-core-internal.h"
#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
#define WPAS_DBUS_IFACE_BSS WPAS_DBUS_INTERFACE ".BSS"
@@ -43,16 +41,6 @@
G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
-static void wpas_iface_properties_changed (DBusGProxy *proxy,
- GHashTable *props,
- gpointer user_data);
-
-static void wpas_iface_scan_done (DBusGProxy *proxy,
- gboolean success,
- gpointer user_data);
-
-static void wpas_iface_get_props (NMSupplicantInterface *self);
-
#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_INTERFACE, \
NMSupplicantInterfacePrivate))
@@ -81,89 +69,53 @@ enum {
typedef struct {
- NMSupplicantManager * smgr;
- gulong smgr_avail_id;
- NMDBusManager * dbus_mgr;
- char * dev;
- gboolean is_wireless;
- gboolean has_credreq; /* Whether querying 802.1x credentials is supported */
- ApSupport ap_support; /* Lightweight AP mode support */
- gboolean fast_supported;
- guint32 max_scan_ssids;
- guint32 ready_count;
-
- char * object_path;
- guint32 state;
- int disconnect_reason;
- NMCallStore * assoc_pcalls;
- NMCallStore * other_pcalls;
-
- gboolean scanning;
-
- DBusGProxy * wpas_proxy;
- DBusGProxy * introspect_proxy;
- DBusGProxy * iface_proxy;
- DBusGProxy * props_proxy;
- char * net_path;
- guint32 blobs_left;
- GHashTable * bss_proxies;
-
- gint32 last_scan; /* timestamp as returned by nm_utils_get_monotonic_timestamp_s() */
-
- NMSupplicantConfig * cfg;
-
- gboolean disposed;
+ char * dev;
+ gboolean is_wireless;
+ gboolean has_credreq; /* Whether querying 802.1x credentials is supported */
+ ApSupport ap_support; /* Lightweight AP mode support */
+ gboolean fast_supported;
+ guint32 max_scan_ssids;
+ guint32 ready_count;
+
+ char * object_path;
+ guint32 state;
+ int disconnect_reason;
+
+ gboolean scanning;
+
+ GDBusProxy * wpas_proxy;
+ GCancellable * init_cancellable;
+ GDBusProxy * iface_proxy;
+ GCancellable * other_cancellable;
+ GCancellable * assoc_cancellable;
+ char * net_path;
+ guint32 blobs_left;
+ GHashTable * bss_proxies;
+
+ gint32 last_scan; /* timestamp as returned by nm_utils_get_monotonic_timestamp_s() */
+
+ NMSupplicantConfig *cfg;
} NMSupplicantInterfacePrivate;
-static void
-emit_error_helper (NMSupplicantInterface *self,
- GError *err)
-{
- const char *name = NULL;
-
- if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION)
- name = dbus_g_error_get_name (err);
-
- g_signal_emit (self, signals[CONNECTION_ERROR], 0, name, err->message);
-}
+/***************************************************************/
static void
-signal_new_bss (NMSupplicantInterface *self,
- const char *object_path,
- GHashTable *props)
+emit_error_helper (NMSupplicantInterface *self, GError *error)
{
- g_signal_emit (self, signals[NEW_BSS], 0, object_path, props);
-}
+ char *name = NULL;
-static void
-bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *error = NULL;
- GHashTable *props = NULL;
-
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_MAP_OF_VARIANT, &props,
- G_TYPE_INVALID)) {
- signal_new_bss (self, dbus_g_proxy_get_path (proxy), props);
- g_hash_table_destroy (props);
- } else {
- if (!strstr (error->message, "The BSSID requested was invalid")) {
- nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.",
- error->message);
- }
- g_error_free (error);
- }
+ if (g_dbus_error_is_remote_error (error))
+ name = g_dbus_error_get_remote_error (error);
+
+ g_signal_emit (self, signals[CONNECTION_ERROR], 0, name, error->message);
+ g_free (name);
}
static void
-bss_properties_changed (DBusGProxy *proxy,
- const char *interface,
- GHashTable *props,
- const char **unused,
- gpointer user_data)
+bss_props_changed_cb (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ char **invalidated_properties,
+ gpointer user_data)
{
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
@@ -171,111 +123,77 @@ bss_properties_changed (DBusGProxy *proxy,
if (priv->scanning)
priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
- if (g_strcmp0 (interface, WPAS_DBUS_IFACE_BSS) == 0)
- g_signal_emit (self, signals[BSS_UPDATED], 0, dbus_g_proxy_get_path (proxy), props);
+ g_signal_emit (self, signals[BSS_UPDATED], 0,
+ g_dbus_proxy_get_object_path (proxy),
+ changed_properties);
}
static void
-handle_new_bss (NMSupplicantInterface *self,
- const char *object_path,
- GHashTable *props)
+on_bss_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxy *bss_proxy;
- DBusGProxyCall *call;
-
- g_return_if_fail (object_path != NULL);
-
- if (g_hash_table_lookup (priv->bss_proxies, object_path))
+ 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)) {
+ nm_log_dbg (LOGD_SUPPLICANT, "Failed to acquire BSS proxy: (%s)", error->message);
+ g_hash_table_remove (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data)->bss_proxies,
+ g_dbus_proxy_get_object_path (proxy));
+ }
return;
+ }
- bss_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- object_path,
- DBUS_INTERFACE_PROPERTIES);
- g_hash_table_insert (priv->bss_proxies,
- (gpointer) dbus_g_proxy_get_path (bss_proxy),
- bss_proxy);
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- /* Standard D-Bus PropertiesChanged signal */
- dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
- G_TYPE_NONE,
- G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_STRV,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (bss_proxy, "PropertiesChanged",
- G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_STRV,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (bss_proxy, "PropertiesChanged",
- G_CALLBACK (bss_properties_changed),
- self, NULL);
-
- if (props) {
- signal_new_bss (self, object_path, props);
- } else {
- call = dbus_g_proxy_begin_call (bss_proxy, "GetAll",
- bssid_properties_cb,
- self,
- NULL,
- G_TYPE_STRING, WPAS_DBUS_IFACE_BSS,
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, bss_proxy, call);
- }
-}
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
-static void
-wpas_iface_bss_added (DBusGProxy *proxy,
- const char *object_path,
- GHashTable *props,
- gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ iter = properties = g_dbus_proxy_get_cached_property_names (proxy);
+ while (*iter) {
+ GVariant *copy = g_dbus_proxy_get_cached_property (proxy, *iter);
- if (priv->scanning)
- priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
+ g_variant_builder_add (&builder, "{sv}", *iter++, copy);
+ g_variant_unref (copy);
+ }
- handle_new_bss (self, object_path, props);
+ 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));
}
static void
-wpas_iface_bss_removed (DBusGProxy *proxy,
- const char *object_path,
- gpointer user_data)
+handle_new_bss (NMSupplicantInterface *self, const char *object_path)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ GDBusProxy *bss_proxy;
- g_signal_emit (self, signals[BSS_REMOVED], 0, object_path);
-
- g_hash_table_remove (priv->bss_proxies, object_path);
-}
+ g_return_if_fail (object_path != NULL);
-static int
-wpas_state_string_to_enum (const char *str_state)
-{
- if (!strcmp (str_state, "interface_disabled"))
- return NM_SUPPLICANT_INTERFACE_STATE_DISABLED;
- else if (!strcmp (str_state, "disconnected"))
- return NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED;
- else if (!strcmp (str_state, "inactive"))
- return NM_SUPPLICANT_INTERFACE_STATE_INACTIVE;
- else if (!strcmp (str_state, "scanning"))
- return NM_SUPPLICANT_INTERFACE_STATE_SCANNING;
- else if (!strcmp (str_state, "authenticating"))
- return NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING;
- else if (!strcmp (str_state, "associating"))
- return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING;
- else if (!strcmp (str_state, "associated"))
- return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED;
- else if (!strcmp (str_state, "4way_handshake"))
- return NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE;
- else if (!strcmp (str_state, "group_handshake"))
- return NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE;
- else if (!strcmp (str_state, "completed"))
- return NM_SUPPLICANT_INTERFACE_STATE_COMPLETED;
+ if (g_hash_table_lookup (priv->bss_proxies, object_path))
+ return;
- nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant state '%s'", str_state);
- return -1;
+ bss_proxy = g_object_new (G_TYPE_DBUS_PROXY,
+ "g-bus-type", G_BUS_TYPE_SYSTEM,
+ "g-flags", G_DBUS_PROXY_FLAGS_NONE,
+ "g-name", WPAS_DBUS_SERVICE,
+ "g-object-path", object_path,
+ "g-interface-name", WPAS_DBUS_IFACE_BSS,
+ NULL);
+ g_hash_table_insert (priv->bss_proxies,
+ (char *) g_dbus_proxy_get_object_path (bss_proxy),
+ bss_proxy);
+ g_signal_connect (bss_proxy, "g-properties-changed", G_CALLBACK (bss_props_changed_cb), self);
+ g_async_initable_init_async (G_ASYNC_INITABLE (bss_proxy),
+ G_PRIORITY_DEFAULT,
+ priv->other_cancellable,
+ (GAsyncReadyCallback) on_bss_proxy_acquired,
+ self);
}
static void
@@ -297,39 +215,23 @@ set_state (NMSupplicantInterface *self, guint32 new_state)
g_return_if_fail (new_state > NM_SUPPLICANT_INTERFACE_STATE_READY);
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
- /* Get properties again to update to the actual wpa_supplicant
- * interface state.
- */
- wpas_iface_get_props (self);
- } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
- /* Cancel all pending calls when going down */
- nm_call_store_clear (priv->other_pcalls);
- nm_call_store_clear (priv->assoc_pcalls);
-
- /* Disconnect supplicant manager state listeners since we're done */
- if (priv->smgr_avail_id) {
- g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id);
- priv->smgr_avail_id = 0;
+ if (priv->other_cancellable) {
+ g_warn_if_fail (priv->other_cancellable == NULL);
+ g_cancellable_cancel (priv->other_cancellable);
+ g_clear_object (&priv->other_cancellable);
}
+ priv->other_cancellable = g_cancellable_new ();
+ } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
+ if (priv->init_cancellable)
+ g_cancellable_cancel (priv->init_cancellable);
+ g_clear_object (&priv->init_cancellable);
- if (priv->iface_proxy) {
- dbus_g_proxy_disconnect_signal (priv->iface_proxy,
- "PropertiesChanged",
- G_CALLBACK (wpas_iface_properties_changed),
- self);
- dbus_g_proxy_disconnect_signal (priv->iface_proxy,
- "ScanDone",
- G_CALLBACK (wpas_iface_scan_done),
- self);
- dbus_g_proxy_disconnect_signal (priv->iface_proxy,
- "BSSAdded",
- G_CALLBACK (wpas_iface_bss_added),
- self);
- dbus_g_proxy_disconnect_signal (priv->iface_proxy,
- "BSSRemoved",
- G_CALLBACK (wpas_iface_bss_removed),
- self);
- }
+ if (priv->other_cancellable)
+ g_cancellable_cancel (priv->other_cancellable);
+ g_clear_object (&priv->other_cancellable);
+
+ if (priv->iface_proxy)
+ g_signal_handlers_disconnect_by_data (priv->iface_proxy, self);
}
priv->state = new_state;
@@ -348,6 +250,34 @@ set_state (NMSupplicantInterface *self, guint32 new_state)
priv->disconnect_reason);
}
+static int
+wpas_state_string_to_enum (const char *str_state)
+{
+ if (!strcmp (str_state, "interface_disabled"))
+ return NM_SUPPLICANT_INTERFACE_STATE_DISABLED;
+ else if (!strcmp (str_state, "disconnected"))
+ return NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED;
+ else if (!strcmp (str_state, "inactive"))
+ return NM_SUPPLICANT_INTERFACE_STATE_INACTIVE;
+ else if (!strcmp (str_state, "scanning"))
+ return NM_SUPPLICANT_INTERFACE_STATE_SCANNING;
+ else if (!strcmp (str_state, "authenticating"))
+ return NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING;
+ else if (!strcmp (str_state, "associating"))
+ return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING;
+ else if (!strcmp (str_state, "associated"))
+ return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED;
+ else if (!strcmp (str_state, "4way_handshake"))
+ return NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE;
+ else if (!strcmp (str_state, "group_handshake"))
+ return NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE;
+ else if (!strcmp (str_state, "completed"))
+ return NM_SUPPLICANT_INTERFACE_STATE_COMPLETED;
+
+ nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant state '%s'", str_state);
+ return -1;
+}
+
static void
set_state_from_string (NMSupplicantInterface *self, const char *new_state)
{
@@ -396,107 +326,36 @@ nm_supplicant_interface_get_last_scan_time (NMSupplicantInterface *self)
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->last_scan;
}
-static void
-wpas_iface_scan_done (DBusGProxy *proxy,
- gboolean success,
- gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- /* Cache last scan completed time */
- priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
- g_signal_emit (self, signals[SCAN_DONE], 0, success);
-}
+#define MATCH_PROPERTY(p, n, v, t) (!strcmp (p, n) && g_variant_is_of_type (v, t))
static void
-parse_capabilities (NMSupplicantInterface *self, GHashTable *props)
+parse_capabilities (NMSupplicantInterface *self, GVariant *capabilities)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GValue *value;
gboolean have_active = FALSE, have_ssid = FALSE;
+ gint32 max_scan_ssids = -1;
+ const char **array;
- g_return_if_fail (props != NULL);
-
- value = g_hash_table_lookup (props, "Scan");
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRV)) {
- const char **vals = g_value_get_boxed (value);
- const char **iter = vals;
+ g_return_if_fail (capabilities && g_variant_is_of_type (capabilities, G_VARIANT_TYPE_VARDICT));
- while (iter && *iter && (!have_active || !have_ssid)) {
- if (g_strcmp0 (*iter, "active") == 0)
- have_active = TRUE;
- else if (g_strcmp0 (*iter, "ssid") == 0)
- have_ssid = TRUE;
- iter++;
- }
+ if (g_variant_lookup (capabilities, "Scan", "^a&s", &array)) {
+ if (_nm_utils_string_in_list ("active", array))
+ have_active = TRUE;
+ if (_nm_utils_string_in_list ("ssid", array))
+ have_ssid = TRUE;
+ g_free (array);
}
- value = g_hash_table_lookup (props, "MaxScanSSID");
- if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) {
+ if (g_variant_lookup (capabilities, "MaxScanSSID", "i", &max_scan_ssids)) {
/* We need active scan and SSID probe capabilities to care about MaxScanSSIDs */
- if (have_active && have_ssid) {
+ if (max_scan_ssids > 0 && have_active && have_ssid) {
/* wpa_supplicant's WPAS_MAX_SCAN_SSIDS value is 16, but for speed
* and to ensure we don't disclose too many SSIDs from the hidden
* list, we'll limit to 5.
*/
- priv->max_scan_ssids = CLAMP (g_value_get_int (value), 0, 5);
+ priv->max_scan_ssids = CLAMP (max_scan_ssids, 0, 5);
nm_log_info (LOGD_SUPPLICANT, "(%s) supports %d scan SSIDs",
- priv->dev, priv->max_scan_ssids);
- }
- }
-}
-
-static void
-wpas_iface_properties_changed (DBusGProxy *proxy,
- GHashTable *props,
- gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GValue *value;
-
- value = g_hash_table_lookup (props, "Scanning");
- if (value && G_VALUE_HOLDS_BOOLEAN (value))
- set_scanning (self, g_value_get_boolean (value));
-
- value = g_hash_table_lookup (props, "State");
- if (value && G_VALUE_HOLDS_STRING (value)) {
- if (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY) {
- /* Only transition to actual wpa_supplicant interface states (ie,
- * anything > READY) after the NMSupplicantInterface has had a
- * chance to initialize, which is signalled by entering the READY
- * state.
- */
- set_state_from_string (self, g_value_get_string (value));
- }
- }
-
- value = g_hash_table_lookup (props, "BSSs");
- if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) {
- GPtrArray *paths = g_value_get_boxed (value);
- int i;
-
- for (i = 0; paths && (i < paths->len); i++)
- handle_new_bss (self, g_ptr_array_index (paths, i), NULL);
- }
-
- value = g_hash_table_lookup (props, "Capabilities");
- if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_VARIANT))
- parse_capabilities (self, g_value_get_boxed (value));
-
- /* Disconnect reason is currently only given for deauthentication events,
- * not disassociation; currently they are IEEE 802.11 "reason codes",
- * defined by (IEEE 802.11-2007, 7.3.1.7, Table 7-22). Any locally caused
- * deauthentication will be negative, while authentications caused by the
- * AP will be positive.
- */
- value = g_hash_table_lookup (props, "DisconnectReason");
- if (value && G_VALUE_HOLDS (value, G_TYPE_INT)) {
- priv->disconnect_reason = g_value_get_int (value);
- if (priv->disconnect_reason != 0) {
- nm_log_warn (LOGD_SUPPLICANT, "Connection disconnected (reason %d)",
- priv->disconnect_reason);
+ priv->dev, priv->max_scan_ssids);
}
}
}
@@ -513,43 +372,6 @@ iface_check_ready (NMSupplicantInterface *self)
}
}
-static void
-iface_get_props_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GHashTable *props = NULL;
- GError *error = NULL;
-
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_MAP_OF_VARIANT, &props,
- G_TYPE_INVALID)) {
- wpas_iface_properties_changed (NULL, props, self);
- g_hash_table_destroy (props);
- } else {
- nm_log_warn (LOGD_SUPPLICANT, "could not get interface properties: %s.",
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
- iface_check_ready (self);
-}
-
-static void
-wpas_iface_get_props (NMSupplicantInterface *self)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
-
- call = dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
- iface_get_props_cb,
- self,
- NULL,
- G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, priv->props_proxy, call);
-}
-
gboolean
nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self,
const char *field,
@@ -557,6 +379,7 @@ nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self,
GError **error)
{
NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *reply = NULL;
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
g_return_val_if_fail (field != NULL, FALSE);
@@ -567,74 +390,63 @@ nm_supplicant_interface_credentials_reply (NMSupplicantInterface *self,
/* Need a network block object path */
g_return_val_if_fail (priv->net_path, FALSE);
- return dbus_g_proxy_call_with_timeout (priv->iface_proxy, "NetworkReply",
- 5000,
- error,
- DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
- G_TYPE_STRING, field,
- G_TYPE_STRING, value,
- G_TYPE_INVALID);
+ reply = g_dbus_proxy_call_sync (priv->iface_proxy,
+ "NetworkReply",
+ g_variant_new ("(oss)",
+ priv->net_path,
+ field,
+ value),
+ G_DBUS_CALL_FLAGS_NONE,
+ 5000,
+ NULL,
+ error);
+ /* reply will be unrefed when function exits */
+ return !!reply;
}
-static void
-wpas_iface_network_request (DBusGProxy *proxy,
- const char *object_path,
- const char *field,
- const char *message,
- gpointer user_data)
+static gboolean
+_dbus_error_has_name (GError *error, const char *dbus_error_name)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- g_return_if_fail (priv->has_credreq == TRUE);
- g_return_if_fail (priv->net_path != NULL);
- g_return_if_fail (g_strcmp0 (object_path, priv->net_path) == 0);
+ gs_free char *error_name = NULL;
+ gboolean is_error = FALSE;
- g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message);
+ if (error && g_dbus_error_is_remote_error (error)) {
+ error_name = g_dbus_error_get_remote_error (error);
+ is_error = !g_strcmp0 (error_name, dbus_error_name);
+ }
+ return is_error;
}
static void
-iface_check_netreply_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+iface_check_netreply_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *error = NULL;
-
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if ( dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)
- || dbus_g_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs")) {
- /* We know NetworkReply is supported if the NetworkReply method returned
- * successfully (which is unexpected since we sent a bogus network
- * object path) or if we got an "InvalidArgs" (which indicates NetworkReply
- * is supported). We know it's not supported if we get an
- * "UnknownMethod" error.
- */
- priv->has_credreq = TRUE;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *variant = NULL;
+ gs_free_error GError *error = NULL;
+ gs_free char *dbus_err = NULL;
+
+ /* We know NetworkReply is supported if the NetworkReply method returned
+ * successfully (which is unexpected since we sent a bogus network
+ * object path) or if we got an "InvalidArgs" (which indicates NetworkReply
+ * is supported). We know it's not supported if we get an
+ * "UnknownMethod" error.
+ */
- nm_log_dbg (LOGD_SUPPLICANT, "Supplicant %s network credentials requests",
- priv->has_credreq ? "supports" : "does not support");
- }
- g_clear_error (&error);
+ variant = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- iface_check_ready (self);
-}
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-static void
-wpas_iface_check_network_reply (NMSupplicantInterface *self)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
+ if (variant || _dbus_error_has_name (error, "fi.w1.wpa_supplicant1.InvalidArgs"))
+ priv->has_credreq = TRUE;
- priv->ready_count++;
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "NetworkReply",
- iface_check_netreply_cb,
- self,
- NULL,
- DBUS_TYPE_G_OBJECT_PATH, "/foobaraasdfasdf",
- G_TYPE_STRING, "foobar",
- G_TYPE_STRING, "foobar",
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, priv->iface_proxy, call);
+ nm_log_dbg (LOGD_SUPPLICANT, "Supplicant %s network credentials requests",
+ priv->has_credreq ? "supports" : "does not support");
+
+ iface_check_ready (self);
}
ApSupport
@@ -657,207 +469,271 @@ nm_supplicant_interface_set_ap_support (NMSupplicantInterface *self,
}
static void
-iface_check_ap_mode_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+iface_check_ap_mode_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- char *data;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *variant = NULL;
+ gs_free_error GError *error = NULL;
+ const char *data;
/* The ProbeRequest method only exists if AP mode has been enabled */
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (dbus_g_proxy_end_call (proxy, call_id, NULL,
- G_TYPE_STRING,
- &data,
- G_TYPE_INVALID)) {
- if (data && strstr (data, "ProbeRequest"))
+ variant = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(s)"))) {
+ g_variant_get (variant, "(&s)", &data);
+ if (strstr (data, "ProbeRequest"))
priv->ap_support = AP_SUPPORT_YES;
- g_free (data);
}
iface_check_ready (self);
}
+#define MATCH_SIGNAL(s, n, v, t) (!strcmp (s, n) && g_variant_is_of_type (v, t))
+
static void
-wpas_iface_check_ap_mode (NMSupplicantInterface *self)
+signal_cb (GDBusProxy *proxy,
+ const gchar *sender,
+ const gchar *signal,
+ GVariant *args,
+ gpointer user_data)
{
+ NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
+ const char *path, *field, *message;
+ gboolean success;
- priv->ready_count++;
+ if (MATCH_SIGNAL (signal, "ScanDone", args, G_VARIANT_TYPE ("(b)"))) {
+ /* Cache last scan completed time */
+ priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
- /* If the global supplicant capabilities property is not present, we can
- * fall back to checking whether the ProbeRequest method is supported. If
- * neither of these works we have no way of determining if AP mode is
- * supported or not. hostap 1.0 and earlier don't support either of these.
- */
- call = dbus_g_proxy_begin_call (priv->introspect_proxy, "Introspect",
- iface_check_ap_mode_cb,
- self,
- NULL,
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, priv->introspect_proxy, call);
+ g_variant_get (args, "(b)", &success);
+ g_signal_emit (self, signals[SCAN_DONE], 0, success);
+ } else if (MATCH_SIGNAL (signal, "BSSAdded", args, G_VARIANT_TYPE ("(oa{sv})"))) {
+ if (priv->scanning)
+ priv->last_scan = nm_utils_get_monotonic_timestamp_s ();
+
+ g_variant_get (args, "(&oa{sv})", &path, NULL);
+ handle_new_bss (self, path);
+ } else if (MATCH_SIGNAL (signal, "BSSRemoved", args, G_VARIANT_TYPE ("(o)"))) {
+ g_variant_get (args, "(&o)", &path);
+ g_signal_emit (self, signals[BSS_REMOVED], 0, path);
+ g_hash_table_remove (priv->bss_proxies, path);
+ } else if (MATCH_SIGNAL (signal, "NetworkRequest", args, G_VARIANT_TYPE ("(oss)"))) {
+ g_variant_get (args, "(&o&s&s)", &path, &field, &message);
+ if (priv->has_credreq && priv->net_path && !g_strcmp0 (path, priv->net_path))
+ g_signal_emit (self, signals[CREDENTIALS_REQUEST], 0, field, message);
+ }
}
static void
-interface_add_done (NMSupplicantInterface *self, char *path)
+props_changed_cb (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ GStrv invalidated_properties,
+ gpointer user_data)
{
+ NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ const char *s, **array, **iter;
+ gboolean b = FALSE;
+ gint32 i32;
+ GVariant *v;
+
+ if (g_variant_lookup (changed_properties, "Scanning", "b", &b))
+ set_scanning (self, b);
+
+ if ( g_variant_lookup (changed_properties, "State", "&s", &s)
+ && priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY) {
+ /* Only transition to actual wpa_supplicant interface states (ie,
+ * anything > READY) after the NMSupplicantInterface has had a
+ * chance to initialize, which is signalled by entering the READY
+ * state.
+ */
+ set_state_from_string (self, s);
+ }
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
+ if (g_variant_lookup (changed_properties, "BSSs", "^a&s", &array)) {
+ iter = array;
+ while (*iter)
+ handle_new_bss (self, *iter++);
+ g_free (array);
+ }
- priv->object_path = path;
-
- priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- path,
- WPAS_DBUS_IFACE_INTERFACE);
-
- dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE,
- DBUS_TYPE_G_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (priv->iface_proxy, "PropertiesChanged",
- DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "PropertiesChanged",
- G_CALLBACK (wpas_iface_properties_changed),
- self, NULL);
-
- dbus_g_proxy_add_signal (priv->iface_proxy, "ScanDone",
- G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanDone",
- G_CALLBACK (wpas_iface_scan_done),
- self,
- NULL);
-
- dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
- G_TYPE_NONE,
- DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (priv->iface_proxy, "BSSAdded",
- DBUS_TYPE_G_OBJECT_PATH, DBUS_TYPE_G_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSAdded",
- G_CALLBACK (wpas_iface_bss_added),
- self,
- NULL);
-
- dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE,
- DBUS_TYPE_G_OBJECT_PATH,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (priv->iface_proxy, "BSSRemoved",
- DBUS_TYPE_G_OBJECT_PATH,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSRemoved",
- G_CALLBACK (wpas_iface_bss_removed),
- self,
- NULL);
-
- dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
- G_TYPE_NONE,
- DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (priv->iface_proxy, "NetworkRequest",
- DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "NetworkRequest",
- G_CALLBACK (wpas_iface_network_request),
- self,
- NULL);
-
- priv->introspect_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- priv->object_path,
- DBUS_INTERFACE_INTROSPECTABLE);
-
- priv->props_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- path,
- DBUS_INTERFACE_PROPERTIES);
- /* Get initial properties and check whether NetworkReply is supported */
- priv->ready_count = 1;
- wpas_iface_get_props (self);
+ v = g_variant_lookup_value (changed_properties, "Capabilities", G_VARIANT_TYPE_VARDICT);
+ if (v) {
+ parse_capabilities (self, v);
+ g_variant_unref (v);
+ }
- /* These two increment ready_count themselves */
- wpas_iface_check_network_reply (self);
- if (priv->ap_support == AP_SUPPORT_UNKNOWN)
- wpas_iface_check_ap_mode (self);
+ if (g_variant_lookup (changed_properties, "DisconnectReason", "i", &i32)) {
+ /* Disconnect reason is currently only given for deauthentication events,
+ * not disassociation; currently they are IEEE 802.11 "reason codes",
+ * defined by (IEEE 802.11-2007, 7.3.1.7, Table 7-22). Any locally caused
+ * deauthentication will be negative, while authentications caused by the
+ * AP will be positive.
+ */
+ priv->disconnect_reason = i32;
+ if (priv->disconnect_reason != 0) {
+ nm_log_warn (LOGD_SUPPLICANT, "Connection disconnected (reason %d)",
+ priv->disconnect_reason);
+ }
+ }
}
static void
-interface_get_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+on_iface_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *error = NULL;
- char *path = NULL;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_free_error GError *error = NULL;
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_OBJECT_PATH, &path,
- G_TYPE_INVALID)) {
- interface_add_done (self, path);
- } else {
- nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
- priv->dev, error->message);
- g_clear_error (&error);
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ if (!g_async_initable_init_finish (G_ASYNC_INITABLE (proxy), result, &error)) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ nm_log_warn (LOGD_SUPPLICANT, "Failed to acquire wpa_supplicant interface proxy: (%s)", error->message);
+ set_state (NM_SUPPLICANT_INTERFACE (user_data), NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ }
+ return;
+ }
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ g_signal_connect (priv->iface_proxy, "g-signal", G_CALLBACK (signal_cb), self);
+
+ /* Check whether NetworkReply and AP mode are supported */
+ priv->ready_count = 1;
+ g_dbus_proxy_call (priv->iface_proxy,
+ "NetworkReply",
+ g_variant_new ("(oss)",
+ "/fff",
+ "foobar",
+ "foobar"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) iface_check_netreply_cb,
+ self);
+
+ if (priv->ap_support == AP_SUPPORT_UNKNOWN) {
+ /* If the global supplicant capabilities property is not present, we can
+ * fall back to checking whether the ProbeRequest method is supported. If
+ * neither of these works we have no way of determining if AP mode is
+ * supported or not. hostap 1.0 and earlier don't support either of these.
+ */
+ priv->ready_count++;
+ g_dbus_proxy_call (priv->iface_proxy,
+ "org.freedesktop.DBus.Introspectable.Introspect",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) iface_check_ap_mode_cb,
+ self);
}
}
static void
-interface_get (NMSupplicantInterface *self)
+interface_add_done (NMSupplicantInterface *self, const char *path)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
- call = dbus_g_proxy_begin_call (priv->wpas_proxy, "GetInterface",
- interface_get_cb,
- self,
- NULL,
- G_TYPE_STRING, priv->dev,
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, priv->wpas_proxy, call);
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
+
+ priv->object_path = g_strdup (path);
+ priv->iface_proxy = g_object_new (G_TYPE_DBUS_PROXY,
+ "g-bus-type", G_BUS_TYPE_SYSTEM,
+ "g-flags", G_DBUS_PROXY_FLAGS_NONE,
+ "g-name", WPAS_DBUS_SERVICE,
+ "g-object-path", priv->object_path,
+ "g-interface-name", WPAS_DBUS_IFACE_INTERFACE,
+ NULL);
+ g_signal_connect (priv->iface_proxy, "g-properties-changed", G_CALLBACK (props_changed_cb), self);
+ g_async_initable_init_async (G_ASYNC_INITABLE (priv->iface_proxy),
+ G_PRIORITY_DEFAULT,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) on_iface_proxy_acquired,
+ self);
}
static void
-interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+interface_get_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *error = NULL;
- char *path = NULL;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *variant = NULL;
+ gs_free_error GError *error = NULL;
+ char *path;
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_OBJECT_PATH, &path,
- G_TYPE_INVALID)) {
+ variant = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(o)"))) {
+ g_variant_get (variant, "(o)", &path);
interface_add_done (self, path);
+ g_free (path);
} else {
- if (dbus_g_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
- /* Interface already added, just get its object path */
- interface_get (self);
- } else if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_EXEC_FAILED)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_FORK_FAILED)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_FAILED)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_TIMEOUT)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY)
- || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_TIMED_OUT)
- || dbus_g_error_has_name (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
- /* Supplicant wasn't running and could not be launched via service
- * activation. Wait for it to start by moving back to the INIT
- * state.
- */
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s",
- priv->dev, error->message);
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_INIT);
- } else {
- nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
- priv->dev, error->message);
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
- }
- g_clear_error (&error);
+ nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s", priv->dev, error->message);
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ }
+}
+
+static void
+interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
+{
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_free_error GError *error = NULL;
+ gs_unref_variant GVariant *variant = NULL;
+ char *path;
+
+ variant = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE ("(o)"))) {
+ g_variant_get (variant, "(o)", &path);
+ interface_add_done (self, path);
+ g_free (path);
+ } else if (_dbus_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
+ /* Interface already added, just get its object path */
+ g_dbus_proxy_call (priv->wpas_proxy,
+ "GetInterface",
+ g_variant_new ("(s)", priv->dev),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) interface_get_cb,
+ self);
+ } else if ( g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_EXEC_FAILED)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FORK_FAILED)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FAILED)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMEOUT)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NO_REPLY)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMED_OUT)
+ || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
+ /* Supplicant wasn't running and could not be launched via service
+ * activation. Wait for it to start by moving back to the INIT
+ * state.
+ */
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s",
+ priv->dev, error->message);
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_INIT);
+ } else {
+ nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s", priv->dev, error->message);
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
}
}
@@ -868,59 +744,90 @@ interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data
#endif
static void
-interface_add (NMSupplicantInterface *self, gboolean is_wireless)
+on_wpas_proxy_acquired (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
- GHashTable *hash;
- GValue driver = G_VALUE_INIT;
- GValue ifname = G_VALUE_INIT;
-
- /* Can only start the interface from INIT state */
- g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_free_error GError *error = NULL;
+ GDBusProxy *wpas_proxy;
+ GVariantBuilder props;
+
+ wpas_proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
+ if (!wpas_proxy) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ nm_log_warn (LOGD_SUPPLICANT, "Failed to acquire wpa_supplicant proxy: (%s)",
+ error ? error->message : "unknown");
+ set_state (NM_SUPPLICANT_INTERFACE (user_data), NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ }
+ return;
+ }
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev);
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- /* Move to starting to prevent double-calls of interface_add() */
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
+ priv->wpas_proxy = wpas_proxy;
/* Try to add the interface to the supplicant. If the supplicant isn't
* running, this will start it via D-Bus activation and return the response
* when the supplicant has started.
*/
- hash = g_hash_table_new (g_str_hash, g_str_equal);
+ g_variant_builder_init (&props, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&props, "{sv}",
+ "Driver",
+ g_variant_new_string (priv->is_wireless ? DEFAULT_WIFI_DRIVER : "wired"));
+ g_variant_builder_add (&props, "{sv}",
+ "Ifname",
+ g_variant_new_string (priv->dev));
+
+ g_dbus_proxy_call (priv->wpas_proxy,
+ "CreateInterface",
+ g_variant_new ("(a{sv})", &props),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) interface_add_cb,
+ self);
+}
- g_value_init (&driver, G_TYPE_STRING);
- g_value_set_string (&driver, is_wireless ? DEFAULT_WIFI_DRIVER : "wired");
- g_hash_table_insert (hash, "Driver", &driver);
+static void
+interface_add (NMSupplicantInterface *self, gboolean is_wireless)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- g_value_init (&ifname, G_TYPE_STRING);
- g_value_set_string (&ifname, priv->dev);
- g_hash_table_insert (hash, "Ifname", &ifname);
+ /* Can only start the interface from INIT state */
+ g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
- call = dbus_g_proxy_begin_call (priv->wpas_proxy, "CreateInterface",
- interface_add_cb,
- self,
- NULL,
- DBUS_TYPE_G_MAP_OF_VARIANT, hash,
- G_TYPE_INVALID);
- nm_call_store_add (priv->other_pcalls, priv->wpas_proxy, call);
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev);
+
+ priv->is_wireless = is_wireless;
+
+ /* Move to starting to prevent double-calls of interface_add() */
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
- g_hash_table_destroy (hash);
- g_value_unset (&driver);
- g_value_unset (&ifname);
+ g_warn_if_fail (priv->init_cancellable == NULL);
+ g_clear_object (&priv->init_cancellable);
+ priv->init_cancellable = g_cancellable_new ();
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ NULL,
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE,
+ priv->init_cancellable,
+ (GAsyncReadyCallback) on_wpas_proxy_acquired,
+ self);
}
-static void
-smgr_avail_cb (NMSupplicantManager *smgr,
- GParamSpec *pspec,
- gpointer user_data)
+void
+nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self,
+ gboolean available)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- if (nm_supplicant_manager_available (smgr)) {
+ if (available) {
/* This can happen if the supplicant couldn't be activated but
* for some reason was started after the activation failure.
*/
@@ -933,27 +840,14 @@ smgr_avail_cb (NMSupplicantManager *smgr,
}
static void
-remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- GError *error = NULL;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
- nm_log_dbg (LOGD_SUPPLICANT, "Couldn't remove network from supplicant interface: %s.",
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static void
-disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+log_result_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- GError *error = NULL;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *error = NULL;
- if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
- nm_log_warn (LOGD_SUPPLICANT, "Couldn't disconnect supplicant interface: %s.",
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
+ reply = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (!reply && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ nm_log_warn (LOGD_SUPPLICANT, "Failed to %s: %s.", error->message, (char *) user_data);
}
void
@@ -965,10 +859,11 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self)
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- /* Clear and cancel all pending calls related to a prior
- * connection attempt.
- */
- nm_call_store_clear (priv->assoc_pcalls);
+ /* Cancel all pending calls related to a prior connection attempt */
+ if (priv->assoc_cancellable) {
+ g_cancellable_cancel (priv->assoc_cancellable);
+ g_clear_object (&priv->assoc_cancellable);
+ }
/* Don't do anything if there is no connection to the supplicant yet. */
if (!priv->iface_proxy)
@@ -977,36 +872,41 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self)
/* Disconnect from the current AP */
if ( (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
&& (priv->state <= NM_SUPPLICANT_INTERFACE_STATE_COMPLETED)) {
- dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect",
- disconnect_cb,
- NULL, NULL,
- G_TYPE_INVALID);
+ g_dbus_proxy_call (priv->iface_proxy,
+ "Disconnect",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) log_result_cb,
+ "disconnect");
}
/* Remove any network that was added by NetworkManager */
if (priv->net_path) {
- dbus_g_proxy_begin_call (priv->iface_proxy, "RemoveNetwork",
- remove_network_cb,
- NULL, NULL,
- DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
- G_TYPE_INVALID);
+ g_dbus_proxy_call (priv->iface_proxy,
+ "RemoveNetwork",
+ g_variant_new ("(o)", priv->net_path),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->other_cancellable,
+ (GAsyncReadyCallback) log_result_cb,
+ "remove network");
g_free (priv->net_path);
priv->net_path = NULL;
}
}
static void
-select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+select_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *err = NULL;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *err = NULL;
- nm_call_store_remove (priv->assoc_pcalls, proxy, call_id);
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ reply = g_dbus_proxy_call_finish (proxy, result, &err);
+ if (!reply && !g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't select network config: %s.", err->message);
- emit_error_helper (self, err);
- g_error_free (err);
+ emit_error_helper (NM_SUPPLICANT_INTERFACE (user_data), err);
}
}
@@ -1014,111 +914,136 @@ static void
call_select_network (NMSupplicantInterface *self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
/* We only select the network after all blobs (if any) have been set */
if (priv->blobs_left == 0) {
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork",
- select_network_cb,
- self,
- NULL,
- DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
- G_TYPE_INVALID);
- nm_call_store_add (priv->assoc_pcalls, priv->iface_proxy, call);
+ g_dbus_proxy_call (priv->iface_proxy,
+ "SelectNetwork",
+ g_variant_new ("(o)", priv->net_path),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) select_network_cb,
+ self);
}
}
static void
-add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+add_blob_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *err = NULL;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *err = NULL;
- priv->blobs_left--;
+ reply = g_dbus_proxy_call_finish (proxy, result, &err);
+ if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- nm_call_store_remove (priv->assoc_pcalls, proxy, call_id);
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ priv->blobs_left--;
+ if (reply)
+ call_select_network (self);
+ else {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message);
emit_error_helper (self, err);
- g_error_free (err);
- } else
- call_select_network (self);
+ }
}
static void
-add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *err = NULL;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *error = NULL;
GHashTable *blobs;
GHashTableIter iter;
- gpointer name, data;
- DBusGProxyCall *call;
+ const char *blob_name;
+ GByteArray *blob_data;
+
+ reply = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (reply && !g_variant_is_of_type (reply, G_VARIANT_TYPE ("(o)"))) {
+ error = g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
+ "Unexpected AddNetwork reply type %s",
+ g_variant_get_type_string (reply));
+ }
g_free (priv->net_path);
priv->net_path = NULL;
- nm_call_store_remove (priv->assoc_pcalls, proxy, call_id);
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_OBJECT_PATH, &priv->net_path,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.",
- err->message);
- emit_error_helper (self, err);
- g_error_free (err);
+ if (error) {
+ nm_log_warn (LOGD_SUPPLICANT, "Adding network to supplicant failed: %s.", error->message);
+ emit_error_helper (self, error);
return;
}
- /* Send blobs first; otherwise jump to sending the config settings */
+ g_variant_get (reply, "(o)", &priv->net_path);
+ g_assert (priv->net_path);
+
+ /* Send blobs first; otherwise jump to selecting the network */
blobs = nm_supplicant_config_get_blobs (priv->cfg);
priv->blobs_left = g_hash_table_size (blobs);
+
g_hash_table_iter_init (&iter, blobs);
- while (g_hash_table_iter_next (&iter, &name, &data)) {
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddBlob",
- add_blob_cb,
- self,
- NULL,
- G_TYPE_STRING, name,
- DBUS_TYPE_G_UCHAR_ARRAY, data,
- G_TYPE_INVALID);
- nm_call_store_add (priv->assoc_pcalls, priv->iface_proxy, call);
+ while (g_hash_table_iter_next (&iter, (gpointer) &blob_name, (gpointer) &blob_data)) {
+ g_dbus_proxy_call (priv->iface_proxy,
+ "AddBlob",
+ g_variant_new ("(s@ay)",
+ blob_name,
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ blob_data->data, blob_data->len, 1)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) add_blob_cb,
+ self);
}
call_select_network (self);
}
static void
-set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+set_ap_scan_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *err = NULL;
- DBusGProxyCall *call;
- GHashTable *config_hash;
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *error = NULL;
+
+ reply = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- nm_call_store_remove (priv->assoc_pcalls, proxy, call_id);
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ self = NM_SUPPLICANT_INTERFACE (user_data);
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (!reply) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't send AP scan mode to the supplicant interface: %s.",
- err->message);
- emit_error_helper (self, err);
- g_error_free (err);
+ error->message);
+ emit_error_helper (self, error);
return;
}
nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d",
nm_supplicant_config_get_ap_scan (priv->cfg));
- config_hash = nm_supplicant_config_get_hash (priv->cfg);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddNetwork",
- add_network_cb,
- self,
- NULL,
- DBUS_TYPE_G_MAP_OF_VARIANT, config_hash,
- G_TYPE_INVALID);
- g_hash_table_destroy (config_hash);
- nm_call_store_add (priv->assoc_pcalls, priv->iface_proxy, call);
+ g_dbus_proxy_call (priv->iface_proxy,
+ "AddNetwork",
+ g_variant_new ("(@a{sv})", nm_supplicant_config_to_variant (priv->cfg)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) add_network_cb,
+ self);
}
gboolean
@@ -1126,8 +1051,6 @@ nm_supplicant_interface_set_config (NMSupplicantInterface *self,
NMSupplicantConfig *cfg)
{
NMSupplicantInterfacePrivate *priv;
- DBusGProxyCall *call;
- GValue value = G_VALUE_INIT;
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
@@ -1143,103 +1066,75 @@ nm_supplicant_interface_set_config (NMSupplicantInterface *self,
return FALSE;
}
- if (priv->cfg)
- g_object_unref (priv->cfg);
- priv->cfg = cfg;
-
- if (cfg == NULL)
- return TRUE;
-
- g_object_ref (priv->cfg);
-
- g_value_init (&value, G_TYPE_UINT);
- g_value_set_uint (&value, nm_supplicant_config_get_ap_scan (priv->cfg));
-
- call = dbus_g_proxy_begin_call (priv->props_proxy, "Set",
- set_ap_scan_cb,
- self,
- NULL,
- G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
- G_TYPE_STRING, "ApScan",
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID);
- nm_call_store_add (priv->assoc_pcalls, priv->props_proxy, call);
-
- g_value_unset (&value);
- return call != NULL;
-}
-
-static void
-scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GError *err = NULL;
-
- nm_call_store_remove (priv->other_pcalls, proxy, call_id);
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID))
- nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", err->message);
-
- g_signal_emit (self, signals[SCAN_DONE], 0, err ? FALSE : TRUE);
- g_clear_error (&err);
+ g_clear_object (&priv->cfg);
+ if (cfg) {
+ priv->cfg = g_object_ref (cfg);
+ g_dbus_proxy_call (priv->iface_proxy,
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)",
+ WPAS_DBUS_IFACE_INTERFACE,
+ "ApScan",
+ g_variant_new_uint32 (nm_supplicant_config_get_ap_scan (priv->cfg))),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->assoc_cancellable,
+ (GAsyncReadyCallback) set_ap_scan_cb,
+ self);
+ }
+ return TRUE;
}
static void
-destroy_gvalue (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static GValue *
-string_to_gvalue (const char *str)
+scan_request_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
- GValue *val = g_slice_new0 (GValue);
+ gs_unref_variant GVariant *reply = NULL;
+ gs_free_error GError *error = NULL;
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
- return val;
-}
-
-static GValue *
-byte_array_array_to_gvalue (const GPtrArray *array)
-{
- GValue *val = g_slice_new0 (GValue);
+ reply = g_dbus_proxy_call_finish (proxy, result, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR);
- g_value_set_boxed (val, array);
- return val;
+ if (error)
+ nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", error->message);
+ g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[SCAN_DONE], 0, error ? FALSE : TRUE);
}
gboolean
nm_supplicant_interface_request_scan (NMSupplicantInterface *self, const GPtrArray *ssids)
{
NMSupplicantInterfacePrivate *priv;
- DBusGProxyCall *call;
- GHashTable *hash;
+ GVariantBuilder builder;
+ guint i;
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
/* Scan parameters */
- hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue);
- g_hash_table_insert (hash, "Type", string_to_gvalue ("active"));
- if (ssids)
- g_hash_table_insert (hash, "SSIDs", byte_array_array_to_gvalue (ssids));
-
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "Scan",
- scan_request_cb,
- self,
- NULL,
- DBUS_TYPE_G_MAP_OF_VARIANT, hash,
- G_TYPE_INVALID);
- g_hash_table_destroy (hash);
- nm_call_store_add (priv->other_pcalls, priv->iface_proxy, call);
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&builder, "{sv}", "Type", g_variant_new_string ("active"));
+ if (ssids) {
+ GVariantBuilder ssids_builder;
+
+ g_variant_builder_init (&ssids_builder, G_VARIANT_TYPE_BYTESTRING_ARRAY);
+ for (i = 0; i < ssids->len; i++) {
+ GByteArray *ssid = g_ptr_array_index (ssids, i);
+ g_variant_builder_add (&ssids_builder, "@ay",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ ssid->data, ssid->len, 1));
+ }
+ g_variant_builder_add (&builder, "{sv}", "SSIDs", g_variant_builder_end (&ssids_builder));
+ }
- return call != NULL;
+ g_dbus_proxy_call (priv->iface_proxy,
+ "Scan",
+ g_variant_new ("(a{sv})", &builder),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ priv->other_cancellable,
+ (GAsyncReadyCallback) scan_request_cb,
+ self);
+ return TRUE;
}
guint32
@@ -1323,8 +1218,7 @@ nm_supplicant_interface_get_max_scan_ssids (NMSupplicantInterface *self)
/*******************************************************************/
NMSupplicantInterface *
-nm_supplicant_interface_new (NMSupplicantManager *smgr,
- const char *ifname,
+nm_supplicant_interface_new (const char *ifname,
gboolean is_wireless,
gboolean fast_supported,
ApSupport ap_support,
@@ -1332,21 +1226,12 @@ nm_supplicant_interface_new (NMSupplicantManager *smgr,
{
NMSupplicantInterface *self;
NMSupplicantInterfacePrivate *priv;
- guint id;
- g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL);
g_return_val_if_fail (ifname != NULL, NULL);
self = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE, NULL);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- priv->smgr = g_object_ref (smgr);
- id = g_signal_connect (priv->smgr,
- "notify::" NM_SUPPLICANT_MANAGER_AVAILABLE,
- G_CALLBACK (smgr_avail_cb),
- self);
- priv->smgr_avail_id = id;
-
priv->dev = g_strdup (ifname);
priv->is_wireless = is_wireless;
priv->fast_supported = fast_supported;
@@ -1362,19 +1247,8 @@ static void
nm_supplicant_interface_init (NMSupplicantInterface * self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGConnection *bus;
priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
- priv->assoc_pcalls = nm_call_store_new ();
- priv->other_pcalls = nm_call_store_new ();
- priv->dbus_mgr = nm_dbus_manager_get ();
-
- bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
- priv->wpas_proxy = dbus_g_proxy_new_for_name (bus,
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- WPAS_DBUS_INTERFACE);
-
priv->bss_proxies = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
}
@@ -1412,49 +1286,24 @@ dispose (GObject *object)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
- if (priv->disposed) {
- G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
- return;
- }
- priv->disposed = TRUE;
+ g_clear_object (&priv->iface_proxy);
- /* Cancel pending calls before unrefing the dbus manager */
- nm_call_store_clear (priv->other_pcalls);
- nm_call_store_destroy (priv->other_pcalls);
+ if (priv->init_cancellable)
+ g_cancellable_cancel (priv->init_cancellable);
+ g_clear_object (&priv->init_cancellable);
- nm_call_store_clear (priv->assoc_pcalls);
- nm_call_store_destroy (priv->assoc_pcalls);
+ if (priv->other_cancellable)
+ g_cancellable_cancel (priv->other_cancellable);
+ g_clear_object (&priv->other_cancellable);
- if (priv->props_proxy)
- g_object_unref (priv->props_proxy);
+ g_clear_object (&priv->wpas_proxy);
+ g_clear_pointer (&priv->bss_proxies, (GDestroyNotify) g_hash_table_destroy);
- if (priv->iface_proxy)
- g_object_unref (priv->iface_proxy);
+ g_clear_pointer (&priv->net_path, g_free);
+ g_clear_pointer (&priv->dev, g_free);
+ g_clear_pointer (&priv->object_path, g_free);
- g_free (priv->net_path);
-
- if (priv->introspect_proxy)
- g_object_unref (priv->introspect_proxy);
-
- if (priv->wpas_proxy)
- g_object_unref (priv->wpas_proxy);
-
- g_hash_table_destroy (priv->bss_proxies);
-
- if (priv->smgr) {
- if (priv->smgr_avail_id)
- g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id);
- g_object_unref (priv->smgr);
- }
-
- g_free (priv->dev);
-
- priv->dbus_mgr = NULL;
-
- if (priv->cfg)
- g_object_unref (priv->cfg);
-
- g_free (priv->object_path);
+ g_clear_object (&priv->cfg);
/* Chain up to the parent class */
G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
@@ -1502,7 +1351,7 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMSupplicantInterfaceClass, new_bss),
NULL, NULL, NULL,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VARIANT);
signals[BSS_UPDATED] =
g_signal_new (NM_SUPPLICANT_INTERFACE_BSS_UPDATED,
diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h
index 0112e40eae..1b1139d404 100644
--- a/src/supplicant-manager/nm-supplicant-interface.h
+++ b/src/supplicant-manager/nm-supplicant-interface.h
@@ -119,13 +119,15 @@ typedef struct {
GType nm_supplicant_interface_get_type (void);
-NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr,
- const char *ifname,
+NMSupplicantInterface * nm_supplicant_interface_new (const char *ifname,
gboolean is_wireless,
gboolean fast_supported,
ApSupport ap_support,
gboolean start_now);
+void nm_supplicant_interface_set_supplicant_available (NMSupplicantInterface *self,
+ gboolean available);
+
gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface,
NMSupplicantConfig * cfg);
diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c
index 9a7a69844b..d07e23aeab 100644
--- a/src/supplicant-manager/nm-supplicant-manager.c
+++ b/src/supplicant-manager/nm-supplicant-manager.c
@@ -27,9 +27,8 @@
#include "nm-supplicant-manager.h"
#include "nm-supplicant-interface.h"
-#include "nm-dbus-manager.h"
#include "nm-logging.h"
-#include "nm-dbus-glib-types.h"
+#include "nm-core-internal.h"
#define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_MANAGER, \
@@ -37,25 +36,16 @@
G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT)
-/* Properties */
-enum {
- PROP_0 = 0,
- PROP_AVAILABLE,
- LAST_PROP
-};
-
typedef struct {
- NMDBusManager * dbus_mgr;
- guint name_owner_id;
- DBusGProxy * proxy;
- DBusGProxy * props_proxy;
- gboolean running;
+ GDBusProxy * proxy;
+ GCancellable * cancellable;
+ gboolean running;
+
GHashTable * ifaces;
gboolean fast_supported;
ApSupport ap_support;
guint die_count_reset_id;
guint die_count;
- gboolean disposed;
} NMSupplicantManagerPrivate;
/********************************************************************/
@@ -90,14 +80,16 @@ nm_supplicant_manager_iface_get (NMSupplicantManager * self,
start_now = !die_count_exceeded (priv->die_count);
nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
- iface = nm_supplicant_interface_new (self,
- ifname,
+ iface = nm_supplicant_interface_new (ifname,
is_wireless,
priv->fast_supported,
priv->ap_support,
start_now);
- if (iface)
- g_hash_table_insert (priv->ifaces, g_strdup (ifname), iface);
+ if (iface) {
+ g_hash_table_insert (priv->ifaces,
+ (char *) nm_supplicant_interface_get_ifname (iface),
+ iface);
+ }
} else {
nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname);
}
@@ -125,35 +117,27 @@ nm_supplicant_manager_iface_release (NMSupplicantManager *self,
/* Ask wpa_supplicant to remove this interface */
op = nm_supplicant_interface_get_object_path (iface);
if (priv->running && priv->proxy && op) {
- dbus_g_proxy_call_no_reply (priv->proxy, "RemoveInterface",
- DBUS_TYPE_G_OBJECT_PATH, op,
- G_TYPE_INVALID);
+ g_dbus_proxy_call (priv->proxy,
+ "RemoveInterface",
+ g_variant_new ("(o)", op),
+ G_DBUS_CALL_FLAGS_NONE,
+ 3000,
+ NULL,
+ NULL,
+ NULL);
}
g_hash_table_remove (priv->ifaces, ifname);
}
static void
-get_capabilities_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+update_capabilities (NMSupplicantManager *self)
{
- NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
NMSupplicantInterface *iface;
GHashTableIter hash_iter;
- GError *error = NULL;
- GHashTable *props = NULL;
- GValue *value;
- char **iter;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_MAP_OF_VARIANT, &props,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_CORE, "Unexpected error requesting supplicant properties: (%d) %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- return;
- }
+ const char **array;
+ GVariant *value;
/* The supplicant only advertises global capabilities if the following
* commit has been applied:
@@ -165,13 +149,17 @@ get_capabilities_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_
* dbus: Add global capabilities property
*/
priv->ap_support = AP_SUPPORT_UNKNOWN;
- value = g_hash_table_lookup (props, "Capabilities");
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRV)) {
- priv->ap_support = AP_SUPPORT_NO;
- for (iter = g_value_get_boxed (value); iter && *iter; iter++) {
- if (strcasecmp (*iter, "ap") == 0)
+
+ value = g_dbus_proxy_get_cached_property (priv->proxy, "Capabilities");
+ if (value) {
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) {
+ array = g_variant_get_strv (value, NULL);
+ priv->ap_support = AP_SUPPORT_NO;
+ if (_nm_utils_string_in_list ("ap", array))
priv->ap_support = AP_SUPPORT_YES;
+ g_free (array);
}
+ g_variant_unref (value);
}
/* Tell all interfaces about results of the AP check */
@@ -185,32 +173,35 @@ get_capabilities_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_
/* EAP-FAST */
priv->fast_supported = FALSE;
- value = g_hash_table_lookup (props, "EapMethods");
- if (value && G_VALUE_HOLDS (value, G_TYPE_STRV)) {
- for (iter = g_value_get_boxed (value); iter && *iter; iter++) {
- if (strcasecmp (*iter, "fast") == 0)
+ value = g_dbus_proxy_get_cached_property (priv->proxy, "EapMethods");
+ if (value) {
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING_ARRAY)) {
+ array = g_variant_get_strv (value, NULL);
+ if (_nm_utils_string_in_list ("fast", array))
priv->fast_supported = TRUE;
+ g_free (array);
}
+ g_variant_unref (value);
}
nm_log_dbg (LOGD_SUPPLICANT, "EAP-FAST is %ssupported", priv->fast_supported ? "" : "not ");
-
- g_hash_table_unref (props);
}
static void
-check_capabilities (NMSupplicantManager *self)
+availability_changed (NMSupplicantManager *self, gboolean available)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+ GList *ifaces, *iter;
- dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
- get_capabilities_cb, self, NULL,
- G_TYPE_STRING, WPAS_DBUS_INTERFACE,
- G_TYPE_INVALID);
+ /* priv->ifaces may be modified if availability changes; can't use GHashTableIter */
+ ifaces = g_hash_table_get_values (priv->ifaces);
+ for (iter = ifaces; iter; iter = iter->next)
+ nm_supplicant_interface_set_supplicant_available (NM_SUPPLICANT_INTERFACE (iter->data), available);
+ g_list_free (ifaces);
}
-gboolean
-nm_supplicant_manager_available (NMSupplicantManager *self)
+static gboolean
+is_available (NMSupplicantManager *self)
{
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
@@ -223,22 +214,26 @@ static void
set_running (NMSupplicantManager *self, gboolean now_running)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- gboolean old_available = nm_supplicant_manager_available (self);
+ gboolean old_available = is_available (self);
+ gboolean new_available;
priv->running = now_running;
- if (old_available != nm_supplicant_manager_available (self))
- g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE);
+ new_available = is_available (self);
+ if (old_available != new_available)
+ availability_changed (self, new_available);
}
static void
set_die_count (NMSupplicantManager *self, guint new_die_count)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- gboolean old_available = nm_supplicant_manager_available (self);
+ gboolean old_available = is_available (self);
+ gboolean new_available;
priv->die_count = new_die_count;
- if (old_available != nm_supplicant_manager_available (self))
- g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE);
+ new_available = is_available (self);
+ if (old_available != new_available)
+ availability_changed (self, new_available);
}
static gboolean
@@ -255,28 +250,21 @@ wpas_die_count_reset_cb (gpointer user_data)
}
static void
-name_owner_changed (NMDBusManager *dbus_mgr,
- const char *name,
- const char *old_owner,
- const char *new_owner,
- gpointer user_data)
+name_owner_cb (GDBusProxy *proxy, GParamSpec *pspec, gpointer user_data)
{
NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- gboolean old_owner_good = (old_owner && strlen (old_owner));
- gboolean new_owner_good = (new_owner && strlen (new_owner));
+ char *owner;
- /* We only care about the supplicant here */
- if (strcmp (WPAS_DBUS_SERVICE, name) != 0)
- return;
+ g_return_if_fail (proxy == priv->proxy);
- if (!old_owner_good && new_owner_good) {
- nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant started");
- set_running (self, TRUE);
- check_capabilities (self);
- } else if (old_owner_good && !new_owner_good) {
- nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant stopped");
+ owner = g_dbus_proxy_get_name_owner (proxy);
+ nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant %s", owner ? "running" : "stopped");
+ if (owner) {
+ set_running (self, TRUE);
+ update_capabilities (self);
+ } else if (priv->running) {
/* Reschedule the die count reset timeout. Every time the supplicant
* dies we wait 10 seconds before resetting the counter. If the
* supplicant died more than twice before the timer is reset, then
@@ -297,6 +285,33 @@ name_owner_changed (NMDBusManager *dbus_mgr,
priv->fast_supported = FALSE;
}
+
+ g_free (owner);
+}
+
+static void
+on_proxy_acquired (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ NMSupplicantManager *self;
+ NMSupplicantManagerPrivate *priv;
+ GError *error = NULL;
+ GDBusProxy *proxy;
+
+ proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
+ if (!proxy) {
+ nm_log_warn (LOGD_SUPPLICANT,
+ "Failed to acquire wpa_supplicant proxy: Wi-Fi and 802.1x will not be available (%s)",
+ error->message);
+ g_clear_error (&error);
+ return;
+ }
+
+ self = NM_SUPPLICANT_MANAGER (user_data);
+ priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+
+ priv->proxy = proxy;
+ g_signal_connect (priv->proxy, "notify::g-name-owner", G_CALLBACK (name_owner_cb), self);
+ name_owner_cb (priv->proxy, NULL, self);
}
/*******************************************************************/
@@ -307,50 +322,19 @@ static void
nm_supplicant_manager_init (NMSupplicantManager *self)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- DBusGConnection *bus;
-
- priv->dbus_mgr = nm_dbus_manager_get ();
- priv->name_owner_id = g_signal_connect (priv->dbus_mgr,
- NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
- G_CALLBACK (name_owner_changed),
- self);
- priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, WPAS_DBUS_SERVICE);
-
- bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
- priv->proxy = dbus_g_proxy_new_for_name (bus,
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- WPAS_DBUS_INTERFACE);
-
- priv->props_proxy = dbus_g_proxy_new_for_name (bus,
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- DBUS_INTERFACE_PROPERTIES);
-
- priv->ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-
- /* Check generic supplicant capabilities */
- if (priv->running)
- check_capabilities (self);
-}
-
-static void
-set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-}
-static void
-get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- switch (prop_id) {
- case PROP_AVAILABLE:
- g_value_set_boolean (value, nm_supplicant_manager_available (NM_SUPPLICANT_MANAGER (object)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ priv->ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+ priv->cancellable = g_cancellable_new ();
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE,
+ priv->cancellable,
+ (GAsyncReadyCallback) on_proxy_acquired,
+ self);
}
static void
@@ -358,29 +342,19 @@ dispose (GObject *object)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
- if (priv->disposed)
- goto out;
- priv->disposed = TRUE;
-
- if (priv->die_count_reset_id)
+ if (priv->die_count_reset_id) {
g_source_remove (priv->die_count_reset_id);
-
- if (priv->dbus_mgr) {
- if (priv->name_owner_id)
- g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
- priv->dbus_mgr = NULL;
+ priv->die_count_reset_id = 0;
}
- g_hash_table_destroy (priv->ifaces);
-
- if (priv->proxy)
- g_object_unref (priv->proxy);
+ if (priv->cancellable) {
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
+ }
- if (priv->props_proxy)
- g_object_unref (priv->props_proxy);
+ g_clear_pointer (&priv->ifaces, g_hash_table_unref);
+ g_clear_object (&priv->proxy);
-out:
- /* Chain up to the parent class */
G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
}
@@ -391,15 +365,6 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
- object_class->get_property = get_property;
- object_class->set_property = set_property;
object_class->dispose = dispose;
-
- g_object_class_install_property
- (object_class, PROP_AVAILABLE,
- g_param_spec_boolean (NM_SUPPLICANT_MANAGER_AVAILABLE, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
}
diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h
index 5e7f1eb596..3b8fddf4e6 100644
--- a/src/supplicant-manager/nm-supplicant-manager.h
+++ b/src/supplicant-manager/nm-supplicant-manager.h
@@ -26,11 +26,6 @@
#include "nm-supplicant-types.h"
#include "nm-device.h"
-#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1"
-#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1"
-#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1"
-
-
G_BEGIN_DECLS
#define NM_TYPE_SUPPLICANT_MANAGER (nm_supplicant_manager_get_type ())
@@ -40,8 +35,6 @@ G_BEGIN_DECLS
#define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER))
#define NM_SUPPLICANT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass))
-#define NM_SUPPLICANT_MANAGER_AVAILABLE "available"
-
struct _NMSupplicantManager
{
GObject parent;
@@ -63,6 +56,4 @@ NMSupplicantInterface *nm_supplicant_manager_iface_get (NMSupplicantManager *mgr
void nm_supplicant_manager_iface_release (NMSupplicantManager *mgr,
NMSupplicantInterface *iface);
-gboolean nm_supplicant_manager_available (NMSupplicantManager *mgr);
-
#endif /* __NETWORKMANAGER_SUPPLICANT_MANAGER_H__ */
diff --git a/src/supplicant-manager/nm-supplicant-types.h b/src/supplicant-manager/nm-supplicant-types.h
index 619f0c3e91..1c16e49433 100644
--- a/src/supplicant-manager/nm-supplicant-types.h
+++ b/src/supplicant-manager/nm-supplicant-types.h
@@ -21,6 +21,10 @@
#ifndef __NETWORKMANAGER_SUPPLICANT_TYPES_H__
#define __NETWORKMANAGER_SUPPLICANT_TYPES_H__
+#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1"
+#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1"
+#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1"
+
typedef struct _NMSupplicantManager NMSupplicantManager;
typedef struct _NMSupplicantInterface NMSupplicantInterface;
typedef struct _NMSupplicantConfig NMSupplicantConfig;
diff --git a/src/supplicant-manager/tests/test-supplicant-config.c b/src/supplicant-manager/tests/test-supplicant-config.c
index 5ffead40d4..937757b220 100644
--- a/src/supplicant-manager/tests/test-supplicant-config.c
+++ b/src/supplicant-manager/tests/test-supplicant-config.c
@@ -41,78 +41,67 @@
static gboolean
validate_opt (const char *detail,
- GHashTable *hash,
+ GVariant *config,
const char *key,
OptType val_type,
gconstpointer expected,
size_t expected_len)
{
- GValue *value;
- gint int_val;
- GByteArray *array;
+ char *config_key;
+ GVariant *config_value;
+ gboolean found = FALSE;
+ const guint8 *bytes;
+ gsize len;
const char *s;
const unsigned char *expected_array = expected;
- int result;
-
- ASSERT (hash != NULL, detail, "hash was NULL");
-
- value = g_hash_table_lookup (hash, key);
- ASSERT (value != NULL,
- detail, "option '%s' expected but not found in config hash.");
-
- switch (val_type) {
- case TYPE_INT:
- ASSERT (G_VALUE_HOLDS_INT (value),
- detail, "config hash item '%s' was not TYPE_INT.", key);
- int_val = g_value_get_int (value);
- ASSERT (int_val == GPOINTER_TO_INT (expected),
- detail, "unexpected config hash item '%s' value %d (expected %d)",
- key, int_val, GPOINTER_TO_INT (expected));
- break;
- case TYPE_BYTES:
- ASSERT (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY),
- detail, "config hash item '%s' was not TYPE_BYTES.", key);
- array = g_value_get_boxed (value);
- ASSERT (array->len == expected_len,
- detail, "unexpected config hash item '%s' length %d (expected %d)",
- key, array->len, expected_len);
- result = memcmp (array->data, expected_array, expected_len);
- ASSERT (result == 0, detail, "unexpected config hash item '%s' value", key);
- break;
- case TYPE_KEYWORD:
- case TYPE_STRING:
- ASSERT (G_VALUE_HOLDS_STRING (value),
- detail, "config hash item '%s' was not TYPE_STRING or TYPE_KEYWORD.", key);
- if (expected_len == -1)
- expected_len = strlen ((const char *) expected);
- s = g_value_get_string (value);
- ASSERT (s != NULL, detail, "unexpected NULL config hash string item '%s'.", key);
- ASSERT (strlen (s) == expected_len,
- detail, "unexpected config hash string item '%s' length %d (expected %d)",
- key, strlen (s), expected_len);
- result = strcmp (s, (const char *) expected);
- ASSERT (result == 0,
- detail, "unexpected config hash string item '%s' value '%s' (expected '%s')",
- key, s, (const char *) expected);
- break;
- default:
- g_warning ("unknown supplicant config hash item '%s' option type %d",
- key, val_type);
- return FALSE;
+ GVariantIter iter;
+
+ g_assert (g_variant_is_of_type (config, G_VARIANT_TYPE_VARDICT));
+
+ g_variant_iter_init (&iter, config);
+ while (g_variant_iter_next (&iter, "{&sv}", (gpointer) &config_key, (gpointer) &config_value)) {
+ if (!strcmp (key, config_key)) {
+ found = TRUE;
+ switch (val_type) {
+ case TYPE_INT:
+ g_assert (g_variant_is_of_type (config_value, G_VARIANT_TYPE_INT32));
+ g_assert_cmpint (g_variant_get_int32 (config_value), ==, GPOINTER_TO_INT (expected));
+ break;
+ case TYPE_BYTES:
+ g_assert (g_variant_is_of_type (config_value, G_VARIANT_TYPE_BYTESTRING));
+ bytes = g_variant_get_fixed_array (config_value, &len, 1);
+ g_assert_cmpint (len, ==, expected_len);
+ g_assert (memcmp (bytes, expected_array, expected_len) == 0);
+ break;
+ case TYPE_KEYWORD:
+ case TYPE_STRING:
+ g_assert (g_variant_is_of_type (config_value, G_VARIANT_TYPE_STRING));
+ if (expected_len == -1)
+ expected_len = strlen ((const char *) expected);
+ s = g_variant_get_string (config_value, NULL);
+ g_assert_cmpint (strlen (s), ==, expected_len);
+ g_assert_cmpstr (s, ==, expected);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+ g_variant_unref (config_value);
}
- return TRUE;
+ return found;
}
static void
test_wifi_open (void)
{
- NMConnection *connection;
+ gs_unref_object NMConnection *connection = NULL;
+ gs_unref_object NMSupplicantConfig *config = NULL;
+ gs_unref_variant GVariant *config_dict = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingIPConfig *s_ip4;
- gs_unref_object NMSupplicantConfig *config = NULL;
- GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
@@ -156,9 +145,9 @@ test_wifi_open (void)
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
- ASSERT (nm_connection_verify (connection, &error) == TRUE,
- "wifi-open", "failed to verify connection: %s",
- (error && error->message) ? error->message : "(unknown)");
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
config = nm_supplicant_config_new ();
@@ -170,29 +159,21 @@ test_wifi_open (void)
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
- ASSERT (success == TRUE,
- "wifi-open", "failed to add wireless setting to supplicant config.");
+ g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'key_mgmt' value 'NONE'");
- success = nm_supplicant_config_add_no_security (config);
- ASSERT (success == TRUE,
- "wifi-open", "failed to add wireless security to supplicant config.");
+ g_assert (nm_supplicant_config_add_no_security (config));
g_test_assert_expected_messages ();
- hash = nm_supplicant_config_get_hash (config);
- ASSERT (hash != NULL,
- "wifi-open", "failed to hash supplicant config options.");
-
- validate_opt ("wifi-open", hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
- validate_opt ("wifi-open", hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
- validate_opt ("wifi-open", hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
- validate_opt ("wifi-open", hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
+ config_dict = nm_supplicant_config_to_variant (config);
+ g_assert (config_dict);
- g_hash_table_unref (hash);
- g_object_unref (connection);
+ validate_opt ("wifi-open", config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
+ validate_opt ("wifi-open", config_dict, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
+ validate_opt ("wifi-open", config_dict, "bssid", TYPE_KEYWORD, bssid_str, -1);
+ validate_opt ("wifi-open", config_dict, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
}
static void
@@ -202,13 +183,13 @@ test_wifi_wep_key (const char *detail,
const unsigned char *expected,
size_t expected_size)
{
- NMConnection *connection;
+ gs_unref_object NMConnection *connection = NULL;
+ gs_unref_object NMSupplicantConfig *config = NULL;
+ gs_unref_variant GVariant *config_dict = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSettingIPConfig *s_ip4;
- gs_unref_object NMSupplicantConfig *config = NULL;
- GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
@@ -262,9 +243,9 @@ test_wifi_wep_key (const char *detail,
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
- ASSERT (nm_connection_verify (connection, &error) == TRUE,
- detail, "failed to verify connection: %s",
- (error && error->message) ? error->message : "(unknown)");
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
config = nm_supplicant_config_new ();
@@ -276,9 +257,7 @@ test_wifi_wep_key (const char *detail,
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
- ASSERT (success == TRUE,
- detail, "failed to add wireless setting to supplicant config.");
+ g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
@@ -287,27 +266,21 @@ test_wifi_wep_key (const char *detail,
"*added 'wep_key0' value *");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'wep_tx_keyidx' value '0'");
- success = nm_supplicant_config_add_setting_wireless_security (config,
+ g_assert (nm_supplicant_config_add_setting_wireless_security (config,
s_wsec,
NULL,
- "376aced7-b28c-46be-9a62-fcdf072571da");
- ASSERT (success == TRUE,
- detail, "failed to add wireless security to supplicant config.");
+ "376aced7-b28c-46be-9a62-fcdf072571da"));
g_test_assert_expected_messages ();
- hash = nm_supplicant_config_get_hash (config);
- ASSERT (hash != NULL,
- detail, "failed to hash supplicant config options.");
+ config_dict = nm_supplicant_config_to_variant (config);
+ g_assert (config_dict);
- validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
- validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
- validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
- validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
- validate_opt (detail, hash, "wep_tx_keyidx", TYPE_INT, GINT_TO_POINTER (0), -1);
- validate_opt (detail, hash, "wep_key0", TYPE_BYTES, expected, expected_size);
-
- g_hash_table_unref (hash);
- g_object_unref (connection);
+ validate_opt (detail, config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
+ validate_opt (detail, config_dict, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
+ validate_opt (detail, config_dict, "bssid", TYPE_KEYWORD, bssid_str, -1);
+ validate_opt (detail, config_dict, "key_mgmt", TYPE_KEYWORD, "NONE", -1);
+ validate_opt (detail, config_dict, "wep_tx_keyidx", TYPE_INT, GINT_TO_POINTER (0), -1);
+ validate_opt (detail, config_dict, "wep_key0", TYPE_BYTES, expected, expected_size);
}
static void
@@ -340,13 +313,13 @@ test_wifi_wpa_psk (const char *detail,
const unsigned char *expected,
size_t expected_size)
{
- NMConnection *connection;
+ gs_unref_object NMConnection *connection = NULL;
+ gs_unref_object NMSupplicantConfig *config = NULL;
+ gs_unref_variant GVariant *config_dict = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
NMSettingIPConfig *s_ip4;
- gs_unref_object NMSupplicantConfig *config = NULL;
- GHashTable *hash;
char *uuid;
gboolean success;
GError *error = NULL;
@@ -406,9 +379,9 @@ test_wifi_wpa_psk (const char *detail,
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
- ASSERT (nm_connection_verify (connection, &error) == TRUE,
- detail, "failed to verify connection: %s",
- (error && error->message) ? error->message : "(unknown)");
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
config = nm_supplicant_config_new ();
@@ -420,9 +393,7 @@ test_wifi_wpa_psk (const char *detail,
"*added 'bssid' value '11:22:33:44:55:66'*");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'freq_list' value *");
- success = nm_supplicant_config_add_setting_wireless (config, s_wifi, 0);
- ASSERT (success == TRUE,
- detail, "failed to add wireless setting to supplicant config.");
+ g_assert (nm_supplicant_config_add_setting_wireless (config, s_wifi, 0));
g_test_assert_expected_messages ();
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
@@ -435,29 +406,23 @@ test_wifi_wpa_psk (const char *detail,
"*added 'pairwise' value 'TKIP CCMP'");
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*added 'group' value 'TKIP CCMP'");
- success = nm_supplicant_config_add_setting_wireless_security (config,
+ g_assert (nm_supplicant_config_add_setting_wireless_security (config,
s_wsec,
NULL,
- "376aced7-b28c-46be-9a62-fcdf072571da");
- ASSERT (success == TRUE,
- detail, "failed to add wireless security to supplicant config.");
+ "376aced7-b28c-46be-9a62-fcdf072571da"));
g_test_assert_expected_messages ();
- hash = nm_supplicant_config_get_hash (config);
- ASSERT (hash != NULL,
- detail, "failed to hash supplicant config options.");
-
- validate_opt (detail, hash, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
- validate_opt (detail, hash, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
- validate_opt (detail, hash, "bssid", TYPE_KEYWORD, bssid_str, -1);
- validate_opt (detail, hash, "key_mgmt", TYPE_KEYWORD, "WPA-PSK", -1);
- validate_opt (detail, hash, "proto", TYPE_KEYWORD, "WPA RSN", -1);
- validate_opt (detail, hash, "pairwise", TYPE_KEYWORD, "TKIP CCMP", -1);
- validate_opt (detail, hash, "group", TYPE_KEYWORD, "TKIP CCMP", -1);
- validate_opt (detail, hash, "psk", key_type, expected, expected_size);
-
- g_hash_table_unref (hash);
- g_object_unref (connection);
+ config_dict = nm_supplicant_config_to_variant (config);
+ g_assert (config_dict);
+
+ validate_opt (detail, config_dict, "scan_ssid", TYPE_INT, GINT_TO_POINTER (1), -1);
+ validate_opt (detail, config_dict, "ssid", TYPE_BYTES, ssid_data, sizeof (ssid_data));
+ validate_opt (detail, config_dict, "bssid", TYPE_KEYWORD, bssid_str, -1);
+ validate_opt (detail, config_dict, "key_mgmt", TYPE_KEYWORD, "WPA-PSK", -1);
+ validate_opt (detail, config_dict, "proto", TYPE_KEYWORD, "WPA RSN", -1);
+ validate_opt (detail, config_dict, "pairwise", TYPE_KEYWORD, "TKIP CCMP", -1);
+ validate_opt (detail, config_dict, "group", TYPE_KEYWORD, "TKIP CCMP", -1);
+ validate_opt (detail, config_dict, "psk", key_type, expected, expected_size);
}
static void
@@ -478,18 +443,12 @@ NMTST_DEFINE ();
int main (int argc, char **argv)
{
- char *base;
-
nmtst_init (&argc, &argv, TRUE);
- /* The tests */
- test_wifi_open ();
- test_wifi_wep ();
- test_wifi_wpa_psk_types ();
+ g_test_add_func ("/supplicant-config/wifi-open", test_wifi_open);
+ g_test_add_func ("/supplicant-config/wifi-wep", test_wifi_wep);
+ g_test_add_func ("/supplicant-config/wifi-wpa-psk-types", test_wifi_wpa_psk_types);
- base = g_path_get_basename (argv[0]);
- fprintf (stdout, "%s: SUCCESS\n", base);
- g_free (base);
- return 0;
+ return g_test_run ();
}