2008-07-11 Dan Williams <dcbw@redhat.com>

Modify the NMDevice::state-changed signal to include the previous state
	and reason. Enables the applet to provide more information why device
	activation failed.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3819 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2008-07-11 10:28:53 +00:00
committed by Tambet Ingo
parent 9228a199fd
commit 95bb76aa7f
20 changed files with 675 additions and 304 deletions

View File

@@ -1,3 +1,9 @@
2008-07-11 Dan Williams <dcbw@redhat.com>
Modify the NMDevice::state-changed signal to include the previous state
and reason. Enables the applet to provide more information why device
activation failed.
2008-07-09 Dan Williams <dcbw@redhat.com> 2008-07-09 Dan Williams <dcbw@redhat.com>
* callouts/Makefile.am * callouts/Makefile.am

View File

@@ -212,6 +212,108 @@ typedef enum
} NMDeviceState; } NMDeviceState;
/*
* Device state change reason codes
*/
typedef enum {
/* No reason given */
NM_DEVICE_STATE_REASON_NONE = 0,
/* Unknown error */
NM_DEVICE_STATE_REASON_UNKNOWN,
/* Device is now managed */
NM_DEVICE_STATE_REASON_NOW_MANAGED,
/* Device is now managed unmanaged */
NM_DEVICE_STATE_REASON_NOW_UNMANAGED,
/* The device could not be readied for configuration */
NM_DEVICE_STATE_REASON_CONFIG_FAILED,
/* IP configuration could not be reserved (no available address, timeout, etc) */
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE,
/* The IP config is no longer valid */
NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED,
/* Secrets were required, but not provided */
NM_DEVICE_STATE_REASON_NO_SECRETS,
/* 802.1x supplicant disconnected */
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT,
/* 802.1x supplicant configuration failed */
NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED,
/* 802.1x supplicant failed */
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED,
/* 802.1x supplicant took too long to authenticate */
NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT,
/* PPP service failed to start */
NM_DEVICE_STATE_REASON_PPP_START_FAILED,
/* PPP service disconnected */
NM_DEVICE_STATE_REASON_PPP_DISCONNECT,
/* PPP failed */
NM_DEVICE_STATE_REASON_PPP_FAILED,
/* DHCP client failed to start */
NM_DEVICE_STATE_REASON_DHCP_START_FAILED,
/* DHCP client error */
NM_DEVICE_STATE_REASON_DHCP_ERROR,
/* DHCP client failed */
NM_DEVICE_STATE_REASON_DHCP_FAILED,
/* Shared connection service failed to start */
NM_DEVICE_STATE_REASON_SHARED_START_FAILED,
/* AutoIP service failed to start */
NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED,
/* AutoIP service error */
NM_DEVICE_STATE_REASON_AUTOIP_ERROR,
/* AutoIP service failed */
NM_DEVICE_STATE_REASON_AUTOIP_FAILED,
/* The line is busy */
NM_DEVICE_STATE_REASON_MODEM_BUSY,
/* No dial tone */
NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE,
/* No carrier could be established */
NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER,
/* The dialing request timed out */
NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT,
/* The dialing attempt failed */
NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED,
/* Modem initialization failed */
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED,
/* Failed to select the specified APN */
NM_DEVICE_STATE_REASON_GSM_APN_FAILED,
/* Failed to register with the requested network */
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED,
/* PIN check failed */
NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED,
/* Unused */
NM_DEVICE_STATE_REASON_LAST = 0xFFFF
} NMDeviceStateReason;
typedef enum { typedef enum {
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0, NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0,
@@ -222,6 +324,5 @@ typedef enum {
NM_ACTIVE_CONNECTION_STATE_ACTIVATED NM_ACTIVE_CONNECTION_STATE_ACTIVATED
} NMActiveConnectionState; } NMActiveConnectionState;
#endif /* NETWORK_MANAGER_H */ #endif /* NETWORK_MANAGER_H */

View File

@@ -52,11 +52,21 @@
<signal name="StateChanged"> <signal name="StateChanged">
<arg name="state" type="u" tp:type="NM_DEVICE_STATE"> <arg name="new-state" type="u" tp:type="NM_DEVICE_STATE">
<tp:docstring> <tp:docstring>
The new state of the device. The new state of the device.
</tp:docstring> </tp:docstring>
</arg> </arg>
<arg name="old-state" type="u" tp:type="NM_DEVICE_STATE">
<tp:docstring>
The previous state of the device.
</tp:docstring>
</arg>
<arg name="reason" type="u" tp:type="NM_DEVICE_STATE_REASON">
<tp:docstring>
A reason for the state transition.
</tp:docstring>
</arg>
</signal> </signal>
<tp:enum name="NM_DEVICE_STATE" type="u"> <tp:enum name="NM_DEVICE_STATE" type="u">

View File

@@ -9,6 +9,7 @@
#include "nm-device-private.h" #include "nm-device-private.h"
#include "nm-object-private.h" #include "nm-object-private.h"
#include "nm-object-cache.h" #include "nm-object-cache.h"
#include "nm-marshal.h"
#include "nm-device-bindings.h" #include "nm-device-bindings.h"
@@ -47,6 +48,14 @@ enum {
LAST_PROP LAST_PROP
}; };
enum {
STATE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static void static void
nm_device_init (NMDevice *device) nm_device_init (NMDevice *device)
@@ -108,7 +117,6 @@ register_for_property_changed (NMDevice *device)
{ NM_DEVICE_CAPABILITIES, nm_object_demarshal_generic, &priv->capabilities }, { NM_DEVICE_CAPABILITIES, nm_object_demarshal_generic, &priv->capabilities },
{ NM_DEVICE_MANAGED, nm_object_demarshal_generic, &priv->managed }, { NM_DEVICE_MANAGED, nm_object_demarshal_generic, &priv->managed },
{ NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
{ NM_DEVICE_STATE, nm_object_demarshal_generic, &priv->state },
{ NULL }, { NULL },
}; };
@@ -117,6 +125,23 @@ register_for_property_changed (NMDevice *device)
property_changed_info); property_changed_info);
} }
static void
device_state_changed (DBusGProxy *proxy,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->state != new_state) {
priv->state = new_state;
g_signal_emit (self, signals[STATE_CHANGED], 0, new_state, old_state, reason);
nm_object_queue_notify (NM_OBJECT (self), "state");
}
}
static GObject* static GObject*
constructor (GType type, constructor (GType type,
guint n_construct_params, guint n_construct_params,
@@ -140,6 +165,21 @@ constructor (GType type,
register_for_property_changed (NM_DEVICE (object)); register_for_property_changed (NM_DEVICE (object));
dbus_g_object_register_marshaller (nm_marshal_VOID__UINT_UINT_UINT,
G_TYPE_NONE,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->proxy,
"StateChanged",
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "StateChanged",
G_CALLBACK (device_state_changed),
NM_DEVICE (object),
NULL);
return G_OBJECT (object); return G_OBJECT (object);
} }
@@ -303,6 +343,17 @@ nm_device_class_init (NMDeviceClass *device_class)
"Product string", "Product string",
NULL, NULL,
G_PARAM_READABLE)); G_PARAM_READABLE));
/* signals */
signals[STATE_CHANGED] =
g_signal_new ("state-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMDeviceClass, state_changed),
NULL, NULL,
nm_marshal_VOID__UINT_UINT_UINT,
G_TYPE_NONE, 3,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
} }
GObject * GObject *

View File

