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>
* callouts/Makefile.am

View file

@ -212,6 +212,108 @@ typedef enum
} 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 {
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0,
@ -222,6 +324,5 @@ typedef enum {
NM_ACTIVE_CONNECTION_STATE_ACTIVATED
} NMActiveConnectionState;
#endif /* NETWORK_MANAGER_H */

View file

@ -52,11 +52,21 @@
<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>
The new state of the device.
</tp:docstring>
</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>
<tp:enum name="NM_DEVICE_STATE" type="u">

View file

@ -9,6 +9,7 @@
#include "nm-device-private.h"
#include "nm-object-private.h"
#include "nm-object-cache.h"
#include "nm-marshal.h"
#include "nm-device-bindings.h"
@ -47,6 +48,14 @@ enum {
LAST_PROP
};
enum {
STATE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static void
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_MANAGED, nm_object_demarshal_generic, &priv->managed },
{ NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
{ NM_DEVICE_STATE, nm_object_demarshal_generic, &priv->state },
{ NULL },
};
@ -117,6 +125,23 @@ register_for_property_changed (NMDevice *device)
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*
constructor (GType type,
guint n_construct_params,
@ -140,6 +165,21 @@ constructor (GType type,
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);
}
@ -303,6 +343,17 @@ nm_device_class_init (NMDeviceClass *device_class)
"Product string",
NULL,
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 *

View file

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

View file

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

View file

@ -515,12 +515,16 @@ active_connection_default_changed (NMActRequest *req,
}
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;
NMConnection *connection = get_device_connection (device);
switch (state) {
switch (new_state) {
case NM_DEVICE_STATE_FAILED:
/* Mark the connection invalid so it doesn't get automatically chosen */
if (connection) {

View file

@ -78,8 +78,46 @@ enum {
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 *
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);
}
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 {
NMActRequest *req;
char *setting_name;

View file

@ -81,6 +81,7 @@ dial_done (NMSerialDevice *device,
int reply_index,
gpointer user_data)
{
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
gboolean success = FALSE;
switch (reply_index) {
@ -90,15 +91,19 @@ dial_done (NMSerialDevice *device,
break;
case 1:
nm_info ("Busy");
reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
break;
case 2:
nm_warning ("No dial tone");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
break;
case 3:
nm_warning ("No carrier");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
break;
case -1:
nm_warning ("Dialing timed out");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
break;
default:
nm_warning ("Dialing failed");
@ -108,7 +113,7 @@ dial_done (NMSerialDevice *device,
if (success)
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
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
@ -127,7 +132,9 @@ do_dial (NMSerialDevice *device)
g_free (command);
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
@ -141,11 +148,15 @@ init_done (NMSerialDevice *device,
break;
case -1:
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;
default:
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;
}
}
@ -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);
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
real_act_stage1_prepare (NMDevice *device)
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
NMSerialDevice *serial_device = NM_SERIAL_DEVICE (device);
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));
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;
}
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;
}
@ -352,12 +367,18 @@ nm_cdma_device_init (NMCdmaDevice *self)
static gboolean
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;
}
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);
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
* 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);
/* 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_UNMANAGED:
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);
if (state == NM_DEVICE_STATE_UNAVAILABLE) {
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) {
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
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;
}
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);
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
* 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);
return;
}
@ -714,7 +718,8 @@ link_timeout_cb (gpointer user_data)
req = nm_device_get_act_request (dev);
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;
}
@ -731,11 +736,11 @@ link_timeout_cb (gpointer user_data)
if (!setting_name)
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));
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,
SECRETS_CALLER_ETHERNET, NULL, NULL);
@ -743,7 +748,7 @@ link_timeout_cb (gpointer user_data)
time_out:
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;
}
@ -779,15 +784,16 @@ static gboolean
supplicant_mgr_state_cb_handler (gpointer 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 (info->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
NMDevice *dev = NM_DEVICE (info->self);
supplicant_interface_clean (info->self);
if (nm_device_is_activating (dev))
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
}
}
g_slice_free (struct state_cb_data, info);
@ -816,7 +822,7 @@ build_supplicant_config (NMDeviceEthernet *self)
{
DBusGProxy *proxy;
const char *con_path;
NMSupplicantConfig *config;
NMSupplicantConfig *config = NULL;
NMSetting8021x *security;
NMConnection *connection;
@ -829,31 +835,30 @@ build_supplicant_config (NMDeviceEthernet *self)
return NULL;
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))
return config;
if (!nm_supplicant_config_add_setting_8021x (config, security, con_path, TRUE)) {
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.");
g_object_unref (config);
return NULL;
return config;
}
static gboolean
supplicant_iface_state_cb_handler (gpointer 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) {
NMSupplicantConfig *config;
const char *iface;
gboolean success = FALSE;
iface = nm_device_get_iface (NM_DEVICE (info->self));
iface = nm_device_get_iface (device);
config = build_supplicant_config (info->self);
if (config) {
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (info->self);
success = nm_supplicant_interface_set_config (priv->supplicant.iface, 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);
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);
if (nm_device_is_activating (dev))
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
}
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);
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;
}
@ -986,7 +991,7 @@ handle_auth_or_fail (NMDeviceEthernet *self,
if (tries > 3)
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);
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)
nm_info ("Activation (%s/wired): asking for new secrets", iface);
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;
}
@ -1079,7 +1084,7 @@ supplicant_interface_init (NMDeviceEthernet *self)
}
static NMActStageReturn
nm_8021x_stage2_config (NMDeviceEthernet *self)
nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{
NMConnection *connection;
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));
if (!security) {
nm_warning ("Invalid or missing 802.1X security");
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
return ret;
}
@ -1101,16 +1107,22 @@ nm_8021x_stage2_config (NMDeviceEthernet *self)
/* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL);
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.",
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 {
nm_info ("Activation (%s/wired): connection '%s' requires no security. No secrets needed.",
iface, s_connection->id);
if (supplicant_interface_init (self))
ret = NM_ACT_STAGE_RETURN_POSTPONE;
else
*reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
}
return ret;
@ -1126,19 +1138,16 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_
switch (status) {
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;
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;
case NM_PPP_STATUS_DEAD:
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED);
else
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED);
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_PPP_FAILED);
break;
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;
default:
break;
@ -1159,12 +1168,12 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
}
static NMActStageReturn
pppoe_stage2_config (NMDeviceEthernet *self)
pppoe_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMActRequest *req;
GError *err = NULL;
NMActStageReturn ret;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
req = nm_device_get_act_request (NM_DEVICE (self));
g_assert (req);
@ -1182,24 +1191,27 @@ pppoe_stage2_config (NMDeviceEthernet *self)
self);
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} 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_object_unref (priv->ppp_manager);
priv->ppp_manager = NULL;
ret = NM_ACT_STAGE_RETURN_FAILURE;
*reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
}
return ret;
}
static NMActStageReturn
real_act_stage2_config (NMDevice *device)
real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{
NMSettingConnection *s_connection;
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));
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);
if (security)
ret = nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device));
ret = nm_8021x_stage2_config (NM_DEVICE_ETHERNET (device), reason);
else
ret = NM_ACT_STAGE_RETURN_SUCCESS;
} 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 {
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;
}
@ -1222,7 +1235,9 @@ real_act_stage2_config (NMDevice *device)
}
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);
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. */
/* 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;
NMSettingWired *s_wired;

View file

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

View file

@ -63,7 +63,10 @@ struct _NMDeviceInterface {
void (*deactivate) (NMDeviceInterface *device);
/* 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);

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_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);

View file

@ -2011,10 +2011,11 @@ link_timeout_cb (gpointer user_data)
req = nm_device_get_act_request (dev);
ap = nm_device_wifi_get_activation_ap (self);
if (req == NULL || ap == NULL) {
/* shouldn't ever happen */
nm_warning ("couldn't get activation request or activation AP.");
if (nm_device_is_activating (dev)) {
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;
}
@ -2024,7 +2025,7 @@ link_timeout_cb (gpointer user_data)
* fail.
*/
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;
}
@ -2061,7 +2062,7 @@ link_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev));
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,
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) {
cleanup_association_attempt (self, FALSE);
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);
@ -2263,8 +2265,10 @@ supplicant_mgr_state_cb_handler (gpointer user_data)
supplicant_interface_release (self);
}
if (nm_device_get_state (dev) > NM_DEVICE_STATE_UNAVAILABLE)
nm_device_state_changed (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_REASON_SUPPLICANT_FAILED);
}
} else if (new_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
dev_state = nm_device_get_state (dev);
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,
* we can transition to the DISCONNECTED state.
*/
if (priv->supplicant.iface)
nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED);
if (priv->supplicant.iface) {
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);
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:
g_free (cb_data->name);
@ -2401,7 +2407,7 @@ handle_auth_or_fail (NMDeviceWifi *self,
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);
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, "
"failing activation.",
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 {
/* Authentication failed, encryption key is probably bad */
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_device_get_iface (dev));
} 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
real_act_stage1_prepare (NMDevice *dev)
real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
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
* (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.
*/
ap = nm_device_wifi_get_activation_ap (self);
if (!ap) {
NMActRequest *req;
NMConnection *connection;
GSList *iter;
if (ap)
goto done;
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (req);
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (req);
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
/* Find a compatible AP in the scan list */
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
NMAccessPoint *candidate = NM_AP (iter->data);
/* Find a compatible AP in the scan list */
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
NMAccessPoint *candidate = NM_AP (iter->data);
if (nm_ap_check_compatible (candidate, connection)) {
ap = candidate;
break;
}
if (nm_ap_check_compatible (candidate, connection)) {
ap = candidate;
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;
}
@ -2749,7 +2757,7 @@ real_connection_secrets_updated (NMDevice *dev,
}
static NMActStageReturn
real_act_stage2_config (NMDevice *dev)
real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{
NMDeviceWifi * self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
@ -2763,6 +2771,8 @@ real_act_stage2_config (NMDevice *dev)
NMSettingConnection * s_connection;
const char * setting_name;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
remove_supplicant_timeouts (self);
req = nm_device_get_act_request (dev);
@ -2780,11 +2790,17 @@ real_act_stage2_config (NMDevice *dev)
/* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) {
NMActStageReturn auth_ret;
nm_info ("Activation (%s/wireless): access point '%s' has security,"
" but secrets are required.",
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 {
NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection,
NM_TYPE_SETTING_WIRELESS);
@ -2804,6 +2820,7 @@ real_act_stage2_config (NMDevice *dev)
if (config == NULL) {
nm_warning ("Activation (%s/wireless): couldn't build wireless "
"configuration.", iface);
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out;
}
@ -2817,19 +2834,21 @@ real_act_stage2_config (NMDevice *dev)
if (!nm_supplicant_interface_set_config (priv->supplicant.iface, config)) {
nm_warning ("Activation (%s/wireless): couldn't send wireless "
"configuration to the supplicant.", iface);
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out;
}
if (!start_supplicant_connection_timeout (self))
if (!start_supplicant_connection_timeout (self)) {
*reason = NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED;
goto out;
}
/* We'll get stage3 started when the supplicant connects */
ret = NM_ACT_STAGE_RETURN_POSTPONE;
out:
if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
if (ret == NM_ACT_STAGE_RETURN_FAILURE)
cleanup_association_attempt (self, TRUE);
}
if (config) {
/* Supplicant interface object refs the config; we no longer care about
@ -2842,7 +2861,8 @@ out:
static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *dev,
NMIP4Config **config)
NMIP4Config **config,
NMDeviceStateReason *reason)
{
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMDeviceClass *parent_class;
@ -2852,7 +2872,7 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
/* Chain up to parent */
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) {
NMConnection *connection;
@ -2874,7 +2894,8 @@ real_act_stage4_get_ip4_config (NMDevice *dev,
static NMActStageReturn
real_act_stage4_ip_config_timeout (NMDevice *dev,
NMIP4Config **config)
NMIP4Config **config,
NMDeviceStateReason *reason)
{
NMDeviceWifi * self = NM_DEVICE_WIFI (dev);
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) {
nm_info ("Activation (%s/wireless): asking for new secrets",
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) {
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 */
klass = NM_DEVICE_WIFI_GET_CLASS (self);
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 {
/* Non-encrypted network or authentication is enforced by some
* entity (AP, RADIUS server, etc), but IP configure failed. Alert
* the user.
*/
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
ret = NM_ACT_STAGE_RETURN_FAILURE;
}
@ -3250,12 +3274,18 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
static gboolean
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;
}
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);
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;
}
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
if (new_state <= NM_DEVICE_STATE_UNAVAILABLE) {
/* Clean up the supplicant interface because in these states the
* device cannot be used.
*/
@ -3275,7 +3305,7 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
supplicant_interface_release (self);
}
switch (state) {
switch (new_state) {
case NM_DEVICE_STATE_UNMANAGED:
clear_aps = TRUE;
break;
@ -3333,7 +3363,7 @@ nm_device_wifi_new (const char *udi,
return NULL;
g_signal_connect (obj, "state-changed",
G_CALLBACK (state_changed_cb),
G_CALLBACK (device_state_changed),
NULL);
return NM_DEVICE_WIFI (obj);
@ -3398,10 +3428,15 @@ nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled)
if (!priv->supplicant.iface)
supplicant_interface_acquire (self);
if (priv->supplicant.iface)
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED);
if (priv->supplicant.iface) {
nm_device_state_changed (NM_DEVICE (self),
NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_NONE);
}
} 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);
}
}

