summary refs log tree commit diff
path: root/libnm/nm-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm/nm-device.c')
-rw-r--r--libnm/nm-device.c231
1 files changed, 39 insertions, 192 deletions
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index b3dc01b2..02b5cad5 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -28,29 +28,12 @@
 
 #include "nm-dbus-interface.h"
 #include "nm-active-connection.h"
-#include "nm-device-ethernet.h"
-#include "nm-device-adsl.h"
-#include "nm-device-wifi.h"
-#include "nm-device-modem.h"
 #include "nm-device-bt.h"
-#include "nm-device-olpc-mesh.h"
-#include "nm-device-wimax.h"
-#include "nm-device-infiniband.h"
-#include "nm-device-bond.h"
-#include "nm-device-team.h"
-#include "nm-device-bridge.h"
-#include "nm-device-vlan.h"
-#include "nm-device-vxlan.h"
-#include "nm-device-generic.h"
-#include "nm-device-ip-tunnel.h"
-#include "nm-device-macvlan.h"
-#include "nm-device-private.h"
 #include "nm-dhcp4-config.h"
 #include "nm-dhcp6-config.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
 #include "nm-object-private.h"
-#include "nm-object-cache.h"
 #include "nm-remote-connection.h"
 #include "nm-core-internal.h"
 #include "nm-utils.h"
@@ -58,18 +41,12 @@
 #include "nm-device-tun.h"
 #include "nm-setting-connection.h"
 
-#include "nmdbus-device.h"
+#include "introspection/org.freedesktop.NetworkManager.Device.h"
 
-static GType _nm_device_decide_type (GVariant *value);
 static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error);
 static NMLldpNeighbor *nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor);
 
-G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT,
-                         _nm_object_register_type_func (g_define_type_id,
-                                                        _nm_device_decide_type,
-                                                        NM_DBUS_INTERFACE_DEVICE,
-                                                        "DeviceType");
-                         )
+G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_OBJECT);
 
 #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
 
@@ -213,11 +190,7 @@ demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value,
 }
 
 static void
-device_state_changed (NMDBusDevice *proxy,
-                      guint new_state,
-                      guint old_state,
-                      guint reason,
-                      gpointer user_data);
+device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
 
 static void
 init_dbus (NMObject *object)
@@ -226,6 +199,7 @@ init_dbus (NMObject *object)
 	const NMPropertiesInfo property_info[] = {
 		{ NM_DEVICE_UDI,               &priv->udi },
 		{ NM_DEVICE_INTERFACE,         &priv->iface },
+		{ NM_DEVICE_DEVICE_TYPE,       &priv->device_type },
 		{ NM_DEVICE_IP_INTERFACE,      &priv->ip_iface },
 		{ NM_DEVICE_DRIVER,            &priv->driver },
 		{ NM_DEVICE_DRIVER_VERSION,    &priv->driver_version },
@@ -251,7 +225,6 @@ init_dbus (NMObject *object)
 
 		/* Properties that exist in D-Bus but that we don't track */
 		{ "ip4-address", NULL },
-		{ "device-type", NULL },
 
 		{ NULL },
 	};
@@ -263,136 +236,50 @@ init_dbus (NMObject *object)
 	                                NM_DBUS_INTERFACE_DEVICE,
 	                                property_info);
 
-	g_signal_connect (priv->proxy, "state-changed",
-	                  G_CALLBACK (device_state_changed), object);
-}
-
-typedef struct {
-	NMDeviceState old_state;
-	NMDeviceState new_state;
-	NMDeviceStateReason reason;
-} StateChangeData;
-
-static void
-device_state_change_reloaded (GObject *object,
-                              GAsyncResult *result,
-                              gpointer user_data)
-{
-	NMDevice *self = NM_DEVICE (object);
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-	StateChangeData *data = user_data;
-	NMDeviceState old_state = data->old_state;
-	NMDeviceState new_state = data->new_state;
-	NMDeviceStateReason reason = data->reason;
-
-	g_slice_free (StateChangeData, data);
-
-	_nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
-
-	/* If the device changes state several times in rapid succession, then we'll
-	 * queue several reload_properties() calls, and there's no guarantee that
-	 * they'll finish in the right order. In that case, only emit the signal
-	 * for the last one.
-	 */
-	if (priv->last_seen_state != new_state)
-		return;
-
-	/* Ensure that nm_device_get_state() will return the right value even if
-	 * we haven't processed the corresponding PropertiesChanged yet.
-	 */
-	priv->state = new_state;
-
-	g_signal_emit (self, signals[STATE_CHANGED], 0,
-	               new_state, old_state, reason);
+	g_signal_connect (priv->proxy, "notify::state-reason",
+	                  G_CALLBACK (device_state_reason_changed), object);
 }
 
 static void
-device_state_changed (NMDBusDevice *proxy,
-                      guint new_state,
-                      guint old_state,
-                      guint reason,
-                      gpointer user_data)
+device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
 {
 	NMDevice *self = NM_DEVICE (user_data);
 	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
-	StateChangeData *data;
-
-	if (old_state == new_state)
-		return;
-
-	/* Our object-valued properties (eg, ip4_config) will still
-	 * have their old values at this point, because NMObject is
-	 * in the process of asynchronously reading the new values.
-	 * Wait for that to finish before emitting the signal.
-	 */
-	priv->last_seen_state = new_state;
 
-	data = g_slice_new (StateChangeData);
-	data->old_state = old_state;
-	data->new_state = new_state;
-	data->reason = reason;
-	_nm_object_reload_properties_async (NM_OBJECT (user_data),
-	                                    NULL,
-	                                    device_state_change_reloaded,
-	                                    data);
+	g_signal_emit (self, signals[STATE_CHANGED], 0,
+	               priv->state, priv->last_seen_state, priv->reason);
+	priv->last_seen_state = priv->state;
 }
 
-static GType
-_nm_device_gtype_from_dtype (NMDeviceType dtype)
+static NMDeviceType
+coerce_type (NMDeviceType type)
 {
-	switch (dtype) {
-	case NM_DEVICE_TYPE_VETH:
+	switch (type) {
 	case NM_DEVICE_TYPE_ETHERNET:
-		return NM_TYPE_DEVICE_ETHERNET;
 	case NM_DEVICE_TYPE_WIFI:
-		return NM_TYPE_DEVICE_WIFI;
-	case NM_DEVICE_TYPE_MODEM:
-		return NM_TYPE_DEVICE_MODEM;
 	case NM_DEVICE_TYPE_BT:
-		return NM_TYPE_DEVICE_BT;
-	case NM_DEVICE_TYPE_ADSL:
-		return NM_TYPE_DEVICE_ADSL;
 	case NM_DEVICE_TYPE_OLPC_MESH:
-		return NM_TYPE_DEVICE_OLPC_MESH;
 	case NM_DEVICE_TYPE_WIMAX:
-		return NM_TYPE_DEVICE_WIMAX;
+	case NM_DEVICE_TYPE_MODEM:
 	case NM_DEVICE_TYPE_INFINIBAND:
-		return NM_TYPE_DEVICE_INFINIBAND;
 	case NM_DEVICE_TYPE_BOND:
-		return NM_TYPE_DEVICE_BOND;
 	case NM_DEVICE_TYPE_TEAM:
-		return NM_TYPE_DEVICE_TEAM;
 	case NM_DEVICE_TYPE_BRIDGE:
-		return NM_TYPE_DEVICE_BRIDGE;
 	case NM_DEVICE_TYPE_VLAN:
-		return NM_TYPE_DEVICE_VLAN;
-	case NM_DEVICE_TYPE_GENERIC:
-		return NM_TYPE_DEVICE_GENERIC;
-	case NM_DEVICE_TYPE_TUN:
-		return NM_TYPE_DEVICE_TUN;
-	case NM_DEVICE_TYPE_IP_TUNNEL:
-		return NM_TYPE_DEVICE_IP_TUNNEL;
+	case NM_DEVICE_TYPE_ADSL:
+	case NM_DEVICE_TYPE_MACSEC:
 	case NM_DEVICE_TYPE_MACVLAN:
-		return NM_TYPE_DEVICE_MACVLAN;
 	case NM_DEVICE_TYPE_VXLAN:
-		return NM_TYPE_DEVICE_VXLAN;
-	default:
-		g_warning ("Unknown device type %d", dtype);
-		return G_TYPE_INVALID;
+	case NM_DEVICE_TYPE_IP_TUNNEL:
+	case NM_DEVICE_TYPE_TUN:
+	case NM_DEVICE_TYPE_VETH:
+	case NM_DEVICE_TYPE_GENERIC:
+	case NM_DEVICE_TYPE_UNUSED1:
+	case NM_DEVICE_TYPE_UNUSED2:
+	case NM_DEVICE_TYPE_UNKNOWN:
+		return type;
 	}
-}
-
-static void
-constructed (GObject *object)
-{
-	NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
-
-	G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
-
-	/* Catch failure of subclasses to call _nm_device_set_device_type() */
-	g_warn_if_fail (priv->device_type != NM_DEVICE_TYPE_UNKNOWN);
-	/* Catch a subclass setting the wrong type */
-	g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type));
+	return NM_DEVICE_TYPE_UNKNOWN;
 }
 
 static void
@@ -410,6 +297,8 @@ dispose (GObject *object)
 	g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
 	g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
 
+	g_clear_object (&priv->proxy);
+
 	G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
 }
 