@@ -34,6 +34,12 @@ typedef struct {
typedef struct { typedef struct {
NMObjectClass parent; NMObjectClass parent;
/* Signals */
void (*state_changed) (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason);
} NMDeviceClass; } NMDeviceClass;
GType nm_device_get_type (void); GType nm_device_get_type (void);

View File

@@ -7,6 +7,7 @@ VOID:OBJECT,POINTER,UINT
VOID:POINTER VOID:POINTER
VOID:STRING,STRING,STRING VOID:STRING,STRING,STRING
VOID:UINT,UINT VOID:UINT,UINT
VOID:UINT,UINT,UINT
VOID:STRING,STRING VOID:STRING,STRING
VOID:STRING,UCHAR VOID:STRING,UCHAR
VOID:STRING,OBJECT VOID:STRING,OBJECT

View File

@@ -515,12 +515,16 @@ active_connection_default_changed (NMActRequest *req,
} }
static void static void
device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMPolicy *policy = (NMPolicy *) user_data; NMPolicy *policy = (NMPolicy *) user_data;
NMConnection *connection = get_device_connection (device); NMConnection *connection = get_device_connection (device);
switch (state) { switch (new_state) {
case NM_DEVICE_STATE_FAILED: case NM_DEVICE_STATE_FAILED:
/* Mark the connection invalid so it doesn't get automatically chosen */ /* Mark the connection invalid so it doesn't get automatically chosen */
if (connection) { if (connection) {

View File

@@ -78,8 +78,46 @@ enum {
LAST_PROP LAST_PROP
}; };
static void device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data);
static void
device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{
NMActRequest *self = NM_ACT_REQUEST (user_data);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
NMActiveConnectionState new_ac_state;
gboolean new_default = FALSE;
/* Set NMActiveConnection state based on the device's state */
switch (new_state) {
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
break;
case NM_DEVICE_STATE_ACTIVATED:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
new_default = priv->is_default;
break;
default:
new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
break;
}
if (new_ac_state != priv->state) {
priv->state = new_ac_state;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
}
if (new_default != priv->is_default) {
priv->is_default = new_default;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
}
}
NMActRequest * NMActRequest *
nm_act_request_new (NMConnection *connection, nm_act_request_new (NMConnection *connection,
@@ -303,42 +341,6 @@ nm_act_request_class_init (NMActRequestClass *req_class)
nm_active_connection_install_type_info (object_class); nm_active_connection_install_type_info (object_class);
} }
static void
device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
{
NMActRequest *self = NM_ACT_REQUEST (user_data);
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
NMActiveConnectionState new_state;
gboolean new_default = FALSE;
/* Set NMActiveConnection state based on the device's state */
switch (state) {
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
new_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
break;
case NM_DEVICE_STATE_ACTIVATED:
new_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
new_default = priv->is_default;
break;
default:
new_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
break;
}
if (new_state != priv->state) {
priv->state = new_state;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
}
if (new_default != priv->is_default) {
priv->is_default = new_default;
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
}
}
typedef struct GetSecretsInfo { typedef struct GetSecretsInfo {
NMActRequest *req; NMActRequest *req;
char *setting_name; char *setting_name;

View File

@@ -81,6 +81,7 @@ dial_done (NMSerialDevice *device,
int reply_index, int reply_index,
gpointer user_data) gpointer user_data)
{ {
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
gboolean success = FALSE; gboolean success = FALSE;
switch (reply_index) { switch (reply_index) {
@@ -90,15 +91,19 @@ dial_done (NMSerialDevice *device,
break; break;
case 1: case 1:
nm_info ("Busy"); nm_info ("Busy");
reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
break; break;
case 2: case 2:
nm_warning ("No dial tone"); nm_warning ("No dial tone");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
break; break;
case 3: case 3:
nm_warning ("No carrier"); nm_warning ("No carrier");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
break; break;
case -1: case -1:
nm_warning ("Dialing timed out"); nm_warning ("Dialing timed out");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
break; break;
default: default:
nm_warning ("Dialing failed"); nm_warning ("Dialing failed");
@@ -108,7 +113,7 @@ dial_done (NMSerialDevice *device,
if (success) if (success)
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device)); nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
else else
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, reason);
} }
static void static void
@@ -127,7 +132,9 @@ do_dial (NMSerialDevice *device)
g_free (command); g_free (command);
if (id == 0) if (id == 0)
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_UNKNOWN);
} }
static void static void
@@ -141,11 +148,15 @@ init_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("Modem initialization timed out"); nm_warning ("Modem initialization timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
break; break;
default: default:
nm_warning ("Modem initialization failed"); nm_warning ("Modem initialization failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
return; return;
} }
} }
@@ -160,11 +171,11 @@ init_modem (NMSerialDevice *device, gpointer user_data)
id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL); id = nm_serial_device_wait_for_reply (device, 10, responses, responses, init_done, NULL);
if (id == 0) if (id == 0)
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
} }
static NMActStageReturn static NMActStageReturn
real_act_stage1_prepare (NMDevice *device) real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{ {
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
NMSettingSerial *setting; NMSettingSerial *setting;
@@ -172,10 +183,14 @@ real_act_stage1_prepare (NMDevice *device)
setting = NM_SETTING_SERIAL (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_SERIAL)); setting = NM_SETTING_SERIAL (cdma_device_get_setting (NM_CDMA_DEVICE (device), NM_TYPE_SETTING_SERIAL));
if (!nm_serial_device_open (serial_device, setting)) if (!nm_serial_device_open (serial_device, setting)) {
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
}
id = nm_serial_device_flash (serial_device, 100, init_modem, NULL); id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
if (!id)
*reason = NM_DEVICE_STATE_REASON_UNKNOWN;
return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -352,12 +367,18 @@ nm_cdma_device_init (NMCdmaDevice *self)
static gboolean static gboolean
unavailable_to_disconnected (gpointer user_data) unavailable_to_disconnected (gpointer user_data)
{ {
nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (user_data),
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
return FALSE; return FALSE;
} }
static void static void
device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDeviceInterface *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMCdmaDevice *self = NM_CDMA_DEVICE (user_data); NMCdmaDevice *self = NM_CDMA_DEVICE (user_data);
NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (self); NMCdmaDevicePrivate *priv = NM_CDMA_DEVICE_GET_PRIVATE (self);
@@ -372,11 +393,11 @@ device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer u
* DISCONNECTED because the device is ready to use. Otherwise the carrier-on * DISCONNECTED because the device is ready to use. Otherwise the carrier-on
* handler will handle the transition to DISCONNECTED when the carrier is detected. * handler will handle the transition to DISCONNECTED when the carrier is detected.
*/ */
if (state == NM_DEVICE_STATE_UNAVAILABLE) if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self);
/* Make sure we don't leave the serial device open */ /* Make sure we don't leave the serial device open */
switch (state) { switch (new_state) {
case NM_DEVICE_STATE_NEED_AUTH: case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_UNAVAILABLE:

View File

@@ -176,10 +176,10 @@ set_carrier (NMDeviceEthernet *self, const gboolean carrier)
nm_info ("(%s): carrier now %s (device state %d)", nm_device_get_iface (NM_DEVICE (self)), carrier ? "ON" : "OFF", state); nm_info ("(%s): carrier now %s (device state %d)", nm_device_get_iface (NM_DEVICE (self)), carrier ? "ON" : "OFF", state);
if (state == NM_DEVICE_STATE_UNAVAILABLE) { if (state == NM_DEVICE_STATE_UNAVAILABLE) {
if (carrier) if (carrier)
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
} else if (state >= NM_DEVICE_STATE_DISCONNECTED) { } else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
if (!carrier) if (!carrier)
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NONE);
} }
} }
@@ -224,12 +224,16 @@ nm_device_ethernet_carrier_off (NMNetlinkMonitor *monitor,
static gboolean static gboolean
unavailable_to_disconnected (gpointer user_data) unavailable_to_disconnected (gpointer user_data)
{ {
nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
return FALSE; return FALSE;
} }
static void static void
device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDeviceInterface *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -244,7 +248,7 @@ device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer u
* DISCONNECTED because the device is ready to use. Otherwise the carrier-on * DISCONNECTED because the device is ready to use. Otherwise the carrier-on
* handler will handle the transition to DISCONNECTED when the carrier is detected. * handler will handle the transition to DISCONNECTED when the carrier is detected.
*/ */
if ((state == NM_DEVICE_STATE_UNAVAILABLE) && priv->carrier) { if ((new_state == NM_DEVICE_STATE_UNAVAILABLE) && priv->carrier) {
priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self);
return; return;
} }
@@ -714,7 +718,8 @@ link_timeout_cb (gpointer user_data)
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
return FALSE; return FALSE;
} }
@@ -731,11 +736,11 @@ link_timeout_cb (gpointer user_data)
if (!setting_name) if (!setting_name)
goto time_out; goto time_out;
nm_info ("Activation (%s/wired): disconnected during association," nm_info ("Activation (%s/wired): disconnected during authentication,"
" asking for new key.", nm_device_get_iface (dev)); " asking for new key.", nm_device_get_iface (dev));
supplicant_interface_clean (self); supplicant_interface_clean (self);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_request_connection_secrets (req, setting_name, TRUE, nm_act_request_request_connection_secrets (req, setting_name, TRUE,
SECRETS_CALLER_ETHERNET, NULL, NULL); SECRETS_CALLER_ETHERNET, NULL, NULL);
@@ -743,7 +748,7 @@ link_timeout_cb (gpointer user_data)
time_out: time_out:
nm_info ("%s: link timed out.", nm_device_get_iface (dev)); nm_info ("%s: link timed out.", nm_device_get_iface (dev));
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
return FALSE; return FALSE;
} }
@@ -779,15 +784,16 @@ static gboolean
supplicant_mgr_state_cb_handler (gpointer user_data) supplicant_mgr_state_cb_handler (gpointer user_data)
{ {
struct state_cb_data *info = (struct state_cb_data *) user_data; struct state_cb_data *info = (struct state_cb_data *) user_data;
NMDevice *device = NM_DEVICE (info->self);
/* If the supplicant went away, release the supplicant interface */ /* If the supplicant went away, release the supplicant interface */
if (info->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) { if (info->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
NMDevice *dev = NM_DEVICE (info->self);
supplicant_interface_clean (info->self); supplicant_interface_clean (info->self);
if (nm_device_is_activating (dev)) if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
}
} }
g_slice_free (struct state_cb_data, info); g_slice_free (struct state_cb_data, info);
@@ -816,7 +822,7 @@ build_supplicant_config (NMDeviceEthernet *self)
{ {
DBusGProxy *proxy; DBusGProxy *proxy;
const char *con_path; const char *con_path;
NMSupplicantConfig *config; NMSupplicantConfig *config = NULL;
NMSetting8021x *security; NMSetting8021x *security;
NMConnection *connection; NMConnection *connection;
@@ -829,31 +835,30 @@ build_supplicant_config (NMDeviceEthernet *self)
return NULL; return NULL;
security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
if (nm_supplicant_config_add_setting_8021x (config, security, con_path, TRUE)) if (!nm_supplicant_config_add_setting_8021x (config, security, con_path, TRUE)) {
return config; nm_warning ("Couldn't add 802.1X security setting to supplicant config.");
g_object_unref (config);
config = NULL;
}
nm_warning ("Couldn't add 802.1X security setting to supplicant config."); return config;
g_object_unref (config);
return NULL;
} }
static gboolean static gboolean
supplicant_iface_state_cb_handler (gpointer user_data) supplicant_iface_state_cb_handler (gpointer user_data)
{ {
struct state_cb_data *info = (struct state_cb_data *) user_data; struct state_cb_data *info = (struct state_cb_data *) user_data;
NMDevice *dev = NM_DEVICE (info->self); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
NMDevice *device = NM_DEVICE (info->self);
if (info->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) { if (info->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
NMSupplicantConfig *config; NMSupplicantConfig *config;
const char *iface; const char *iface;
gboolean success = FALSE; gboolean success = FALSE;
iface = nm_device_get_iface (NM_DEVICE (info->self)); iface = nm_device_get_iface (device);
config = build_supplicant_config (info->self); config = build_supplicant_config (info->self);
if (config) { if (config) {
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
success = nm_supplicant_interface_set_config (priv->supplicant.iface, config); success = nm_supplicant_interface_set_config (priv->supplicant.iface, config);
g_object_unref (config); g_object_unref (config);
@@ -864,14 +869,14 @@ supplicant_iface_state_cb_handler (gpointer user_data)
nm_warning ("Activation (%s/wired): couldn't build security configuration.", iface); nm_warning ("Activation (%s/wired): couldn't build security configuration.", iface);
if (!success) if (!success)
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
} } else if (info->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
NMDeviceState state = nm_device_get_state (device);
else if (info->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
supplicant_interface_clean (info->self); supplicant_interface_clean (info->self);
if (nm_device_is_activating (dev)) if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
} }
g_slice_free (struct state_cb_data, info); g_slice_free (struct state_cb_data, info);
@@ -951,7 +956,7 @@ supplicant_iface_connection_error_cb_handler (gpointer user_data)
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data); NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
supplicant_interface_clean (self); supplicant_interface_clean (self);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
return FALSE; return FALSE;
} }
@@ -986,7 +991,7 @@ handle_auth_or_fail (NMDeviceEthernet *self,
if (tries > 3) if (tries > 3)
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_connection_clear_secrets (connection); nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL); setting_name = nm_connection_need_secrets (connection, NULL);
@@ -1027,7 +1032,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
if (handle_auth_or_fail (self, req, TRUE) == NM_ACT_STAGE_RETURN_POSTPONE) if (handle_auth_or_fail (self, req, TRUE) == NM_ACT_STAGE_RETURN_POSTPONE)
nm_info ("Activation (%s/wired): asking for new secrets", iface); nm_info ("Activation (%s/wired): asking for new secrets", iface);
else else
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
return FALSE; return FALSE;
} }
@@ -1079,7 +1084,7 @@ supplicant_interface_init (NMDeviceEthernet *self)
} }
static NMActStageReturn static NMActStageReturn
nm_8021x_stage2_config (NMDeviceEthernet *self) nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{ {
NMConnection *connection; NMConnection *connection;
NMSetting8021x *security; NMSetting8021x *security;
@@ -1092,6 +1097,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self)
security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X)); security = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
if (!security) { if (!security) {
nm_warning ("Invalid or missing 802.1X security"); nm_warning ("Invalid or missing 802.1X security");
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return ret; return ret;
} }
@@ -1101,16 +1107,22 @@ nm_8021x_stage2_config (NMDeviceEthernet *self)
/* If we need secrets, get them */ /* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL); setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) { if (setting_name) {
NMActRequest *req = nm_device_get_act_request (NM_DEVICE (self));
nm_info ("Activation (%s/wired): connection '%s' has security, but secrets are required.", nm_info ("Activation (%s/wired): connection '%s' has security, but secrets are required.",
iface, s_connection->id); iface, s_connection->id);
ret = handle_auth_or_fail (self, nm_device_get_act_request (NM_DEVICE (self)), FALSE); ret = handle_auth_or_fail (self, req, FALSE);
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
} else { } else {
nm_info ("Activation (%s/wired): connection '%s' requires no security. No secrets needed.", nm_info ("Activation (%s/wired): connection '%s' requires no security. No secrets needed.",
iface, s_connection->id); iface, s_connection->id);
if (supplicant_interface_init (self)) if (supplicant_interface_init (self))
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
else
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
} }
return ret; return ret;
@@ -1126,19 +1138,16 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_
switch (status) { switch (status) {
case NM_PPP_STATUS_NETWORK: case NM_PPP_STATUS_NETWORK:
nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG); nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
break; break;
case NM_PPP_STATUS_DISCONNECT: case NM_PPP_STATUS_DISCONNECT:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
break; break;
case NM_PPP_STATUS_DEAD: case NM_PPP_STATUS_DEAD:
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED);
else
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED);
break; break;
case NM_PPP_STATUS_AUTHENTICATE: case NM_PPP_STATUS_AUTHENTICATE:
nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
break; break;
default: default:
break; break;
@@ -1159,12 +1168,12 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
} }
static NMActStageReturn static NMActStageReturn
pppoe_stage2_config (NMDeviceEthernet *self) pppoe_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{ {
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMActRequest *req; NMActRequest *req;
GError *err = NULL; GError *err = NULL;
NMActStageReturn ret; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
req = nm_device_get_act_request (NM_DEVICE (self)); req = nm_device_get_act_request (NM_DEVICE (self));
g_assert (req); g_assert (req);
@@ -1182,24 +1191,27 @@ pppoe_stage2_config (NMDeviceEthernet *self)
self); self);
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else { } else {
nm_warning ("%s", err->message); nm_warning ("(%s): PPPoE failed to start: %s",
nm_device_get_iface (NM_DEVICE (self)), err->message);
g_error_free (err); g_error_free (err);
g_object_unref (priv->ppp_manager); g_object_unref (priv->ppp_manager);
priv->ppp_manager = NULL; priv->ppp_manager = NULL;
ret = NM_ACT_STAGE_RETURN_FAILURE; *reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
} }
return ret; return ret;
} }
static NMActStageReturn static NMActStageReturn
real_act_stage2_config (NMDevice *device) real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{ {
NMSettingConnection *s_connection; NMSettingConnection *s_connection;
NMActStageReturn ret; NMActStageReturn ret;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
s_connection = NM_SETTING_CONNECTION (device_get_setting (device, NM_TYPE_SETTING_CONNECTION)); s_connection = NM_SETTING_CONNECTION (device_get_setting (device, NM_TYPE_SETTING_CONNECTION));
g_assert (s_connection); g_assert (s_connection);
@@ -1208,13 +1220,14 @@ real_act_stage2_config (NMDevice *device)
security = (NMSetting8021x *) device_get_setting (device, NM_TYPE_SETTING_802_1X); security = (NMSetting8021x *) device_get_setting (device, NM_TYPE_SETTING_802_1X);
if (security) if (security)
ret = nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device)); ret = nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device), reason);
else else
ret = NM_ACT_STAGE_RETURN_SUCCESS; ret = NM_ACT_STAGE_RETURN_SUCCESS;
} else if (!strcmp (s_connection->type, NM_SETTING_PPPOE_SETTING_NAME)) } else if (!strcmp (s_connection->type, NM_SETTING_PPPOE_SETTING_NAME))
ret = pppoe_stage2_config (NM_DEVICE_ETHERNET (device)); ret = pppoe_stage2_config (NM_DEVICE_ETHERNET (device), reason);
else { else {
nm_warning ("Invalid connection type '%s' for ethernet device", s_connection->type); nm_warning ("Invalid connection type '%s' for ethernet device", s_connection->type);
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE; ret = NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -1222,7 +1235,9 @@ real_act_stage2_config (NMDevice *device)
} }
static NMActStageReturn static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *device, NMIP4Config **config) real_act_stage4_get_ip4_config (NMDevice *device,
NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -1235,9 +1250,9 @@ real_act_stage4_get_ip4_config (NMDevice *device, NMIP4Config **config)
/* Regular ethernet connection. */ /* Regular ethernet connection. */
/* Chain up to parent */ /* Chain up to parent */
ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage4_get_ip4_config (device, config); ret = NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->act_stage4_get_ip4_config (device, config, reason);
if ((ret == NM_ACT_STAGE_RETURN_SUCCESS)) { if (ret == NM_ACT_STAGE_RETURN_SUCCESS) {
NMConnection *connection; NMConnection *connection;
NMSettingWired *s_wired; NMSettingWired *s_wired;

View File

@@ -1,5 +1,6 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#include "nm-marshal.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-device-interface.h" #include "nm-device-interface.h"
#include "nm-ip4-config.h" #include "nm-ip4-config.h"
@@ -125,9 +126,9 @@ nm_device_interface_init (gpointer g_iface)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMDeviceInterface, state_changed), G_STRUCT_OFFSET (NMDeviceInterface, state_changed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__UINT, nm_marshal_VOID__UINT_UINT_UINT,
G_TYPE_NONE, 1, G_TYPE_NONE, 3,
G_TYPE_UINT); G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
dbus_g_object_type_install_info (iface_type, dbus_g_object_type_install_info (iface_type,
&dbus_glib_nm_device_interface_object_info); &dbus_glib_nm_device_interface_object_info);

View File

@@ -63,7 +63,10 @@ struct _NMDeviceInterface {
void (*deactivate) (NMDeviceInterface *device); void (*deactivate) (NMDeviceInterface *device);
/* Signals */ /* Signals */
void (*state_changed) (NMDeviceInterface *device, NMDeviceState state); void (*state_changed) (NMDeviceInterface *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason);
}; };
GQuark nm_device_interface_error_quark (void); GQuark nm_device_interface_error_quark (void);

