mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 07:10:07 +01:00
supplicant: collapse supplicant interface states
We only really need one state for the supplicant interface which simplifies handling in the Wifi and Wired device classes quite a bit. It also simplifies the supplicant interface class too. One behavioral change in the device classes is not running the supplicant interface state changes from an idle; we'll have to see if that causes problems. ISTR long ago that processing the state change signals directly caused some issues, but we've significantly reworked somethings since then so we may be able to get away with this now.
This commit is contained in:
parent
4d63f08403
commit
f3a1366b55
6 changed files with 470 additions and 1067 deletions
|
|
@ -78,30 +78,17 @@ typedef enum
|
|||
#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ())
|
||||
#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
|
||||
|
||||
typedef struct SupplicantStateTask {
|
||||
NMDeviceEthernet *self;
|
||||
guint32 new_state;
|
||||
guint32 old_state;
|
||||
gboolean mgr_task;
|
||||
guint source_id;
|
||||
} SupplicantStateTask;
|
||||
|
||||
typedef struct Supplicant {
|
||||
NMSupplicantManager *mgr;
|
||||
NMSupplicantInterface *iface;
|
||||
|
||||
/* signal handler ids */
|
||||
guint mgr_state_id;
|
||||
guint iface_error_id;
|
||||
guint iface_state_id;
|
||||
guint iface_con_state_id;
|
||||
|
||||
/* Timeouts and idles */
|
||||
guint iface_con_error_cb_id;
|
||||
guint con_timeout_id;
|
||||
|
||||
GSList *iface_tasks;
|
||||
GSList *mgr_tasks;
|
||||
} Supplicant;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -996,30 +983,6 @@ remove_supplicant_timeouts (NMDeviceEthernet *self)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finish_supplicant_task (SupplicantStateTask *task, gboolean remove_source)
|
||||
{
|
||||
NMDeviceEthernet *self = task->self;
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
/* idle/timeout handlers should pass FALSE for remove_source, since they
|
||||
* will tell glib to remove their source from the mainloop by returning
|
||||
* FALSE when they exit. When called from this NMDevice's dispose handler,
|
||||
* remove_source should be TRUE to cancel all outstanding idle/timeout
|
||||
* handlers asynchronously.
|
||||
*/
|
||||
if (task->source_id && remove_source)
|
||||
g_source_remove (task->source_id);
|
||||
|
||||
if (task->mgr_task)
|
||||
priv->supplicant.mgr_tasks = g_slist_remove (priv->supplicant.mgr_tasks, task);
|
||||
else
|
||||
priv->supplicant.iface_tasks = g_slist_remove (priv->supplicant.iface_tasks, task);
|
||||
|
||||
memset (task, 0, sizeof (SupplicantStateTask));
|
||||
g_slice_free (SupplicantStateTask, task);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_supplicant_interface_error_handler (NMDeviceEthernet *self)
|
||||
{
|
||||
|
|
@ -1044,28 +1007,14 @@ supplicant_interface_release (NMDeviceEthernet *self)
|
|||
remove_supplicant_timeouts (self);
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
|
||||
/* Clean up all pending supplicant interface state idle tasks */
|
||||
while (priv->supplicant.iface_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
|
||||
|
||||
if (priv->supplicant.iface_con_state_id) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_con_state_id);
|
||||
priv->supplicant.iface_con_state_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.iface_state_id > 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
|
||||
priv->supplicant.iface_state_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.mgr_state_id) {
|
||||
g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
|
||||
priv->supplicant.mgr_state_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.iface) {
|
||||
nm_supplicant_interface_disconnect (priv->supplicant.iface);
|
||||
nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
|
||||
nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
|
||||
priv->supplicant.iface = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1127,77 +1076,6 @@ time_out:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
schedule_state_handler (NMDeviceEthernet *self,
|
||||
GSourceFunc handler,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gboolean mgr_task)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
SupplicantStateTask *task;
|
||||
|
||||
if (new_state == old_state)
|
||||
return TRUE;
|
||||
|
||||
task = g_slice_new0 (SupplicantStateTask);
|
||||
if (!task) {
|
||||
nm_log_err (LOGD_DEVICE, "Not enough memory to process supplicant manager state change.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
task->self = self;
|
||||
task->new_state = new_state;
|
||||
task->old_state = old_state;
|
||||
task->mgr_task = mgr_task;
|
||||
|
||||
task->source_id = g_idle_add (handler, task);
|
||||
if (mgr_task)
|
||||
priv->supplicant.mgr_tasks = g_slist_append (priv->supplicant.mgr_tasks, task);
|
||||
else
|
||||
priv->supplicant.iface_tasks = g_slist_append (priv->supplicant.iface_tasks, task);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_mgr_state_cb_handler (gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDevice *device = NM_DEVICE (task->self);
|
||||
|
||||
/* If the supplicant went away, release the supplicant interface */
|
||||
if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
|
||||
supplicant_interface_release (task->self);
|
||||
|
||||
if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_mgr_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
|
||||
"(%s): supplicant manager state: %s -> %s",
|
||||
nm_device_get_iface (NM_DEVICE (user_data)),
|
||||
nm_supplicant_manager_state_to_string (old_state),
|
||||
nm_supplicant_manager_state_to_string (new_state));
|
||||
|
||||
schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
|
||||
supplicant_mgr_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static NMSupplicantConfig *
|
||||
build_supplicant_config (NMDeviceEthernet *self)
|
||||
{
|
||||
|
|
@ -1224,20 +1102,33 @@ build_supplicant_config (NMDeviceEthernet *self)
|
|||
return config;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_state_cb_handler (gpointer user_data)
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
|
||||
NMDevice *device = NM_DEVICE (task->self);
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMSupplicantConfig *config;
|
||||
gboolean success = FALSE;
|
||||
NMDeviceState devstate;
|
||||
|
||||
if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
|
||||
NMSupplicantConfig *config;
|
||||
const char *iface;
|
||||
gboolean success = FALSE;
|
||||
if (new_state == old_state)
|
||||
return;
|
||||
|
||||
iface = nm_device_get_iface (device);
|
||||
config = build_supplicant_config (task->self);
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
|
||||
"(%s): supplicant interface state: %s -> %s",
|
||||
nm_device_get_iface (device),
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
devstate = nm_device_get_state (device);
|
||||
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
config = build_supplicant_config (self);
|
||||
if (config) {
|
||||
success = nm_supplicant_interface_set_config (priv->supplicant.iface, config);
|
||||
g_object_unref (config);
|
||||
|
|
@ -1246,99 +1137,54 @@ supplicant_iface_state_cb_handler (gpointer user_data)
|
|||
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation (%s/wired): couldn't send security "
|
||||
"configuration to the supplicant.",
|
||||
iface);
|
||||
nm_device_get_iface (device));
|
||||
}
|
||||
} else {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation (%s/wired): couldn't build security configuration.",
|
||||
iface);
|
||||
nm_device_get_iface (device));
|
||||
}
|
||||
|
||||
if (!success)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
} else if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
NMDeviceState state = nm_device_get_state (device);
|
||||
|
||||
supplicant_interface_release (task->self);
|
||||
|
||||
if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
|
||||
"(%s): supplicant interface state: %s -> %s",
|
||||
nm_device_get_iface (NM_DEVICE (user_data)),
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
|
||||
supplicant_iface_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_connection_state_cb_handler (gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDevice *dev = NM_DEVICE (task->self);
|
||||
|
||||
if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
|
||||
remove_supplicant_interface_error_handler (task->self);
|
||||
remove_supplicant_timeouts (task->self);
|
||||
if (!success) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
remove_supplicant_timeouts (self);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
|
||||
if (devstate == NM_DEVICE_STATE_CONFIG) {
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.",
|
||||
nm_device_get_iface (dev));
|
||||
nm_device_activate_schedule_stage3_ip_config_start (dev);
|
||||
nm_device_get_iface (device));
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
}
|
||||
} else if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
|
||||
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
|
||||
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
/* Start the link timeout so we allow some time for reauthentication */
|
||||
if (!priv->supplicant_timeout_id)
|
||||
priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, dev);
|
||||
priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
supplicant_interface_release (self);
|
||||
remove_supplicant_timeouts (self);
|
||||
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
|
||||
"(%s) supplicant connection state: %s -> %s",
|
||||
nm_device_get_iface (NM_DEVICE (user_data)),
|
||||
nm_supplicant_interface_connection_state_to_string (old_state),
|
||||
nm_supplicant_interface_connection_state_to_string (new_state));
|
||||
|
||||
schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
|
||||
supplicant_iface_connection_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -1456,38 +1302,26 @@ supplicant_interface_init (NMDeviceEthernet *self)
|
|||
iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
|
||||
/* Create supplicant interface */
|
||||
priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr, iface, FALSE);
|
||||
priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, iface, FALSE);
|
||||
if (!priv->supplicant.iface) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
|
||||
"Couldn't initialize supplicant interface for %s.",
|
||||
iface);
|
||||
supplicant_interface_release (self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Listen for it's state signals */
|
||||
priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface,
|
||||
"state",
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
"state",
|
||||
G_CALLBACK (supplicant_iface_state_cb),
|
||||
self);
|
||||
|
||||
/* Hook up error signal handler to capture association errors */
|
||||
priv->supplicant.iface_error_id = g_signal_connect (priv->supplicant.iface,
|
||||
"connection-error",
|
||||
G_CALLBACK (supplicant_iface_connection_error_cb),
|
||||
self);
|
||||
|
||||
priv->supplicant.iface_con_state_id = g_signal_connect (priv->supplicant.iface,
|
||||
"connection-state",
|
||||
G_CALLBACK (supplicant_iface_connection_state_cb),
|
||||
self);
|
||||
|
||||
/* Listen for supplicant manager state changes */
|
||||
priv->supplicant.mgr_state_id = g_signal_connect (priv->supplicant.mgr,
|
||||
"state",
|
||||
G_CALLBACK (supplicant_mgr_state_cb),
|
||||
self);
|
||||
"connection-error",
|
||||
G_CALLBACK (supplicant_iface_connection_error_cb),
|
||||
self);
|
||||
|
||||
/* Set up a timeout on the connection attempt to fail it after 25 seconds */
|
||||
priv->supplicant.con_timeout_id = g_timeout_add_seconds (25, supplicant_connection_timeout_cb, self);
|
||||
|
|
@ -2047,12 +1881,6 @@ dispose (GObject *object)
|
|||
|
||||
priv->disposed = TRUE;
|
||||
|
||||
/* Clean up all pending supplicant tasks */
|
||||
while (priv->supplicant.iface_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
|
||||
while (priv->supplicant.mgr_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.mgr_tasks->data, TRUE);
|
||||
|
||||
if (priv->link_connected_id) {
|
||||
g_signal_handler_disconnect (priv->monitor, priv->link_connected_id);
|
||||
priv->link_connected_id = 0;
|
||||
|
|
|
|||
|
|
@ -113,34 +113,21 @@ typedef enum {
|
|||
#define NM_WIFI_ERROR (nm_wifi_error_quark ())
|
||||
#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
|
||||
|
||||
typedef struct SupplicantStateTask {
|
||||
NMDeviceWifi *self;
|
||||
guint32 new_state;
|
||||
guint32 old_state;
|
||||
gboolean mgr_task;
|
||||
guint source_id;
|
||||
} SupplicantStateTask;
|
||||
|
||||
typedef struct Supplicant {
|
||||
NMSupplicantManager *mgr;
|
||||
NMSupplicantInterface *iface;
|
||||
|
||||
/* signal handler ids */
|
||||
guint mgr_state_id;
|
||||
guint iface_error_id;
|
||||
guint iface_state_id;
|
||||
guint iface_scanned_ap_id;
|
||||
guint iface_scan_request_result_id;
|
||||
guint iface_scan_results_id;
|
||||
guint iface_con_state_id;
|
||||
guint iface_notify_scanning_id;
|
||||
|
||||
/* Timeouts and idles */
|
||||
guint iface_con_error_cb_id;
|
||||
guint con_timeout_id;
|
||||
|
||||
GSList *mgr_tasks;
|
||||
GSList *iface_tasks;
|
||||
} Supplicant;
|
||||
|
||||
struct _NMDeviceWifiPrivate {
|
||||
|
|
@ -199,15 +186,10 @@ static void cleanup_association_attempt (NMDeviceWifi * self,
|
|||
|
||||
static void remove_supplicant_timeouts (NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_state_cb (NMSupplicantInterface * iface,
|
||||
static void supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self);
|
||||
gpointer user_data);
|
||||
|
||||
static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
|
||||
GHashTable *properties,
|
||||
|
|
@ -221,11 +203,6 @@ static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface,
|
|||
guint32 num_bssids,
|
||||
NMDeviceWifi * self);
|
||||
|
||||
static void supplicant_mgr_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
|
||||
GParamSpec * pspec,
|
||||
NMDeviceWifi * self);
|
||||
|
|
@ -625,10 +602,7 @@ constructor (GType type,
|
|||
|
||||
/* Connect to the supplicant manager */
|
||||
priv->supplicant.mgr = nm_supplicant_manager_get ();
|
||||
priv->supplicant.mgr_state_id = g_signal_connect (priv->supplicant.mgr,
|
||||
"state",
|
||||
G_CALLBACK (supplicant_mgr_state_cb),
|
||||
self);
|
||||
g_assert (priv->supplicant.mgr);
|
||||
|
||||
/* The ipw2x00 drivers don't integrate with the kernel rfkill subsystem until
|
||||
* 2.6.33. Thus all our nice libgudev magic is useless. So we get to poll.
|
||||
|
|
@ -657,17 +631,13 @@ static gboolean
|
|||
supplicant_interface_acquire (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
guint id, mgr_state;
|
||||
guint id;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (priv->supplicant.mgr != NULL, FALSE);
|
||||
/* interface already acquired? */
|
||||
g_return_val_if_fail (priv->supplicant.iface == NULL, TRUE);
|
||||
|
||||
mgr_state = nm_supplicant_manager_get_state (priv->supplicant.mgr);
|
||||
g_return_val_if_fail (mgr_state == NM_SUPPLICANT_MANAGER_STATE_IDLE, FALSE);
|
||||
|
||||
priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr,
|
||||
priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr,
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
TRUE);
|
||||
if (priv->supplicant.iface == NULL) {
|
||||
|
|
@ -700,12 +670,6 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
|||
self);
|
||||
priv->supplicant.iface_scan_results_id = id;
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"connection-state",
|
||||
G_CALLBACK (supplicant_iface_connection_state_cb),
|
||||
self);
|
||||
priv->supplicant.iface_con_state_id = id;
|
||||
|
||||
id = g_signal_connect (priv->supplicant.iface,
|
||||
"notify::scanning",
|
||||
G_CALLBACK (supplicant_iface_notify_scanning_cb),
|
||||
|
|
@ -715,30 +679,6 @@ supplicant_interface_acquire (NMDeviceWifi *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
finish_supplicant_task (SupplicantStateTask *task, gboolean remove_source)
|
||||
{
|
||||
NMDeviceWifi *self = task->self;
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
/* idle/timeout handlers should pass FALSE for remove_source, since they
|
||||
* will tell glib to remove their source from the mainloop by returning
|
||||
* FALSE when they exit. When called from this NMDevice's dispose handler,
|
||||
* remove_source should be TRUE to cancel all outstanding idle/timeout
|
||||
* handlers asynchronously.
|
||||
*/
|
||||
if (task->source_id && remove_source)
|
||||
g_source_remove (task->source_id);
|
||||
|
||||
if (task->mgr_task)
|
||||
priv->supplicant.mgr_tasks = g_slist_remove (priv->supplicant.mgr_tasks, task);
|
||||
else
|
||||
priv->supplicant.iface_tasks = g_slist_remove (priv->supplicant.iface_tasks, task);
|
||||
|
||||
memset (task, 0, sizeof (SupplicantStateTask));
|
||||
g_slice_free (SupplicantStateTask, task);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_supplicant_interface_error_handler (NMDeviceWifi *self)
|
||||
{
|
||||
|
|
@ -776,10 +716,6 @@ supplicant_interface_release (NMDeviceWifi *self)
|
|||
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
|
||||
/* Clean up all pending supplicant interface state idle tasks */
|
||||
while (priv->supplicant.iface_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
|
||||
|
||||
if (priv->supplicant.iface_state_id > 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
|
||||
priv->supplicant.iface_state_id = 0;
|
||||
|
|
@ -800,11 +736,6 @@ supplicant_interface_release (NMDeviceWifi *self)
|
|||
priv->supplicant.iface_scan_results_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.iface_con_state_id > 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_con_state_id);
|
||||
priv->supplicant.iface_con_state_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.iface_notify_scanning_id > 0) {
|
||||
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_notify_scanning_id);
|
||||
priv->supplicant.iface_notify_scanning_id = 0;
|
||||
|
|
@ -814,7 +745,7 @@ supplicant_interface_release (NMDeviceWifi *self)
|
|||
/* Tell the supplicant to disconnect from the current AP */
|
||||
nm_supplicant_interface_disconnect (priv->supplicant.iface);
|
||||
|
||||
nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
|
||||
nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
|
||||
priv->supplicant.iface = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1837,11 +1768,11 @@ scanning_allowed (NMDeviceWifi *self)
|
|||
}
|
||||
|
||||
/* Don't scan if the supplicant is busy */
|
||||
sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface);
|
||||
if ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE
|
||||
sup_state = nm_supplicant_interface_get_state (priv->supplicant.iface);
|
||||
if ( sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE
|
||||
|| sup_state == NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE
|
||||
|| nm_supplicant_interface_get_scanning (priv->supplicant.iface))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -2441,253 +2372,97 @@ time_out:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
schedule_state_handler (NMDeviceWifi *self,
|
||||
GSourceFunc handler,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gboolean mgr_task)
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface *iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv;
|
||||
SupplicantStateTask *task;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (handler != NULL, FALSE);
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMDeviceState devstate;
|
||||
gboolean scanning;
|
||||
|
||||
if (new_state == old_state)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
|
||||
"(%s): supplicant interface state: %s -> %s",
|
||||
nm_device_get_iface (device),
|
||||
nm_supplicant_interface_state_to_string (old_state),
|
||||
nm_supplicant_interface_state_to_string (new_state));
|
||||
|
||||
task = g_slice_new0 (SupplicantStateTask);
|
||||
if (!task) {
|
||||
nm_log_err (LOGD_WIFI, "Not enough memory to process supplicant manager state change.");
|
||||
return FALSE;
|
||||
}
|
||||
devstate = nm_device_get_state (device);
|
||||
scanning = nm_supplicant_interface_get_scanning (iface);
|
||||
|
||||
task->self = self;
|
||||
task->new_state = new_state;
|
||||
task->old_state = old_state;
|
||||
task->mgr_task = mgr_task;
|
||||
|
||||
task->source_id = g_idle_add (handler, task);
|
||||
if (mgr_task)
|
||||
priv->supplicant.mgr_tasks = g_slist_append (priv->supplicant.mgr_tasks, task);
|
||||
else
|
||||
priv->supplicant.iface_tasks = g_slist_append (priv->supplicant.iface_tasks, task);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_state_cb_handler (gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDeviceWifi *self;
|
||||
NMDeviceWifiPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (task != NULL, FALSE);
|
||||
|
||||
self = task->self;
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_log_info (LOGD_WIFI, "(%s): supplicant interface state: %s -> %s",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_supplicant_interface_state_to_string (task->old_state),
|
||||
nm_supplicant_interface_state_to_string (task->new_state));
|
||||
|
||||
if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
|
||||
switch (new_state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_READY:
|
||||
priv->scan_interval = SCAN_INTERVAL_MIN;
|
||||
|
||||
/* If the interface can now be activated because the supplicant is now
|
||||
* available, transition to DISCONNECTED.
|
||||
*/
|
||||
if ( (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_UNAVAILABLE)
|
||||
&& nm_device_is_available (NM_DEVICE (self))) {
|
||||
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED,
|
||||
if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE);
|
||||
}
|
||||
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): supplicant ready, requesting initial scan",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
nm_log_dbg (LOGD_WIFI_SCAN,
|
||||
"(%s): supplicant ready, requesting initial scan",
|
||||
nm_device_get_iface (device));
|
||||
|
||||
/* Request a scan to get latest results */
|
||||
cancel_pending_scan (self);
|
||||
request_wireless_scan (self);
|
||||
} else if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
|
||||
cleanup_association_attempt (self, FALSE);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
supplicant_iface_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
schedule_state_handler (self,
|
||||
supplicant_iface_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
supplicant_iface_connection_state_cb_handler (gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDeviceWifi *self = task->self;
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
NMDevice *dev = NM_DEVICE (self);
|
||||
gboolean scanning;
|
||||
|
||||
if (!nm_device_get_act_request (dev)) {
|
||||
/* The device is not activating or already activated; do nothing. */
|
||||
goto out;
|
||||
}
|
||||
|
||||
nm_log_info (LOGD_WIFI, "(%s): supplicant connection state: %s -> %s",
|
||||
nm_device_get_iface (dev),
|
||||
nm_supplicant_interface_connection_state_to_string (task->old_state),
|
||||
nm_supplicant_interface_connection_state_to_string (task->new_state));
|
||||
|
||||
scanning = nm_supplicant_interface_get_scanning (priv->supplicant.iface);
|
||||
|
||||
if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
|
||||
remove_supplicant_interface_error_handler (self);
|
||||
remove_supplicant_timeouts (self);
|
||||
|
||||
/* If this is the initial association during device activation,
|
||||
* schedule the next activation stage.
|
||||
*/
|
||||
if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
|
||||
if (devstate == NM_DEVICE_STATE_CONFIG) {
|
||||
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self);
|
||||
const GByteArray * ssid = nm_ap_get_ssid (ap);
|
||||
const GByteArray *ssid = nm_ap_get_ssid (ap);
|
||||
|
||||
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation (%s/wireless) Stage 2 of 5 (Device Configure) "
|
||||
"successful. Connected to wireless network '%s'.",
|
||||
nm_device_get_iface (dev),
|
||||
nm_device_get_iface (device),
|
||||
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
|
||||
nm_device_activate_schedule_stage3_ip_config_start (dev);
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
}
|
||||
} else if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
|
||||
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
|
||||
if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
|
||||
/* Start the link timeout so we allow some time for reauthentication,
|
||||
* use a longer timeout if we are scanning since some cards take a
|
||||
* while to scan.
|
||||
*/
|
||||
if (!priv->link_timeout_id) {
|
||||
priv->link_timeout_id = g_timeout_add_seconds (scanning ? 30 : 15,
|
||||
link_timeout_cb, self);
|
||||
link_timeout_cb, self);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
|
||||
cleanup_association_attempt (self, FALSE);
|
||||
supplicant_interface_release (self);
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
/* Signal scanning state changes */
|
||||
if ( task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING
|
||||
|| task->old_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING)
|
||||
if ( new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
|
||||
|| old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
|
||||
g_object_notify (G_OBJECT (self), "scanning");
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
schedule_state_handler (self,
|
||||
supplicant_iface_connection_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
supplicant_mgr_state_cb_handler (gpointer user_data)
|
||||
{
|
||||
SupplicantStateTask *task = (SupplicantStateTask *) user_data;
|
||||
NMDeviceWifi *self;
|
||||
NMDeviceWifiPrivate *priv;
|
||||
NMDevice *dev;
|
||||
NMDeviceState dev_state;
|
||||
|
||||
g_return_val_if_fail (task != NULL, FALSE);
|
||||
|
||||
self = task->self;
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
dev = NM_DEVICE (self);
|
||||
|
||||
nm_log_info (LOGD_WIFI, "(%s): supplicant manager state: %s -> %s",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_supplicant_manager_state_to_string (task->old_state),
|
||||
nm_supplicant_manager_state_to_string (task->new_state));
|
||||
|
||||
/* If the supplicant went away, release the supplicant interface */
|
||||
if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
|
||||
if (priv->supplicant.iface) {
|
||||
cleanup_association_attempt (self, FALSE);
|
||||
supplicant_interface_release (self);
|
||||
}
|
||||
|
||||
if (nm_device_get_state (dev) > NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
nm_device_state_changed (dev, NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
|
||||
}
|
||||
} else if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
|
||||
dev_state = nm_device_get_state (dev);
|
||||
if ( priv->enabled
|
||||
&& !priv->supplicant.iface
|
||||
&& (dev_state >= NM_DEVICE_STATE_UNAVAILABLE)
|
||||
&& (nm_device_get_firmware_missing (NM_DEVICE (self)) == FALSE)) {
|
||||
/* request a supplicant interface from the supplicant manager */
|
||||
supplicant_interface_acquire (self);
|
||||
|
||||
/* if wireless is enabled and we have a supplicant interface,
|
||||
* we can transition to the DISCONNECTED state.
|
||||
*/
|
||||
if (priv->supplicant.iface) {
|
||||
nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish_supplicant_task (task, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_mgr_state_cb (NMSupplicantInterface * iface,
|
||||
guint32 new_state,
|
||||
guint32 old_state,
|
||||
NMDeviceWifi *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
schedule_state_handler (self,
|
||||
supplicant_mgr_state_cb_handler,
|
||||
new_state,
|
||||
old_state,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
struct iface_con_error_cb_data {
|
||||
|
|
@ -3845,20 +3620,9 @@ dispose (GObject *object)
|
|||
priv->periodic_source_id = 0;
|
||||
}
|
||||
|
||||
/* Clean up all pending supplicant tasks */
|
||||
while (priv->supplicant.iface_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
|
||||
while (priv->supplicant.mgr_tasks)
|
||||
finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.mgr_tasks->data, TRUE);
|
||||
|
||||
cleanup_association_attempt (self, TRUE);
|
||||
supplicant_interface_release (self);
|
||||
|
||||
if (priv->supplicant.mgr_state_id) {
|
||||
g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
|
||||
priv->supplicant.mgr_state_id = 0;
|
||||
}
|
||||
|
||||
if (priv->supplicant.mgr) {
|
||||
g_object_unref (priv->supplicant.mgr);
|
||||
priv->supplicant.mgr = NULL;
|
||||
|
|
|
|||
|
|
@ -47,15 +47,6 @@ G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
|
|||
NM_TYPE_SUPPLICANT_INTERFACE, \
|
||||
NMSupplicantInterfacePrivate))
|
||||
|
||||
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_set_state (NMSupplicantInterface *self,
|
||||
guint32 new_state);
|
||||
|
||||
|
||||
/* Signals */
|
||||
enum {
|
||||
STATE, /* change in the interface's state */
|
||||
|
|
@ -63,7 +54,6 @@ enum {
|
|||
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
|
||||
};
|
||||
|
|
@ -74,16 +64,14 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
|||
enum {
|
||||
PROP_0 = 0,
|
||||
PROP_STATE,
|
||||
PROP_CONNECTION_STATE,
|
||||
PROP_SCANNING,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
NMSupplicantManager * smgr;
|
||||
gulong smgr_state_sig_handler;
|
||||
gulong smgr_running_id;
|
||||
NMDBusManager * dbus_mgr;
|
||||
char * dev;
|
||||
gboolean is_wireless;
|
||||
|
|
@ -93,9 +81,9 @@ typedef struct
|
|||
NMCallStore * assoc_pcalls;
|
||||
NMCallStore * other_pcalls;
|
||||
|
||||
guint32 con_state;
|
||||
gboolean scanning;
|
||||
|
||||
DBusGProxy * wpas_proxy;
|
||||
DBusGProxy * iface_proxy;
|
||||
DBusGProxy * net_proxy;
|
||||
|
||||
|
|
@ -186,28 +174,6 @@ nm_supplicant_info_destroy (gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
try_remove_iface (DBusGConnection *g_connection,
|
||||
const char *path)
|
||||
{
|
||||
DBusGProxy *proxy;
|
||||
|
||||
g_return_if_fail (g_connection != NULL);
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
proxy = dbus_g_proxy_new_for_name (g_connection,
|
||||
WPAS_DBUS_SERVICE,
|
||||
WPAS_DBUS_PATH,
|
||||
WPAS_DBUS_INTERFACE);
|
||||
if (!proxy)
|
||||
return;
|
||||
|
||||
dbus_g_proxy_call_no_reply (proxy, "removeInterface",
|
||||
DBUS_TYPE_G_OBJECT_PATH, path,
|
||||
G_TYPE_INVALID);
|
||||
g_object_unref (proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_error_helper (NMSupplicantInterface *self,
|
||||
GError *err)
|
||||
|
|
@ -344,50 +310,80 @@ wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data)
|
|||
}
|
||||
|
||||
static guint32
|
||||
wpas_state_string_to_enum (const char * str_state)
|
||||
wpas_state_string_to_enum (const char *str_state)
|
||||
{
|
||||
guint32 enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
|
||||
guint32 enum_state = NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED;
|
||||
|
||||
if (!strcmp (str_state, "DISCONNECTED"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED;
|
||||
else if (!strcmp (str_state, "INACTIVE"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_INACTIVE;
|
||||
else if (!strcmp (str_state, "SCANNING"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_SCANNING;
|
||||
else if (!strcmp (str_state, "ASSOCIATING"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING;
|
||||
else if (!strcmp (str_state, "ASSOCIATED"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED;
|
||||
else if (!strcmp (str_state, "4WAY_HANDSHAKE"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE;
|
||||
else if (!strcmp (str_state, "GROUP_HANDSHAKE"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE;
|
||||
else if (!strcmp (str_state, "COMPLETED"))
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED;
|
||||
enum_state = NM_SUPPLICANT_INTERFACE_STATE_COMPLETED;
|
||||
|
||||
return enum_state;
|
||||
}
|
||||
|
||||
static void
|
||||
set_state (NMSupplicantInterface *self, guint32 new_state)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
guint32 old_state = priv->state;
|
||||
|
||||
g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
|
||||
|
||||
if (new_state == priv->state)
|
||||
return;
|
||||
|
||||
/* DOWN is a terminal state */
|
||||
g_return_if_fail (priv->state != NM_SUPPLICANT_INTERFACE_STATE_DOWN);
|
||||
|
||||
/* Cannot regress to READY or INIT from higher states */
|
||||
if (priv->state <= NM_SUPPLICANT_INTERFACE_STATE_READY)
|
||||
g_return_if_fail (new_state > priv->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);
|
||||
|
||||
/* Disconnect supplicant manager state listeners since we're done */
|
||||
if (priv->smgr_running_id) {
|
||||
g_signal_handler_disconnect (priv->smgr, priv->smgr_running_id);
|
||||
priv->smgr_running_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
priv->state = new_state;
|
||||
g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
|
||||
}
|
||||
|
||||
/* Supplicant state signal handler */
|
||||
static void
|
||||
wpas_iface_handle_state_change (DBusGProxy *proxy,
|
||||
const char *str_new_state,
|
||||
const char *str_old_state,
|
||||
gpointer user_data)
|
||||
{
|
||||
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, signals[CONNECTION_STATE], 0, priv->con_state, old_state);
|
||||
set_state (NM_SUPPLICANT_INTERFACE (user_data),
|
||||
wpas_state_string_to_enum (str_new_state));
|
||||
}
|
||||
|
||||
|
||||
/* Explicit state request reply handler */
|
||||
static void
|
||||
iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||
{
|
||||
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
|
||||
GError *err = NULL;
|
||||
char *state_str = NULL;
|
||||
|
||||
|
|
@ -397,12 +393,8 @@ iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
|||
nm_log_warn (LOGD_SUPPLICANT, "could not get interface state: %s.", err->message);
|
||||
g_error_free (err);
|
||||
} else {
|
||||
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
|
||||
|
||||
priv->con_state = wpas_state_string_to_enum (state_str);
|
||||
set_state (info->interface, wpas_state_string_to_enum (state_str));
|
||||
g_free (state_str);
|
||||
nm_supplicant_interface_set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -479,225 +471,181 @@ nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
|
|||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
if (priv->scanning)
|
||||
return TRUE;
|
||||
if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING)
|
||||
if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||
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 (_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, "StateChange",
|
||||
G_CALLBACK (wpas_iface_handle_state_change),
|
||||
self,
|
||||
NULL);
|
||||
|
||||
dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID);
|
||||
dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable",
|
||||
G_CALLBACK (wpas_iface_query_scan_results),
|
||||
self,
|
||||
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),
|
||||
self,
|
||||
NULL);
|
||||
|
||||
/* Interface added to the supplicant; get its initial state. */
|
||||
wpas_iface_get_state (self);
|
||||
wpas_iface_get_scanning (self);
|
||||
|
||||
set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY);
|
||||
}
|
||||
|
||||
static void
|
||||
interface_get_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;
|
||||
GError *error = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
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 getting interface: %s",
|
||||
priv->dev, err->message);
|
||||
}
|
||||
|
||||
g_error_free (err);
|
||||
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_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);
|
||||
nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
|
||||
priv->dev, error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self,
|
||||
gboolean get_only)
|
||||
interface_get (NMSupplicantInterface *self)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
NMSupplicantInfo *info;
|
||||
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);
|
||||
|
||||
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_destroy,
|
||||
G_TYPE_STRING, priv->dev,
|
||||
G_TYPE_INVALID);
|
||||
nm_supplicant_info_set_call (info, call);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_supplicant_interface_start (NMSupplicantInterface * self)
|
||||
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;
|
||||
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 {
|
||||
nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
|
||||
priv->dev, error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
interface_add (NMSupplicantInterface * self, gboolean is_wireless)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
guint32 state;
|
||||
DBusGProxyCall *call;
|
||||
NMSupplicantInfo *info;
|
||||
GHashTable *hash;
|
||||
GValue *driver;
|
||||
|
||||
/* 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);
|
||||
|
||||
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.
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls);
|
||||
|
||||
driver = g_new0 (GValue, 1);
|
||||
g_value_init (driver, G_TYPE_STRING);
|
||||
g_value_set_string (driver, is_wireless ? "wext" : "wired");
|
||||
|
||||
hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_hash_table_insert (hash, "driver", driver);
|
||||
|
||||
call = dbus_g_proxy_begin_call (priv->wpas_proxy, "addInterface",
|
||||
interface_add_cb,
|
||||
info,
|
||||
nm_supplicant_info_destroy,
|
||||
G_TYPE_STRING, priv->dev,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, hash,
|
||||
G_TYPE_INVALID);
|
||||
|
||||
g_hash_table_destroy (hash);
|
||||
g_value_unset (driver);
|
||||
g_free (driver);
|
||||
|
||||
nm_supplicant_info_set_call (info, call);
|
||||
}
|
||||
|
||||
static void
|
||||
smgr_running_cb (NMSupplicantManager *smgr,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
|
||||
|
||||
if (nm_supplicant_manager_running (smgr)) {
|
||||
/* This can happen if the supplicant couldn't be activated but
|
||||
* for some reason was started after the activation failure.
|
||||
*/
|
||||
} else
|
||||
nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nm_supplicant_interface_set_state (NMSupplicantInterface * self,
|
||||
guint32 new_state)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
guint32 old_state;
|
||||
|
||||
g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
|
||||
|
||||
if (new_state == priv->state)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
priv->state = new_state;
|
||||
g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
|
||||
}
|
||||
|
||||
static void
|
||||
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_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
|
||||
{
|
||||
|
|
@ -742,16 +690,13 @@ 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->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
|
||||
|| priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) {
|
||||
/* 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) {
|
||||
if (priv->net_proxy) {
|
||||
g_object_unref (priv->net_proxy);
|
||||
priv->net_proxy = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1011,14 +956,6 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
|
|||
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)
|
||||
{
|
||||
|
|
@ -1067,24 +1004,30 @@ 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)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_INIT:
|
||||
return "init";
|
||||
case NM_SUPPLICANT_INTERFACE_STATE_STARTING:
|
||||
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_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:
|
||||
|
|
@ -1094,35 +1037,28 @@ nm_supplicant_interface_state_to_string (guint32 state)
|
|||
}
|
||||
|
||||
const char *
|
||||
nm_supplicant_interface_connection_state_to_string (guint32 state)
|
||||
nm_supplicant_interface_get_device (NMSupplicantInterface * self)
|
||||
{
|
||||
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:
|
||||
break;
|
||||
}
|
||||
return "unknown";
|
||||
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, FALSE);
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
|
||||
|
||||
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
|
||||
}
|
||||
|
|
@ -1147,14 +1083,15 @@ nm_supplicant_interface_new (NMSupplicantManager *smgr,
|
|||
|
||||
priv->smgr = g_object_ref (smgr);
|
||||
id = g_signal_connect (priv->smgr,
|
||||
"state",
|
||||
G_CALLBACK (smgr_state_changed),
|
||||
"notify::" NM_SUPPLICANT_MANAGER_RUNNING,
|
||||
G_CALLBACK (smgr_running_cb),
|
||||
self);
|
||||
priv->smgr_state_sig_handler = id;
|
||||
priv->smgr_running_id = id;
|
||||
|
||||
priv->dev = g_strdup (ifname);
|
||||
priv->is_wireless = is_wireless;
|
||||
nm_supplicant_interface_start (self);
|
||||
|
||||
interface_add (self, priv->is_wireless);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
@ -1164,12 +1101,18 @@ static void
|
|||
nm_supplicant_interface_init (NMSupplicantInterface * self)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
|
||||
DBusGConnection *bus;
|
||||
|
||||
priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
|
||||
priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
|
||||
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
|
||||
|
|
@ -1195,9 +1138,6 @@ get_property (GObject *object,
|
|||
case PROP_STATE:
|
||||
g_value_set_uint (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->state);
|
||||
break;
|
||||
case PROP_CONNECTION_STATE:
|
||||
g_value_set_uint (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->con_state);
|
||||
break;
|
||||
case PROP_SCANNING:
|
||||
g_value_set_boolean (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->scanning);
|
||||
break;
|
||||
|
|
@ -1211,7 +1151,6 @@ static void
|
|||
dispose (GObject *object)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
|
||||
guint32 sm_state;
|
||||
|
||||
if (priv->disposed) {
|
||||
G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
|
||||
|
|
@ -1219,27 +1158,21 @@ dispose (GObject *object)
|
|||
}
|
||||
priv->disposed = TRUE;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->iface_proxy)
|
||||
g_object_unref (priv->iface_proxy);
|
||||
|
||||
if (priv->net_proxy)
|
||||
g_object_unref (priv->net_proxy);
|
||||
|
||||
if (priv->wpas_proxy)
|
||||
g_object_unref (priv->wpas_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);
|
||||
if (priv->smgr_running_id)
|
||||
g_signal_handler_disconnect (priv->smgr, priv->smgr_running_id);
|
||||
g_object_unref (priv->smgr);
|
||||
}
|
||||
|
||||
|
|
@ -1338,15 +1271,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
|
|||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
|
||||
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);
|
||||
|
||||
signals[CONNECTION_ERROR] =
|
||||
g_signal_new ("connection-error",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
|
|
|
|||
|
|
@ -26,47 +26,25 @@
|
|||
#include <dbus/dbus.h>
|
||||
#include "nm-supplicant-types.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.
|
||||
* A mix of wpa_supplicant interface states and internal states.
|
||||
*/
|
||||
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_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))
|
||||
|
|
@ -103,11 +81,6 @@ typedef struct {
|
|||
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,
|
||||
|
|
@ -128,20 +101,16 @@ 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 */
|
||||
|
|
|
|||
|
|
@ -26,19 +26,7 @@
|
|||
#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;
|
||||
GHashTable * ifaces;
|
||||
gboolean disposed;
|
||||
guint poke_id;
|
||||
} NMSupplicantManagerPrivate;
|
||||
|
||||
#define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
NM_TYPE_SUPPLICANT_MANAGER, \
|
||||
|
|
@ -46,84 +34,26 @@ typedef struct {
|
|||
|
||||
G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT)
|
||||
|
||||
/* Signals */
|
||||
/* Properties */
|
||||
enum {
|
||||
STATE, /* change in the manager's state */
|
||||
LAST_SIGNAL
|
||||
PROP_0 = 0,
|
||||
PROP_RUNNING,
|
||||
LAST_PROP
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
typedef struct {
|
||||
NMDBusManager * dbus_mgr;
|
||||
guint name_owner_id;
|
||||
DBusGProxy * proxy;
|
||||
gboolean running;
|
||||
GHashTable * ifaces;
|
||||
gboolean disposed;
|
||||
} NMSupplicantManagerPrivate;
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
static gboolean
|
||||
poke_supplicant_cb (gpointer user_data)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
out:
|
||||
/* Reschedule the poke */
|
||||
priv->poke_id = g_timeout_add_seconds (SUPPLICANT_POKE_INTERVAL,
|
||||
poke_supplicant_cb,
|
||||
(gpointer) self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_supplicant_manager_get_state (NMSupplicantManager * self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
|
||||
|
||||
return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state;
|
||||
}
|
||||
|
||||
static void
|
||||
set_state (NMSupplicantManager *self, guint32 new_state)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
guint32 old_state;
|
||||
|
||||
if (new_state != priv->state) {
|
||||
old_state = priv->state;
|
||||
priv->state = new_state;
|
||||
g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
startup (NMSupplicantManager * self)
|
||||
{
|
||||
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)
|
||||
set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE);
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
NMSupplicantInterface *
|
||||
nm_supplicant_manager_get_iface (NMSupplicantManager * self,
|
||||
nm_supplicant_manager_iface_get (NMSupplicantManager * self,
|
||||
const char *ifname,
|
||||
gboolean is_wireless)
|
||||
{
|
||||
|
|
@ -149,34 +79,37 @@ nm_supplicant_manager_get_iface (NMSupplicantManager * self,
|
|||
}
|
||||
|
||||
void
|
||||
nm_supplicant_manager_release_iface (NMSupplicantManager *self,
|
||||
nm_supplicant_manager_iface_release (NMSupplicantManager *self,
|
||||
NMSupplicantInterface *iface)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv;
|
||||
const char *ifname;
|
||||
const char *ifname, *op;
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
ifname = nm_supplicant_interface_get_ifname (iface);
|
||||
g_assert (ifname);
|
||||
g_hash_table_remove (priv->ifaces, ifname);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_supplicant_manager_state_to_string (guint32 state)
|
||||
gboolean
|
||||
nm_supplicant_manager_running (NMSupplicantManager *self)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_SUPPLICANT_MANAGER_STATE_DOWN:
|
||||
return "down";
|
||||
case NM_SUPPLICANT_MANAGER_STATE_IDLE:
|
||||
return "idle";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "unknown";
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
|
||||
|
||||
return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->running;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -186,34 +119,23 @@ name_owner_changed (NMDBusManager *dbus_mgr,
|
|||
const char *new_owner,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSupplicantManager * self = (NMSupplicantManager *) user_data;
|
||||
NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
gboolean old_owner_good = (old_owner && strlen (old_owner));
|
||||
gboolean new_owner_good = (new_owner && strlen (new_owner));
|
||||
|
||||
/* Can't handle the signal if its not from the supplicant service */
|
||||
/* We only care about the supplicant here */
|
||||
if (strcmp (WPAS_DBUS_SERVICE, name) != 0)
|
||||
return;
|
||||
|
||||
if (!old_owner_good && new_owner_good) {
|
||||
gboolean running;
|
||||
|
||||
running = startup (self);
|
||||
|
||||
if (running && priv->poke_id) {
|
||||
g_source_remove (priv->poke_id);
|
||||
priv->poke_id = 0;
|
||||
}
|
||||
nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant started");
|
||||
priv->running = TRUE;
|
||||
g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_RUNNING);
|
||||
} else if (old_owner_good && !new_owner_good) {
|
||||
set_state (self, NM_SUPPLICANT_MANAGER_STATE_DOWN);
|
||||
|
||||
if (priv->poke_id)
|
||||
g_source_remove (priv->poke_id);
|
||||
|
||||
/* Poke the supplicant so that it gets activated by dbus system bus
|
||||
* activation.
|
||||
*/
|
||||
priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self);
|
||||
nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant stopped");
|
||||
priv->running = FALSE;
|
||||
g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_RUNNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,24 +159,40 @@ static void
|
|||
nm_supplicant_manager_init (NMSupplicantManager * self)
|
||||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
|
||||
gboolean running;
|
||||
DBusGConnection *bus;
|
||||
|
||||
priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
priv->poke_id = 0;
|
||||
priv->name_owner_id = g_signal_connect (priv->dbus_mgr,
|
||||
"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);
|
||||
}
|
||||
|
||||
running = startup (self);
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
g_signal_connect (priv->dbus_mgr,
|
||||
"name-owner-changed",
|
||||
G_CALLBACK (name_owner_changed),
|
||||
self);
|
||||
|
||||
if (!running) {
|
||||
/* Try to activate the supplicant */
|
||||
priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self);
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id) {
|
||||
case PROP_RUNNING:
|
||||
g_value_set_boolean (value, NM_SUPPLICANT_MANAGER_GET_PRIVATE (object)->running);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -263,22 +201,22 @@ dispose (GObject *object)
|
|||
{
|
||||
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
if (priv->disposed) {
|
||||
G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
|
||||
return;
|
||||
}
|
||||
if (priv->disposed)
|
||||
goto out;
|
||||
priv->disposed = TRUE;
|
||||
|
||||
if (priv->poke_id) {
|
||||
g_source_remove (priv->poke_id);
|
||||
priv->poke_id = 0;
|
||||
}
|
||||
|
||||
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));
|
||||
priv->dbus_mgr = NULL;
|
||||
}
|
||||
|
||||
g_hash_table_destroy (priv->ifaces);
|
||||
|
||||
if (priv->proxy)
|
||||
g_object_unref (priv->proxy);
|
||||
|
||||
out:
|
||||
/* Chain up to the parent class */
|
||||
G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
@ -286,19 +224,19 @@ dispose (GObject *object)
|
|||
static void
|
||||
nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
|
||||
{
|
||||
GObjectClass * object_class = G_OBJECT_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
|
||||
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->dispose = dispose;
|
||||
|
||||
/* Signals */
|
||||
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);
|
||||
g_object_class_install_property (object_class, PROP_RUNNING,
|
||||
g_param_spec_boolean (NM_SUPPLICANT_MANAGER_RUNNING,
|
||||
"Running",
|
||||
"Running",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,23 +33,6 @@
|
|||
|
||||
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))
|
||||
|
|
@ -57,6 +40,8 @@ enum {
|
|||
#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_RUNNING "running"
|
||||
|
||||
struct _NMSupplicantManager
|
||||
{
|
||||
GObject parent;
|
||||
|
|
@ -65,24 +50,19 @@ 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);
|
||||
|
||||
const char *nm_supplicant_manager_state_to_string (guint32 state);
|
||||
gboolean nm_supplicant_manager_running (NMSupplicantManager *mgr);
|
||||
|
||||
#endif /* NM_SUPPLICANT_MANAGER_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue