2006-11-25 Dan Williams <dcbw@redhat.com>

* src/supplicant-manager/nm-supplicant-types.h
		- new file; move all supplicant manager object typedefs here for
			#include sanity

	* src/supplicant-manager/nm-supplicant-interface.c
	  src/supplicant-manager/nm-supplicant-interface.h
		- new file; an object that interfaces an NMDevice object to the
			supplicant and handles signals from the supplicant.  This object
			does all necessary DBus communication with wpa_supplicant.

	* src/supplicant-manager/nm-supplicant-manager.c
	  src/supplicant-manager/nm-supplicant-manager.h
		- Actually do something.  Track the state of the wpa_supplicant service
			and deal with its comings & goings.  Handle life events of
			supplicant interfaces too.
		- Move NMSupplicantManager typedef to nm-supplicant-types.h

	* src/supplicant-manager/nm-supplicant-connection.h
		- Move NMSupplicantConnection typedef to nm-supplicant-types.h

	* src/supplicant-manager/Makefile.am
		- Add new files to build, and add libnm-util to includes

	* src/nm-marshal.list
		- New marshaler type: VOID:UINT,UINT

	* src/nm-device-802-3-ethernet.c
		- (real_init): grab a supplicant interface
		- (nm_device_802_3_ethernet_dispose): release the supplicant interface
		- (supplicant_iface_state_cb): new function, stub for handling
			supplicant interface state changes

	* src/nm-device-802-11-wireless.c
		- (real_init): grab a supplicant interface
		- (nm_device_802_11_wireless_dispose): release the supplicant interface
		- (supplicant_iface_state_cb): new function, stub for handling
			supplicant interface state changes

	* src/NetworkManager.c
		- (main): create and keep the supplicant manager around for the lifetime
			of NetworkManager

	* src/Makefile.am
		- Link to the supplicant manager sub-library and use the supplicant
			manager includes


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2125 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2006-11-25 15:41:04 +00:00
parent 81c31e820a
commit 4bc25ba3bf
13 changed files with 1296 additions and 18 deletions

View File

@@ -1,3 +1,51 @@
2006-11-25 Dan Williams <dcbw@redhat.com>
* src/supplicant-manager/nm-supplicant-types.h
- new file; move all supplicant manager object typedefs here for
#include sanity
* src/supplicant-manager/nm-supplicant-interface.c
src/supplicant-manager/nm-supplicant-interface.h
- new file; an object that interfaces an NMDevice object to the
supplicant and handles signals from the supplicant. This object
does all necessary DBus communication with wpa_supplicant.
* src/supplicant-manager/nm-supplicant-manager.c
src/supplicant-manager/nm-supplicant-manager.h
- Actually do something. Track the state of the wpa_supplicant service
and deal with its comings & goings. Handle life events of
supplicant interfaces too.
- Move NMSupplicantManager typedef to nm-supplicant-types.h
* src/supplicant-manager/nm-supplicant-connection.h
- Move NMSupplicantConnection typedef to nm-supplicant-types.h
* src/supplicant-manager/Makefile.am
- Add new files to build, and add libnm-util to includes
* src/nm-marshal.list
- New marshaler type: VOID:UINT,UINT
* src/nm-device-802-3-ethernet.c
- (real_init): grab a supplicant interface
- (nm_device_802_3_ethernet_dispose): release the supplicant interface
- (supplicant_iface_state_cb): new function, stub for handling
supplicant interface state changes
* src/nm-device-802-11-wireless.c
- (real_init): grab a supplicant interface
- (nm_device_802_11_wireless_dispose): release the supplicant interface
- (supplicant_iface_state_cb): new function, stub for handling
supplicant interface state changes
* src/NetworkManager.c
- (main): create and keep the supplicant manager around for the lifetime
of NetworkManager
* src/Makefile.am
- Link to the supplicant manager sub-library and use the supplicant
manager includes
2006-11-25 Dan Williams <dcbw@redhat.com>
Rework DBus manager signal handling to be more flexible. Previously,

View File

@@ -5,6 +5,7 @@ INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/src/named-manager \
-I${top_srcdir}/src/vpn-manager \
-I${top_srcdir}/src/dhcp-manager \
-I${top_srcdir}/src/supplicant-manager \
-I${top_srcdir}/utils \
-I${top_srcdir}/libnm-util
@@ -123,6 +124,7 @@ NetworkManager_LDADD = \
./named-manager/libnamed-manager.la \
./vpn-manager/libvpn-manager.la \
./dhcp-manager/libdhcp-manager.la \
./supplicant-manager/libsupplicant-manager.la \
./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la