View file

@ -154,7 +154,7 @@ device_start (gpointer user_data)
NMDevice *self = NM_DEVICE (user_data);
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;
}
@ -381,7 +381,7 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us
switch (status) {
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;
default:
break;
@ -400,6 +400,7 @@ nm_device_activate_stage1_device_prepare (gpointer user_data)
NMDevice *self = NM_DEVICE (user_data);
const char * iface;
NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */
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);
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) {
goto out;
} 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;
}
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@ -449,14 +450,14 @@ nm_device_activate_schedule_stage1_device_prepare (NMDevice *self)
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev)
real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
{
/* Nothing to do */
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static NMActStageReturn
real_act_stage2_config (NMDevice *dev)
real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{
/* Nothing to do */
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);
const char * iface;
NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */
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);
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)) {
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;
}
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)
goto out;
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;
}
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@ -563,7 +565,7 @@ aipd_cleanup (NMDevice *self)
}
static NMIP4Config *
aipd_get_ip4_config (NMDevice *self)
aipd_get_ip4_config (NMDevice *self, NMDeviceStateReason *reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMIP4Config *config = NULL;
@ -572,6 +574,11 @@ aipd_get_ip4_config (NMDevice *self)
g_return_val_if_fail (priv->aipd_addr > 0, NULL);
config = nm_ip4_config_new ();
if (!config) {
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NULL;
}
addr = g_malloc0 (sizeof (NMSettingIP4Address));
addr->address = (guint32) priv->aipd_addr;
addr->prefix = 16;
@ -581,13 +588,15 @@ aipd_get_ip4_config (NMDevice *self)
}
static gboolean
handle_autoip_change (NMDevice *self)
handle_autoip_change (NMDevice *self, NMDeviceStateReason *reason)
{
NMActRequest *req;
NMConnection *connection;
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) {
nm_warning ("failed to get autoip config for rebind");
return FALSE;
@ -600,7 +609,7 @@ handle_autoip_change (NMDevice *self)
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_device_get_iface (self));
return FALSE;
@ -644,18 +653,19 @@ nm_device_handle_autoip4_event (NMDevice *self,
if (strcmp (event, "BIND") == 0) {
struct in_addr ip;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
if (inet_pton (AF_INET, address, &ip) <= 0) {
nm_warning ("(%s): invalid address %s received from avahi-autoipd.",
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;
}
if ((ip.s_addr & IPV4LL_NETMASK) != IPV4LL_NETWORK) {
nm_warning ("(%s): invalid address %s received from avahi-autoipd.",
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;
}
@ -672,8 +682,8 @@ nm_device_handle_autoip4_event (NMDevice *self,
break;
case NM_DEVICE_STATE_ACTIVATED:
priv->aipd_addr = ip.s_addr;
if (!handle_autoip_change (self))
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
if (!handle_autoip_change (self, &reason))
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
break;
default:
nm_warning ("(%s): unexpected avahi-autoip event %s for %s.",
@ -685,7 +695,7 @@ nm_device_handle_autoip4_event (NMDevice *self,
iface, address, event);
/* 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);
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
@ -798,13 +808,15 @@ aipd_exec (NMDevice *self, GError **error)
}
static NMActStageReturn
real_act_stage3_ip_config_start (NMDevice *self)
real_act_stage3_ip_config_start (NMDevice *self, NMDeviceStateReason *reason)
{
NMSettingIP4Config *s_ip4;
NMActRequest *req;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
const char *iface;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
iface = nm_device_get_iface (self);
req = nm_device_get_act_request (self);
@ -830,8 +842,10 @@ real_act_stage3_ip_config_start (NMDevice *self)
* stuff happens.
*/
ret = NM_ACT_STAGE_RETURN_POSTPONE;
} else
} else {
*reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE;
}
} else if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) {
GError *error = NULL;
@ -845,6 +859,7 @@ real_act_stage3_ip_config_start (NMDevice *self)
" to start avahi-autoipd: %s", iface, error->message);
g_error_free (error);
aipd_cleanup (self);
*reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
ret = NM_ACT_STAGE_RETURN_FAILURE;
}
}
@ -863,8 +878,9 @@ static gboolean
nm_device_activate_stage3_ip_config_start (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
const char * iface;
const char *iface;
NMActStageReturn ret;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
/* Clear the activation source ID now that this stage has run */
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);
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)
goto out;
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;
}
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@ -940,7 +956,7 @@ reserve_shared_ip (void)
}
static NMIP4Config *
nm_device_new_ip4_shared_config (NMDevice *self)
nm_device_new_ip4_shared_config (NMDevice *self, NMDeviceStateReason *reason)
{
NMIP4Config *config = NULL;
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);
tmp_addr = reserve_shared_ip ();
if (!tmp_addr)
if (!tmp_addr) {
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NULL;
}
config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address));
@ -970,7 +988,8 @@ nm_device_new_ip4_shared_config (NMDevice *self)
static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *self,
NMIP4Config **config)
NMIP4Config **config,
NMDeviceStateReason *reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
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 (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (nm_device_get_act_request (self));
g_assert (connection);
@ -990,17 +1010,22 @@ real_act_stage4_get_ip4_config (NMDevice *self,
nm_device_get_iface (self));
if (*config)
nm_utils_merge_ip4_config (*config, s_ip4);
else
*reason = NM_DEVICE_STATE_REASON_DHCP_ERROR;
} else {
g_assert (s_ip4);
g_assert (s_ip4->method);
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)) {
*config = nm_ip4_config_new ();
if (*config)
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)) {
*config = nm_device_new_ip4_shared_config (self);
*config = nm_device_new_ip4_shared_config (self, reason);
if (*config)
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)
{
NMDevice *self = NM_DEVICE (user_data);
NMIP4Config * ip4_config = NULL;
NMIP4Config *ip4_config = NULL;
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 */
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);
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)
goto out;
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;
}
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
@ -1083,12 +1109,14 @@ nm_device_activate_schedule_stage4_ip_config_get (NMDevice *self)
static NMActStageReturn
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);
/* DHCP failed; connection must fail */
*reason = NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE;
return NM_ACT_STAGE_RETURN_FAILURE;
}
@ -1103,9 +1131,10 @@ static gboolean
nm_device_activate_stage4_ip_config_timeout (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMIP4Config * ip4_config = NULL;
const char * iface;
NMIP4Config *ip4_config = NULL;
const char *iface;
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 */
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);
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) {
goto out;
} 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;
}
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;
NMConnection *connection;
NMSettingIP4Config *s_ip4;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
ip4_config = g_object_get_data (G_OBJECT (nm_device_get_act_request (self)),
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...",
iface);
if (!nm_device_set_ip4_config (self, ip4_config)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
if (!nm_device_set_ip4_config (self, ip4_config, &reason)) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
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)) {
nm_warning ("(%s): failed to start dnsmasq: %s", iface, error->message);
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;
}
@ -1208,7 +1238,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
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:
nm_info ("Activation (%s) Stage 5 of 5 (IP Configure Commit) complete.",
@ -1338,6 +1368,7 @@ static void
nm_device_deactivate (NMDeviceInterface *device)
{
NMDevice *self = NM_DEVICE (device);
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
g_return_if_fail (self != NULL);
@ -1346,7 +1377,7 @@ nm_device_deactivate (NMDeviceInterface *device)
nm_device_deactivate_quickly (self);
/* 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. */
nm_system_device_flush_ip4_routes (self);
@ -1393,7 +1424,7 @@ connection_secrets_failed_cb (NMActRequest *req,
{
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
@ -1452,7 +1483,7 @@ nm_device_activate (NMDeviceInterface *device,
* that the activation request isn't deferred because the deferred bit
* 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);
return TRUE;
@ -1515,6 +1546,7 @@ handle_dhcp_lease_change (NMDevice *device)
NMSettingIP4Config *s_ip4;
NMConnection *connection;
NMActRequest *req;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
if (!nm_device_get_use_dhcp (device)) {
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));
if (!config) {
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;
}
@ -1539,9 +1571,9 @@ handle_dhcp_lease_change (NMDevice *device)
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_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_END: /* dhclient exited normally */
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) {
if (nm_device_get_use_dhcp (device)) {
/* 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;
@ -1658,13 +1690,14 @@ nm_device_get_ip4_config (NMDevice *self)
gboolean
nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config)
nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReason *reason)
{
NMDevicePrivate *priv;
const char *ip_iface;
gboolean success;
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
g_return_val_if_fail (reason != NULL, FALSE);
priv = NM_DEVICE_GET_PRIVATE (self);
@ -1881,8 +1914,10 @@ nm_device_dispose (GObject *object)
*/
if (self->priv->managed) {
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
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);
@ -2070,12 +2105,14 @@ failed_to_disconnected (gpointer user_data)
NMDevice *device = NM_DEVICE (user_data);
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;
}
void
nm_device_state_changed (NMDevice *device, NMDeviceState state)
nm_device_state_changed (NMDevice *device,
NMDeviceState state,
NMDeviceStateReason reason)
{
NMDevicePrivate *priv;
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_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 */
@ -2184,6 +2221,9 @@ nm_device_set_managed (NMDevice *device, gboolean managed)
g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED);
/* 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,
GError **error);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self);
NMActStageReturn (* act_stage2_config) (NMDevice *self);
NMActStageReturn (* act_stage3_ip_config_start) (NMDevice *self);
NMActStageReturn (* act_stage1_prepare) (NMDevice *self,
NMDeviceStateReason *reason);
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,
NMIP4Config **config);
NMIP4Config **config,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage4_ip_config_timeout) (NMDevice *self,
NMIP4Config **config);
NMIP4Config **config,
NMDeviceStateReason *reason);
void (* deactivate) (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);
gboolean nm_device_set_ip4_config (NMDevice *dev,
NMIP4Config *config);
NMIP4Config *config,
NMDeviceStateReason *reason);
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);
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
@ -100,7 +100,7 @@ modem_get_reply (NMGsmDevice *self,
id = nm_serial_device_get_reply (serial, timeout, terminators, callback, NULL);
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 *
@ -127,6 +127,7 @@ dial_done (NMSerialDevice *device,
gpointer user_data)
{
gboolean success = FALSE;
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_UNKNOWN;
switch (reply_index) {
case 0:
@ -135,25 +136,30 @@ dial_done (NMSerialDevice *device,
break;
case 1:
nm_info ("Busy");
reason = NM_DEVICE_STATE_REASON_MODEM_BUSY;
break;
case 2:
nm_warning ("No dial tone");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE;
break;
case 3:
nm_warning ("No carrier");
reason = NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER;
break;
case -1:
nm_warning ("Dialing timed out");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT;
break;
default:
nm_warning ("Dialing failed");
reason = NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED;
break;
}
if (success)
nm_device_activate_schedule_stage2_device_config (NM_DEVICE (device));
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
@ -194,7 +200,9 @@ set_apn_done (NMSerialDevice *device,
break;
default:
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;
}
}
@ -231,11 +239,15 @@ manual_registration_done (NMSerialDevice *device,
break;
case -1:
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;
default:
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;
}
}
@ -301,15 +313,21 @@ automatic_registration_response (NMSerialDevice *device,
break;
case 3:
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;
case -1:
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;
default:
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;
}
}
@ -347,11 +365,15 @@ init_full_done (NMSerialDevice *device,
break;
case -1:
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;
default:
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;
}
}
@ -377,7 +399,9 @@ enter_pin_done (NMSerialDevice *device,
break;
case -1:
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;
default:
nm_warning ("Invalid secret");
@ -443,7 +467,9 @@ enter_pin (NMGsmDevice *device, gboolean retry)
g_free (command);
} else {
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_SETTING_GSM_SETTING_NAME,
retry,
@ -472,11 +498,15 @@ check_pin_done (NMSerialDevice *device,
break;
case -1:
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;
default:
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;
}
}
@ -501,11 +531,15 @@ init_done (NMSerialDevice *device,
break;
case -1:
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;
default:
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;
}
}
@ -519,7 +553,7 @@ init_modem (NMSerialDevice *device, gpointer user_data)
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *device)
real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
NMGsmDevicePrivate *priv = NM_GSM_DEVICE_GET_PRIVATE (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));
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;
}
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;
}
@ -723,12 +761,18 @@ nm_gsm_device_init (NMGsmDevice *self)
static gboolean
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;
}
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);
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
* 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);
/* 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_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:

View file

@ -53,10 +53,6 @@ static void connection_added_default_handler (NMManager *manager,
NMConnection *connection,
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,
const char *udi,
const char *type_name,
@ -369,6 +365,30 @@ pending_connection_info_destroy (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
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
manager_hidden_ap_found (NMDeviceInterface *device,
NMAccessPoint *ap,
@ -1696,8 +1696,12 @@ internal_activate_device (NMManager *manager,
if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error))
return NULL;
if (nm_device_get_act_request (device))
nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED);
/* Tear down any existing connection */
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);
success = nm_device_interface_activate (dev_iface, req, error);
@ -1947,7 +1951,9 @@ nm_manager_deactivate_connection (NMManager *manager,
continue;
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;
goto done;
}

View file

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

View file

@ -175,15 +175,19 @@ nm_vpn_connection_set_vpn_state (NMVPNConnection *connection,
}
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);
if (state <= NM_DEVICE_STATE_DISCONNECTED) {
if (new_state <= NM_DEVICE_STATE_DISCONNECTED) {
nm_vpn_connection_set_vpn_state (connection,
NM_VPN_CONNECTION_STATE_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_STATE_FAILED,
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 */
dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev);
if (dev_ip4_config)
nm_device_set_ip4_config (priv->parent_dev, g_object_ref (dev_ip4_config));
if (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) {