diff options
| author | Michael Biebl <biebl@debian.org> | 2011-04-21 10:42:53 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2011-04-21 10:42:53 +0200 |
| commit | 8baa1aca8dfd35e3190d7d5655eb83b5b901e263 (patch) | |
| tree | a9ac1e67d0c22a48330c76f08fc5291f85307055 /src/supplicant-manager | |
| parent | f75dd6fd1975146623052b843b182dc32c3fbe46 (diff) | |
Imported Upstream version 0.8.4.0 upstream/0.8.4.0
Diffstat (limited to 'src/supplicant-manager')
| -rw-r--r-- | src/supplicant-manager/Makefile.in | 50 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-interface.c | 1588 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-interface.h | 78 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-manager.c | 427 | ||||
| -rw-r--r-- | src/supplicant-manager/nm-supplicant-manager.h | 44 | ||||
| -rw-r--r-- | src/supplicant-manager/tests/Makefile.in | 50 |
6 files changed, 1246 insertions, 991 deletions
diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in index cfee4510..08ffaece 100644 --- a/src/supplicant-manager/Makefile.in +++ b/src/supplicant-manager/Makefile.in @@ -38,16 +38,11 @@ subdir = src/supplicant-manager DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -71,7 +66,7 @@ AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -140,6 +135,7 @@ am__relativize = \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -148,6 +144,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -164,7 +162,6 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ -DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -173,7 +170,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GIO_CFLAGS = @GIO_CFLAGS@ GIO_LIBS = @GIO_LIBS@ @@ -182,8 +178,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ +GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ @@ -198,23 +194,13 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ -INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ -INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ -INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -222,8 +208,6 @@ LIBDL = @LIBDL@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ LIBM = @LIBM@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ @@ -232,15 +216,13 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ +MSGFMT_OPTS = @MSGFMT_OPTS@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -266,9 +248,12 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ RANLIB = @RANLIB@ RESOLVCONF_PATH = @RESOLVCONF_PATH@ @@ -283,13 +268,10 @@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index e9e58f39..a65a458f 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"; } diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index e32411d7..bee5436f 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -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) 2007 - 2008 Novell, Inc. */ @@ -26,27 +26,47 @@ #include <dbus/dbus.h> #include "nm-supplicant-types.h" +G_BEGIN_DECLS + /* * Supplicant interface states - * A mix of wpa_supplicant interface states and internal states. + * The states are linear, ie INIT -> READY -> DOWN and state may only be + * changed in one direction. If an interface reaches the DOWN state, it + * cannot be re-initialized; it must be torn down and a new one created. + * + * INIT: interface has been created, but cannot be used yet; it is waiting + * for pending requests of the supplicant to complete. + * READY: interface is ready for use + * DOWN: interface has been removed or has otherwise been made invalid; it + * must be torn down. + * + * Note: LAST is an invalid state and only used for boundary checking. */ enum { NM_SUPPLICANT_INTERFACE_STATE_INIT = 0, NM_SUPPLICANT_INTERFACE_STATE_STARTING, NM_SUPPLICANT_INTERFACE_STATE_READY, - NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, - NM_SUPPLICANT_INTERFACE_STATE_INACTIVE, - NM_SUPPLICANT_INTERFACE_STATE_SCANNING, - NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING, - NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING, - NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED, - NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE, - NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE, - NM_SUPPLICANT_INTERFACE_STATE_COMPLETED, NM_SUPPLICANT_INTERFACE_STATE_DOWN, NM_SUPPLICANT_INTERFACE_STATE_LAST }; + +/* + * Supplicant interface connection states + * The wpa_supplicant state for the connection. + */ +enum { + NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED = 0, + NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE, + NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING, + NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING, + NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED, + NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE, + NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE, + NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED, + NM_SUPPLICANT_INTERFACE_CON_STATE_LAST +}; + #define NM_TYPE_SUPPLICANT_INTERFACE (nm_supplicant_interface_get_type ()) #define NM_SUPPLICANT_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterface)) #define NM_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) @@ -54,12 +74,6 @@ enum { #define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE)) #define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) -#define NM_SUPPLICANT_INTERFACE_STATE "state" -#define NM_SUPPLICANT_INTERFACE_REMOVED "removed" -#define NM_SUPPLICANT_INTERFACE_NEW_BSS "new-bss" -#define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done" -#define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error" - struct _NMSupplicantInterface { GObject parent; }; @@ -77,14 +91,23 @@ typedef struct { /* interface was removed by the supplicant */ void (*removed) (NMSupplicantInterface * iface); - /* interface saw a new BSS */ - void (*new_bss) (NMSupplicantInterface *iface, - GHashTable *props); + /* interface saw a new access point from a scan */ + void (*scanned_ap) (NMSupplicantInterface * iface, + DBusMessage * message); - /* wireless scan is done */ - void (*scan_done) (NMSupplicantInterface *iface, + /* result of a wireless scan request */ + void (*scan_req_result) (NMSupplicantInterface * iface, gboolean success); + /* scan results returned from supplicant */ + void (*scan_results) (NMSupplicantInterface * iface, + guint num_bssids); + + /* link state of the device's connection */ + void (*connection_state) (NMSupplicantInterface * iface, + guint32 new_state, + guint32 old_state); + /* an error occurred during a connection request */ void (*connection_error) (NMSupplicantInterface * iface, const char * name, @@ -96,8 +119,7 @@ GType nm_supplicant_interface_get_type (void); NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, - gboolean is_wireless, - gboolean start_now); + gboolean is_wireless); gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, NMSupplicantConfig * cfg); @@ -106,16 +128,18 @@ void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface); -const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface); - gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self); guint32 nm_supplicant_interface_get_state (NMSupplicantInterface * self); +guint32 nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self); + const char *nm_supplicant_interface_state_to_string (guint32 state); +const char *nm_supplicant_interface_connection_state_to_string (guint32 state); + gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self); -const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self); +G_END_DECLS #endif /* NM_SUPPLICANT_INTERFACE_H */ diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 8209da21..a2cf58eb 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.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) 2007 - 2008 Novell, Inc. */ @@ -26,7 +26,19 @@ #include "nm-supplicant-manager.h" #include "nm-supplicant-interface.h" #include "nm-dbus-manager.h" +#include "nm-marshal.h" #include "nm-logging.h" +#include "nm-glib-compat.h" + +#define SUPPLICANT_POKE_INTERVAL 120 + +typedef struct { + NMDBusManager * dbus_mgr; + guint32 state; + GSList * ifaces; + gboolean dispose_has_run; + guint poke_id; +} NMSupplicantManagerPrivate; #define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SUPPLICANT_MANAGER, \ @@ -34,283 +46,298 @@ 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; - gboolean running; - GHashTable * ifaces; - guint die_count_reset_id; - guint die_count; - gboolean disposed; -} NMSupplicantManagerPrivate; +static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old, + const char *new, + gpointer user_data); -/********************************************************************/ +static void nm_supplicant_manager_set_state (NMSupplicantManager * self, + guint32 new_state); -static inline gboolean -die_count_exceeded (guint32 count) -{ - return count > 2; -} +static gboolean nm_supplicant_manager_startup (NMSupplicantManager * self); -NMSupplicantInterface * -nm_supplicant_manager_iface_get (NMSupplicantManager * self, - const char *ifname, - gboolean is_wireless) -{ - NMSupplicantManagerPrivate *priv; - NMSupplicantInterface *iface = NULL; - gboolean start_now; - g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); - g_return_val_if_fail (ifname != NULL, NULL); +/* Signals */ +enum { + STATE, /* change in the manager's state */ + LAST_SIGNAL +}; +static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 }; - priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - iface = g_hash_table_lookup (priv->ifaces, ifname); - if (!iface) { - /* If we're making the supplicant take a time out for a bit, don't - * let the supplicant interface start immediately, just let it hang - * around in INIT state until we're ready to talk to the supplicant - * again. - */ - start_now = !die_count_exceeded (priv->die_count); +NMSupplicantManager * +nm_supplicant_manager_get (void) +{ + static NMSupplicantManager * singleton = NULL; - nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname); - iface = nm_supplicant_interface_new (self, ifname, is_wireless, start_now); - if (iface) - g_hash_table_insert (priv->ifaces, g_strdup (ifname), iface); + if (!singleton) { + singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL)); } else { - nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname); + g_object_ref (singleton); } - return iface; + g_assert (singleton); + return singleton; } -void -nm_supplicant_manager_iface_release (NMSupplicantManager *self, - NMSupplicantInterface *iface) +static gboolean +poke_supplicant_cb (gpointer user_data) { - NMSupplicantManagerPrivate *priv; - const char *ifname, *op; - - g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); - g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface)); - - ifname = nm_supplicant_interface_get_ifname (iface); - g_assert (ifname); - - priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - - g_return_if_fail (g_hash_table_lookup (priv->ifaces, ifname) == iface); - - /* 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); + NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data); + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + DBusGConnection *g_connection; + DBusGProxy *proxy; + const char *tmp = "ignoreme"; + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + proxy = dbus_g_proxy_new_for_name (g_connection, + WPAS_DBUS_SERVICE, + WPAS_DBUS_PATH, + WPAS_DBUS_INTERFACE); + if (!proxy) { + nm_log_warn (LOGD_SUPPLICANT, "Error: could not init wpa_supplicant proxy"); + goto out; } - g_hash_table_remove (priv->ifaces, ifname); -} + nm_log_info (LOGD_SUPPLICANT, "Trying to start the supplicant..."); + dbus_g_proxy_call_no_reply (proxy, "getInterface", G_TYPE_STRING, tmp, G_TYPE_INVALID); + g_object_unref (proxy); -gboolean -nm_supplicant_manager_available (NMSupplicantManager *self) -{ - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE); +out: + /* Reschedule the poke */ + priv->poke_id = g_timeout_add_seconds (SUPPLICANT_POKE_INTERVAL, + poke_supplicant_cb, + (gpointer) self); - if (die_count_exceeded (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->die_count)) - return FALSE; - return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->running; + return FALSE; } static void -set_running (NMSupplicantManager *self, gboolean now_running) +nm_supplicant_manager_init (NMSupplicantManager * self) { NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - gboolean old_available = nm_supplicant_manager_available (self); + gboolean running; - priv->running = now_running; - if (old_available != nm_supplicant_manager_available (self)) - g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE); + priv->dispose_has_run = FALSE; + priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN; + priv->dbus_mgr = nm_dbus_manager_get (); + priv->poke_id = 0; + + running = nm_supplicant_manager_startup (self); + + g_signal_connect (priv->dbus_mgr, + "name-owner-changed", + G_CALLBACK (nm_supplicant_manager_name_owner_changed), + self); + + if (!running) { + /* Try to activate the supplicant */ + priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self); + } } static void -set_die_count (NMSupplicantManager *self, guint new_die_count) +nm_supplicant_manager_dispose (GObject *object) { - NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - gboolean old_available = nm_supplicant_manager_available (self); + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object); + + if (priv->dispose_has_run) { + G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); + return; + } + + priv->dispose_has_run = TRUE; + + if (priv->poke_id) { + g_source_remove (priv->poke_id); + priv->poke_id = 0; + } + + if (priv->dbus_mgr) { + g_object_unref (G_OBJECT (priv->dbus_mgr)); + priv->dbus_mgr = NULL; + } - priv->die_count = new_die_count; - if (old_available != nm_supplicant_manager_available (self)) - g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE); + /* Chain up to the parent class */ + G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); } -static gboolean -wpas_die_count_reset_cb (gpointer user_data) +static void +nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) { - NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data); - NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + GObjectClass * object_class = G_OBJECT_CLASS (klass); - /* Reset the die count back to zero, which allows use of the supplicant again */ - priv->die_count_reset_id = 0; - set_die_count (self, 0); - nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant die count reset"); - return FALSE; + g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate)); + + object_class->dispose = nm_supplicant_manager_dispose; + + /* Signals */ + nm_supplicant_manager_signals[STATE] = + g_signal_new ("state", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSupplicantManagerClass, state), + NULL, NULL, + _nm_marshal_VOID__UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); } static void -name_owner_changed (NMDBusManager *dbus_mgr, - const char *name, - const char *old_owner, - const char *new_owner, - gpointer user_data) +nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) { - NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data); + NMSupplicantManager * self = (NMSupplicantManager *) 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)); - /* We only care about the supplicant here */ + /* Can't handle the signal if its not from the supplicant service */ if (strcmp (WPAS_DBUS_SERVICE, name) != 0) return; if (!old_owner_good && new_owner_good) { - nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant started"); - set_running (self, TRUE); - } else if (old_owner_good && !new_owner_good) { - nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant stopped"); + gboolean 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 - * we don't try to talk to the supplicant for a while. - */ - if (priv->die_count_reset_id) - g_source_remove (priv->die_count_reset_id); - priv->die_count_reset_id = g_timeout_add_seconds (10, wpas_die_count_reset_cb, self); - set_die_count (self, priv->die_count + 1); - - if (die_count_exceeded (priv->die_count)) { - nm_log_info (LOGD_SUPPLICANT, - "wpa_supplicant die count %d; ignoring for 10 seconds", - priv->die_count); + running = nm_supplicant_manager_startup (self); + + if (running && priv->poke_id) { + g_source_remove (priv->poke_id); + priv->poke_id = 0; } + } else if (old_owner_good && !new_owner_good) { + nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_DOWN); + + if (priv->poke_id) + g_source_remove (priv->poke_id); - set_running (self, FALSE); + /* Poke the supplicant so that it gets activated by dbus system bus + * activation. + */ + priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self); } } -/*******************************************************************/ -NMSupplicantManager * -nm_supplicant_manager_get (void) +guint32 +nm_supplicant_manager_get_state (NMSupplicantManager * self) { - static NMSupplicantManager *singleton = NULL; - - if (!singleton) - singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL)); - else - g_object_ref (singleton); + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE); - g_assert (singleton); - return singleton; + return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state; } static void -nm_supplicant_manager_init (NMSupplicantManager * self) +nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state) { NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - DBusGConnection *bus; + guint32 old_state; - 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->ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); -} + if (new_state == priv->state) + return; -static void -set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + old_state = priv->state; + priv->state = new_state; + g_signal_emit (self, + nm_supplicant_manager_signals[STATE], + 0, + priv->state, + old_state); } -static void -get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static gboolean +nm_supplicant_manager_startup (NMSupplicantManager * self) { - 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; - } + gboolean running; + + /* FIXME: convert to pending call */ + running = nm_dbus_manager_name_has_owner (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->dbus_mgr, + WPAS_DBUS_SERVICE); + if (running) + nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE); + + return running; } -static void -dispose (GObject *object) +NMSupplicantInterface * +nm_supplicant_manager_get_iface (NMSupplicantManager * self, + const char *ifname, + gboolean is_wireless) { - NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object); + NMSupplicantManagerPrivate *priv; + NMSupplicantInterface * iface = NULL; + GSList * elt; - if (priv->disposed) - goto out; - priv->disposed = TRUE; + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); + g_return_val_if_fail (ifname != NULL, NULL); - if (priv->die_count_reset_id) - g_source_remove (priv->die_count_reset_id); + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - if (priv->dbus_mgr) { - if (priv->name_owner_id) - g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id); - g_object_unref (G_OBJECT (priv->dbus_mgr)); - } + /* Ensure we don't already have this interface */ + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { + NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; - g_hash_table_destroy (priv->ifaces); + if (!strcmp (ifname, nm_supplicant_interface_get_device (if_tmp))) { + iface = if_tmp; + break; + } + } - if (priv->proxy) - g_object_unref (priv->proxy); + if (!iface) { + nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname); + iface = nm_supplicant_interface_new (self, ifname, is_wireless); + if (iface) + priv->ifaces = g_slist_append (priv->ifaces, iface); + } else { + nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname); + } -out: - /* Chain up to the parent class */ - G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); + return iface; } -static void -nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) +void +nm_supplicant_manager_release_iface (NMSupplicantManager * self, + NMSupplicantInterface * iface) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSupplicantManagerPrivate *priv; + GSList * elt; - g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate)); + g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface)); + + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { + NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; + + if (if_tmp == iface) { + /* Remove the iface from the supplicant manager's list and + * dereference to match additional reference in get_iface. + */ + priv->ifaces = g_slist_remove_link (priv->ifaces, elt); + g_slist_free_1 (elt); + g_object_unref (iface); + break; + } + } +} - g_object_class_install_property (object_class, PROP_AVAILABLE, - g_param_spec_boolean (NM_SUPPLICANT_MANAGER_AVAILABLE, - "Available", - "Available", - FALSE, - G_PARAM_READABLE)); +const char * +nm_supplicant_manager_state_to_string (guint32 state) +{ + switch (state) { + case NM_SUPPLICANT_MANAGER_STATE_DOWN: + return "down"; + case NM_SUPPLICANT_MANAGER_STATE_IDLE: + return "idle"; + default: + break; + } + return "unknown"; } + diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h index 9e2f3b21..fef2a774 100644 --- a/src/supplicant-manager/nm-supplicant-manager.h +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -26,13 +26,30 @@ #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" +#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant" +#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant" +#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant" G_BEGIN_DECLS +/* + * Supplicant manager states + * Either state may transition to the other state at any time. + * + * DOWN: supplicant manager has been created, but cannot be used; the supplicant + * is either not running or has not yet been fully initialized. + * IDLE: supplicant manager is ready for use + * + * Note: LAST is an invalid state and only used for boundary checking. + */ +enum { + NM_SUPPLICANT_MANAGER_STATE_DOWN = 0, + NM_SUPPLICANT_MANAGER_STATE_IDLE, + NM_SUPPLICANT_MANAGER_STATE_LAST +}; + + #define NM_TYPE_SUPPLICANT_MANAGER (nm_supplicant_manager_get_type ()) #define NM_SUPPLICANT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManager)) #define NM_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass)) @@ -40,8 +57,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; @@ -50,19 +65,24 @@ struct _NMSupplicantManager typedef struct { GObjectClass parent; + + /* class members */ + void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state); } NMSupplicantManagerClass; GType nm_supplicant_manager_get_type (void); -NMSupplicantManager *nm_supplicant_manager_get (void); +NMSupplicantManager * nm_supplicant_manager_get (void); + +guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr); -NMSupplicantInterface *nm_supplicant_manager_iface_get (NMSupplicantManager *mgr, - const char *ifname, - gboolean is_wireless); +NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr, + const char *ifname, + gboolean is_wireless); -void nm_supplicant_manager_iface_release (NMSupplicantManager *mgr, - NMSupplicantInterface *iface); +void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr, + NMSupplicantInterface * iface); -gboolean nm_supplicant_manager_available (NMSupplicantManager *mgr); +const char *nm_supplicant_manager_state_to_string (guint32 state); #endif /* NM_SUPPLICANT_MANAGER_H */ diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in index 58cb15f3..ac812e2e 100644 --- a/src/supplicant-manager/tests/Makefile.in +++ b/src/supplicant-manager/tests/Makefile.in @@ -39,16 +39,11 @@ subdir = src/supplicant-manager/tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ - $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ - $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ - $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -68,7 +63,7 @@ AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) am__v_lt_0 = --silent DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -99,6 +94,7 @@ ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ ALL_LINGUAS = @ALL_LINGUAS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -107,6 +103,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -123,7 +121,6 @@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCLIENT_VERSION = @DHCLIENT_VERSION@ DHCPCD_PATH = @DHCPCD_PATH@ DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ -DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -132,7 +129,6 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ GIO_CFLAGS = @GIO_CFLAGS@ GIO_LIBS = @GIO_LIBS@ @@ -141,8 +137,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ GLIB_LIBS = @GLIB_LIBS@ GMODULE_CFLAGS = @GMODULE_CFLAGS@ GMODULE_LIBS = @GMODULE_LIBS@ +GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ @@ -157,23 +153,13 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ INTLLIBS = @INTLLIBS@ INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ INTLTOOL_MERGE = @INTLTOOL_MERGE@ INTLTOOL_PERL = @INTLTOOL_PERL@ INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ -INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ -INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ -INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ -INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ -INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ -INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ -INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ IPTABLES_PATH = @IPTABLES_PATH@ -IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@ -IWMX_SDK_LIBS = @IWMX_SDK_LIBS@ KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -181,8 +167,6 @@ LIBDL = @LIBDL@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ LIBM = @LIBM@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ @@ -191,15 +175,13 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ +MSGFMT_OPTS = @MSGFMT_OPTS@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -225,9 +207,12 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ RANLIB = @RANLIB@ RESOLVCONF_PATH = @RESOLVCONF_PATH@ @@ -242,13 +227,10 @@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ |