summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2017-03-05 15:30:24 +0100
committerLubomir Rintel <lkundrak@v3.sk>2017-03-17 10:21:19 +0100
commit8b649a8c84c0d46c1d4108da34567ee37765acd8 (patch)
tree5275ec0d9e0fd624ef9d8cccfa5aba738bb27253
parent67688fd2e5d68ef0f59b8034ed7f8d2f925f07e1 (diff)
downloadNetworkManager-8b649a8c84c0d46c1d4108da34567ee37765acd8.tar.gz
active-connection: emit a StateChanged signal on state changes
It includes a reason code that makes it possible for the clients to be more reasonable about error messages. The reason code is essentially copied from the VPN, plus three more reasons that were useful for non-VPN connections.
-rw-r--r--introspection/org.freedesktop.NetworkManager.Connection.Active.xml14
-rw-r--r--libnm-core/nm-dbus-interface.h58
-rw-r--r--libnm/libnm.ver1
-rw-r--r--src/devices/nm-device.c4
-rw-r--r--src/nm-act-request.c8
-rw-r--r--src/nm-active-connection.c12
-rw-r--r--src/nm-active-connection.h6
-rw-r--r--src/nm-manager.c16
-rw-r--r--src/vpn/nm-vpn-connection.c5
9 files changed, 113 insertions, 11 deletions
diff --git a/introspection/org.freedesktop.NetworkManager.Connection.Active.xml b/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
index 3ffa4cd67a..31a485c9ff 100644
--- a/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
+++ b/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
@@ -81,6 +81,20 @@
<property name="State" type="u" access="read"/>
<!--
+ StateChanged:
+ @state: (<link linkend="NMActiveConnectionState">NMActiveConnectionState</link>) The new state of the active connection.
+ @reason: (<link linkend="NMActiveConnectionStateReason">NMActiveConnectionStateReason</link>) Reason code describing the change to the new state.
+
+ Emitted when the state of the active connection has changed.
+
+ Since: 1.8
+ -->
+ <signal name="StateChanged">
+ <arg name="state" type="u"/>
+ <arg name="reason" type="u"/>
+ </signal>
+
+ <!--
Default:
Whether this active connection is the default IPv4 connection, i.e.
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index 89c2ab1628..16318b78bc 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -30,6 +30,7 @@
#ifndef NM_VERSION_H
#define NM_AVAILABLE_IN_1_2
+#define NM_AVAILABLE_IN_1_8
#endif
/*
@@ -641,6 +642,62 @@ typedef enum {
} NMActiveConnectionState;
/**
+ * NMActiveConnectionStateReason:
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN: The reason for the active connection
+ * state change is unknown.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_NONE: No reason was given for the active
+ * connection state change.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED: The active connection changed
+ * state because the user disconnected it.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED: The active connection
+ * changed state because the device it was using was disconnected.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED: The service providing the
+ * VPN connection was stopped.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID: The IP config of the active
+ * connection was invalid.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT: The connection attempt to
+ * the VPN service timed out.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT: A timeout occurred
+ * while starting the service providing the VPN connection.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED: Starting the service
+ * providing the VPN connection failed.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS: Necessary secrets for the
+ * connection were not provided.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED: Authentication to the
+ * server failed.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED: The connection was
+ * deleted from settings.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED: Master connection of this
+ * connection failed to activate.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED: Could not create the
+ * software device link.
+ * @NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED: The device this connection
+ * depended on disappeared.
+ *
+ * Active connection state reasons.
+ *
+ * Since: 1.8
+ */
+NM_AVAILABLE_IN_1_8
+typedef enum {
+ NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN = 0,
+ NM_ACTIVE_CONNECTION_STATE_REASON_NONE = 1,
+ NM_ACTIVE_CONNECTION_STATE_REASON_USER_DISCONNECTED = 2,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED = 3,
+ NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_STOPPED = 4,
+ NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID = 5,
+ NM_ACTIVE_CONNECTION_STATE_REASON_CONNECT_TIMEOUT = 6,
+ NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT = 7,
+ NM_ACTIVE_CONNECTION_STATE_REASON_SERVICE_START_FAILED = 8,
+ NM_ACTIVE_CONNECTION_STATE_REASON_NO_SECRETS = 9,
+ NM_ACTIVE_CONNECTION_STATE_REASON_LOGIN_FAILED = 10,
+ NM_ACTIVE_CONNECTION_STATE_REASON_CONNECTION_REMOVED = 11,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED = 12,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED = 13,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED = 14,
+} NMActiveConnectionStateReason;
+
+/**
* NMSecretAgentGetSecretsFlags:
* @NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE: no special behavior; by default no
* user interaction is allowed and requests for secrets are fulfilled from
@@ -693,6 +750,7 @@ typedef enum /*< flags >*/ {
#ifndef NM_VERSION_H
#undef NM_AVAILABLE_IN_1_2
+#undef NM_AVAILABLE_IN_1_8
#endif
#define NM_LLDP_ATTR_DESTINATION "destination"
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 4b3d02fdfa..cfa52e25bc 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1146,6 +1146,7 @@ global:
libnm_1_8_0 {
global:
+ nm_active_connection_state_reason_get_type;
nm_connection_get_setting_dummy;
nm_device_dummy_get_type;
nm_ip_route_get_variant_attribute_spec;
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 5cd8ca0f1c..10f870f3ff 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -9029,7 +9029,9 @@ static void
_clear_queued_act_request (NMDevicePrivate *priv)
{
if (priv->queued_act_request) {
- nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+ nm_active_connection_set_state ((NMActiveConnection *) priv->queued_act_request,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED);
g_clear_object (&priv->queued_act_request);
}
}
diff --git a/src/nm-act-request.c b/src/nm-act-request.c
index e4f6492365..6d8bb0652e 100644
--- a/src/nm-act-request.c
+++ b/src/nm-act-request.c
@@ -397,6 +397,7 @@ device_state_changed (NMActiveConnection *active,
{
NMActiveConnectionState cur_ac_state = nm_active_connection_get_state (active);
NMActiveConnectionState ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
+ NMActiveConnectionStateReason ac_state_reason = NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN;
/* Decide which device state changes to handle when this active connection
* is not the device's current request. Two cases here: (a) the AC is
@@ -451,6 +452,7 @@ device_state_changed (NMActiveConnection *active,
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
ac_state = NM_ACTIVE_CONNECTION_STATE_DEACTIVATED;
+ ac_state_reason = NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_DISCONNECTED;
g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_notify), active);
break;
@@ -464,7 +466,7 @@ device_state_changed (NMActiveConnection *active,
nm_active_connection_set_default6 (active, FALSE);
}
- nm_active_connection_set_state (active, ac_state);
+ nm_active_connection_set_state (active, ac_state, ac_state_reason);
}
static void
@@ -486,7 +488,9 @@ master_failed (NMActiveConnection *self)
}
/* If no device, or the device wasn't active, just move to deactivated state */
- nm_active_connection_set_state (self, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+ nm_active_connection_set_state (self,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEPENDENCY_FAILED);
}
/*****************************************************************************/
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 320ba45828..eb528da8c3 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -95,6 +95,7 @@ enum {
DEVICE_CHANGED,
DEVICE_METERED_CHANGED,
PARENT_ACTIVE,
+ STATE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -209,7 +210,8 @@ nm_active_connection_get_state (NMActiveConnection *self)
void
nm_active_connection_set_state (NMActiveConnection *self,
- NMActiveConnectionState new_state)
+ NMActiveConnectionState new_state,
+ NMActiveConnectionStateReason reason)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
NMActiveConnectionState old_state;
@@ -236,6 +238,7 @@ nm_active_connection_set_state (NMActiveConnection *self,
old_state = priv->state;
priv->state = new_state;
priv->state_set = TRUE;
+ g_signal_emit (self, signals[STATE_CHANGED], 0, new_state, reason);
_notify (self, PROP_STATE);
check_master_ready (self);
@@ -1418,6 +1421,13 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
NULL, NULL, NULL,
G_TYPE_NONE, 1, NM_TYPE_ACTIVE_CONNECTION);
+ signals[STATE_CHANGED] =
+ g_signal_new (NM_ACTIVE_CONNECTION_STATE_CHANGED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class),
NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON,
NULL);
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index ba231c3077..8d3478c79d 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -57,6 +57,9 @@
#define NM_ACTIVE_CONNECTION_INT_MASTER_READY "int-master-ready"
#define NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE "int-activation-type"
+/* Signals */
+#define NM_ACTIVE_CONNECTION_STATE_CHANGED "state-changed"
+
/* Internal signals*/
#define NM_ACTIVE_CONNECTION_DEVICE_CHANGED "device-changed"
#define NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED "device-metered-changed"
@@ -139,7 +142,8 @@ gboolean nm_active_connection_get_default6 (NMActiveConnection *self);
NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *self);
void nm_active_connection_set_state (NMActiveConnection *self,
- NMActiveConnectionState state);
+ NMActiveConnectionState state,
+ NMActiveConnectionStateReason reason);
NMDevice * nm_active_connection_get_device (NMActiveConnection *self);
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 649f8464fd..fb4c444846 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -3061,12 +3061,16 @@ active_connection_parent_active (NMActiveConnection *active,
} else {
_LOGW (LOGD_CORE, "Could not realize device '%s': %s",
nm_device_get_iface (device), error->message);
- nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+ nm_active_connection_set_state (active,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REALIZE_FAILED);
}
} else {
_LOGW (LOGD_CORE, "The parent connection device '%s' depended on disappeared.",
nm_device_get_iface (device));
- nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+ nm_active_connection_set_state (active,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_REASON_DEVICE_REMOVED);
}
}
@@ -3396,8 +3400,12 @@ _internal_activation_failed (NMManager *self,
error_desc);
if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
- nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
- nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
+ nm_active_connection_set_state (active,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATING,
+ NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN);
+ nm_active_connection_set_state (active,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN);
}
}
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
index 912972cb90..d05079cac7 100644
--- a/src/vpn/nm-vpn-connection.c
+++ b/src/vpn/nm-vpn-connection.c
@@ -447,7 +447,7 @@ dispatcher_pre_down_done (guint call_id, gpointer user_data)
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
priv->dispatcher_id = 0;
- _set_vpn_state (self, STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE);
+ _set_vpn_state (self, STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED, FALSE);
}
static void
@@ -500,7 +500,8 @@ _set_vpn_state (NMVpnConnection *self,
/* Update active connection base class state */
nm_active_connection_set_state (NM_ACTIVE_CONNECTION (self),
- _state_to_ac_state (vpn_state));
+ _state_to_ac_state (vpn_state),
+ (NMActiveConnectionStateReason) reason);
/* Clear any in-progress secrets request */
cancel_get_secrets (self);