View File

@@ -55,6 +55,7 @@
#include "nm-dbus-nm.h"
#include "nm-dbus-manager.h"
#include "nm-dbus-device.h"
#include "nm-supplicant-manager.h"
#include "nm-dbus-net.h"
#include "nm-netlink-monitor.h"
#include "nm-dhcp-manager.h"
@@ -743,6 +744,7 @@ main (int argc, char *argv[])
char * user_pidfile = NULL;
NMDBusManager * dbus_mgr;
DBusConnection *dbus_connection;
NMSupplicantManager * sup_mgr = NULL;
int exit_status = EXIT_FAILURE;
guint32 id;
@@ -846,6 +848,13 @@ main (int argc, char *argv[])
nm_dbus_manager_register_method_list (dbus_mgr, nm_data->device_methods);
nm_data->net_methods = nm_dbus_net_methods_setup (nm_data);
/* Initialize the supplicant manager */
sup_mgr = nm_supplicant_manager_get ();
if (!sup_mgr) {
nm_error ("Failed to initialize the supplicant manager.");
goto done;
}
nm_data->vpn_manager = nm_vpn_manager_new (nm_data);
if (!nm_data->vpn_manager) {
nm_warning ("Failed to start the VPN manager.");
@@ -907,6 +916,10 @@ done:
nm_dbus_manager_remove_signal_handler (dbus_mgr, nm_data->nmi_sig_handler_id);
nm_data_free (nm_data);
if (sup_mgr)
g_object_unref (sup_mgr);
/* nm_data_free needs the dbus connection, so must kill the
* dbus manager after that.
*/

View File

@@ -41,6 +41,8 @@
#include "NetworkManagerPolicy.h"
#include "nm-activation-request.h"
#include "nm-dbus-nmi.h"
#include "nm-supplicant-manager.h"
#include "nm-supplicant-interface.h"
#include "wpa_ctrl.h"
#include "cipher.h"
@@ -84,6 +86,8 @@ struct _NMDevice80211WirelessPrivate
struct _Supplicant supplicant;
NMSupplicantInterface * sup_iface;
guint32 failed_link_count;
GSource * link_timeout;
gulong wireless_event_id;
@@ -139,6 +143,11 @@ static void nm_device_802_11_wireless_event (NmNetlinkMonitor *monitor,
int data_len,
NMDevice80211Wireless *self);
static void supplicant_iface_state_cb (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state,
NMDevice80211Wireless *self);
/*
* nm_device_802_11_wireless_update_bssid
@@ -390,6 +399,7 @@ real_init (NMDevice *dev)
guint32 caps;
NMSock * sk;
NmNetlinkMonitor * monitor;
NMSupplicantManager * sup_mgr;
self->priv->is_initialized = TRUE;
self->priv->scanning = FALSE;
@@ -448,6 +458,20 @@ real_init (NMDevice *dev)
self->priv->wireless_event_id =
g_signal_connect (G_OBJECT (monitor), "wireless-event",
G_CALLBACK (nm_device_802_11_wireless_event), self);
sup_mgr = nm_supplicant_manager_get ();
self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr,
NM_DEVICE (self));
if (self->priv->sup_iface == NULL) {
nm_warning ("Couldn't initialize supplicant interface for %s.",
nm_device_get_iface (NM_DEVICE (self)));
} else {
g_signal_connect (G_OBJECT (self->priv->sup_iface),
"state",
G_CALLBACK (supplicant_iface_state_cb),
self);
}
g_object_unref (sup_mgr);
}
@@ -2385,6 +2409,28 @@ ap_is_auth_required (NMAccessPoint *ap, gboolean *has_key)
}
/****************************************************************************
* WPA Supplicant control stuff
*
*/
static void
supplicant_iface_state_cb (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state,
NMDevice80211Wireless *self)
{
g_return_if_fail (self != NULL);
nm_info ("(%s) supplicant interface is now in state %d (from %d).",
nm_device_get_iface (NM_DEVICE (self)),
new_state,
old_state);
}
/****************************************************************************/
/* WPA Supplicant control stuff
*
@@ -3323,7 +3369,8 @@ nm_device_802_11_wireless_dispose (GObject *object)
/* Only do this part of the cleanup if the object is initialized */
if (self->priv->is_initialized)
{
NMData * data = nm_device_get_app_data (NM_DEVICE (self));
NMData * data = nm_device_get_app_data (NM_DEVICE (self));
NMSupplicantManager * sup_mgr;
self->priv->is_initialized = FALSE;
@@ -3337,6 +3384,10 @@ nm_device_802_11_wireless_dispose (GObject *object)
g_signal_handler_disconnect (G_OBJECT (data->netlink_monitor),
self->priv->wireless_event_id);
sup_mgr = nm_supplicant_manager_get ();
nm_supplicant_manager_release_iface (sup_mgr, self->priv->sup_iface);
g_object_unref (sup_mgr);
}
/* Chain up to the parent class */

View File

@@ -33,6 +33,7 @@
#include "nm-activation-request.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerPolicy.h"
#include "nm-supplicant-manager.h"
#include "nm-utils.h"
#include "kernel-types.h"
@@ -46,6 +47,8 @@ struct _NMDevice8023EthernetPrivate
char * carrier_file_path;
gulong link_connected_id;
gulong link_disconnected_id;
NMSupplicantInterface * sup_iface;
};
static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev);
@@ -58,6 +61,11 @@ static void nm_device_802_3_ethernet_link_deactivated (NmNetlinkMonitor *monitor
GObject *obj,
NMDevice8023Ethernet *self);
static void supplicant_iface_state_cb (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state,
NMDevice80211Wireless *self);
static void
nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self)
@@ -74,6 +82,7 @@ real_init (NMDevice *dev)
NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev);
NMData * app_data;
NmNetlinkMonitor * monitor;
NMSupplicantManager * sup_mgr;
app_data = nm_device_get_app_data (NM_DEVICE (self));
monitor = app_data->netlink_monitor;
@@ -85,6 +94,20 @@ real_init (NMDevice *dev)
self->priv->link_disconnected_id =
g_signal_connect (G_OBJECT (monitor), "interface-disconnected",
G_CALLBACK (nm_device_802_3_ethernet_link_deactivated), self);
sup_mgr = nm_supplicant_manager_get ();
self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr,
NM_DEVICE (self));
if (self->priv->sup_iface == NULL) {
nm_warning ("Couldn't initialize supplicant interface for %s.",
nm_device_get_iface (NM_DEVICE (self)));
} else {
g_signal_connect (G_OBJECT (self->priv->sup_iface),
"state",
G_CALLBACK (supplicant_iface_state_cb),
self);
}
g_object_unref (sup_mgr);
}
static gboolean
@@ -300,6 +323,7 @@ nm_device_802_3_ethernet_dispose (GObject *object)
NMDevice8023EthernetClass * klass = NM_DEVICE_802_3_ETHERNET_GET_CLASS (object);
NMDeviceClass * parent_class;
NMData * data = nm_device_get_app_data (NM_DEVICE (self));
NMSupplicantManager * sup_mgr;
if (self->priv->dispose_has_run)
/* If dispose did already run, return. */
@@ -314,6 +338,10 @@ nm_device_802_3_ethernet_dispose (GObject *object)
* the most simple solution is to unref all members on which you own a
* reference.
*/
sup_mgr = nm_supplicant_manager_get ();
nm_supplicant_manager_release_iface (sup_mgr, self->priv->sup_iface);
self->priv->sup_iface = NULL;
g_object_unref (sup_mgr);
g_signal_handler_disconnect (G_OBJECT (data->netlink_monitor),
self->priv->link_connected_id);
@@ -384,6 +412,25 @@ nm_device_802_3_ethernet_get_type (void)
}
/****************************************************************************
* WPA Supplicant control stuff
*
*/
static void
supplicant_iface_state_cb (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state,
NMDevice80211Wireless *self)
{
g_return_if_fail (self != NULL);
nm_info ("(%s) supplicant interface is now in state %d (from %d).",
nm_device_get_iface (NM_DEVICE (self)),
new_state,
old_state);
}
/**************************************/
/* Ethtool capability detection */
/**************************************/

