diff options
Diffstat (limited to 'libnm-glib/nm-device.c')
| -rw-r--r-- | libnm-glib/nm-device.c | 786 |
1 files changed, 320 insertions, 466 deletions
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 1f9f3671..96a037d5 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2011 Red Hat, Inc. + * Copyright (C) 2007 - 2012 Red Hat, Inc. */ #include <string.h> @@ -30,16 +30,32 @@ #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-vlan.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-object-private.h" #include "nm-object-cache.h" -#include "nm-marshal.h" +#include "nm-glib-marshal.h" +#include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" -#include "nm-device-bindings.h" +static GType _nm_device_type_for_path (DBusGConnection *connection, + const char *path); +static void _nm_device_type_for_path_async (DBusGConnection *connection, + const char *path, + NMObjectTypeCallbackFunc callback, + gpointer user_data); -G_DEFINE_TYPE (NMDevice, nm_device, NM_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, + _nm_object_register_type_func (g_define_type_id, _nm_device_type_for_path, + _nm_device_type_for_path_async); + ) + +#define DBUS_G_TYPE_UINT_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID)) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) @@ -56,17 +72,13 @@ typedef struct { gboolean managed; gboolean firmware_missing; NMIP4Config *ip4_config; - gboolean got_ip4_config; NMDHCP4Config *dhcp4_config; - gboolean got_dhcp4_config; NMIP6Config *ip6_config; - gboolean got_ip6_config; NMDHCP6Config *dhcp6_config; - gboolean got_dhcp6_config; NMDeviceState state; + NMDeviceStateReason reason; NMActiveConnection *active_connection; - gboolean got_active_connection; GUdevClient *client; char *product; @@ -85,6 +97,7 @@ enum { PROP_DHCP4_CONFIG, PROP_IP6_CONFIG, PROP_STATE, + PROP_STATE_REASON, PROP_PRODUCT, PROP_VENDOR, PROP_DHCP6_CONFIG, @@ -110,211 +123,56 @@ nm_device_init (NMDevice *device) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); priv->state = NM_DEVICE_STATE_UNKNOWN; + priv->reason = NM_DEVICE_STATE_REASON_NONE; } static gboolean -demarshal_ip4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - const char *path; - NMIP4Config *config = NULL; - DBusGConnection *connection; - - if (value) { - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - return FALSE; - - 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); - config = NM_IP4_CONFIG (nm_ip4_config_new (connection, path)); - } - } - } - - priv->got_ip4_config = TRUE; - - if (priv->ip4_config) { - g_object_unref (priv->ip4_config); - priv->ip4_config = NULL; - } - - if (config) - priv->ip4_config = config; - - _nm_object_queue_notify (object, NM_DEVICE_IP4_CONFIG); - return TRUE; -} - -static gboolean -demarshal_dhcp4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - const char *path; - NMDHCP4Config *config = NULL; - DBusGConnection *connection; - - if (value) { - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - return FALSE; - - 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); - config = NM_DHCP4_CONFIG (nm_dhcp4_config_new (connection, path)); - } - } - } - - priv->got_dhcp4_config = TRUE; - - if (priv->dhcp4_config) { - g_object_unref (priv->dhcp4_config); - priv->dhcp4_config = NULL; - } - - if (config) - priv->dhcp4_config = config; - - _nm_object_queue_notify (object, NM_DEVICE_DHCP4_CONFIG); - return TRUE; -} - -static gboolean -demarshal_ip6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - const char *path; - NMIP6Config *config = NULL; - DBusGConnection *connection; - - if (value) { - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - return FALSE; - - 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); - config = NM_IP6_CONFIG (nm_ip6_config_new (connection, path)); - } - } - } - - priv->got_ip6_config = TRUE; - - if (priv->ip6_config) { - g_object_unref (priv->ip6_config); - priv->ip6_config = NULL; - } - - if (config) - priv->ip6_config = config; - - _nm_object_queue_notify (object, NM_DEVICE_IP6_CONFIG); - return TRUE; -} - -static gboolean -demarshal_dhcp6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +demarshal_state_reason (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - const char *path; - NMDHCP6Config *config = NULL; - DBusGConnection *connection; - - if (value) { - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - return FALSE; - - 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); - config = NM_DHCP6_CONFIG (nm_dhcp6_config_new (connection, path)); - } - } - } - priv->got_dhcp6_config = TRUE; - - if (priv->dhcp6_config) { - g_object_unref (priv->dhcp6_config); - priv->dhcp6_config = NULL; - } - - if (config) - priv->dhcp6_config = config; - - _nm_object_queue_notify (object, NM_DEVICE_DHCP6_CONFIG); - 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)) + if (!G_VALUE_HOLDS (value, DBUS_G_TYPE_UINT_STRUCT)) return FALSE; - priv->got_active_connection = TRUE; + dbus_g_type_struct_get (value, + 0, &priv->state, + 1, &priv->reason, + G_MAXUINT); - 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); + _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON); return TRUE; } static void -register_for_property_changed (NMDevice *device) +register_properties (NMDevice *device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const NMPropertiesChangedInfo property_changed_info[] = { - { NM_DEVICE_UDI, _nm_object_demarshal_generic, &priv->udi }, - { NM_DEVICE_INTERFACE, _nm_object_demarshal_generic, &priv->iface }, - { NM_DEVICE_IP_INTERFACE, _nm_object_demarshal_generic, &priv->ip_iface }, - { NM_DEVICE_DRIVER, _nm_object_demarshal_generic, &priv->driver }, - { NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities }, - { NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed }, - { NM_DEVICE_FIRMWARE_MISSING, _nm_object_demarshal_generic, &priv->firmware_missing }, - { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, - { 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 }, + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_UDI, &priv->udi }, + { NM_DEVICE_INTERFACE, &priv->iface }, + { NM_DEVICE_IP_INTERFACE, &priv->ip_iface }, + { NM_DEVICE_DRIVER, &priv->driver }, + { NM_DEVICE_CAPABILITIES, &priv->capabilities }, + { NM_DEVICE_MANAGED, &priv->managed }, + { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing }, + { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG }, + { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG }, + { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG }, + { NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG }, + { NM_DEVICE_STATE, &priv->state }, + { NM_DEVICE_STATE_REASON, &priv->state, demarshal_state_reason }, + { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION }, + + /* Properties that exist in D-Bus but that we don't track */ + { "ip4-address", NULL }, + { "device-type", NULL }, + { NULL }, }; - _nm_object_handle_properties_changed (NM_OBJECT (device), - priv->proxy, - property_changed_info); + _nm_object_register_properties (NM_OBJECT (device), + priv->proxy, + property_info); } static void @@ -325,39 +183,68 @@ device_state_changed (DBusGProxy *proxy, 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; + if (old_state != new_state) { + /* Update state here since the PropertyChanged signal for state + * might come in a bit later, but a client might ask for the + * state via nm_device_get_state() as a result of this signal. + * When the PC signal does come in that will trigger the glib + * property notify signal so we don't need to do that here. + */ + NM_DEVICE_GET_PRIVATE (self)->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, - GObjectConstructParam *construct_params) +static GType +_nm_device_gtype_from_dtype (NMDeviceType dtype) +{ + switch (dtype) { + 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_OLPC_MESH: + return NM_TYPE_DEVICE_OLPC_MESH; + case NM_DEVICE_TYPE_WIMAX: + return NM_TYPE_DEVICE_WIMAX; + case NM_DEVICE_TYPE_INFINIBAND: + return NM_TYPE_DEVICE_INFINIBAND; + case NM_DEVICE_TYPE_BOND: + return NM_TYPE_DEVICE_BOND; + case NM_DEVICE_TYPE_VLAN: + return NM_TYPE_DEVICE_VLAN; + default: + g_warning ("Unknown device type %d", dtype); + return G_TYPE_INVALID; + } +} + +static void +constructed (GObject *object) { - NMObject *object; NMDevicePrivate *priv; - object = (NMObject *) G_OBJECT_CLASS (nm_device_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; + G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); priv = NM_DEVICE_GET_PRIVATE (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)); - priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), NM_DBUS_SERVICE, - nm_object_get_path (object), + nm_object_get_path (NM_OBJECT (object)), NM_DBUS_INTERFACE_DEVICE); - register_for_property_changed (NM_DEVICE (object)); + register_properties (NM_DEVICE (object)); - dbus_g_object_register_marshaller (_nm_marshal_VOID__UINT_UINT_UINT, + dbus_g_object_register_marshaller (_nm_glib_marshal_VOID__UINT_UINT_UINT, G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID); @@ -371,8 +258,6 @@ constructor (GType type, G_CALLBACK (device_state_changed), NM_DEVICE (object), NULL); - - return G_OBJECT (object); } static void @@ -426,6 +311,7 @@ get_property (GObject *object, GParamSpec *pspec) { NMDevice *device = NM_DEVICE (object); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); switch (prop_id) { case PROP_DEVICE_TYPE: @@ -467,6 +353,14 @@ get_property (GObject *object, case PROP_STATE: g_value_set_uint (value, nm_device_get_state (device)); break; + case PROP_STATE_REASON: + g_value_set_boxed (value, + dbus_g_type_specialized_construct (DBUS_G_TYPE_UINT_STRUCT)); + dbus_g_type_struct_set (value, + 0, priv->state, + 1, priv->reason, + G_MAXUINT); + break; case PROP_ACTIVE_CONNECTION: g_value_set_object (value, nm_device_get_active_connection (device)); break; @@ -510,7 +404,7 @@ nm_device_class_init (NMDeviceClass *device_class) g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); /* virtual methods */ - object_class->constructor = constructor; + object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; @@ -556,7 +450,7 @@ nm_device_class_init (NMDeviceClass *device_class) "Device Type", "Numeric device type (ie ethernet, wifi, etc)", NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READABLE)); /** * NMDevice:udi: * @@ -694,6 +588,19 @@ nm_device_class_init (NMDeviceClass *device_class) G_PARAM_READABLE)); /** + * NMDevice:state-reason: + * + * The state and reason of the device. + **/ + g_object_class_install_property + (object_class, PROP_STATE_REASON, + g_param_spec_boxed (NM_DEVICE_STATE_REASON, + "StateReason", + "StateReason", + DBUS_G_TYPE_UINT_STRUCT, + G_PARAM_READABLE)); + + /** * NMDevice:active-connection: * * The #NMActiveConnection object that "owns" this device during activation. @@ -747,40 +654,50 @@ nm_device_class_init (NMDeviceClass *device_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMDeviceClass, state_changed), NULL, NULL, - _nm_marshal_VOID__UINT_UINT_UINT, + _nm_glib_marshal_VOID__UINT_UINT_UINT, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); } /** - * nm_device_new: - * @connection: the #DBusGConnection - * @path: the DBus object path of the device - * - * Creates a new #NMDevice. + * _nm_device_set_device_type: + * @device: the device + * @dtype: the NM device type * - * Returns: (transfer full): a new device + * Sets the NM device type if it wasn't set during construction. INTERNAL + * ONLY METHOD. **/ -GObject * -nm_device_new (DBusGConnection *connection, const char *path) +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_type_for_path (DBusGConnection *connection, + const char *path) { DBusGProxy *proxy; GError *err = NULL; GValue value = {0,}; - GType dtype = 0; - NMDevice *device = NULL; NMDeviceType nm_dtype; - g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (path != NULL, NULL); - proxy = dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, "org.freedesktop.DBus.Properties"); if (!proxy) { g_warning ("%s: couldn't create D-Bus object proxy.", __func__); - return NULL; + return G_TYPE_INVALID; } if (!dbus_g_proxy_call (proxy, @@ -789,44 +706,100 @@ nm_device_new (DBusGConnection *connection, const char *path) G_TYPE_STRING, "DeviceType", G_TYPE_INVALID, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { + g_object_unref (proxy); g_warning ("Error in get_property: %s\n", err->message); g_error_free (err); - goto out; } + g_object_unref (proxy); nm_dtype = g_value_get_uint (&value); - switch (nm_dtype) { - case NM_DEVICE_TYPE_ETHERNET: - dtype = NM_TYPE_DEVICE_ETHERNET; - break; - case NM_DEVICE_TYPE_WIFI: - dtype = NM_TYPE_DEVICE_WIFI; - break; - case NM_DEVICE_TYPE_MODEM: - dtype = NM_TYPE_DEVICE_MODEM; - break; - case NM_DEVICE_TYPE_BT: - dtype = NM_TYPE_DEVICE_BT; - break; - case NM_DEVICE_TYPE_WIMAX: - dtype = NM_TYPE_DEVICE_WIMAX; - break; - default: - g_warning ("Unknown device type %d", g_value_get_uint (&value)); - break; - } + return _nm_device_gtype_from_dtype (nm_dtype); +} - if (dtype) { - device = (NMDevice *) g_object_new (dtype, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, path, - NM_DEVICE_DEVICE_TYPE, nm_dtype, - NULL); +/** + * nm_device_new: + * @connection: the #DBusGConnection + * @path: the DBus object path of the device + * + * Creates a new #NMDevice. + * + * Returns: (transfer full): a new device + **/ +GObject * +nm_device_new (DBusGConnection *connection, const char *path) +{ + GType dtype; + NMDevice *device = NULL; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + dtype = _nm_device_type_for_path (connection, path); + if (dtype == G_TYPE_INVALID) + return NULL; + + device = (NMDevice *) g_object_new (dtype, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); + _nm_object_ensure_inited (NM_OBJECT (device)); + return G_OBJECT (device); +} + +typedef struct { + DBusGConnection *connection; + NMObjectTypeCallbackFunc callback; + gpointer user_data; +} NMDeviceAsyncData; + +static void +async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) +{ + NMDeviceAsyncData *async_data = user_data; + GValue value = G_VALUE_INIT; + const char *path = dbus_g_proxy_get_path (proxy); + GError *error = NULL; + GType type; + + if (dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_VALUE, &value, + G_TYPE_INVALID)) { + NMDeviceType dtype; + + dtype = g_value_get_uint (&value); + type = _nm_device_gtype_from_dtype (dtype); + } else { + g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message); + g_error_free (error); + type = G_TYPE_INVALID; } -out: + async_data->callback (type, async_data->user_data); g_object_unref (proxy); - return G_OBJECT (device); + g_slice_free (NMDeviceAsyncData, async_data); +} + +static void +_nm_device_type_for_path_async (DBusGConnection *connection, + const char *path, + NMObjectTypeCallbackFunc callback, + gpointer user_data) +{ + NMDeviceAsyncData *async_data; + DBusGProxy *proxy; + + async_data = g_slice_new (NMDeviceAsyncData); + async_data->connection = connection; + async_data->callback = callback; + async_data->user_data = user_data; + + proxy = dbus_g_proxy_new_for_name (connection, NM_DBUS_SERVICE, path, + "org.freedesktop.DBus.Properties"); + dbus_g_proxy_begin_call (proxy, "Get", + async_got_type, async_data, NULL, + G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, + G_TYPE_STRING, "DeviceType", + G_TYPE_INVALID); } /** @@ -841,19 +814,10 @@ out: const char * nm_device_get_iface (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->iface) { - priv->iface = _nm_object_get_string_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Interface", - NULL); - } - - return priv->iface; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->iface; } /** @@ -869,19 +833,10 @@ nm_device_get_iface (NMDevice *device) const char * nm_device_get_ip_iface (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->ip_iface) { - priv->ip_iface = _nm_object_get_string_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "IpInterface", - NULL); - } - - return priv->ip_iface; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->ip_iface; } /** @@ -913,19 +868,10 @@ nm_device_get_device_type (NMDevice *self) const char * nm_device_get_udi (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->udi) { - priv->udi = _nm_object_get_string_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Udi", - NULL); - } - - return priv->udi; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->udi; } /** @@ -940,19 +886,10 @@ nm_device_get_udi (NMDevice *device) const char * nm_device_get_driver (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->driver) { - priv->driver = _nm_object_get_string_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Driver", - NULL); - } - - return priv->driver; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->driver; } /** @@ -966,19 +903,10 @@ nm_device_get_driver (NMDevice *device) NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->capabilities) { - priv->capabilities = _nm_object_get_uint_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Capabilities", - NULL); - } - - return priv->capabilities; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->capabilities; } /** @@ -992,19 +920,10 @@ nm_device_get_capabilities (NMDevice *device) gboolean nm_device_get_managed (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->managed) { - priv->managed = _nm_object_get_boolean_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Managed", - NULL); - } - - return priv->managed; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->managed; } /** @@ -1020,19 +939,10 @@ nm_device_get_managed (NMDevice *device) gboolean nm_device_get_firmware_missing (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->firmware_missing) { - priv->firmware_missing = _nm_object_get_boolean_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "FirmwareMissing", - NULL); - } - - return priv->firmware_missing; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->firmware_missing; } /** @@ -1046,30 +956,10 @@ nm_device_get_firmware_missing (NMDevice *device) NMIP4Config * 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->got_ip4_config == TRUE) - return priv->ip4_config; - - 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; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->ip4_config; } /** @@ -1084,30 +974,10 @@ nm_device_get_ip4_config (NMDevice *device) NMDHCP4Config * 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->got_dhcp4_config == TRUE) - return priv->dhcp4_config; - - 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; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config; } /** @@ -1121,30 +991,10 @@ nm_device_get_dhcp4_config (NMDevice *device) NMIP6Config * 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->got_ip6_config == TRUE) - return priv->ip6_config; - - 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; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->ip6_config; } /** @@ -1159,30 +1009,10 @@ nm_device_get_ip6_config (NMDevice *device) NMDHCP6Config * 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->got_dhcp6_config == TRUE) - return priv->dhcp6_config; - - 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; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config; } /** @@ -1196,19 +1026,31 @@ nm_device_get_dhcp6_config (NMDevice *device) NMDeviceState nm_device_get_state (NMDevice *device) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); - priv = NM_DEVICE_GET_PRIVATE (device); - if (priv->state == NM_DEVICE_STATE_UNKNOWN) { - priv->state = _nm_object_get_uint_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "State", - NULL); - } + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->state; +} - return priv->state; +/** + * nm_device_get_state_reason: + * @device: a #NMDevice + * @reason: (out) (allow-none): location to store reason (#NMDeviceStateReason), or NULL + * + * Gets the current #NMDevice state (return value) and the reason for entering + * the state (@reason argument). + * + * Returns: the current device state + **/ +NMDeviceState +nm_device_get_state_reason (NMDevice *device, NMDeviceStateReason *reason) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); + + _nm_object_ensure_inited (NM_OBJECT (device)); + if (reason) + *reason = NM_DEVICE_GET_PRIVATE (device)->reason; + return NM_DEVICE_GET_PRIVATE (device)->state; } /** @@ -1223,30 +1065,10 @@ nm_device_get_state (NMDevice *device) 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; + _nm_object_ensure_inited (NM_OBJECT (device)); + return NM_DEVICE_GET_PRIVATE (device)->active_connection; } /* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */ @@ -1453,11 +1275,14 @@ typedef struct { static void deactivate_cb (DBusGProxy *proxy, - GError *error, + DBusGProxyCall *call, gpointer user_data) { DeactivateInfo *info = user_data; + GError *error = NULL; + dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_INVALID); if (info->fn) info->fn (info->device, error, info->user_data); else if (error) { @@ -1467,6 +1292,7 @@ deactivate_cb (DBusGProxy *proxy, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } + g_clear_error (&error); g_object_unref (info->device); g_slice_free (DeactivateInfo, info); @@ -1497,9 +1323,9 @@ nm_device_disconnect (NMDevice *device, info->user_data = user_data; info->device = g_object_ref (device); - org_freedesktop_NetworkManager_Device_disconnect_async (NM_DEVICE_GET_PRIVATE (device)->proxy, - deactivate_cb, - info); + dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Disconnect", + deactivate_cb, info, NULL, + G_TYPE_INVALID); } /** @@ -1521,8 +1347,35 @@ nm_device_disconnect (NMDevice *device, gboolean nm_device_connection_valid (NMDevice *device, NMConnection *connection) { - if (NM_DEVICE_GET_CLASS (device)->connection_valid) - return NM_DEVICE_GET_CLASS (device)->connection_valid (device, connection); + return nm_device_connection_compatible (device, connection, NULL); +} + +/** + * nm_device_connection_compatible: + * @device: an #NMDevice to validate @connection against + * @connection: an #NMConnection to validate against @device + * @error: return location for a #GError, or %NULL + * + * Validates a given connection for a given #NMDevice object and returns + * whether the connection may be activated with the device. For example if + * @device is a WiFi device that supports only WEP encryption, the connection + * will only be valid if it is a WiFi connection which describes a WEP or open + * network, and will not be valid if it describes a WPA network, or if it is + * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the + * device. + * + * This function does the same as nm_device_connection_valid(), i.e. checking + * compatibility of the given device and connection. But, in addition, it sets + * GError when FALSE is returned. + * + * Returns: %TRUE if the connection may be activated with this device, %FALSE + * if is incompatible with the device's capabilities and characteristics. + **/ +gboolean +nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + if (NM_DEVICE_GET_CLASS (device)->connection_compatible) + return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error); return FALSE; } @@ -1537,7 +1390,8 @@ nm_device_connection_valid (NMDevice *device, NMConnection *connection) * contain any WiFi connections in @connections that allow connection to * unencrypted or WEP-enabled SSIDs. The returned list will not contain * Ethernet, Bluetooth, WiFi WPA connections, or any other connection that is - * incompatible with the device. + * incompatible with the device. To get the full list of connections see + * nm_remote_settings_list_connections(). * * Returns: (transfer container) (element-type NetworkManager.Connection): a * list of #NMConnection objects that could be activated with the given @device. |