View File

@@ -30,7 +30,9 @@ void nm_device_set_device_type (NMDevice *dev, NMDeviceType type);
void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device); void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device);
void nm_device_state_changed (NMDevice *device, NMDeviceState state); void nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason);
gboolean nm_device_hw_bring_up (NMDevice *self, gboolean wait); gboolean nm_device_hw_bring_up (NMDevice *self, gboolean wait);

View File

@@ -2011,10 +2011,11 @@ link_timeout_cb (gpointer user_data)
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
ap = nm_device_wifi_get_activation_ap (self); ap = nm_device_wifi_get_activation_ap (self);
if (req == NULL || ap == NULL) { if (req == NULL || ap == NULL) {
/* shouldn't ever happen */
nm_warning ("couldn't get activation request or activation AP."); nm_warning ("couldn't get activation request or activation AP.");
if (nm_device_is_activating (dev)) { if (nm_device_is_activating (dev)) {
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NONE);
} }
return FALSE; return FALSE;
} }
@@ -2024,7 +2025,7 @@ link_timeout_cb (gpointer user_data)
* fail. * fail.
*/ */
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
return FALSE; return FALSE;
} }
@@ -2061,7 +2062,7 @@ link_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): disconnected during association," nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev)); " asking for new key.", nm_device_get_iface (dev));
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_request_connection_secrets (req, setting_name, TRUE, nm_act_request_request_connection_secrets (req, setting_name, TRUE,
SECRETS_CALLER_WIFI, NULL, NULL); SECRETS_CALLER_WIFI, NULL, NULL);
@@ -2139,7 +2140,8 @@ supplicant_iface_state_cb_handler (gpointer user_data)
} else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { } else if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
cleanup_association_attempt (self, FALSE); cleanup_association_attempt (self, FALSE);
supplicant_interface_release (self); supplicant_interface_release (self);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
} }
g_slice_free (struct state_cb_data, cb_data); g_slice_free (struct state_cb_data, cb_data);
@@ -2263,8 +2265,10 @@ supplicant_mgr_state_cb_handler (gpointer user_data)
supplicant_interface_release (self); supplicant_interface_release (self);
} }
if (nm_device_get_state (dev) > NM_DEVICE_STATE_UNAVAILABLE) if (nm_device_get_state (dev) > NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_state_changed (dev, NM_DEVICE_STATE_UNAVAILABLE); nm_device_state_changed (dev, NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
}
} else if (new_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) { } else if (new_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
dev_state = nm_device_get_state (dev); dev_state = nm_device_get_state (dev);
if ( priv->enabled if ( priv->enabled
@@ -2276,8 +2280,10 @@ supplicant_mgr_state_cb_handler (gpointer user_data)
/* if wireless is enabled and we have a supplicant interface, /* if wireless is enabled and we have a supplicant interface,
* we can transition to the DISCONNECTED state. * we can transition to the DISCONNECTED state.
*/ */
if (priv->supplicant.iface) if (priv->supplicant.iface) {
nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
}
} }
} }
@@ -2326,7 +2332,7 @@ supplicant_iface_connection_error_cb_handler (gpointer user_data)
cb_data->message); cb_data->message);
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
out: out:
g_free (cb_data->name); g_free (cb_data->name);
@@ -2401,7 +2407,7 @@ handle_auth_or_fail (NMDeviceWifi *self,
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
} }
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
nm_connection_clear_secrets (connection); nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL); setting_name = nm_connection_need_secrets (connection, NULL);
@@ -2463,7 +2469,8 @@ supplicant_connection_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): association took too long, " nm_info ("Activation (%s/wireless): association took too long, "
"failing activation.", "failing activation.",
nm_device_get_iface (dev)); nm_device_get_iface (dev));
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT);
} else { } else {
/* Authentication failed, encryption key is probably bad */ /* Authentication failed, encryption key is probably bad */
nm_info ("Activation (%s/wireless): association took too long.", nm_info ("Activation (%s/wireless): association took too long.",
@@ -2473,7 +2480,8 @@ supplicant_connection_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): asking for new secrets", nm_info ("Activation (%s/wireless): asking for new secrets",
nm_device_get_iface (dev)); nm_device_get_iface (dev));
} else { } else {
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
} }
} }
@@ -2650,11 +2658,14 @@ out:
static NMActStageReturn static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev) real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
{ {
NMDeviceWifi *self = NM_DEVICE_WIFI (dev); NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *ap = NULL; NMAccessPoint *ap = NULL;
NMActRequest *req;
NMConnection *connection;
GSList *iter;
/* If the user is trying to connect to an AP that NM doesn't yet know about /* If the user is trying to connect to an AP that NM doesn't yet know about
* (hidden network or something), create an fake AP from the security * (hidden network or something), create an fake AP from the security
@@ -2662,54 +2673,51 @@ real_act_stage1_prepare (NMDevice *dev)
* scan list, which should show up when the connection is successful. * scan list, which should show up when the connection is successful.
*/ */
ap = nm_device_wifi_get_activation_ap (self); ap = nm_device_wifi_get_activation_ap (self);
if (!ap) { if (ap)
NMActRequest *req; goto done;
NMConnection *connection;
GSList *iter;
req = nm_device_get_act_request (NM_DEVICE (self)); req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (req); connection = nm_act_request_get_connection (req);
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
/* Find a compatible AP in the scan list */ /* Find a compatible AP in the scan list */
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
NMAccessPoint *candidate = NM_AP (iter->data); NMAccessPoint *candidate = NM_AP (iter->data);
if (nm_ap_check_compatible (candidate, connection)) { if (nm_ap_check_compatible (candidate, connection)) {
ap = candidate; ap = candidate;
break; break;
}
} }
/* If no compatible AP was found, create a fake AP (network is likely
* hidden) and try to use that.
*/
if (!ap) {
ap = nm_ap_new_fake_from_connection (connection);
g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE);
switch (nm_ap_get_mode (ap)) {
case NM_802_11_MODE_ADHOC:
nm_ap_set_user_created (ap, TRUE);
break;
case NM_802_11_MODE_INFRA:
default:
nm_ap_set_broadcast (ap, FALSE);
break;
}
priv->ap_list = g_slist_append (priv->ap_list, ap);
nm_ap_export_to_dbus (ap);
g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap);
}
nm_act_request_set_specific_object (req, nm_ap_get_dbus_path (ap));
} }
set_current_ap (self, ap); /* If no compatible AP was found, create a fake AP (network is likely
* hidden) and try to use that.
*/
if (!ap) {
ap = nm_ap_new_fake_from_connection (connection);
g_return_val_if_fail (ap != NULL, NM_ACT_STAGE_RETURN_FAILURE);
switch (nm_ap_get_mode (ap)) {
case NM_802_11_MODE_ADHOC:
nm_ap_set_user_created (ap, TRUE);
break;
case NM_802_11_MODE_INFRA:
default:
nm_ap_set_broadcast (ap, FALSE);
break;
}
priv->ap_list = g_slist_append (priv->ap_list, ap);
nm_ap_export_to_dbus (ap);
g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap);
}
nm_act_request_set_specific_object (req, nm_ap_get_dbus_path (ap));
done:
set_current_ap (self, ap);
return NM_ACT_STAGE_RETURN_SUCCESS; return NM_ACT_STAGE_RETURN_SUCCESS;
} }
@@ -2749,7 +2757,7 @@ real_connection_secrets_updated (NMDevice *dev,
} }
static NMActStageReturn static NMActStageReturn
real_act_stage2_config (NMDevice *dev) real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{ {
NMDeviceWifi * self = NM_DEVICE_WIFI (dev); NMDeviceWifi * self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
@@ -2763,6 +2771,8 @@ real_act_stage2_config (NMDevice *dev)
NMSettingConnection * s_connection; NMSettingConnection * s_connection;
const char * setting_name; const char * setting_name;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
remove_supplicant_timeouts (self); remove_supplicant_timeouts (self);
req = nm_device_get_act_request (dev); req = nm_device_get_act_request (dev);
@@ -2780,11 +2790,17 @@ real_act_stage2_config (NMDevice *dev)
/* If we need secrets, get them */ /* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL); setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) { if (setting_name) {
NMActStageReturn auth_ret;
nm_info ("Activation (%s/wireless): access point '%s' has security," nm_info ("Activation (%s/wireless): access point '%s' has security,"
" but secrets are required.", " but secrets are required.",
iface, s_connection->id); iface, s_connection->id);
return handle_auth_or_fail (self, req, FALSE); auth_ret = handle_auth_or_fail (self, req, FALSE);
if (auth_ret == NM_ACT_STAGE_RETURN_FAILURE) {
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
goto out;
}
} else { } else {
NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection,
NM_TYPE_SETTING_WIRELESS); NM_TYPE_SETTING_WIRELESS);
@@ -2804,6 +2820,7 @@ real_act_stage2_config (NMDevice *dev)
if (config == NULL) { if (config == NULL) {
nm_warning ("Activation (%s/wireless): couldn't build wireless " nm_warning ("Activation (%s/wireless): couldn't build wireless "
"configuration.", iface); "configuration.", iface);
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out; goto out;
} }
@@ -2817,19 +2834,21 @@ real_act_stage2_config (NMDevice *dev)
if (!nm_supplicant_interface_set_config (priv->supplicant.iface, config)) { if (!nm_supplicant_interface_set_config (priv->supplicant.iface, config)) {
nm_warning ("Activation (%s/wireless): couldn't send wireless " nm_warning ("Activation (%s/wireless): couldn't send wireless "
"configuration to the supplicant.", iface); "configuration to the supplicant.", iface);
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out; goto out;
} }
if (!start_supplicant_connection_timeout (self)) if (!start_supplicant_connection_timeout (self)) {
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out; goto out;
}
/* We'll get stage3 started when the supplicant connects */ /* We'll get stage3 started when the supplicant connects */
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
out: out:
if (ret == NM_ACT_STAGE_RETURN_FAILURE) { if (ret == NM_ACT_STAGE_RETURN_FAILURE)
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
}
if (config) { if (config) {
/* Supplicant interface object refs the config; we no longer care about /* Supplicant interface object refs the config; we no longer care about
@@ -2842,7 +2861,8 @@ out:
static NMActStageReturn static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *dev, real_act_stage4_get_ip4_config (NMDevice *dev,
NMIP4Config **config) NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMDeviceClass *parent_class; NMDeviceClass *parent_class;
@@ -2852,7 +2872,7 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
/* Chain up to parent */ /* Chain up to parent */
parent_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class); parent_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class);
ret = parent_class->act_stage4_get_ip4_config (dev, config); ret = parent_class->act_stage4_get_ip4_config (dev, config, reason);
if ((ret == NM_ACT_STAGE_RETURN_SUCCESS) && *config) { if ((ret == NM_ACT_STAGE_RETURN_SUCCESS) && *config) {
NMConnection *connection; NMConnection *connection;
@@ -2874,7 +2894,8 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
static NMActStageReturn static NMActStageReturn
real_act_stage4_ip_config_timeout (NMDevice *dev, real_act_stage4_ip_config_timeout (NMDevice *dev,
NMIP4Config **config) NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
NMDeviceWifi * self = NM_DEVICE_WIFI (dev); NMDeviceWifi * self = NM_DEVICE_WIFI (dev);
NMAccessPoint * ap = nm_device_wifi_get_activation_ap (self); NMAccessPoint * ap = nm_device_wifi_get_activation_ap (self);
@@ -2910,6 +2931,8 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
nm_info ("Activation (%s/wireless): asking for new secrets", nm_info ("Activation (%s/wireless): asking for new secrets",
nm_device_get_iface (dev)); nm_device_get_iface (dev));
} else {
*reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
} }
} else if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) { } else if (nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) {
NMDeviceWifiClass * klass; NMDeviceWifiClass * klass;
@@ -2918,12 +2941,13 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
/* For Ad-Hoc networks, chain up to parent to get a Zeroconf IP */ /* For Ad-Hoc networks, chain up to parent to get a Zeroconf IP */
klass = NM_DEVICE_WIFI_GET_CLASS (self); klass = NM_DEVICE_WIFI_GET_CLASS (self);
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
ret = parent_class->act_stage4_ip_config_timeout (dev, &real_config); ret = parent_class->act_stage4_ip_config_timeout (dev, &real_config, reason);
} else { } else {
/* Non-encrypted network or authentication is enforced by some /* Non-encrypted network or authentication is enforced by some
* entity (AP, RADIUS server, etc), but IP configure failed. Alert * entity (AP, RADIUS server, etc), but IP configure failed. Alert
* the user. * the user.
*/ */
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
ret = NM_ACT_STAGE_RETURN_FAILURE; ret = NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -3250,12 +3274,18 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
static gboolean static gboolean
unavailable_to_disconnected (gpointer user_data) unavailable_to_disconnected (gpointer user_data)
{ {
nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (user_data),
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
return FALSE; return FALSE;
} }
static void static void
state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifi *self = NM_DEVICE_WIFI (device);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
@@ -3267,7 +3297,7 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
priv->state_to_disconnected_id = 0; priv->state_to_disconnected_id = 0;
} }
if (state <= NM_DEVICE_STATE_UNAVAILABLE) { if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) {
/* Clean up the supplicant interface because in these states the /* Clean up the supplicant interface because in these states the
* device cannot be used. * device cannot be used.
*/ */
@@ -3275,7 +3305,7 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
supplicant_interface_release (self); supplicant_interface_release (self);
} }
switch (state) { switch (new_state) {
case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNMANAGED:
clear_aps = TRUE; clear_aps = TRUE;
break; break;
@@ -3333,7 +3363,7 @@ nm_device_wifi_new (const char *udi,
return NULL; return NULL;
g_signal_connect (obj, "state-changed", g_signal_connect (obj, "state-changed",
G_CALLBACK (state_changed_cb), G_CALLBACK (device_state_changed),
NULL); NULL);
return NM_DEVICE_WIFI (obj); return NM_DEVICE_WIFI (obj);
@@ -3398,10 +3428,15 @@ nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled)
if (!priv->supplicant.iface) if (!priv->supplicant.iface)
supplicant_interface_acquire (self); supplicant_interface_acquire (self);
if (priv->supplicant.iface) if (priv->supplicant.iface) {
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
}
} else { } else {
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE); nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_NONE);
nm_device_hw_take_down (NM_DEVICE (self), TRUE); nm_device_hw_take_down (NM_DEVICE (self), TRUE);
} }
} }

View File

@@ -154,7 +154,7 @@ device_start (gpointer user_data)
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
self->priv->start_timer = 0; self->priv->start_timer = 0;
nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE); nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
return FALSE; return FALSE;
} }
@@ -381,7 +381,7 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us
switch (status) { switch (status) {
case NM_DNSMASQ_STATUS_DEAD: case NM_DNSMASQ_STATUS_DEAD:
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
break; break;
default: default:
break; break;
@@ -400,6 +400,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data)
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
const char * iface; const char * iface;
NMActStageReturn ret; NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */ /* Clear the activation source ID now that this stage has run */
if (self->priv->act_source_id > 0) if (self->priv->act_source_id > 0)
@@ -407,13 +408,13 @@ nm_device_activate_stage1_device_prepare (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); nm_info ("Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface);
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE); nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self); ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, &reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
goto out; goto out;
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@@ -449,14 +450,14 @@ nm_device_activate_schedule_stage1_device_prepare (NMDevice *self)
} }
static NMActStageReturn static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev) real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
{ {
/* Nothing to do */ /* Nothing to do */
return NM_ACT_STAGE_RETURN_SUCCESS; return NM_ACT_STAGE_RETURN_SUCCESS;
} }
static NMActStageReturn static NMActStageReturn
real_act_stage2_config (NMDevice *dev) real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{ {
/* Nothing to do */ /* Nothing to do */
return NM_ACT_STAGE_RETURN_SUCCESS; return NM_ACT_STAGE_RETURN_SUCCESS;
@@ -475,6 +476,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
const char * iface; const char * iface;
NMActStageReturn ret; NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */ /* Clear the activation source ID now that this stage has run */
if (self->priv->act_source_id > 0) if (self->priv->act_source_id > 0)
@@ -482,19 +484,19 @@ nm_device_activate_stage2_device_config (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface);
nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG); nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
if (!nm_device_bring_up (self, FALSE)) { if (!nm_device_bring_up (self, FALSE)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
goto out; goto out;
} }
ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self); ret = NM_DEVICE_GET_CLASS (self)->act_stage2_config (self, &reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
goto out; goto out;
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
{ {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@@ -563,7 +565,7 @@ aipd_cleanup (NMDevice *self)
} }
static NMIP4Config * static NMIP4Config *
aipd_get_ip4_config (NMDevice *self) aipd_get_ip4_config (NMDevice *self, NMDeviceStateReason *reason)
{ {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMIP4Config *config = NULL; NMIP4Config *config = NULL;
@@ -572,6 +574,11 @@ aipd_get_ip4_config (NMDevice *self)
g_return_val_if_fail (priv->aipd_addr > 0, NULL); g_return_val_if_fail (priv->aipd_addr > 0, NULL);
config = nm_ip4_config_new (); config = nm_ip4_config_new ();
if (!config) {
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NULL;
}
addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr = g_malloc0 (sizeof (NMSettingIP4Address));
addr->address = (guint32) priv->aipd_addr; addr->address = (guint32) priv->aipd_addr;
addr->prefix = 16; addr->prefix = 16;
@@ -581,13 +588,15 @@ aipd_get_ip4_config (NMDevice *self)
} }
static gboolean static gboolean
handle_autoip_change (NMDevice *self) handle_autoip_change (NMDevice *self, NMDeviceStateReason *reason)
{ {
NMActRequest *req; NMActRequest *req;
NMConnection *connection; NMConnection *connection;
NMIP4Config *config; NMIP4Config *config;
config = aipd_get_ip4_config (self); g_return_val_if_fail (reason != NULL, FALSE);
config = aipd_get_ip4_config (self, reason);
if (!config) { if (!config) {
nm_warning ("failed to get autoip config for rebind"); nm_warning ("failed to get autoip config for rebind");
return FALSE; return FALSE;
@@ -600,7 +609,7 @@ handle_autoip_change (NMDevice *self)
g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config); g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config);
if (!nm_device_set_ip4_config (self, config)) { if (!nm_device_set_ip4_config (self, config, reason)) {
nm_warning ("(%s): failed to update IP4 config in response to autoip event.", nm_warning ("(%s): failed to update IP4 config in response to autoip event.",
nm_device_get_iface (self)); nm_device_get_iface (self));
return FALSE; return FALSE;
@@ -644,18 +653,19 @@ nm_device_handle_autoip4_event (NMDevice *self,
if (strcmp (event, "BIND") == 0) { if (strcmp (event, "BIND") == 0) {
struct in_addr ip; struct in_addr ip;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
if (inet_pton (AF_INET, address, &ip) <= 0) { if (inet_pton (AF_INET, address, &ip) <= 0) {
nm_warning ("(%s): invalid address %s received from avahi-autoipd.", nm_warning ("(%s): invalid address %s received from avahi-autoipd.",
iface, address); iface, address);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
return; return;
} }
if ((ip.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) { if ((ip.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
nm_warning ("(%s): invalid address %s received from avahi-autoipd.", nm_warning ("(%s): invalid address %s received from avahi-autoipd.",
iface, address); iface, address);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_ERROR);
return; return;
} }
@@ -672,8 +682,8 @@ nm_device_handle_autoip4_event (NMDevice *self,
break; break;
case NM_DEVICE_STATE_ACTIVATED: case NM_DEVICE_STATE_ACTIVATED:
priv->aipd_addr = ip.s_addr; priv->aipd_addr = ip.s_addr;
if (!handle_autoip_change (self)) if (!handle_autoip_change (self, &reason))
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
break; break;
default: default:
nm_warning ("(%s): unexpected avahi-autoip event %s for %s.", nm_warning ("(%s): unexpected avahi-autoip event %s for %s.",
@@ -685,7 +695,7 @@ nm_device_handle_autoip4_event (NMDevice *self,
iface, address, event); iface, address, event);
/* The address is gone; terminate the connection or fail activation */ /* The address is gone; terminate the connection or fail activation */
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
} }
} }
@@ -716,7 +726,7 @@ aipd_watch_cb (GPid pid, gint status, gpointer user_data)
state = nm_device_get_state (self); state = nm_device_get_state (self);
if (nm_device_is_activating (self) || (state == NM_DEVICE_STATE_ACTIVATED)) if (nm_device_is_activating (self) || (state == NM_DEVICE_STATE_ACTIVATED))
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_AUTOIP_FAILED);
} }
static gboolean static gboolean
@@ -798,13 +808,15 @@ aipd_exec (NMDevice *self, GError **error)
} }
static NMActStageReturn static NMActStageReturn
real_act_stage3_ip_config_start (NMDevice *self) real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason)
{ {
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMActRequest *req; NMActRequest *req;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
const char *iface; const char *iface;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
req = nm_device_get_act_request (self); req = nm_device_get_act_request (self);
@@ -830,8 +842,10 @@ real_act_stage3_ip_config_start (NMDevice *self)
* stuff happens. * stuff happens.
*/ */
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else } else {
*reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE; ret = NM_ACT_STAGE_RETURN_FAILURE;
}
} else if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) { } else if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) {
GError *error = NULL; GError *error = NULL;
@@ -845,6 +859,7 @@ real_act_stage3_ip_config_start (NMDevice *self)
" to start avahi-autoipd: %s", iface, error->message); " to start avahi-autoipd: %s", iface, error->message);
g_error_free (error); g_error_free (error);
aipd_cleanup (self); aipd_cleanup (self);
*reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE; ret = NM_ACT_STAGE_RETURN_FAILURE;
} }
} }
@@ -863,8 +878,9 @@ static gboolean
nm_device_activate_stage3_ip_config_start (gpointer user_data) nm_device_activate_stage3_ip_config_start (gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
const char * iface; const char *iface;
NMActStageReturn ret; NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */ /* Clear the activation source ID now that this stage has run */
if (self->priv->act_source_id > 0) if (self->priv->act_source_id > 0)
@@ -872,14 +888,14 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); nm_info ("Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface);
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG); nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self); ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, &reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
goto out; goto out;
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
{ {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@@ -940,7 +956,7 @@ reserve_shared_ip (void)
} }
static NMIP4Config * static NMIP4Config *
nm_device_new_ip4_shared_config (NMDevice *self) nm_device_new_ip4_shared_config (NMDevice *self, NMDeviceStateReason *reason)
{ {
NMIP4Config *config = NULL; NMIP4Config *config = NULL;
NMSettingIP4Address *addr; NMSettingIP4Address *addr;
@@ -952,8 +968,10 @@ nm_device_new_ip4_shared_config (NMDevice *self)
shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal); shared_ips = g_hash_table_new (g_direct_hash, g_direct_equal);
tmp_addr = reserve_shared_ip (); tmp_addr = reserve_shared_ip ();
if (!tmp_addr) if (!tmp_addr) {
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NULL; return NULL;
}
config = nm_ip4_config_new (); config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address)); addr = g_malloc0 (sizeof (NMSettingIP4Address));
@@ -970,7 +988,8 @@ nm_device_new_ip4_shared_config (NMDevice *self)
static NMActStageReturn static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *self, real_act_stage4_get_ip4_config (NMDevice *self,
NMIP4Config **config) NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
@@ -979,6 +998,7 @@ real_act_stage4_get_ip4_config (NMDevice *self,
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (nm_device_get_act_request (self)); connection = nm_act_request_get_connection (nm_device_get_act_request (self));
g_assert (connection); g_assert (connection);
@@ -990,17 +1010,22 @@ real_act_stage4_get_ip4_config (NMDevice *self,
nm_device_get_iface (self)); nm_device_get_iface (self));
if (*config) if (*config)
nm_utils_merge_ip4_config (*config, s_ip4); nm_utils_merge_ip4_config (*config, s_ip4);
else
*reason = NM_DEVICE_STATE_REASON_DHCP_ERROR;
} else { } else {
g_assert (s_ip4); g_assert (s_ip4);
g_assert (s_ip4->method);
if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) { if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) {
*config = aipd_get_ip4_config (self); *config = aipd_get_ip4_config (self, reason);
} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { } else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
*config = nm_ip4_config_new (); *config = nm_ip4_config_new ();
if (*config) if (*config)
nm_utils_merge_ip4_config (*config, s_ip4); nm_utils_merge_ip4_config (*config, s_ip4);
else
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
} else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { } else if (!strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
*config = nm_device_new_ip4_shared_config (self); *config = nm_device_new_ip4_shared_config (self, reason);
if (*config) if (*config)
priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self)); priv->dnsmasq_manager = nm_dnsmasq_manager_new (nm_device_get_ip_iface (self));
} }
@@ -1026,9 +1051,10 @@ static gboolean
nm_device_activate_stage4_ip_config_get (gpointer user_data) nm_device_activate_stage4_ip_config_get (gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
NMIP4Config * ip4_config = NULL; NMIP4Config *ip4_config = NULL;
NMActStageReturn ret; NMActStageReturn ret;
const char * iface = NULL; const char *iface = NULL;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */ /* Clear the activation source ID now that this stage has run */
if (self->priv->act_source_id > 0) if (self->priv->act_source_id > 0)
@@ -1037,12 +1063,12 @@ nm_device_activate_stage4_ip_config_get (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 4 of 5 (IP Configure Get) started...", iface); nm_info ("Activation (%s) Stage 4 of 5 (IP Configure Get) started...", iface);
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, &ip4_config); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_get_ip4_config (self, &ip4_config, &reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
goto out; goto out;
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE))
{ {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@@ -1083,12 +1109,14 @@ nm_device_activate_schedule_stage4_ip_config_get (NMDevice *self)
static NMActStageReturn static NMActStageReturn
real_act_stage4_ip_config_timeout (NMDevice *self, real_act_stage4_ip_config_timeout (NMDevice *self,
NMIP4Config **config) NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
/* DHCP failed; connection must fail */ /* DHCP failed; connection must fail */
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -1103,9 +1131,10 @@ static gboolean
nm_device_activate_stage4_ip_config_timeout (gpointer user_data) nm_device_activate_stage4_ip_config_timeout (gpointer user_data)
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
NMIP4Config * ip4_config = NULL; NMIP4Config *ip4_config = NULL;
const char * iface; const char *iface;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */ /* Clear the activation source ID now that this stage has run */
if (self->priv->act_source_id > 0) if (self->priv->act_source_id > 0)
@@ -1114,11 +1143,11 @@ nm_device_activate_stage4_ip_config_timeout (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 4 of 5 (IP Configure Timeout) started...", iface); nm_info ("Activation (%s) Stage 4 of 5 (IP Configure Timeout) started...", iface);
ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip_config_timeout (self, &ip4_config); ret = NM_DEVICE_GET_CLASS (self)->act_stage4_ip_config_timeout (self, &ip4_config, &reason);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
goto out; goto out;
} else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) { } else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@@ -1173,6 +1202,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
const char *iface; const char *iface;
NMConnection *connection; NMConnection *connection;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
ip4_config = g_object_get_data (G_OBJECT (nm_device_get_act_request (self)), ip4_config = g_object_get_data (G_OBJECT (nm_device_get_act_request (self)),
NM_ACT_REQUEST_IP4_CONFIG); NM_ACT_REQUEST_IP4_CONFIG);
@@ -1186,8 +1216,8 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) started...", nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) started...",
iface); iface);
if (!nm_device_set_ip4_config (self, ip4_config)) { if (!nm_device_set_ip4_config (self, ip4_config, &reason)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
goto out; goto out;
} }
@@ -1199,7 +1229,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) { if (!nm_dnsmasq_manager_start (priv->dnsmasq_manager, ip4_config, &error)) {
nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message); nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
g_error_free (error); g_error_free (error);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
goto out; goto out;
} }
@@ -1208,7 +1238,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
self); self);
} }
nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED); nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
out: out:
nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) complete.", nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) complete.",
@@ -1338,6 +1368,7 @@ static void
nm_device_deactivate (NMDeviceInterface *device) nm_device_deactivate (NMDeviceInterface *device)
{ {
NMDevice *self = NM_DEVICE (device); NMDevice *self = NM_DEVICE (device);
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
g_return_if_fail (self != NULL); g_return_if_fail (self != NULL);
@@ -1346,7 +1377,7 @@ nm_device_deactivate (NMDeviceInterface *device)
nm_device_deactivate_quickly (self); nm_device_deactivate_quickly (self);
/* Clean up nameservers and addresses */ /* Clean up nameservers and addresses */
nm_device_set_ip4_config (self, NULL); nm_device_set_ip4_config (self, NULL, &reason);
/* Take out any entries in the routing table and any IP address the device had. */ /* Take out any entries in the routing table and any IP address the device had. */
nm_system_device_flush_ip4_routes (self); nm_system_device_flush_ip4_routes (self);
@@ -1393,7 +1424,7 @@ connection_secrets_failed_cb (NMActRequest *req,
{ {
NMDevice *self = NM_DEVICE (user_data); NMDevice *self = NM_DEVICE (user_data);
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
} }
static gboolean static gboolean
@@ -1452,7 +1483,7 @@ nm_device_activate (NMDeviceInterface *device,
* that the activation request isn't deferred because the deferred bit * that the activation request isn't deferred because the deferred bit
* gets cleared a bit too early, when the connection becomes valid. * gets cleared a bit too early, when the connection becomes valid.
*/ */
nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE); nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_REASON_NONE);
nm_device_activate_schedule_stage1_device_prepare (self); nm_device_activate_schedule_stage1_device_prepare (self);
return TRUE; return TRUE;
@@ -1515,6 +1546,7 @@ handle_dhcp_lease_change (NMDevice *device)
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
NMConnection *connection; NMConnection *connection;
NMActRequest *req; NMActRequest *req;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_device_get_use_dhcp (device)) { if (!nm_device_get_use_dhcp (device)) {
nm_warning ("got DHCP rebind for device that wasn't using DHCP."); nm_warning ("got DHCP rebind for device that wasn't using DHCP.");
@@ -1525,7 +1557,7 @@ handle_dhcp_lease_change (NMDevice *device)
nm_device_get_iface (device)); nm_device_get_iface (device));
if (!config) { if (!config) {
nm_warning ("failed to get DHCP config for rebind"); nm_warning ("failed to get DHCP config for rebind");
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
return; return;
} }
@@ -1539,9 +1571,9 @@ handle_dhcp_lease_change (NMDevice *device)
g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config); g_object_set_data (G_OBJECT (req), NM_ACT_REQUEST_IP4_CONFIG, config);
if (!nm_device_set_ip4_config (device, config)) { if (!nm_device_set_ip4_config (device, config, &reason)) {
nm_warning ("Failed to update IP4 config in response to DHCP event."); nm_warning ("Failed to update IP4 config in response to DHCP event.");
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
} }
} }
@@ -1580,11 +1612,11 @@ dhcp_state_changed (NMDHCPManager *dhcp_manager,
case DHC_ABEND: /* dhclient exited abnormally */ case DHC_ABEND: /* dhclient exited abnormally */
case DHC_END: /* dhclient exited normally */ case DHC_END: /* dhclient exited normally */
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_DHCP_FAILED);
} else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { } else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
if (nm_device_get_use_dhcp (device)) { if (nm_device_get_use_dhcp (device)) {
/* dhclient quit and therefore can't renew our lease, kill the conneciton */ /* dhclient quit and therefore can't renew our lease, kill the conneciton */
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
} }
} }
break; break;
@@ -1658,13 +1690,14 @@ nm_device_get_ip4_config (NMDevice *self)
gboolean gboolean
nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config) nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReason *reason)
{ {
NMDevicePrivate *priv; NMDevicePrivate *priv;
const char *ip_iface; const char *ip_iface;
gboolean success; gboolean success;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_val_if_fail (reason != NULL, FALSE);
priv = NM_DEVICE_GET_PRIVATE (self); priv = NM_DEVICE_GET_PRIVATE (self);
@@ -1881,8 +1914,10 @@ nm_device_dispose (GObject *object)
*/ */
if (self->priv->managed) { if (self->priv->managed) {
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
nm_device_take_down (self, FALSE); nm_device_take_down (self, FALSE);
nm_device_set_ip4_config (self, NULL); nm_device_set_ip4_config (self, NULL, &reason);
} }
clear_act_request (self); clear_act_request (self);
@@ -2070,12 +2105,14 @@ failed_to_disconnected (gpointer user_data)
NMDevice *device = NM_DEVICE (user_data); NMDevice *device = NM_DEVICE (user_data);
device->priv->failed_to_disconnected_id = 0; device->priv->failed_to_disconnected_id = 0;
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_NONE);
return FALSE; return FALSE;
} }
void void
nm_device_state_changed (NMDevice *device, NMDeviceState state) nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason)
{ {
NMDevicePrivate *priv; NMDevicePrivate *priv;
NMDeviceState old_state; NMDeviceState old_state;
@@ -2121,7 +2158,7 @@ nm_info ("(%s): device state change: %d -> %d", nm_device_get_iface (device), ol
} }
g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_STATE); g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_STATE);
g_signal_emit_by_name (device, "state-changed", state); g_signal_emit_by_name (device, "state-changed", state, old_state, 0);
/* Post-process the event after internal notification */ /* Post-process the event after internal notification */
@@ -2184,6 +2221,9 @@ nm_device_set_managed (NMDevice *device, gboolean managed)
g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED); g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED);
/* If now managed, jump to unavailable */ /* If now managed, jump to unavailable */
nm_device_state_changed (device, managed ? NM_DEVICE_STATE_UNAVAILABLE : NM_DEVICE_STATE_UNMANAGED); if (managed)
nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
else
nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
} }