View File

@@ -2,3 +2,4 @@ VOID:OBJECT
VOID:OBJECT,POINTER,INT
VOID:POINTER
VOID:POINTER,STRING,STRING,STRING
VOID:UINT,UINT

View File

@@ -1,12 +1,18 @@
INCLUDES = -I${top_srcdir}/utils -I${top_srcdir}/src -I${top_srcdir}/include
INCLUDES = -I${top_srcdir}/utils \
-I${top_srcdir}/src \
-I${top_srcdir}/include \
-I${top_srcdir}/libnm-util
noinst_LTLIBRARIES = libsupplicant-manager.la
libsupplicant_manager_la_SOURCES = \
nm-supplicant-types.h \
nm-supplicant-manager.h \
nm-supplicant-manager.c \
nm-supplicant-connection.h \
nm-supplicant-connection.c \
nm-supplicant-interface.c \
nm-supplicant-interface.h \
nm-supplicant-settings-verify.h \
nm-supplicant-settings-verify.c

View File

@@ -23,6 +23,7 @@
#define NM_SUPPLICANT_CONNECTION_H
#include <glib-object.h>
#include "nm-supplicant-types.h"
#include "nm-device.h"
G_BEGIN_DECLS
@@ -34,7 +35,6 @@ G_BEGIN_DECLS
#define NM_IS_SUPPLICANT_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_CONNECTION))
#define NM_SUPPLICANT_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_CONNECTION, NMSupplicantConnectionClass))
typedef struct _NMSupplicantConnection NMSupplicantConnection;
typedef struct _NMSupplicantConnectionClass NMSupplicantConnectionClass;
typedef struct _NMSupplicantConnectionPrivate NMSupplicantConnectionPrivate;

