summaryrefslogtreecommitdiff
path: root/src/supplicant-manager/nm-supplicant-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/supplicant-manager/nm-supplicant-interface.c')
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c1588
1 files changed, 904 insertions, 684 deletions
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index e9e58f39f..a65a458f5 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2006 - 2010 Red Hat, Inc.
+ * Copyright (C) 2006 - 2008 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -34,48 +34,73 @@
#include "nm-glib-compat.h"
#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
-#define WPAS_DBUS_IFACE_BSS WPAS_DBUS_INTERFACE ".BSS"
+#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID"
#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network"
#define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface"
-#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists"
+#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".ExistsError"
-G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
-static void wpas_iface_properties_changed (DBusGProxy *proxy,
- GHashTable *props,
- gpointer user_data);
+G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
-static void wpas_iface_scan_done (DBusGProxy *proxy,
- gboolean success,
- gpointer user_data);
#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_INTERFACE, \
NMSupplicantInterfacePrivate))
+static void nm_supplicant_interface_set_property (GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+
+static void nm_supplicant_interface_get_property (GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+
+static void nm_supplicant_interface_start (NMSupplicantInterface *self);
+
+static void nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface *self,
+ gboolean get_only);
+
+static void nm_supplicant_interface_smgr_state_changed (NMSupplicantManager *smgr,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data);
+
+static void nm_supplicant_interface_set_state (NMSupplicantInterface *self,
+ guint32 new_state);
+
+
/* Signals */
enum {
STATE, /* change in the interface's state */
REMOVED, /* interface was removed by the supplicant */
- NEW_BSS, /* interface saw a new access point from a scan */
- SCAN_DONE, /* wifi scan is complete */
+ SCANNED_AP, /* interface saw a new access point from a scan */
+ SCAN_REQ_RESULT, /* result of a wireless scan request */
+ SCAN_RESULTS, /* scan results returned from supplicant */
+ CONNECTION_STATE, /* link state of the device's connection */
CONNECTION_ERROR, /* an error occurred during a connection request */
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+static guint nm_supplicant_interface_signals[LAST_SIGNAL] = { 0 };
/* Properties */
enum {
PROP_0 = 0,
+ PROP_SUPPLICANT_MANAGER,
+ PROP_DEVICE,
+ PROP_STATE,
+ PROP_CONNECTION_STATE,
PROP_SCANNING,
LAST_PROP
};
-typedef struct {
+typedef struct
+{
NMSupplicantManager * smgr;
- gulong smgr_avail_id;
+ gulong smgr_state_sig_handler;
NMDBusManager * dbus_mgr;
char * dev;
gboolean is_wireless;
@@ -85,19 +110,18 @@ typedef struct {
NMCallStore * assoc_pcalls;
NMCallStore * other_pcalls;
+ guint32 con_state;
gboolean scanning;
- DBusGProxy * wpas_proxy;
DBusGProxy * iface_proxy;
- DBusGProxy * props_proxy;
- char * net_path;
- guint32 blobs_left;
+ DBusGProxy * net_proxy;
+ guint scan_results_timeout;
guint32 last_scan;
NMSupplicantConfig * cfg;
- gboolean disposed;
+ gboolean dispose_has_run;
} NMSupplicantInterfacePrivate;
static gboolean
@@ -179,488 +203,827 @@ nm_supplicant_info_destroy (gpointer user_data)
}
}
-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);
+NMSupplicantInterface *
+nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless)
+{
+ NMSupplicantInterface * iface;
- g_signal_emit (self, signals[CONNECTION_ERROR], 0, name, err->message);
-}
+ g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL);
+ g_return_val_if_fail (ifname != NULL, NULL);
-static void
-bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- GError *error = NULL;
- GHashTable *props = NULL;
-
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_MAP_OF_VARIANT, &props,
- G_TYPE_INVALID)) {
- g_signal_emit (info->interface, signals[NEW_BSS], 0, 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);
+ iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
+ "supplicant-manager", smgr,
+ "device", ifname,
+ NULL);
+ if (iface) {
+ NM_SUPPLICANT_INTERFACE_GET_PRIVATE (iface)->is_wireless = is_wireless;
+ nm_supplicant_interface_start (iface);
}
+
+ return iface;
}
static void
-request_bss_properties (NMSupplicantInterface *self,
- GPtrArray *paths)
+nm_supplicant_interface_init (NMSupplicantInterface * self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- int i;
- /* Fire off a "properties" call for each returned BSSID */
- for (i = 0; i < paths->len; i++) {
- NMSupplicantInfo *info;
- DBusGProxy *proxy;
- DBusGProxyCall *call;
+ priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
+ priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
+ priv->assoc_pcalls = nm_call_store_new ();
+ priv->other_pcalls = nm_call_store_new ();
- proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- g_ptr_array_index (paths, i),
- DBUS_INTERFACE_PROPERTIES);
- info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (proxy, "GetAll",
- bssid_properties_cb,
- info,
- nm_supplicant_info_destroy,
- G_TYPE_STRING, WPAS_DBUS_IFACE_BSS,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
- g_object_unref (proxy);
- }
+ priv->dispose_has_run = FALSE;
+
+ priv->dbus_mgr = nm_dbus_manager_get ();
}
+
static void
-wpas_iface_bss_added (DBusGProxy *proxy,
- const char *object_path,
- GHashTable *props,
- gpointer user_data)
+nm_supplicant_interface_set_property (GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec)
{
- g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[NEW_BSS], 0, props);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
+ gulong id;
+
+ switch (prop_id) {
+ case PROP_SUPPLICANT_MANAGER:
+ priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value));
+ g_object_ref (G_OBJECT (priv->smgr));
+
+ id = g_signal_connect (priv->smgr,
+ "state",
+ G_CALLBACK (nm_supplicant_interface_smgr_state_changed),
+ object);
+ priv->smgr_state_sig_handler = id;
+ break;
+ case PROP_DEVICE:
+ /* Construct-only */
+ priv->dev = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
-static int
-wpas_state_string_to_enum (const char *str_state)
+static void
+nm_supplicant_interface_get_property (GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec)
{
- 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;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_SUPPLICANT_MANAGER:
+ g_value_set_object (value, G_OBJECT (priv->smgr));
+ break;
+ case PROP_DEVICE:
+ g_value_set_string (value, priv->dev);
+ break;
+ case PROP_STATE:
+ g_value_set_uint (value, priv->state);
+ break;
+ case PROP_CONNECTION_STATE:
+ g_value_set_uint (value, priv->con_state);
+ break;
+ case PROP_SCANNING:
+ g_value_set_boolean (value, priv->scanning);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static void
-set_state (NMSupplicantInterface *self, guint32 new_state)
+try_remove_iface (DBusGConnection *g_connection,
+ const char *path)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- guint32 old_state = priv->state;
+ DBusGProxy *proxy;
- g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
+ g_return_if_fail (g_connection != NULL);
+ g_return_if_fail (path != NULL);
- if (new_state == priv->state)
+ proxy = dbus_g_proxy_new_for_name (g_connection,
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE);
+ if (!proxy)
return;
- /* DOWN is a terminal state */
- g_return_if_fail (priv->state != NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ dbus_g_proxy_call_no_reply (proxy, "removeInterface",
+ DBUS_TYPE_G_OBJECT_PATH, path,
+ G_TYPE_INVALID);
+ g_object_unref (proxy);
+}
- /* Cannot regress to READY, STARTING, or INIT from higher states */
- if (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY)
- g_return_if_fail (new_state > NM_SUPPLICANT_INTERFACE_STATE_READY);
+static void
+nm_supplicant_interface_dispose (GObject *object)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
+ guint32 sm_state;
- if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
- /* Cancel all pending calls when going down */
- cancel_all_callbacks (priv->other_pcalls);
- cancel_all_callbacks (priv->assoc_pcalls);
+ if (priv->dispose_has_run) {
+ G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
+ return;
+ }
- /* 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;
- }
+ priv->dispose_has_run = TRUE;
- 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);
+ /* Ask wpa_supplicant to remove this interface */
+ sm_state = nm_supplicant_manager_get_state (priv->smgr);
+ if (sm_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
+ if (priv->object_path) {
+ try_remove_iface (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ priv->object_path);
}
}
- priv->state = new_state;
- g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
+ if (priv->iface_proxy)
+ g_object_unref (priv->iface_proxy);
+
+ if (priv->net_proxy)
+ g_object_unref (priv->net_proxy);
+
+ if (priv->scan_results_timeout)
+ g_source_remove (priv->scan_results_timeout);
+
+ if (priv->smgr) {
+ g_signal_handler_disconnect (priv->smgr,
+ priv->smgr_state_sig_handler);
+ g_object_unref (priv->smgr);
+ }
+
+ g_free (priv->dev);
+
+ /* Cancel pending calls before unrefing the dbus manager */
+ cancel_all_callbacks (priv->other_pcalls);
+ nm_call_store_destroy (priv->other_pcalls);
+
+ cancel_all_callbacks (priv->assoc_pcalls);
+ nm_call_store_destroy (priv->assoc_pcalls);
+
+ if (priv->dbus_mgr)
+ g_object_unref (priv->dbus_mgr);
+
+ if (priv->cfg)
+ g_object_unref (priv->cfg);
+
+ g_free (priv->object_path);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
}
static void
-set_state_from_string (NMSupplicantInterface *self, const char *new_state)
+nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
{
- int state;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
- state = wpas_state_string_to_enum (new_state);
- g_warn_if_fail (state > 0);
- if (state > 0)
- set_state (self, (guint32) state);
+ object_class->dispose = nm_supplicant_interface_dispose;
+ object_class->set_property = nm_supplicant_interface_set_property;
+ object_class->get_property = nm_supplicant_interface_get_property;
+
+ /* Properties */
+ g_object_class_install_property (object_class,
+ PROP_SUPPLICANT_MANAGER,
+ g_param_spec_object ("supplicant-manager",
+ "Supplicant Manager",
+ "Supplicant manager to which this interface belongs",
+ NM_TYPE_SUPPLICANT_MANAGER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_DEVICE,
+ g_param_spec_string ("device",
+ "Device",
+ "Device which this interface represents to the supplicant",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
+ PROP_STATE,
+ g_param_spec_uint ("state",
+ "State",
+ "State of the supplicant interface; INIT, READY, or DOWN",
+ NM_SUPPLICANT_INTERFACE_STATE_INIT,
+ NM_SUPPLICANT_INTERFACE_STATE_LAST - 1,
+ NM_SUPPLICANT_INTERFACE_STATE_INIT,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_SCANNING,
+ g_param_spec_boolean ("scanning",
+ "Scanning",
+ "Scanning",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* Signals */
+ nm_supplicant_interface_signals[STATE] =
+ g_signal_new ("state",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state),
+ NULL, NULL,
+ _nm_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
+ nm_supplicant_interface_signals[REMOVED] =
+ g_signal_new ("removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ nm_supplicant_interface_signals[SCANNED_AP] =
+ g_signal_new ("scanned-ap",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scanned_ap),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ nm_supplicant_interface_signals[SCAN_REQ_RESULT] =
+ g_signal_new ("scan-req-result",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_req_result),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ nm_supplicant_interface_signals[SCAN_RESULTS] =
+ g_signal_new ("scan-results",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_results),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ nm_supplicant_interface_signals[CONNECTION_STATE] =
+ g_signal_new ("connection-state",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_state),
+ NULL, NULL,
+ _nm_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
+ nm_supplicant_interface_signals[CONNECTION_ERROR] =
+ g_signal_new ("connection-error",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error),
+ NULL, NULL,
+ _nm_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
}
static void
-set_scanning (NMSupplicantInterface *self, gboolean new_scanning)
+emit_error_helper (NMSupplicantInterface *self,
+ GError *err)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- GTimeVal cur_time;
+ const char *name = NULL;
- if (priv->scanning != new_scanning) {
- priv->scanning = new_scanning;
+ if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION)
+ name = dbus_g_error_get_name (err);
- /* Cache time of last scan completion */
- if (priv->scanning == FALSE) {
- g_get_current_time (&cur_time);
- priv->last_scan = cur_time.tv_sec;
+ g_signal_emit (self,
+ nm_supplicant_interface_signals[CONNECTION_ERROR],
+ 0,
+ name,
+ err->message);
+}
+
+static void
+bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ GError *err = NULL;
+ GHashTable *hash = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &hash,
+ G_TYPE_INVALID)) {
+ if (!strstr (err->message, "The BSSID requested was invalid")) {
+ nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.",
+ err->message);
}
+ g_error_free (err);
+ } else {
+ g_signal_emit (info->interface,
+ nm_supplicant_interface_signals[SCANNED_AP],
+ 0,
+ hash);
- g_object_notify (G_OBJECT (self), "scanning");
+ g_hash_table_destroy (hash);
}
}
-gboolean
-nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
+static void
+request_bssid_properties (NMSupplicantInterface * self,
+ const char * op)
{
- NMSupplicantInterfacePrivate *priv;
-
- g_return_val_if_fail (self != NULL, FALSE);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ NMSupplicantInfo *info;
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
- priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- if (priv->scanning)
- return TRUE;
- if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
- return TRUE;
- return FALSE;
+ proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ op,
+ WPAS_DBUS_IFACE_BSSID);
+ info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (proxy, "properties",
+ bssid_properties_cb,
+ info,
+ nm_supplicant_info_destroy,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ g_object_unref (proxy);
}
static void
-wpas_iface_scan_done (DBusGProxy *proxy,
- gboolean success,
- gpointer user_data)
+scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+ GError *err = NULL;
+ GPtrArray *array = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+ DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &array,
+ G_TYPE_INVALID)) {
+ nm_log_warn (LOGD_SUPPLICANT, "could not get scan results: %s.", err->message);
+ g_error_free (err);
+ } else {
+ int i;
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+
+ /* Notify listeners of the result of the scan */
+ g_signal_emit (info->interface,
+ nm_supplicant_interface_signals[SCAN_RESULTS],
+ 0,
+ array->len);
+
+ /* Fire off a "properties" call for each returned BSSID */
+ for (i = 0; i < array->len; i++) {
+ char *op = g_ptr_array_index (array, i);
+
+ request_bssid_properties (info->interface, op);
+ g_free (op);
+ }
+
+ g_ptr_array_free (array, TRUE);
+ }
+}
+
+static gboolean
+request_scan_results (gpointer user_data)
{
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ NMSupplicantInfo *info;
+ DBusGProxyCall *call;
GTimeVal cur_time;
- /* Cache last scan completed time */
+ priv->scan_results_timeout = 0;
+
+ g_return_val_if_fail (priv->iface_proxy != NULL, FALSE);
+
+ info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanResults",
+ scan_results_cb,
+ info,
+ nm_supplicant_info_destroy,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+
g_get_current_time (&cur_time);
priv->last_scan = cur_time.tv_sec;
-
- g_signal_emit (self, signals[SCAN_DONE], 0, success);
+ return FALSE;
}
static void
-wpas_iface_properties_changed (DBusGProxy *proxy,
- GHashTable *props,
- gpointer user_data)
+wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- GValue *value;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
+ GTimeVal cur_time;
- value = g_hash_table_lookup (props, "Scanning");
- if (value && G_VALUE_HOLDS_BOOLEAN (value))
- set_scanning (self, g_value_get_boolean (value));
+ /* Only query scan results if a query is not queued */
+ if (priv->scan_results_timeout)
+ return;
+
+ g_get_current_time (&cur_time);
- value = g_hash_table_lookup (props, "State");
- if (value && G_VALUE_HOLDS_STRING (value))
- set_state_from_string (self, g_value_get_string (value));
+ /* Only fetch scan results every 4s max, but initially do it right away */
+ if (priv->last_scan + 4 < cur_time.tv_sec) {
+ priv->scan_results_timeout = g_idle_add (request_scan_results,
+ user_data);
+ } else {
+ priv->scan_results_timeout =
+ g_timeout_add_seconds ((4 - (cur_time.tv_sec - priv->last_scan)),
+ request_scan_results, user_data);
+ }
+}
- value = g_hash_table_lookup (props, "BSSs");
- if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH))
- request_bss_properties (self, g_value_get_boxed (value));
+static guint32
+wpas_state_string_to_enum (const char * str_state)
+{
+ guint32 enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
+
+ if (!strcmp (str_state, "DISCONNECTED"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
+ else if (!strcmp (str_state, "INACTIVE"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE;
+ else if (!strcmp (str_state, "SCANNING"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING;
+ else if (!strcmp (str_state, "ASSOCIATING"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING;
+ else if (!strcmp (str_state, "ASSOCIATED"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED;
+ else if (!strcmp (str_state, "4WAY_HANDSHAKE"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE;
+ else if (!strcmp (str_state, "GROUP_HANDSHAKE"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE;
+ else if (!strcmp (str_state, "COMPLETED"))
+ enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED;
+
+ return enum_state;
}
static void
-iface_get_props_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+wpas_iface_handle_state_change (DBusGProxy *proxy,
+ const char *str_new_state,
+ const char *str_old_state,
+ gpointer user_data)
{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- GHashTable *props = NULL;
- GError *error = NULL;
-
- 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, info->interface);
- g_hash_table_destroy (props);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
+ guint32 old_state, enum_new_state;
+
+ enum_new_state = wpas_state_string_to_enum (str_new_state);
+ old_state = priv->con_state;
+ priv->con_state = enum_new_state;
+ if (priv->con_state != old_state) {
+ g_signal_emit (user_data,
+ nm_supplicant_interface_signals[CONNECTION_STATE],
+ 0,
+ priv->con_state,
+ old_state);
+ }
+}
+
+
+static void
+iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+ GError *err = NULL;
+ char *state_str = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+ G_TYPE_STRING, &state_str,
+ G_TYPE_INVALID)) {
+ nm_log_warn (LOGD_SUPPLICANT, "could not get interface state: %s.", err->message);
+ g_error_free (err);
} else {
- nm_log_warn (LOGD_SUPPLICANT, "could not get interface properties: %s.",
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+
+ priv->con_state = wpas_state_string_to_enum (state_str);
+ g_free (state_str);
+ nm_supplicant_interface_set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_READY);
}
}
static void
-wpas_iface_get_props (NMSupplicantInterface *self)
+wpas_iface_get_state (NMSupplicantInterface *self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
NMSupplicantInfo *info;
DBusGProxyCall *call;
- info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
- iface_get_props_cb,
+ info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "state",
+ iface_state_cb,
info,
nm_supplicant_info_destroy,
- G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
}
static void
-interface_add_done (NMSupplicantInterface *self, char *path)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
-
- 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_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanDone",
- G_CALLBACK (wpas_iface_scan_done),
- self,
- NULL);
-
- dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
- G_TYPE_NONE,
- G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_add_signal (priv->iface_proxy, "BSSAdded", G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSAdded",
- G_CALLBACK (wpas_iface_bss_added),
- self,
- NULL);
-
- 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 */
- wpas_iface_get_props (self);
-
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY);
-}
-
-static void
-interface_get_cb (DBusGProxy *proxy,
- DBusGProxyCall *call_id,
- gpointer user_data)
+iface_scanning_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GError *error = NULL;
- char *path = NULL;
+ gboolean scanning = FALSE;
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_OBJECT_PATH, &path,
- G_TYPE_INVALID)) {
- interface_add_done (info->interface, path);
- } else {
- nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
- priv->dev, error->message);
- g_clear_error (&error);
- set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ if (dbus_g_proxy_end_call (proxy, call_id, NULL,
+ G_TYPE_BOOLEAN, &scanning,
+ G_TYPE_INVALID)) {
+ if (scanning != priv->scanning) {
+ priv->scanning = scanning;
+ g_object_notify (G_OBJECT (info->interface), "scanning");
+ }
}
}
static void
-interface_get (NMSupplicantInterface *self)
+wpas_iface_get_scanning (NMSupplicantInterface *self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
NMSupplicantInfo *info;
DBusGProxyCall *call;
- info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->wpas_proxy, "GetInterface",
- interface_get_cb,
+ info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanning",
+ iface_scanning_cb,
info,
nm_supplicant_info_destroy,
- G_TYPE_STRING, priv->dev,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
}
static void
-interface_add_cb (DBusGProxy *proxy,
- DBusGProxyCall *call_id,
- gpointer user_data)
+wpas_iface_handle_scanning (DBusGProxy *proxy,
+ gboolean scanning,
+ gpointer user_data)
+{
+ NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ if (scanning != priv->scanning) {
+ priv->scanning = scanning;
+ g_object_notify (G_OBJECT (self), "scanning");
+ }
+}
+
+gboolean
+nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
+{
+ NMSupplicantInterfacePrivate *priv;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ if (priv->scanning)
+ return TRUE;
+ if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING)
+ return TRUE;
+ return FALSE;
+}
+
+static void
+nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GError *error = NULL;
+ GError *err = NULL;
char *path = NULL;
- if (dbus_g_proxy_end_call (proxy, call_id, &error,
- DBUS_TYPE_G_OBJECT_PATH, &path,
- G_TYPE_INVALID)) {
- interface_add_done (info->interface, path);
- } else {
- if (dbus_g_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
- /* Interface already added, just get its object path */
- interface_get (info->interface);
- } else if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)
- || dbus_g_error_has_name (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
- /* Supplicant wasn't running and could 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 (info->interface, NM_SUPPLICANT_INTERFACE_STATE_INIT);
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+ DBUS_TYPE_G_OBJECT_PATH, &path,
+ G_TYPE_INVALID)) {
+
+ if (dbus_g_error_has_name (err, WPAS_ERROR_INVALID_IFACE)) {
+ /* Interface not added, try to add it */
+ nm_supplicant_interface_add_to_supplicant (info->interface, FALSE);
+ } else if (dbus_g_error_has_name (err, WPAS_ERROR_EXISTS_ERROR)) {
+ /* Interface already added, just try to get the interface */
+ nm_supplicant_interface_add_to_supplicant (info->interface, TRUE);
} else {
- nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
- priv->dev, error->message);
- set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
+ priv->dev, err->message);
}
- g_clear_error (&error);
+
+ g_error_free (err);
+ } else {
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
+
+ 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_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID);
+
+ dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_add_signal (priv->iface_proxy, "StateChange", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable",
+ G_CALLBACK (wpas_iface_query_scan_results),
+ info->interface,
+ NULL);
+
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange",
+ G_CALLBACK (wpas_iface_handle_state_change),
+ info->interface,
+ NULL);
+
+ dbus_g_proxy_add_signal (priv->iface_proxy, "Scanning", G_TYPE_BOOLEAN, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "Scanning",
+ G_CALLBACK (wpas_iface_handle_scanning),
+ info->interface,
+ NULL);
+
+ /* Interface added to the supplicant; get its initial state. */
+ wpas_iface_get_state (info->interface);
+ wpas_iface_get_scanning (info->interface);
}
}
static void
-interface_add (NMSupplicantInterface *self, gboolean is_wireless)
+nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self,
+ gboolean get_only)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
NMSupplicantInfo *info;
- GHashTable *hash;
- GValue *driver, *ifname;
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
+
+ proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE);
+ info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
+
+ if (get_only) {
+ call = dbus_g_proxy_begin_call (proxy, "getInterface",
+ nm_supplicant_interface_add_cb,
+ info,
+ nm_supplicant_info_destroy,
+ G_TYPE_STRING, priv->dev,
+ G_TYPE_INVALID);
+ } else {
+ GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
+ GValue *driver;
+
+ driver = g_new0 (GValue, 1);
+ g_value_init (driver, G_TYPE_STRING);
+ g_value_set_string (driver, priv->is_wireless ? "wext" : "wired");
+ g_hash_table_insert (hash, "driver", driver);
+
+ call = dbus_g_proxy_begin_call (proxy, "addInterface",
+ nm_supplicant_interface_add_cb,
+ info,
+ nm_supplicant_info_destroy,
+ G_TYPE_STRING, priv->dev,
+ DBUS_TYPE_G_MAP_OF_VARIANT, hash,
+ G_TYPE_INVALID);
+
+ g_value_unset (driver);
+ g_free (driver);
+ g_hash_table_destroy (hash);
+ }
+
+ g_object_unref (proxy);
+
+ nm_supplicant_info_set_call (info, call);
+}
+
+static void
+nm_supplicant_interface_start (NMSupplicantInterface * self)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ guint32 state;
/* Can only start the interface from INIT state */
g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev);
- /* Move to starting to prevent double-calls of interface_add() */
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
-
- /* 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.
- */
+ state = nm_supplicant_manager_get_state (priv->smgr);
+ if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
+ nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
+ nm_supplicant_interface_add_to_supplicant (self, FALSE);
+ } else if (state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
+ /* Don't do anything; wait for signal from supplicant manager
+ * that its state has changed.
+ */
+ } else
+ nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
+}
- info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls);
+static void
+nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self)
+{
+ switch (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state) {
+ case NM_SUPPLICANT_INTERFACE_STATE_INIT:
+ /* Move to STARTING state when supplicant is ready */
+ nm_supplicant_interface_start (self);
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_STARTING:
+ /* Don't do anything here, though we should never hit this */
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_READY:
+ /* Don't do anything here, though we should never hit this */
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
+ /* Don't do anything here; interface can't get out of DOWN state */
+ break;
+ default:
+ nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant interface state!");
+ break;
+ }
+}
- hash = g_hash_table_new (g_str_hash, g_str_equal);
- driver = g_new0 (GValue, 1);
- g_value_init (driver, G_TYPE_STRING);
- g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired");
- g_hash_table_insert (hash, "Driver", driver);
+static void
+nm_supplicant_interface_set_state (NMSupplicantInterface * self,
+ guint32 new_state)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ guint32 old_state;
- ifname = g_new0 (GValue, 1);
- g_value_init (ifname, G_TYPE_STRING);
- g_value_set_string (ifname, priv->dev);
- g_hash_table_insert (hash, "Ifname", ifname);
+ g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
- call = dbus_g_proxy_begin_call (priv->wpas_proxy, "CreateInterface",
- interface_add_cb,
- info,
- nm_supplicant_info_destroy,
- DBUS_TYPE_G_MAP_OF_VARIANT, hash,
- G_TYPE_INVALID);
+ if (new_state == priv->state)
+ return;
- g_hash_table_destroy (hash);
- g_value_unset (driver);
- g_free (driver);
- g_value_unset (ifname);
- g_free (ifname);
+ old_state = priv->state;
+ if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
+ /* If the interface is transitioning to DOWN and there's are
+ * in-progress pending calls, cancel them.
+ */
+ cancel_all_callbacks (priv->other_pcalls);
+ cancel_all_callbacks (priv->assoc_pcalls);
+ }
- nm_supplicant_info_set_call (info, call);
+ priv->state = new_state;
+ g_signal_emit (self,
+ nm_supplicant_interface_signals[STATE],
+ 0,
+ priv->state,
+ old_state);
}
static void
-smgr_avail_cb (NMSupplicantManager *smgr,
- GParamSpec *pspec,
- gpointer user_data)
+nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
+ NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (user_data);
- if (nm_supplicant_manager_available (smgr)) {
- /* This can happen if the supplicant couldn't be activated but
- * for some reason was started after the activation failure.
- */
- if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT)
- interface_add (self, priv->is_wireless);
- } else {
- /* The supplicant stopped; so we must tear down the interface */
- set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ switch (new_state) {
+ case NM_SUPPLICANT_MANAGER_STATE_DOWN:
+ /* The supplicant went away, likely the connection to it is also
+ * gone. Therefore, this interface must move to the DOWN state
+ * and be disposed of.
+ */
+ nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+ break;
+ case NM_SUPPLICANT_MANAGER_STATE_IDLE:
+ /* Handle the supplicant now being available. */
+ nm_supplicant_interface_handle_supplicant_manager_idle_state (self);
+ break;
+ default:
+ nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
+ break;
}
}
+
static void
remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- GError *error = NULL;
+ GError *err = NULL;
+ guint tmp;
- if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, 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);
+ err->message);
+ g_error_free (err);
}
}
static void
disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- GError *error = NULL;
+ GError *err = NULL;
+ guint tmp;
- if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't disconnect supplicant interface: %s.",
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
+ err->message);
+ g_error_free (err);
}
}
@@ -682,26 +1045,32 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self)
if (!priv->iface_proxy)
return;
- /* Don't try to disconnect if the supplicant interface is already disconnected */
- if ( priv->state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED
- || priv->state == NM_SUPPLICANT_INTERFACE_STATE_INACTIVE) {
- g_free (priv->net_path);
- priv->net_path = NULL;
+ /* Don't try to disconnect if the supplicant interface is already
+ * disconnected.
+ */
+ if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
+ || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) {
+ if (priv->net_proxy) {
+ g_object_unref (priv->net_proxy);
+ priv->net_proxy = NULL;
+ }
+
return;
}
/* Remove any network that was added by NetworkManager */
- if (priv->net_path) {
- dbus_g_proxy_begin_call (priv->iface_proxy, "RemoveNetwork",
+ if (priv->net_proxy) {
+ dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork",
remove_network_cb,
NULL, NULL,
- DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
+ DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy),
G_TYPE_INVALID);
- g_free (priv->net_path);
- priv->net_path = NULL;
+
+ g_object_unref (priv->net_proxy);
+ priv->net_proxy = NULL;
}
- dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect",
+ dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect",
disconnect_cb,
NULL, NULL,
G_TYPE_INVALID);
@@ -712,8 +1081,9 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
GError *err = NULL;
+ guint tmp;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't select network config: %s.", err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
@@ -721,86 +1091,163 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat
}
static void
-call_select_network (NMSupplicantInterface *self)
+set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- DBusGProxyCall *call;
- NMSupplicantInfo *info;
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+ GError *err = NULL;
+ guint tmp;
- /* We only select the network after all blobs (if any) have been set */
- if (priv->blobs_left > 0)
- return;
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network config: %s.", err->message);
+ emit_error_helper (info->interface, err);
+ g_error_free (err);
+ } else {
+ DBusGProxyCall *call;
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork",
- select_network_cb,
+ info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "selectNetwork",
+ select_network_cb,
+ info,
+ nm_supplicant_info_destroy,
+ DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (proxy),
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ }
+}
+
+static void
+call_set_network (NMSupplicantInfo *info)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+ GHashTable *config_hash;
+ DBusGProxyCall *call;
+
+ config_hash = nm_supplicant_config_get_hash (priv->cfg);
+ call = dbus_g_proxy_begin_call (priv->net_proxy, "set",
+ set_network_cb,
info,
nm_supplicant_info_destroy,
- DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
+ DBUS_TYPE_G_MAP_OF_VARIANT, config_hash,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
+ g_hash_table_destroy (config_hash);
}
static void
-add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
GError *err = NULL;
guint tmp;
- priv->blobs_left--;
-
if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
- } else
- call_select_network (info->interface);
+ } else {
+ info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
+ call_set_network (info);
+ }
+}
+
+static GValue *
+byte_array_to_gvalue (const GByteArray *array)
+{
+ GValue *val;
+
+ val = g_slice_new0 (GValue);
+ g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_set_boxed (val, array);
+
+ return val;
}
static void
-add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+blob_free (GValue *val)
+{
+ g_value_unset (val);
+ g_slice_free (GValue, val);
+}
+
+static void
+convert_blob (const char *key, const GByteArray *value, GHashTable *hash)
+{
+ GValue *val;
+
+ val = byte_array_to_gvalue (value);
+ g_hash_table_insert (hash, g_strdup (key), val);
+}
+
+static void
+call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs)
{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GError *err = NULL;
- GHashTable *blobs;
- GHashTableIter iter;
- gpointer name, data;
DBusGProxyCall *call;
- NMSupplicantInfo *blob_info;
+ GHashTable *blobs;
+
+ blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) blob_free);
+ if (!blobs) {
+ const char *msg = "Not enough memory to create blob table.";
- g_free (priv->net_path);
- priv->net_path = NULL;
+ nm_log_warn (LOGD_SUPPLICANT, "%s", msg);
+ g_signal_emit (info->interface,
+ nm_supplicant_interface_signals[CONNECTION_ERROR],
+ 0, "SendBlobError", msg);
+ return;
+ }
+
+ g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs);
+
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "setBlobs",
+ set_blobs_cb,
+ info,
+ nm_supplicant_info_destroy,
+ DBUS_TYPE_G_MAP_OF_VARIANT, blobs,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ g_hash_table_destroy (blobs);
+}
+
+static void
+add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+{
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ GError *err = NULL;
+ char *path = NULL;
if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_OBJECT_PATH, &priv->net_path,
+ DBUS_TYPE_G_OBJECT_PATH, &path,
G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.",
err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
- return;
- }
-
- /* Send blobs first; otherwise jump to sending the config settings */
- 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)) {
- blob_info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddBlob",
- add_blob_cb,
- blob_info,
- nm_supplicant_info_destroy,
- DBUS_TYPE_STRING, name,
- DBUS_TYPE_G_UCHAR_ARRAY, blobs,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (blob_info, call);
+ } else {
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+ GHashTable *blobs;
+
+ priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ path,
+ WPAS_DBUS_IFACE_NETWORK);
+ g_free (path);
+
+ info = nm_supplicant_info_new (info->interface,
+ priv->net_proxy,
+ priv->assoc_pcalls);
+ /* Send any blobs first; if there aren't any jump to sending the
+ * config settings.
+ */
+ blobs = nm_supplicant_config_get_blobs (priv->cfg);
+ if (g_hash_table_size (blobs) > 0)
+ call_set_blobs (info, blobs);
+ else
+ call_set_network (info);
}
-
- call_select_network (info->interface);
}
static void
@@ -809,10 +1256,10 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
GError *err = NULL;
+ guint32 tmp;
DBusGProxyCall *call;
- GHashTable *config_hash;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't send AP scan mode to the supplicant interface: %s.",
err->message);
emit_error_helper (info->interface, err);
@@ -823,15 +1270,12 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d",
nm_supplicant_config_get_ap_scan (priv->cfg));
- info = nm_supplicant_info_new (info->interface, priv->iface_proxy, info->store);
- config_hash = nm_supplicant_config_get_hash (priv->cfg);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddNetwork",
+ info = nm_supplicant_info_new (info->interface, proxy, info->store);
+ call = dbus_g_proxy_begin_call (proxy, "addNetwork",
add_network_cb,
info,
nm_supplicant_info_destroy,
- DBUS_TYPE_G_MAP_OF_VARIANT, config_hash,
G_TYPE_INVALID);
- g_hash_table_destroy (config_hash);
nm_supplicant_info_set_call (info, call);
}
@@ -842,7 +1286,7 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
NMSupplicantInterfacePrivate *priv;
NMSupplicantInfo *info;
DBusGProxyCall *call;
- GValue value = { 0, };
+ guint32 ap_scan;
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
@@ -859,54 +1303,46 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
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));
-
- info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->props_proxy, "Set",
+ info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+ ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan",
set_ap_scan_cb,
info,
nm_supplicant_info_destroy,
- G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
- G_TYPE_STRING, "ApScan",
- G_TYPE_VALUE, &value,
+ G_TYPE_UINT, ap_scan,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
- g_value_unset (&value);
return call != NULL;
}
+const char *
+nm_supplicant_interface_get_device (NMSupplicantInterface * self)
+{
+ g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
+
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
+}
+
static void
scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
GError *err = NULL;
+ guint32 success = 0;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+ G_TYPE_UINT, &success,
+ G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", err->message);
+ g_error_free (err);
}
- g_signal_emit (info->interface, signals[SCAN_DONE], 0, err ? FALSE : TRUE);
- g_clear_error (&err);
-}
-
-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)
-{
- GValue *val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
- return val;
+ /* Notify listeners of the result of the scan */
+ g_signal_emit (info->interface,
+ nm_supplicant_interface_signals[SCAN_REQ_RESULT],
+ 0,
+ success ? TRUE : FALSE);
}
gboolean
@@ -915,24 +1351,17 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface * self)
NMSupplicantInterfacePrivate *priv;
NMSupplicantInfo *info;
DBusGProxyCall *call;
- GHashTable *hash;
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"));
-
info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "Scan",
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan",
scan_request_cb,
info,
nm_supplicant_info_destroy,
- DBUS_TYPE_G_MAP_OF_VARIANT, hash,
G_TYPE_INVALID);
- g_hash_table_destroy (hash);
nm_supplicant_info_set_call (info, call);
return call != NULL;
@@ -946,6 +1375,14 @@ nm_supplicant_interface_get_state (NMSupplicantInterface * self)
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state;
}
+guint32
+nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self)
+{
+ g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED);
+
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->con_state;
+}
+
const char *
nm_supplicant_interface_state_to_string (guint32 state)
{
@@ -956,24 +1393,6 @@ nm_supplicant_interface_state_to_string (guint32 state)
return "starting";
case NM_SUPPLICANT_INTERFACE_STATE_READY:
return "ready";
- case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
- return "disconnected";
- case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE:
- return "inactive";
- case NM_SUPPLICANT_INTERFACE_STATE_SCANNING:
- return "scanning";
- case NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING:
- return "authenticating";
- case NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING:
- return "associating";
- case NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED:
- return "associated";
- case NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE:
- return "4-way handshake";
- case NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE:
- return "group handshake";
- case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
- return "completed";
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
return "down";
default:
@@ -983,227 +1402,28 @@ nm_supplicant_interface_state_to_string (guint32 state)
}
const char *
-nm_supplicant_interface_get_device (NMSupplicantInterface * self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
-
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
-}
-
-const char *
-nm_supplicant_interface_get_object_path (NMSupplicantInterface *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
-
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->object_path;
-}
-
-const char *
-nm_supplicant_interface_get_ifname (NMSupplicantInterface *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
-
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
-}
-
-/*******************************************************************/
-
-NMSupplicantInterface *
-nm_supplicant_interface_new (NMSupplicantManager *smgr,
- const char *ifname,
- gboolean is_wireless,
- gboolean start_now)
-{
- 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);
- if (self) {
- 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;
-
- if (start_now)
- interface_add (self, priv->is_wireless);
- }
-
- return self;
-}
-
-static void
-nm_supplicant_interface_init (NMSupplicantInterface * self)
+nm_supplicant_interface_connection_state_to_string (guint32 state)
{
- 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);
-}
-
-static void
-set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id) {
- case PROP_SCANNING:
- g_value_set_boolean (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->scanning);
- break;
+ switch (state) {
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED:
+ return "disconnected";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE:
+ return "inactive";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING:
+ return "scanning";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING:
+ return "associating";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED:
+ return "associated";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE:
+ return "4-way handshake";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE:
+ return "group handshake";
+ case NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED:
+ return "completed";
default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
-}
-
-static void
-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;
-
- /* Cancel pending calls before unrefing the dbus manager */
- cancel_all_callbacks (priv->other_pcalls);
- nm_call_store_destroy (priv->other_pcalls);
-
- cancel_all_callbacks (priv->assoc_pcalls);
- nm_call_store_destroy (priv->assoc_pcalls);
-
- if (priv->props_proxy)
- g_object_unref (priv->props_proxy);
-
- if (priv->iface_proxy)
- g_object_unref (priv->iface_proxy);
-
- g_free (priv->net_path);
-
- if (priv->wpas_proxy)
- g_object_unref (priv->wpas_proxy);
-
- 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);
-
- if (priv->dbus_mgr)
- g_object_unref (priv->dbus_mgr);
-
- if (priv->cfg)
- g_object_unref (priv->cfg);
-
- g_free (priv->object_path);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
-}
-
-static void
-nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
-
- object_class->dispose = dispose;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
-
- /* Properties */
- g_object_class_install_property (object_class, PROP_SCANNING,
- g_param_spec_boolean ("scanning",
- "Scanning",
- "Scanning",
- FALSE,
- G_PARAM_READABLE));
-
- /* Signals */
- signals[STATE] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_STATE,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state),
- NULL, NULL,
- _nm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-
- signals[REMOVED] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_REMOVED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[NEW_BSS] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_NEW_BSS,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, new_bss),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- signals[SCAN_DONE] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_SCAN_DONE,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_done),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-
- signals[CONNECTION_ERROR] =
- g_signal_new (NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error),
- NULL, NULL,
- _nm_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+ return "unknown";
}