View File

@@ -98,13 +98,18 @@ struct _NMDeviceClass
NMConnection *connection, NMConnection *connection,
GError **error); GError **error);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self); NMActStageReturn (* act_stage1_prepare) (NMDevice *self,
NMActStageReturn (* act_stage2_config) (NMDevice *self); NMDeviceStateReason *reason);
NMActStageReturn (* act_stage3_ip_config_start) (NMDevice *self); NMActStageReturn (* act_stage2_config) (NMDevice *self,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage3_ip_config_start) (NMDevice *self,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage4_get_ip4_config) (NMDevice *self, NMActStageReturn (* act_stage4_get_ip4_config) (NMDevice *self,
NMIP4Config **config); NMIP4Config **config,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage4_ip_config_timeout) (NMDevice *self, NMActStageReturn (* act_stage4_ip_config_timeout) (NMDevice *self,
NMIP4Config **config); NMIP4Config **config,
NMDeviceStateReason *reason);
void (* deactivate) (NMDevice *self); void (* deactivate) (NMDevice *self);
void (* deactivate_quickly) (NMDevice *self); void (* deactivate_quickly) (NMDevice *self);
@@ -133,7 +138,8 @@ void nm_device_set_use_dhcp (NMDevice *dev,
NMIP4Config * nm_device_get_ip4_config (NMDevice *dev); NMIP4Config * nm_device_get_ip4_config (NMDevice *dev);
gboolean nm_device_set_ip4_config (NMDevice *dev, gboolean nm_device_set_ip4_config (NMDevice *dev,
NMIP4Config *config); NMIP4Config *config,
NMDeviceStateReason *reason);
void nm_device_take_down (NMDevice *dev, gboolean wait); void nm_device_take_down (NMDevice *dev, gboolean wait);

View File

@@ -83,7 +83,7 @@ modem_wait_for_reply (NMGsmDevice *self,
id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, NULL); id = nm_serial_device_wait_for_reply (serial, timeout, responses, terminators, callback, NULL);
if (id == 0) if (id == 0)
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
} }
static void static void
@@ -100,7 +100,7 @@ modem_get_reply (NMGsmDevice *self,
id = nm_serial_device_get_reply (serial, timeout, terminators, callback, NULL); id = nm_serial_device_get_reply (serial, timeout, terminators, callback, NULL);
if (id == 0) if (id == 0)
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_UNKNOWN);
} }
static NMSetting * static NMSetting *
@@ -127,6 +127,7 @@ dial_done (NMSerialDevice *device,
gpointer user_data) gpointer user_data)
{ {
gboolean success = FALSE; gboolean success = FALSE;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
switch (reply_index) { switch (reply_index) {
case 0: case 0:
@@ -135,25 +136,30 @@ dial_done (NMSerialDevice *device,
break; break;
case 1: case 1:
nm_info ("Busy"); nm_info ("Busy");
reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
break; break;
case 2: case 2:
nm_warning ("No dial tone"); nm_warning ("No dial tone");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
break; break;
case 3: case 3:
nm_warning ("No carrier"); nm_warning ("No carrier");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
break; break;
case -1: case -1:
nm_warning ("Dialing timed out"); nm_warning ("Dialing timed out");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
break; break;
default: default:
nm_warning ("Dialing failed"); nm_warning ("Dialing failed");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED;
break; break;
} }
if (success) if (success)
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device)); nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
else else
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED, reason);
} }
static void static void
@@ -194,7 +200,9 @@ set_apn_done (NMSerialDevice *device,
break; break;
default: default:
nm_warning ("Setting APN failed"); nm_warning ("Setting APN failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_APN_FAILED);
break; break;
} }
} }
@@ -231,11 +239,15 @@ manual_registration_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("Manual registration timed out"); nm_warning ("Manual registration timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
break; break;
default: default:
nm_warning ("Manual registration failed"); nm_warning ("Manual registration failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
break; break;
} }
} }
@@ -301,15 +313,21 @@ automatic_registration_response (NMSerialDevice *device,
break; break;
case 3: case 3:
nm_warning ("Automatic registration failed: not registered and not searching."); nm_warning ("Automatic registration failed: not registered and not searching.");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
break; break;
case -1: case -1:
nm_warning ("Automatic registration timed out"); nm_warning ("Automatic registration timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
break; break;
default: default:
nm_warning ("Automatic registration failed"); nm_warning ("Automatic registration failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED);
break; break;
} }
} }
@@ -347,11 +365,15 @@ init_full_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("Modem second stage initialization timed out"); nm_warning ("Modem second stage initialization timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
break; break;
default: default:
nm_warning ("Modem second stage initialization failed"); nm_warning ("Modem second stage initialization failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
return; return;
} }
} }
@@ -377,7 +399,9 @@ enter_pin_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("Did not receive response for secret"); nm_warning ("Did not receive response for secret");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
break; break;
default: default:
nm_warning ("Invalid secret"); nm_warning ("Invalid secret");
@@ -443,7 +467,9 @@ enter_pin (NMGsmDevice *device, gboolean retry)
g_free (command); g_free (command);
} else { } else {
nm_info ("(%s): GSM %s secret required", nm_device_get_iface (NM_DEVICE (device)), secret_name); nm_info ("(%s): GSM %s secret required", nm_device_get_iface (NM_DEVICE (device)), secret_name);
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_NEED_AUTH); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_NONE);
nm_act_request_request_connection_secrets (req, nm_act_request_request_connection_secrets (req,
NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SETTING_NAME,
retry, retry,
@@ -472,11 +498,15 @@ check_pin_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("PIN checking timed out"); nm_warning ("PIN checking timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED);
break; break;
default: default:
nm_warning ("PIN checking failed"); nm_warning ("PIN checking failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED);
return; return;
} }
} }
@@ -501,11 +531,15 @@ init_done (NMSerialDevice *device,
break; break;
case -1: case -1:
nm_warning ("Modem initialization timed out"); nm_warning ("Modem initialization timed out");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
break; break;
default: default:
nm_warning ("Modem initialization failed"); nm_warning ("Modem initialization failed");
nm_device_state_changed (NM_DEVICE (device), NM_DEVICE_STATE_FAILED); nm_device_state_changed (NM_DEVICE (device),
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
return; return;
} }
} }
@@ -519,7 +553,7 @@ init_modem (NMSerialDevice *device, gpointer user_data)
} }
static NMActStageReturn static NMActStageReturn
real_act_stage1_prepare (NMDevice *device) real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{ {
NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device); NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (device);
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device); NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
@@ -530,10 +564,14 @@ real_act_stage1_prepare (NMDevice *device)
setting = NM_SETTING_SERIAL (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_SERIAL)); setting = NM_SETTING_SERIAL (gsm_device_get_setting (NM_GSM_DEVICE (device), NM_TYPE_SETTING_SERIAL));
if (!nm_serial_device_open (serial_device, setting)) if (!nm_serial_device_open (serial_device, setting)) {
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return NM_ACT_STAGE_RETURN_FAILURE; return NM_ACT_STAGE_RETURN_FAILURE;
}
id = nm_serial_device_flash (serial_device, 100, init_modem, NULL); id = nm_serial_device_flash (serial_device, 100, init_modem, NULL);
if (!id)
*reason = NM_DEVICE_STATE_REASON_UNKNOWN;
return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE; return id ? NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -723,12 +761,18 @@ nm_gsm_device_init (NMGsmDevice *self)
static gboolean static gboolean
unavailable_to_disconnected (gpointer user_data) unavailable_to_disconnected (gpointer user_data)
{ {
nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (NM_DEVICE (user_data),
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
return FALSE; return FALSE;
} }
static void static void
device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDeviceInterface *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMGsmDevice *self = NM_GSM_DEVICE (user_data); NMGsmDevice *self = NM_GSM_DEVICE (user_data);
NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self); NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (self);
@@ -743,11 +787,11 @@ device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer u
* DISCONNECTED because the device is ready to use. Otherwise the carrier-on * DISCONNECTED because the device is ready to use. Otherwise the carrier-on
* handler will handle the transition to DISCONNECTED when the carrier is detected. * handler will handle the transition to DISCONNECTED when the carrier is detected.
*/ */
if (state == NM_DEVICE_STATE_UNAVAILABLE) if (new_state == NM_DEVICE_STATE_UNAVAILABLE)
priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self);
/* Make sure we don't leave the serial device open */ /* Make sure we don't leave the serial device open */
switch (state) { switch (new_state) {
case NM_DEVICE_STATE_NEED_AUTH: case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_UNAVAILABLE:

View File

@@ -53,10 +53,6 @@ static void connection_added_default_handler (NMManager *manager,
NMConnection *connection, NMConnection *connection,
NMConnectionScope scope); NMConnectionScope scope);
static void manager_device_state_changed (NMDevice *device,
NMDeviceState state,
gpointer user_data);
static void hal_manager_udi_added_cb (NMHalManager *hal_mgr, static void hal_manager_udi_added_cb (NMHalManager *hal_mgr,
const char *udi, const char *udi,
const char *type_name, const char *type_name,
@@ -369,6 +365,30 @@ pending_connection_info_destroy (PendingConnectionInfo *info)
g_slice_free (PendingConnectionInfo, info); g_slice_free (PendingConnectionInfo, info);
} }
static void
manager_device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
switch (new_state) {
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_DISCONNECTED:
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_FAILED:
g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
break;
default:
break;
}
nm_manager_update_state (manager);
}
static void static void
remove_one_device (NMManager *manager, NMDevice *device) remove_one_device (NMManager *manager, NMDevice *device)
{ {
@@ -1448,26 +1468,6 @@ manager_set_wireless_enabled (NMManager *manager, gboolean enabled)
} }
} }
static void
manager_device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
switch (state) {
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_DISCONNECTED:
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_FAILED:
g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
break;
default:
break;
}
nm_manager_update_state (manager);
}
static void static void
manager_hidden_ap_found (NMDeviceInterface *device, manager_hidden_ap_found (NMDeviceInterface *device,
NMAccessPoint *ap, NMAccessPoint *ap,
@@ -1696,8 +1696,12 @@ internal_activate_device (NMManager *manager,
if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error)) if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error))
return NULL; return NULL;
if (nm_device_get_act_request (device)) /* Tear down any existing connection */
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); if (nm_device_get_act_request (device)) {
nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
}
req = nm_act_request_new (connection, specific_object, user_requested, (gpointer) device); req = nm_act_request_new (connection, specific_object, user_requested, (gpointer) device);
success = nm_device_interface_activate (dev_iface, req, error); success = nm_device_interface_activate (dev_iface, req, error);
@@ -1947,7 +1951,9 @@ nm_manager_deactivate_connection (NMManager *manager,
continue; continue;
if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) { if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) {
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); nm_device_state_changed (device,
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
success = TRUE; success = TRUE;
goto done; goto done;
} }