View File

@@ -0,0 +1,722 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2006 Red Hat, Inc.
*/
#include <string.h>
#include <glib.h>
#include "nm-supplicant-interface.h"
#include "nm-supplicant-manager.h"
#include "nm-device.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-utils.h"
#include "nm-marshal.h"
#include "nm-dbus-manager.h"
#include "dbus-dict-helpers.h"
#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
#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 */
SCAN_RESULTS, /* interface has new scan results */
LAST_SIGNAL
};
static guint nm_supplicant_interface_signals[LAST_SIGNAL] = { 0 };
/* Properties */
enum {
PROP_0 = 0,
PROP_SUPPLICANT_MANAGER,
PROP_DEVICE,
PROP_STATE,
LAST_PROP
};
struct _NMSupplicantInterfacePrivate
{
NMSupplicantManager * smgr;
NMDBusManager * dbus_mgr;
NMDevice * dev;
guint32 state;
DBusPendingCall * pcall;
char * wpas_iface_op;
char * wpas_net_op;
guint32 wpas_sig_handler_id;
NMSupplicantConnection * con;
gboolean dispose_has_run;
};
NMSupplicantInterface *
nm_supplicant_interface_new (NMSupplicantManager * smgr, NMDevice * dev)
{
NMSupplicantInterface * iface;
g_return_val_if_fail (smgr != NULL, NULL);
g_return_val_if_fail (dev != NULL, NULL);
iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
"supplicant-manager", smgr,
"device", dev,
NULL);
if (iface) {
nm_supplicant_interface_start (iface);
}
return iface;
}
static void
nm_supplicant_interface_init (NMSupplicantInterface * self)
{
self->priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
self->priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
self->priv->smgr = NULL;
self->priv->dev = NULL;
self->priv->wpas_iface_op = NULL;
self->priv->pcall = NULL;
self->priv->dispose_has_run = FALSE;
self->priv->dbus_mgr = nm_dbus_manager_get (NULL);
}
static void
nm_supplicant_interface_set_property (GObject * object,
guint prop_id,
const GValue * value,
GParamSpec * pspec)
{
NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
switch (prop_id) {
case PROP_SUPPLICANT_MANAGER:
self->priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value));
g_object_ref (G_OBJECT (self->priv->smgr));
g_signal_connect (G_OBJECT (self->priv->smgr),
"state",
G_CALLBACK (nm_supplicant_interface_smgr_state_changed),
self);
break;
case PROP_DEVICE:
self->priv->dev = NM_DEVICE (g_value_get_object (value));
g_object_ref (G_OBJECT (self->priv->dev));
break;
case PROP_STATE:
/* warn on setting read-only property */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_supplicant_interface_get_property (GObject * object,
guint prop_id,
GValue * value,
GParamSpec * pspec)
{
NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
switch (prop_id) {
case PROP_SUPPLICANT_MANAGER:
g_value_set_object (value, G_OBJECT (self->priv->smgr));
break;
case PROP_DEVICE:
g_value_set_object (value, G_OBJECT (self->priv->dev));
break;
case PROP_STATE:
g_value_set_uint (value, self->priv->state);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_supplicant_interface_dispose (GObject *object)
{
NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
NMSupplicantInterfaceClass * klass;
GObjectClass * parent_class;
if (self->priv->dispose_has_run) {
/* If dispose did already run, return. */
return;
}
/* Make sure dispose does not run twice. */
self->priv->dispose_has_run = TRUE;
/*
* In dispose, you are supposed to free all types referenced from this
* object which might themselves hold a reference to self. Generally,
* the most simple solution is to unref all members on which you own a
* reference.
*/
if (self->priv->smgr) {
g_object_unref (self->priv->smgr);
self->priv->smgr = NULL;
}
if (self->priv->dev) {
g_object_unref (self->priv->dev);
self->priv->dev = NULL;
}
if (self->priv->dbus_mgr) {
nm_dbus_manager_remove_signal_handler (self->priv->dbus_mgr,
self->priv->wpas_sig_handler_id);
g_object_unref (self->priv->dbus_mgr);
self->priv->dbus_mgr = NULL;
}
if (self->priv->con) {
g_object_unref (self->priv->con);
self->priv->con = NULL;
}
/* Chain up to the parent class */
klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
parent_class->dispose (object);
}
static void
nm_supplicant_interface_finalize (GObject *object)
{
NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
NMSupplicantInterfaceClass * klass;
GObjectClass * parent_class;
if (self->priv->wpas_iface_op)
g_free (self->priv->wpas_iface_op);
if (self->priv->wpas_net_op)
g_free (self->priv->wpas_net_op);
if (self->priv->pcall) {
dbus_pending_call_cancel (self->priv->pcall);
self->priv->pcall = NULL;
}
/* Chain up to the parent class */
klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
parent_class->finalize (object);
}
static void
nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nm_supplicant_interface_dispose;
object_class->finalize = nm_supplicant_interface_finalize;
object_class->set_property = nm_supplicant_interface_set_property;
object_class->get_property = nm_supplicant_interface_get_property;
g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
/* 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_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_DEVICE,
g_param_spec_object ("device",
"Device",
"Device which this interface represents to the supplicant",
NM_TYPE_DEVICE,
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_DEVICE,
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));
/* 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);
klass->state = NULL;
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);
klass->removed = NULL;
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,
nm_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
klass->scan_results = NULL;
}
GType
nm_supplicant_interface_get_type (void)
{
static GType type = 0;
if (type == 0) {
static const GTypeInfo info = {
sizeof (NMSupplicantInterfaceClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) nm_supplicant_interface_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (NMSupplicantInterface),
0, /* n_preallocs */
(GInstanceInitFunc) nm_supplicant_interface_init,
NULL /* value_table */
};
type = g_type_register_static (G_TYPE_OBJECT,
"NMSupplicantInterface",
&info, 0);
}
return type;
}
static void
set_wpas_iface_op_from_message (NMSupplicantInterface * self,
DBusMessage * message)
{
DBusError error;
char * path = NULL;
dbus_error_init (&error);
/* Interface was found; cache its object path */
if (!dbus_message_get_args (message,
&error,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID)) {
nm_warning ("Error getting interface path from supplicant: %s - %s",
error.name,
error.message);
} else {
if (self->priv->wpas_iface_op)
g_free (self->priv->wpas_iface_op);
self->priv->wpas_iface_op = g_strdup (path);
}
if (dbus_error_is_set (&error))
dbus_error_free (&error);
}
static gboolean
wpas_iface_signal_handler (DBusConnection * connection,
DBusMessage * message,
gpointer user_data)
{
NMSupplicantInterface * self = (NMSupplicantInterface *) user_data;
const char * op = dbus_message_get_path (message);
gboolean handled = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
if (!op || !self->priv->wpas_iface_op)
return FALSE;
/* Only handle signals for our interface */
if (strcmp (op, self->priv->wpas_iface_op) != 0)
return FALSE;
if (dbus_message_is_signal (message, WPAS_DBUS_IFACE_INTERFACE, "ScanResultsAvailable")) {
handled = TRUE;
}
return handled;
}
#define WPAS_ERROR_INVALID_IFACE \
WPAS_DBUS_INTERFACE ".InvalidInterface"
#define WPAS_ERROR_EXISTS_ERROR \
WPAS_DBUS_INTERFACE ".ExistsError"
static void
nm_supplicant_interface_add_cb (DBusPendingCall *pcall,
NMSupplicantInterface * self)
{
DBusError error;
DBusMessage * reply = NULL;
gboolean clear_pcall = TRUE;
g_return_if_fail (pcall != NULL);
g_return_if_fail (self != NULL);
dbus_error_init (&error);
nm_dbus_send_with_callback_replied (pcall, __func__);
if (!dbus_pending_call_get_completed (pcall))
goto out;
if (!(reply = dbus_pending_call_steal_reply (pcall)))
goto out;
if (dbus_message_is_error (reply, WPAS_ERROR_INVALID_IFACE)) {
/* Interface not added, try to add it */
nm_supplicant_interface_add_to_supplicant (self, FALSE);
clear_pcall = FALSE;
} else if (dbus_message_is_error (reply, WPAS_ERROR_EXISTS_ERROR)) {
/* Interface already added, just try to get the interface */
nm_supplicant_interface_add_to_supplicant (self, TRUE);
clear_pcall = FALSE;
} else if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
if (!dbus_set_error_from_message (&error, reply))
goto out;
nm_warning ("Unexpected supplicant error getting interface: %s - %s",
error.name,
error.message);
} else {
guint32 id;
/* Success; cache the object path */
set_wpas_iface_op_from_message (self, reply);
/* Attach to the scan results signal */
id = nm_dbus_manager_register_signal_handler (self->priv->dbus_mgr,
WPAS_DBUS_IFACE_INTERFACE,
WPAS_DBUS_SERVICE,
wpas_iface_signal_handler,
self);
self->priv->wpas_sig_handler_id = id;
/* Interface added to the supplicant; transition to the READY state. */
nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY);
}
out:
if (reply)
dbus_message_unref (reply);
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_pending_call_unref (pcall);
if (self->priv->pcall && clear_pcall)
self->priv->pcall = NULL;
}
static void
nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self,
gboolean get_only)
{
DBusConnection * dbus_connection;
DBusMessage * message = NULL;
DBusMessageIter iter;
const char * dev_iface;
g_return_if_fail (self != NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
/* Request the interface object from the supplicant */
message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
WPAS_DBUS_PATH,
WPAS_DBUS_INTERFACE,
get_only ? "getInterface" : "addInterface");
if (!message) {
nm_warning ("Not enough memory to allocate dbus message.");
goto out;
}
dbus_message_iter_init_append (message, &iter);
dev_iface = nm_device_get_iface (self->priv->dev);
if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dev_iface)) {
nm_warning ("Couldn't add device interface to message.");
goto out;
}
/* Add the supplicant driver name if we're adding */
if (!get_only) {
DBusMessageIter iter_dict;
char * driver = "wext";
if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) {
nm_warning ("dict open write failed!");
goto out;
}
if (nm_device_is_802_3_ethernet (self->priv->dev))
driver = "wired";
if (!nmu_dbus_dict_append_string (&iter_dict, "driver", driver)) {
nm_warning ("couldn't append driver to dict");
goto out;
}
if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) {
nm_warning ("dict close write failed!");
goto out;
}
}
self->priv->pcall = nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_supplicant_interface_add_cb,
self,
NULL,
__func__);
out:
if (message)
dbus_message_unref (message);
}
static void
nm_supplicant_interface_start (NMSupplicantInterface * self)
{
guint32 state;
g_return_if_fail (self != NULL);
/* Can only start the interface from INIT state */
g_return_if_fail (self->priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
/* Just return if the interface is already starting the transition
* to READY.
*/
if (self->priv->pcall)
return;
state = nm_supplicant_manager_get_state (self->priv->smgr);
if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
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_warning ("Unknown supplicant manager state!");
}
}
static void
nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self)
{
g_return_if_fail (self != NULL);
switch (self->priv->state) {
case NM_SUPPLICANT_INTERFACE_STATE_INIT:
/* Start the move to READY state when supplicant is ready */
nm_supplicant_interface_start (self);
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_warning ("Unknown supplicant interface state!");
break;
}
}
static void
nm_supplicant_interface_set_state (NMSupplicantInterface * self,
guint32 new_state)
{
guint32 old_state;
g_return_if_fail (self != NULL);
g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
if (new_state == self->priv->state)
return;
old_state = self->priv->state;
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN && self->priv->pcall) {
/* If the interface is transitioning to DOWN and there's an
* in-progress pending call, cancel it.
*/
dbus_pending_call_cancel (self->priv->pcall);
self->priv->pcall = NULL;
}
self->priv->state = new_state;
g_signal_emit (G_OBJECT (self),
nm_supplicant_interface_signals[STATE],
0,
self->priv->state,
old_state);
}
static void
nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr,
guint32 new_state,
guint32 old_state,
gpointer user_data)
{
NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (user_data);
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_warning ("Unknown supplicant manager state!");
break;
}
}
#if 0
static void
add_connection_to_iface (NMSupplicantInterface *self)
{
DBusConnection * dbus_connection;
DBusMessage * message = NULL;
g_return_if_fail (self != NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
WPAS_DBUS_IFACE_INTERFACE,
self->priv->wpas_iface_op,
"addNetwork");
if (!message) {
nm_warning ("Couldn't create dbus message.");
goto out;
}
#if 0
self->priv->pcall = nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_supplicant_interface_add_connection_cb,
self,
NULL,
__func__);
#endif
out:
;
}
#endif
void
nm_supplicant_interface_set_connection (NMSupplicantInterface * self,
NMSupplicantConnection * con)
{
g_return_if_fail (self != NULL);
if (self->priv->con)
g_object_unref (self->priv->con);
self->priv->con = con;
if (self->priv->con)
g_object_ref (self->priv->con);
}
NMDevice *
nm_supplicant_interface_get_device (NMSupplicantInterface * self)
{
g_return_val_if_fail (self != NULL, NULL);
return self->priv->dev;
}

