summary refs log tree commit diff
path: root/libnm-glib/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-glib/nm-device.c')
-rw-r--r--libnm-glib/nm-device.c202
1 files changed, 151 insertions, 51 deletions
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index 4167c9a7..3b39c9ec 100644
--- a/libnm-glib/nm-device.c
+++ b/libnm-glib/nm-device.c
@@ -56,15 +56,18 @@ typedef struct {
 	gboolean managed;
 	gboolean firmware_missing;
 	NMIP4Config *ip4_config;
-	gboolean null_ip4_config;
+	gboolean got_ip4_config;
 	NMDHCP4Config *dhcp4_config;
-	gboolean null_dhcp4_config;
+	gboolean got_dhcp4_config;
 	NMIP6Config *ip6_config;
-	gboolean null_ip6_config;
+	gboolean got_ip6_config;
 	NMDHCP6Config *dhcp6_config;
-	gboolean null_dhcp6_config;
+	gboolean got_dhcp6_config;
 	NMDeviceState state;
 
+	NMActiveConnection *active_connection;
+	gboolean got_active_connection;
+
 	GUdevClient *client;
 	char *product;
 	char *vendor;
@@ -87,6 +90,7 @@ enum {
 	PROP_DHCP6_CONFIG,
 	PROP_IP_INTERFACE,
 	PROP_DEVICE_TYPE,
+	PROP_ACTIVE_CONNECTION,
 
 	LAST_PROP
 };
@@ -119,13 +123,11 @@ demarshal_ip4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
 	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
 		return FALSE;
 
-	priv->null_ip4_config = FALSE;
+	priv->got_ip4_config = TRUE;
 
-	path = g_value_get_boxed (value);
-	if (path) {
-		if (!strcmp (path, "/"))
-			priv->null_ip4_config = TRUE;
-		else {
+	if (value) {
+		path = g_value_get_boxed (value);
+		if (path) {
 			config = NM_IP4_CONFIG (_nm_object_cache_get (path));
 			if (!config) {
 				connection = nm_object_get_connection (object);
@@ -157,13 +159,11 @@ demarshal_dhcp4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoi
 	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
 		return FALSE;
 
-	priv->null_dhcp4_config = FALSE;
+	priv->got_dhcp4_config = TRUE;
 
-	path = g_value_get_boxed (value);
-	if (path) {
-		if (!strcmp (path, "/"))
-			priv->null_dhcp4_config = TRUE;
-		else {
+	if (value) {
+		path = g_value_get_boxed (value);
+		if (path) {
 			config = NM_DHCP4_CONFIG (_nm_object_cache_get (path));
 			if (!config) {
 				connection = nm_object_get_connection (object);
@@ -195,13 +195,11 @@ demarshal_ip6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
 	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
 		return FALSE;
 
-	priv->null_ip6_config = FALSE;
+	priv->got_ip6_config = TRUE;
 
-	path = g_value_get_boxed (value);
-	if (path) {
-		if (!strcmp (path, "/"))
-			priv->null_ip6_config = TRUE;
-		else {
+	if (value) {
+		path = g_value_get_boxed (value);
+		if (path) {
 			config = NM_IP6_CONFIG (_nm_object_cache_get (path));
 			if (!config) {
 				connection = nm_object_get_connection (object);
@@ -233,13 +231,11 @@ demarshal_dhcp6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoi
 	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
 		return FALSE;
 
-	priv->null_dhcp6_config = FALSE;
+	priv->got_dhcp6_config = TRUE;
 
-	path = g_value_get_boxed (value);
-	if (path) {
-		if (!strcmp (path, "/"))
-			priv->null_dhcp6_config = TRUE;
-		else {
+	if (value) {
+		path = g_value_get_boxed (value);
+		if (path) {
 			config = NM_DHCP6_CONFIG (_nm_object_cache_get (path));
 			if (!config) {
 				connection = nm_object_get_connection (object);
@@ -260,6 +256,42 @@ demarshal_dhcp6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoi
 	return TRUE;
 }
 
+static gboolean
+demarshal_active_connection (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
+{
+	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
+	const char *path;
+	NMActiveConnection *active = NULL;
+	DBusGConnection *connection;
+
+	if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
+		return FALSE;
+
+	priv->got_active_connection = TRUE;
+
+	if (value) {
+		path = g_value_get_boxed (value);
+		if (path) {
+			active = NM_ACTIVE_CONNECTION (_nm_object_cache_get (path));
+			if (!active) {
+				connection = nm_object_get_connection (object);
+				active = NM_ACTIVE_CONNECTION (nm_active_connection_new (connection, path));
+			}
+		}
+	}
+
+	if (priv->active_connection) {
+		g_object_unref (priv->active_connection);
+		priv->active_connection = NULL;
+	}
+
+	if (active)
+		priv->active_connection = active;
+
+	_nm_object_queue_notify (object, NM_DEVICE_ACTIVE_CONNECTION);
+	return TRUE;
+}
+
 static void
 register_for_property_changed (NMDevice *device)
 {
@@ -276,6 +308,7 @@ register_for_property_changed (NMDevice *device)
 		{ NM_DEVICE_DHCP4_CONFIG,     demarshal_dhcp4_config,       &priv->dhcp4_config },
 		{ NM_DEVICE_IP6_CONFIG,       demarshal_ip6_config,         &priv->ip6_config },
 		{ NM_DEVICE_DHCP6_CONFIG,     demarshal_dhcp6_config,       &priv->dhcp6_config },
+		{ NM_DEVICE_ACTIVE_CONNECTION,demarshal_active_connection,  &priv->active_connection },
 		{ NULL },
 	};
 
@@ -365,6 +398,8 @@ dispose (GObject *object)
 		g_object_unref (priv->dhcp6_config);
 	if (priv->client)
 		g_object_unref (priv->client);
+	if (priv->active_connection)
+		g_object_unref (priv->active_connection);
 
 	G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
 }
@@ -432,6 +467,9 @@ get_property (GObject *object,
 	case PROP_STATE:
 		g_value_set_uint (value, nm_device_get_state (device));
 		break;
+	case PROP_ACTIVE_CONNECTION:
+		g_value_set_object (value, nm_device_get_active_connection (device));
+		break;
 	case PROP_PRODUCT:
 		g_value_set_string (value, nm_device_get_product (device));
 		break;
@@ -656,6 +694,19 @@ nm_device_class_init (NMDeviceClass *device_class)
 						  G_PARAM_READABLE));
 
 	/**
+	 * NMDevice:active-connection:
+	 *
+	 * The #NMActiveConnection object that "owns" this device during activation.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_ACTIVE_CONNECTION,
+		 g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION,
+		                      "ActiveConnection",
+		                      "Active Connection",
+		                      NM_TYPE_ACTIVE_CONNECTION,
+		                      G_PARAM_READABLE));
+
+	/**
 	 * NMDevice:vendor:
 	 *
 	 * The vendor string of the device.
@@ -998,22 +1049,25 @@ nm_device_get_ip4_config (NMDevice *device)
 	NMDevicePrivate *priv;
 	char *path;
 	GValue value = { 0, };
+	GError *error = NULL;
 
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (priv->ip4_config)
+	if (priv->got_ip4_config == TRUE)
 		return priv->ip4_config;
-	if (priv->null_ip4_config)
-		return NULL;
 
-	path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip4Config", NULL);
-	if (path) {
+	path = _nm_object_get_object_path_property (NM_OBJECT (device),
+	                                            NM_DBUS_INTERFACE_DEVICE,
+	                                            "Ip4Config",
+	                                            &error);
+	if (error == NULL) {
 		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
 		g_value_take_boxed (&value, path);
 		demarshal_ip4_config (NM_OBJECT (device), NULL, &value, &priv->ip4_config);
 		g_value_unset (&value);
 	}
+	g_clear_error (&error);
 
 	return priv->ip4_config;
 }
@@ -1033,22 +1087,25 @@ nm_device_get_dhcp4_config (NMDevice *device)
 	NMDevicePrivate *priv;
 	char *path;
 	GValue value = { 0, };
+	GError *error = NULL;
 
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (priv->dhcp4_config)
+	if (priv->got_dhcp4_config == TRUE)
 		return priv->dhcp4_config;
-	if (priv->null_dhcp4_config)
-		return NULL;
 
-	path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp4Config", NULL);
-	if (path) {
+	path = _nm_object_get_object_path_property (NM_OBJECT (device),
+	                                            NM_DBUS_INTERFACE_DEVICE,
+	                                            "Dhcp4Config",
+	                                            &error);
+	if (error == NULL) {
 		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
 		g_value_take_boxed (&value, path);
 		demarshal_dhcp4_config (NM_OBJECT (device), NULL, &value, &priv->dhcp4_config);
 		g_value_unset (&value);
 	}
+	g_clear_error (&error);
 
 	return priv->dhcp4_config;
 }
@@ -1067,22 +1124,25 @@ nm_device_get_ip6_config (NMDevice *device)
 	NMDevicePrivate *priv;
 	char *path;
 	GValue value = { 0, };
+	GError *error = NULL;
 
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (priv->ip6_config)
+	if (priv->got_ip6_config == TRUE)
 		return priv->ip6_config;
-	if (priv->null_ip6_config)
-		return NULL;
 
-	path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip6Config", NULL);
-	if (path) {
+	path = _nm_object_get_object_path_property (NM_OBJECT (device),
+	                                            NM_DBUS_INTERFACE_DEVICE,
+	                                            "Ip6Config",
+	                                            &error);
+	if (error == NULL) {
 		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
 		g_value_take_boxed (&value, path);
 		demarshal_ip6_config (NM_OBJECT (device), NULL, &value, &priv->ip6_config);
 		g_value_unset (&value);
 	}
+	g_clear_error (&error);
 
 	return priv->ip6_config;
 }
@@ -1102,22 +1162,25 @@ nm_device_get_dhcp6_config (NMDevice *device)
 	NMDevicePrivate *priv;
 	char *path;
 	GValue value = { 0, };
+	GError *error = NULL;
 
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (priv->dhcp6_config)
+	if (priv->got_dhcp6_config == TRUE)
 		return priv->dhcp6_config;
-	if (priv->null_dhcp6_config)
-		return NULL;
 
-	path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp6Config", NULL);
-	if (path) {
+	path = _nm_object_get_object_path_property (NM_OBJECT (device),
+	                                            NM_DBUS_INTERFACE_DEVICE,
+	                                            "Dhcp6Config",
+	                                            &error);
+	if (error == NULL) {
 		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
 		g_value_take_boxed (&value, path);
 		demarshal_dhcp6_config (NM_OBJECT (device), NULL, &value, &priv->dhcp6_config);
 		g_value_unset (&value);
 	}
+	g_clear_error (&error);
 
 	return priv->dhcp6_config;
 }
@@ -1148,6 +1211,43 @@ nm_device_get_state (NMDevice *device)
 	return priv->state;
 }
 
+/**
+ * nm_device_get_active_connection:
+ * @device: a #NMDevice
+ *
+ * Gets the #NMActiveConnection object which owns this device during activation.
+ *
+ * Returns: the #NMActiveConnection
+ **/
+NMActiveConnection *
+nm_device_get_active_connection (NMDevice *device)
+{
+	NMDevicePrivate *priv;
+	char *path;
+	GValue value = { 0, };
+	GError *error = NULL;
+
+	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+
+	priv = NM_DEVICE_GET_PRIVATE (device);
+	if (priv->got_active_connection == TRUE)
+		return priv->active_connection;
+
+	path = _nm_object_get_object_path_property (NM_OBJECT (device),
+	                                            NM_DBUS_INTERFACE_DEVICE,
+	                                            "ActiveConnection",
+	                                            &error);
+	if (error == NULL) {
+		g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
+		g_value_take_boxed (&value, path);
+		demarshal_active_connection (NM_OBJECT (device), NULL, &value, &priv->active_connection);
+		g_value_unset (&value);
+	}
+	g_clear_error (&error);
+
+	return priv->active_connection;
+}
+
 /* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
 
 static int hex2num (char c)
@@ -1203,7 +1303,7 @@ get_decoded_property (GUdevDevice *device, const char *property)
 }
 
 static void
-nm_device_update_description (NMDevice *device)
+_device_update_description (NMDevice *device)
 {
 	NMDevicePrivate *priv;
 	const char *subsys[3] = { "net", "tty", NULL };
@@ -1318,7 +1418,7 @@ nm_device_get_product (NMDevice *device)
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
 	if (!priv->product)
-		nm_device_update_description (device);
+		_device_update_description (device);
 	return priv->product;
 }
 
@@ -1340,7 +1440,7 @@ nm_device_get_vendor (NMDevice *device)
 
 	priv = NM_DEVICE_GET_PRIVATE (device);
 	if (!priv->vendor)
-		nm_device_update_description (device);
+		_device_update_description (device);
 	return priv->vendor;
 }