View File

@@ -312,7 +312,8 @@ nm_serial_device_set_pending (NMSerialDevice *device,
nm_serial_device_add_timeout (device, timeout); nm_serial_device_add_timeout (device, timeout);
return priv->pending_id;} return priv->pending_id;
}
static void static void
nm_serial_device_pending_done (NMSerialDevice *self) nm_serial_device_pending_done (NMSerialDevice *self)
@@ -975,10 +976,10 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_
switch (status) { switch (status) {
case NM_PPP_STATUS_NETWORK: case NM_PPP_STATUS_NETWORK:
nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG); nm_device_state_changed (device, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
break; break;
case NM_PPP_STATUS_DISCONNECT: case NM_PPP_STATUS_DISCONNECT:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_DISCONNECT);
break; break;
default: default:
break; break;
@@ -1016,7 +1017,7 @@ ppp_stats (NMPPPManager *ppp_manager,
} }
static NMActStageReturn static NMActStageReturn
real_act_stage2_config (NMDevice *device) real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{ {
NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);
NMActRequest *req; NMActRequest *req;
@@ -1050,6 +1051,7 @@ real_act_stage2_config (NMDevice *device)
g_object_unref (priv->ppp_manager); g_object_unref (priv->ppp_manager);
priv->ppp_manager = NULL; priv->ppp_manager = NULL;
*reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE; ret = NM_ACT_STAGE_RETURN_FAILURE;
} }
@@ -1057,7 +1059,9 @@ real_act_stage2_config (NMDevice *device)
} }
static NMActStageReturn static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *device, NMIP4Config **config) real_act_stage4_get_ip4_config (NMDevice *device,
NMIP4Config **config,
NMDeviceStateReason *reason)
{ {
NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device); NMSerialDevicePrivate *priv = NM_SERIAL_DEVICE_GET_PRIVATE (device);

View File

@@ -175,15 +175,19 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
} }
static void static void
device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) device_state_changed (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
gpointer user_data)
{ {
NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
if (state <= NM_DEVICE_STATE_DISCONNECTED) { if (new_state <= NM_DEVICE_STATE_DISCONNECTED) {
nm_vpn_connection_set_vpn_state (connection, nm_vpn_connection_set_vpn_state (connection,
NM_VPN_CONNECTION_STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_DISCONNECTED,
NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
} else if (state == NM_DEVICE_STATE_FAILED) { } else if (new_state == NM_DEVICE_STATE_FAILED) {
nm_vpn_connection_set_vpn_state (connection, nm_vpn_connection_set_vpn_state (connection,
NM_VPN_CONNECTION_STATE_FAILED, NM_VPN_CONNECTION_STATE_FAILED,
NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED); NM_VPN_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
@@ -907,8 +911,17 @@ connection_vpn_state_changed (NMVPNConnection *connection,
/* Reset routes, nameservers, and domains of the currently active device */ /* Reset routes, nameservers, and domains of the currently active device */
dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev); dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev);
if (dev_ip4_config) if (dev_ip4_config) {
nm_device_set_ip4_config (priv->parent_dev, g_object_ref (dev_ip4_config)); NMDeviceStateReason dev_reason = NM_DEVICE_STATE_REASON_NONE;
/* Since the config we're setting is also the device's current
* config, have to ref the config to ensure it doesn't get
* destroyed when the device unrefs it in nm_device_set_ip4_config().
*/
nm_device_set_ip4_config (priv->parent_dev,
g_object_ref (dev_ip4_config),
&dev_reason);
}
} }
if (priv->banner) { if (priv->banner) {