View File

@@ -0,0 +1,98 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2006 Red Hat, Inc.
*/
#ifndef NM_SUPPLICANT_INTERFACE_H
#define NM_SUPPLICANT_INTERFACE_H
#include <glib-object.h>
#include "nm-supplicant-types.h"
#include "nm-device.h"
G_BEGIN_DECLS
/*
* Supplicant interface 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_READY,
NM_SUPPLICANT_INTERFACE_STATE_DOWN,
NM_SUPPLICANT_INTERFACE_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))
#define NM_IS_SUPPLICANT_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SUPPLICANT_INTERFACE))
#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))
typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
typedef struct _NMSupplicantInterfacePrivate NMSupplicantInterfacePrivate;
struct _NMSupplicantInterface
{
GObject parent;
/*< private >*/
NMSupplicantInterfacePrivate *priv;
};
struct _NMSupplicantInterfaceClass
{
GObjectClass parent;
/* class members */
void (* state) (NMSupplicantInterface * iface,
guint32 new_state,
guint32 old_state);
void (* removed) (NMSupplicantInterface * iface);
void (* scan_results) (NMSupplicantInterface * iface);
};
GType nm_supplicant_interface_get_type (void);
NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr,
NMDevice * dev);
void nm_supplicant_interface_set_connection (NMSupplicantInterface * iface,
NMSupplicantConnection * con);
NMDevice * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
G_END_DECLS
#endif /* NM_SUPPLICANT_INTERFACE_H */