@@ -446,7 +335,7 @@ get_property (GObject *object,
 
 	switch (prop_id) {
 	case PROP_DEVICE_TYPE:
-		g_value_set_enum (value, nm_device_get_device_type (device));
+		g_value_set_enum (value, coerce_type (nm_device_get_device_type (device)));
 		break;
 	case PROP_UDI:
 		g_value_set_string (value, nm_device_get_udi (device));
@@ -543,10 +432,6 @@ set_property (GObject *object,
 	gboolean b;
 
 	switch (prop_id) {
-	case PROP_DEVICE_TYPE:
-		/* Construct only */
-		priv->device_type = g_value_get_enum (value);
-		break;
 	case PROP_MANAGED:
 		b = g_value_get_boolean (value);
 		if (priv->managed != b)
@@ -571,11 +456,7 @@ nm_device_class_init (NMDeviceClass *device_class)
 
 	g_type_class_add_private (device_class, sizeof (NMDevicePrivate));
 
-	_nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE);
-	_nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE, NMDBUS_TYPE_DEVICE_PROXY);
-
 	/* virtual methods */
-	object_class->constructed = constructed;
 	object_class->get_property = get_property;
 	object_class->set_property = set_property;
 	object_class->dispose = dispose;
@@ -954,35 +835,6 @@ nm_device_class_init (NMDeviceClass *device_class)
 }
 
 /**
- * _nm_device_set_device_type:
- * @device: the device
- * @dtype: the NM device type
- *
- * Sets the NM device type if it wasn't set during construction.  INTERNAL
- * ONLY METHOD.
- **/
-void
-_nm_device_set_device_type (NMDevice *device, NMDeviceType dtype)
-{
-	NMDevicePrivate *priv;
-
-	g_return_if_fail (device != NULL);
-	g_return_if_fail (dtype != NM_DEVICE_TYPE_UNKNOWN);
-
-	priv = NM_DEVICE_GET_PRIVATE (device);
-	if (priv->device_type == NM_DEVICE_TYPE_UNKNOWN)
-		priv->device_type = dtype;
-	else
-		g_warn_if_fail (dtype == priv->device_type);
-}
-
-static GType
-_nm_device_decide_type (GVariant *value)
-{
-	return _nm_device_gtype_from_dtype (g_variant_get_uint32 (value));
-}
-
-/**
  * nm_device_get_iface:
  * @device: a #NMDevice
  *
@@ -996,7 +848,7 @@ nm_device_get_iface (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->iface;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->iface);
 }
 
 /**
@@ -1014,7 +866,7 @@ nm_device_get_ip_iface (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->ip_iface;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->ip_iface);
 }
 
 /**
@@ -1048,7 +900,7 @@ nm_device_get_udi (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->udi;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->udi);
 }
 
 /**
@@ -1065,7 +917,7 @@ nm_device_get_driver (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->driver;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->driver);
 }
 
 /**
@@ -1082,7 +934,7 @@ nm_device_get_driver_version (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->driver_version;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->driver_version);
 }
 
 /**
@@ -1099,7 +951,7 @@ nm_device_get_firmware_version (NMDevice *device)
 {
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	return NM_DEVICE_GET_PRIVATE (device)->firmware_version;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->firmware_version);
 }
 
 /**
@@ -1124,7 +976,7 @@ nm_device_get_type_description (NMDevice *device)
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
 	if (priv->type_description)
-		return priv->type_description;
+		return nm_str_not_empty (priv->type_description);
 
 	if (NM_DEVICE_GET_CLASS (device)->get_type_description) {
 		desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device);
@@ -1137,7 +989,7 @@ nm_device_get_type_description (NMDevice *device)
 		typename += 8;
 	priv->type_description = g_ascii_strdown (typename, -1);
 
-	return priv->type_description;
+	return nm_str_not_empty (priv->type_description);
 }
 
 /**
@@ -1840,6 +1692,8 @@ get_type_name (NMDevice *device)
 		return _("Tun");
 	case NM_DEVICE_TYPE_VETH:
 		return _("Veth");
+	case NM_DEVICE_TYPE_MACSEC:
+		return _("MACsec");
 	case NM_DEVICE_TYPE_GENERIC:
 	case NM_DEVICE_TYPE_UNUSED1:
 	case NM_DEVICE_TYPE_UNUSED2:
@@ -2084,16 +1938,9 @@ done:
 const char *
 nm_device_get_physical_port_id (NMDevice *device)
 {
-	NMDevicePrivate *priv;
-
 	g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
 
-	priv = NM_DEVICE_GET_PRIVATE (device);
-
-	if (priv->physical_port_id && *priv->physical_port_id)
-		return priv->physical_port_id;
-	else
-		return NULL;
+	return nm_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->physical_port_id);
 }
 
 /**