View File

@@ -19,48 +19,149 @@
*
*/
#include <string.h>
#include <glib.h>
#include <dbus/dbus.h>
#include "nm-supplicant-manager.h"
#include "nm-supplicant-interface.h"
#include "nm-dbus-manager.h"
#include "nm-marshal.h"
#define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_MANAGER, \
NMSupplicantManagerPrivate))
static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection,
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 void nm_supplicant_manager_startup (NMSupplicantManager * self);
/* Signals */
enum {
STATE, /* change in the manager's state */
LAST_SIGNAL
};
static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 };
struct _NMSupplicantManagerPrivate {
gboolean running;
gboolean dispose_has_run;
NMDBusManager * dbus_mgr;
guint32 state;
GSList * ifaces;
gboolean dispose_has_run;
};
NMSupplicantManager *
nm_supplicant_manager_new (void)
nm_supplicant_manager_get (void)
{
NMSupplicantManager * mgr;
static NMSupplicantManager * singleton = NULL;
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
mgr = g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL);
return mgr;
g_static_mutex_lock (&mutex);
if (!singleton) {
singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL));
} else {
g_object_ref (singleton);
}
g_static_mutex_unlock (&mutex);
g_assert (singleton);
return singleton;
}
static void
nm_supplicant_manager_init (NMSupplicantManager * self)
{
self->priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
self->priv->running = FALSE;
self->priv->dispose_has_run = FALSE;
self->priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
self->priv->dbus_mgr = nm_dbus_manager_get (NULL);
nm_supplicant_manager_startup (self);
g_signal_connect (G_OBJECT (self->priv->dbus_mgr),
"name-owner-changed",
G_CALLBACK (nm_supplicant_manager_name_owner_changed),
self);
}
static void
nm_supplicant_manager_dispose (GObject *object)
{
NMSupplicantManager * self = NM_SUPPLICANT_MANAGER (object);
NMSupplicantManagerClass * klass;
GObjectClass * parent_class;
if (self->priv->dispose_has_run) {
/* If dispose did already run, return. */
return;
}
/* Make sure dispose does not run twice. */
self->priv->dispose_has_run = TRUE;
/*
* In dispose, you are supposed to free all types referenced from this
* object which might themselves hold a reference to self. Generally,
* the most simple solution is to unref all members on which you own a
* reference.
*/
if (self->priv->dbus_mgr) {
g_object_unref (G_OBJECT (self->priv->dbus_mgr));
self->priv->dbus_mgr = NULL;
}
/* Chain up to the parent class */
klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
parent_class->dispose (object);
}
static void
nm_supplicant_manager_finalize (GObject *object)
{
NMSupplicantManagerClass * klass;
GObjectClass * parent_class;
/* Chain up to the parent class */
klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
parent_class->finalize (object);
}
static void
nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GObjectClass * object_class = G_OBJECT_CLASS (klass);
/*
object_class->dispose = nm_supplicant_manager_dispose;
object_class->finalize = nm_supplicant_manager_finalize;
*/
g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
/* 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);
klass->state = NULL;
}
GType
@@ -87,3 +188,135 @@ nm_supplicant_manager_get_type (void)
}
return type;
}
static void
nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{
NMSupplicantManager * self = (NMSupplicantManager *) user_data;
gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new && strlen (new));
g_return_if_fail (connection != NULL);
/* 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_supplicant_manager_startup (self);
} else if (old_owner_good && !new_owner_good) {
nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_DOWN);
}
}
guint32
nm_supplicant_manager_get_state (NMSupplicantManager * self)
{
g_return_val_if_fail (self != NULL, FALSE);
return self->priv->state;
}
static void
nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state)
{
guint32 old_state;
g_return_if_fail (self != NULL);
g_return_if_fail (new_state < NM_SUPPLICANT_MANAGER_STATE_LAST);
if (new_state == self->priv->state)
return;
old_state = self->priv->state;
self->priv->state = new_state;
g_signal_emit (G_OBJECT (self),
nm_supplicant_manager_signals[STATE],
0,
self->priv->state,
old_state);
}
static void
nm_supplicant_manager_startup (NMSupplicantManager * self)
{
gboolean running;
/* FIXME: convert to pending call */
running = nm_dbus_manager_name_has_owner (self->priv->dbus_mgr,
WPAS_DBUS_SERVICE);
if (running) {
nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE);
}
}
NMSupplicantInterface *
nm_supplicant_manager_get_iface (NMSupplicantManager * self,
NMDevice * dev)
{
NMSupplicantInterface * iface = NULL;
GSList * elt;
const char * ifname;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (dev != NULL, NULL);
/* Ensure we don't already have this interface */
ifname = nm_device_get_iface (dev);
for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) {
NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
NMDevice * if_dev = nm_supplicant_interface_get_device (if_tmp);
if (!strcmp (nm_device_get_iface (if_dev), ifname)) {
iface = if_tmp;
break;
}
}
if (!iface) {
iface = nm_supplicant_interface_new (self, dev);
if (iface)
self->priv->ifaces = g_slist_append (self->priv->ifaces, iface);
}
/* Object should have 2 references by now; one from the object's creation
* which is for the caller of this function, and one for the supplicant
* manager (because it's kept in the ifaces list) which is grabbed below.
*/
g_object_ref (iface);
return iface;
}
void
nm_supplicant_manager_release_iface (NMSupplicantManager * self,
NMSupplicantInterface * iface)
{
GSList * elt;
g_return_if_fail (self != NULL);
g_return_if_fail (iface != NULL);
for (elt = self->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.
*/
self->priv->ifaces = g_slist_remove_link (self->priv->ifaces, elt);
g_slist_free_1 (elt);
g_object_unref (iface);
break;
}
}
/* One further dereference to match g_object_new() initial refcount of 1 */
g_object_unref (iface);
}

View File

@@ -23,9 +23,33 @@
#define NM_SUPPLICANT_MANAGER_H
#include <glib-object.h>
#include "nm-supplicant-types.h"
#include "nm-device.h"
#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))
@@ -33,7 +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))
typedef struct _NMSupplicantManager NMSupplicantManager;
typedef struct _NMSupplicantManagerClass NMSupplicantManagerClass;
typedef struct _NMSupplicantManagerPrivate NMSupplicantManagerPrivate;
@@ -45,19 +68,24 @@ struct _NMSupplicantManager
NMSupplicantManagerPrivate *priv;
};
struct NMAccessPoint;
struct wpa_ctrl;
struct _NMSupplicantManagerClass
{
GObjectClass parent;
/* class members */
void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state);
};
GType nm_supplicant_manager_get_type (void);
NMSupplicantManager * nm_supplicant_manager_new (void);
NMSupplicantManager * nm_supplicant_manager_get (void);
guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr);
NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr,
NMDevice * dev);
void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr,
NMSupplicantInterface * iface);
#endif /* NM_SUPPLICANT_MANAGER_H */

View File

@@ -0,0 +1,29 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2006 Red Hat, Inc.
*/
#ifndef NM_SUPPLICANT_TYPES_H
#define NM_SUPPLICANT_TYPES_H
typedef struct _NMSupplicantManager NMSupplicantManager;
typedef struct _NMSupplicantInterface NMSupplicantInterface;
typedef struct _NMSupplicantConnection NMSupplicantConnection;
#endif /* NM_SUPPLICANT_TYPES_H */