diff options
| author | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-07-31 10:51:42 +0200 |
| commit | 2e5fa45ddfbb5cffa1e78221f1cea706e2f298af (patch) | |
| tree | 86f69d36c56de3074280456eddc854a780b8e04b /libnm-glib/nm-device.c | |
| parent | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (diff) | |
New upstream version 1.19.90 upstream/1.19.90
Diffstat (limited to 'libnm-glib/nm-device.c')
| -rw-r--r-- | libnm-glib/nm-device.c | 2375 |
1 files changed, 0 insertions, 2375 deletions
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c deleted file mode 100644 index e9b3b30f..00000000 --- a/libnm-glib/nm-device.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2007 - 2008 Novell, Inc. - * Copyright 2007 - 2012 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include <string.h> -#include <libudev.h> - -#include "NetworkManager.h" - -#include "nm-udev-aux/nm-udev-utils.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-generic.h" -#include "nm-device.h" -#include "nm-device-private.h" -#include "nm-object-private.h" -#include "nm-object-cache.h" -#include "nm-remote-connection.h" -#include "nm-types.h" -#include "nm-dbus-glib-types.h" -#include "nm-utils.h" -#include "nm-dbus-helpers-private.h" - -static GType _nm_device_gtype_for_path (DBusGConnection *connection, - const char *path); -static void _nm_device_gtype_for_path_async (DBusGConnection *connection, - const char *path, - NMObjectTypeCallbackFunc callback, - gpointer user_data); -gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); - -G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, - _nm_object_register_type_func (g_define_type_id, _nm_device_gtype_for_path, - _nm_device_gtype_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)) - -typedef struct { - DBusGProxy *proxy; - - char *iface; - char *ip_iface; - NMDeviceType device_type; - char *udi; - char *driver; - char *driver_version; - char *firmware_version; - char *type_description; - NMDeviceCapabilities capabilities; - gboolean real; - gboolean managed; - gboolean firmware_missing; - gboolean autoconnect; - NMIP4Config *ip4_config; - NMDHCP4Config *dhcp4_config; - NMIP6Config *ip6_config; - NMDHCP6Config *dhcp6_config; - NMDeviceState state; - NMDeviceState last_seen_state; - NMDeviceStateReason reason; - - NMActiveConnection *active_connection; - GPtrArray *available_connections; - - NMUdevClient *udev_client; - char *product, *short_product; - char *vendor, *short_vendor; - char *description, *bus_name; - - char *physical_port_id; - guint32 mtu; -} NMDevicePrivate; - -enum { - PROP_0, - PROP_INTERFACE, - PROP_UDI, - PROP_DRIVER, - PROP_DRIVER_VERSION, - PROP_FIRMWARE_VERSION, - PROP_CAPABILITIES, - PROP_REAL, - PROP_MANAGED, - PROP_AUTOCONNECT, - PROP_FIRMWARE_MISSING, - PROP_IP4_CONFIG, - PROP_DHCP4_CONFIG, - PROP_IP6_CONFIG, - PROP_STATE, - PROP_STATE_REASON, - PROP_PRODUCT, - PROP_VENDOR, - PROP_DHCP6_CONFIG, - PROP_IP_INTERFACE, - PROP_DEVICE_TYPE, - PROP_ACTIVE_CONNECTION, - PROP_AVAILABLE_CONNECTIONS, - PROP_PHYSICAL_PORT_ID, - PROP_MTU, - - LAST_PROP -}; - -enum { - STATE_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/** - * nm_device_error_quark: - * - * Registers an error quark for #NMDevice if necessary. - * - * Returns: the error quark used for #NMDevice errors. - * - * Since: 0.9.10 - **/ -GQuark -nm_device_error_quark (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) - quark = g_quark_from_static_string ("nm-device-error-quark"); - return quark; -} - -static void -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_state_reason (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - - if (!G_VALUE_HOLDS (value, DBUS_G_TYPE_UINT_STRUCT)) - return FALSE; - - dbus_g_type_struct_get (value, - 0, &priv->state, - 1, &priv->reason, - G_MAXUINT); - - _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON); - return TRUE; -} - -static void -register_properties (NMDevice *device) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - 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_DRIVER_VERSION, &priv->driver_version }, - { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version }, - { NM_DEVICE_CAPABILITIES, &priv->capabilities }, - { NM_DEVICE_REAL, &priv->real }, - { NM_DEVICE_MANAGED, &priv->managed }, - { NM_DEVICE_AUTOCONNECT, &priv->autoconnect }, - { 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 }, - { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION }, - { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id }, - { NM_DEVICE_MTU, &priv->mtu }, - - /* Properties that exist in D-Bus but that we don't track */ - { "ip4-address", NULL }, - { "device-type", NULL }, - - { NULL }, - }; - - _nm_object_register_properties (NM_OBJECT (device), - priv->proxy, - property_info); -} - -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); -} - -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 (old_state != new_state) { - StateChangeData *data; - - /* 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), - device_state_change_reloaded, - data); - } -} - -static GType -_nm_device_gtype_from_dtype (NMDeviceType dtype) -{ - switch (dtype) { - case NM_DEVICE_TYPE_VETH: - 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_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: - case NM_DEVICE_TYPE_TUN: - case NM_DEVICE_TYPE_IP_TUNNEL: - return NM_TYPE_DEVICE_GENERIC; - default: - /* Fall back to NMDeviceGeneric for unknown devices */ - return NM_TYPE_DEVICE_GENERIC; - } -} - -static void -constructed (GObject *object) -{ - NMDevicePrivate *priv; - - 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 = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE); - - register_properties (NM_DEVICE (object)); - - dbus_g_object_register_marshaller (g_cclosure_marshal_generic, - 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); -} - -static void -dispose (GObject *object) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - - g_clear_object (&priv->proxy); - g_clear_object (&priv->ip4_config); - g_clear_object (&priv->dhcp4_config); - g_clear_object (&priv->ip6_config); - g_clear_object (&priv->dhcp6_config); - g_clear_object (&priv->active_connection); - - priv->udev_client = nm_udev_client_unref (priv->udev_client); - - if (priv->available_connections) { - int i; - - for (i = 0; i < priv->available_connections->len; i++) - g_object_unref (priv->available_connections->pdata[i]); - g_ptr_array_free (priv->available_connections, TRUE); - priv->available_connections = NULL; - } - - G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); -} - -static void -finalize (GObject *object) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - - g_free (priv->iface); - g_free (priv->ip_iface); - g_free (priv->udi); - g_free (priv->driver); - g_free (priv->driver_version); - g_free (priv->firmware_version); - g_free (priv->product); - g_free (priv->short_product); - g_free (priv->vendor); - g_free (priv->short_vendor); - g_free (priv->description); - g_free (priv->bus_name); - g_free (priv->type_description); - g_free (priv->physical_port_id); - - G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); -} - -static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - NMDevice *device = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - _nm_object_ensure_inited (NM_OBJECT (object)); - - switch (prop_id) { - case PROP_DEVICE_TYPE: - g_value_set_uint (value, nm_device_get_device_type (device)); - break; - case PROP_UDI: - g_value_set_string (value, nm_device_get_udi (device)); - break; - case PROP_INTERFACE: - g_value_set_string (value, nm_device_get_iface (device)); - break; - case PROP_IP_INTERFACE: - g_value_set_string (value, nm_device_get_ip_iface (device)); - break; - case PROP_DRIVER: - g_value_set_string (value, nm_device_get_driver (device)); - break; - case PROP_DRIVER_VERSION: - g_value_set_string (value, nm_device_get_driver_version (device)); - break; - case PROP_FIRMWARE_VERSION: - g_value_set_string (value, nm_device_get_firmware_version (device)); - break; - case PROP_CAPABILITIES: - g_value_set_uint (value, nm_device_get_capabilities (device)); - break; - case PROP_REAL: - g_value_set_boolean (value, nm_device_is_real (device)); - break; - case PROP_MANAGED: - g_value_set_boolean (value, nm_device_get_managed (device)); - break; - case PROP_AUTOCONNECT: - g_value_set_boolean (value, nm_device_get_autoconnect (device)); - break; - case PROP_FIRMWARE_MISSING: - g_value_set_boolean (value, nm_device_get_firmware_missing (device)); - break; - case PROP_IP4_CONFIG: - g_value_set_object (value, nm_device_get_ip4_config (device)); - break; - case PROP_DHCP4_CONFIG: - g_value_set_object (value, nm_device_get_dhcp4_config (device)); - break; - case PROP_IP6_CONFIG: - g_value_set_object (value, nm_device_get_ip6_config (device)); - break; - case PROP_DHCP6_CONFIG: - g_value_set_object (value, nm_device_get_dhcp6_config (device)); - break; - 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; - case PROP_AVAILABLE_CONNECTIONS: - g_value_set_boxed (value, nm_device_get_available_connections (device)); - break; - case PROP_PRODUCT: - g_value_set_string (value, nm_device_get_product (device)); - break; - case PROP_VENDOR: - g_value_set_string (value, nm_device_get_vendor (device)); - break; - case PROP_PHYSICAL_PORT_ID: - g_value_set_string (value, nm_device_get_physical_port_id (device)); - break; - case PROP_MTU: - g_value_set_uint (value, nm_device_get_mtu (device)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gboolean b; - - switch (prop_id) { - case PROP_DEVICE_TYPE: - /* construct-only */ - priv->device_type = g_value_get_uint (value); - break; - case PROP_MANAGED: - b = g_value_get_boolean (value); - if (priv->managed != b) - nm_device_set_managed (NM_DEVICE (object), b); - break; - case PROP_AUTOCONNECT: - b = g_value_get_boolean (value); - if (priv->autoconnect != b) - nm_device_set_autoconnect (NM_DEVICE (object), b); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_device_class_init (NMDeviceClass *device_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (device_class); - - g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); - - /* virtual methods */ - object_class->constructed = constructed; - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - device_class->connection_compatible = connection_compatible; - - /* properties */ - - /** - * NMDevice:interface: - * - * The interface of the device. - **/ - g_object_class_install_property - (object_class, PROP_INTERFACE, - g_param_spec_string (NM_DEVICE_INTERFACE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:ip-interface: - * - * The IP interface of the device which should be used for all IP-related - * operations like addressing and routing. - **/ - g_object_class_install_property - (object_class, PROP_IP_INTERFACE, - g_param_spec_string (NM_DEVICE_IP_INTERFACE, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:device-type: - * - * The numeric type of the device. - **/ - g_object_class_install_property - (object_class, PROP_DEVICE_TYPE, - g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "", - NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - /** - * NMDevice:udi: - * - * An operating-system specific device hardware identifier; this is not - * unique to a specific hardware device across reboots or hotplugs. It - * is an opaque string which for some device types (Bluetooth, Modem) - * contains an identifier provided by the underlying hardware service daemon - * such as Bluez or ModemManager, and clients can use this property to - * request more information about the device from those services. - **/ - g_object_class_install_property - (object_class, PROP_UDI, - g_param_spec_string (NM_DEVICE_UDI, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:driver: - * - * The driver of the device. - **/ - g_object_class_install_property - (object_class, PROP_DRIVER, - g_param_spec_string (NM_DEVICE_DRIVER, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:driver-version: - * - * The version of the device driver. - **/ - g_object_class_install_property - (object_class, PROP_DRIVER_VERSION, - g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:firmware-version: - * - * The firmware version of the device. - **/ - g_object_class_install_property - (object_class, PROP_FIRMWARE_VERSION, - g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:capabilities: - * - * The capabilities of the device. - **/ - g_object_class_install_property - (object_class, PROP_CAPABILITIES, - g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:real: - * - * Whether the device is real or is a placeholder device that could - * be created automatically by NetworkManager if one of its - * #NMDevice:available-connections was activated. - * - * Since: 1.2 - **/ - g_object_class_install_property - (object_class, PROP_REAL, - g_param_spec_boolean (NM_DEVICE_REAL, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:managed: - * - * Whether the device is managed by NetworkManager. - **/ - g_object_class_install_property - (object_class, PROP_MANAGED, - g_param_spec_boolean (NM_DEVICE_MANAGED, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:autoconnect: - * - * Whether the device can auto-activate a connection. - **/ - g_object_class_install_property - (object_class, PROP_AUTOCONNECT, - g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "", - TRUE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:firmware-missing: - * - * When %TRUE indicates the device is likely missing firmware required - * for its operation. - **/ - g_object_class_install_property - (object_class, PROP_FIRMWARE_MISSING, - g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:ip4-config: - * - * The #NMIP4Config of the device. - **/ - g_object_class_install_property - (object_class, PROP_IP4_CONFIG, - g_param_spec_object (NM_DEVICE_IP4_CONFIG, "", "", - NM_TYPE_IP4_CONFIG, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:dhcp4-config: - * - * The #NMDHCP4Config of the device. - **/ - g_object_class_install_property - (object_class, PROP_DHCP4_CONFIG, - g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, "", "", - NM_TYPE_DHCP4_CONFIG, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:ip6-config: - * - * The #NMIP6Config of the device. - **/ - g_object_class_install_property - (object_class, PROP_IP6_CONFIG, - g_param_spec_object (NM_DEVICE_IP6_CONFIG, "", "", - NM_TYPE_IP6_CONFIG, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:dhcp6-config: - * - * The #NMDHCP6Config of the device. - **/ - g_object_class_install_property - (object_class, PROP_DHCP6_CONFIG, - g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, "", "", - NM_TYPE_DHCP6_CONFIG, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:state: - * - * The state of the device. - **/ - g_object_class_install_property - (object_class, PROP_STATE, - g_param_spec_uint (NM_DEVICE_STATE, "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * 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, "", "", - DBUS_G_TYPE_UINT_STRUCT, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * 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, "", "", - NM_TYPE_ACTIVE_CONNECTION, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:available-connections: - * - * The available connections (#NMRemoteConnection) of the device - * - * Since: 0.9.8 - **/ - g_object_class_install_property - (object_class, PROP_AVAILABLE_CONNECTIONS, - g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "", - NM_TYPE_OBJECT_ARRAY, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:vendor: - * - * The vendor string of the device. - **/ - g_object_class_install_property - (object_class, PROP_VENDOR, - g_param_spec_string (NM_DEVICE_VENDOR, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:product: - * - * The product string of the device. - **/ - g_object_class_install_property - (object_class, PROP_PRODUCT, - g_param_spec_string (NM_DEVICE_PRODUCT, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:physical-port-id: - * - * The physical port ID of the device. (See - * nm_device_get_physical_port_id().) - * - * Since: 0.9.10 - **/ - g_object_class_install_property - (object_class, PROP_PHYSICAL_PORT_ID, - g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /** - * NMDevice:mtu: - * - * The MTU of the device. - * - * Since: 0.9.10 - **/ - g_object_class_install_property - (object_class, PROP_MTU, - g_param_spec_uint (NM_DEVICE_MTU, "", "", - 0, G_MAXUINT32, 1500, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - /* signals */ - - /** - * NMDevice::state-changed: - * @device: the device object that received the signal - * @new_state: the new state of the device - * @old_state: the previous state of the device - * @reason: the reason describing the state change - * - * Notifies the state change of a #NMDevice. - **/ - 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, NULL, - G_TYPE_NONE, 3, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); -} - -/** - * _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); -} - -NMDeviceType -_nm_device_type_for_path (DBusGConnection *connection, const char *path) -{ - DBusGProxy *proxy; - GError *err = NULL; - GValue value = G_VALUE_INIT; - - proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES); - if (!proxy) { - g_warning ("%s: couldn't create D-Bus object proxy.", __func__); - return G_TYPE_INVALID; - } - - if (!dbus_g_proxy_call (proxy, - "Get", &err, - G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, - G_TYPE_STRING, "DeviceType", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, G_TYPE_INVALID)) { - g_warning ("Error in get_property: %s\n", err->message); - g_error_free (err); - g_object_unref (proxy); - return G_TYPE_INVALID; - } - g_object_unref (proxy); - - return g_value_get_uint (&value); -} - -static GType -_nm_device_gtype_for_path (DBusGConnection *connection, - const char *path) -{ - return _nm_device_gtype_from_dtype (_nm_device_type_for_path (connection, path)); -} - -/** - * 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_gtype_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; - } - - async_data->callback (type, async_data->user_data); - g_object_unref (proxy); - g_slice_free (NMDeviceAsyncData, async_data); -} - -static void -_nm_device_gtype_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 = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_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); -} - -/** - * nm_device_get_iface: - * @device: a #NMDevice - * - * Gets the interface name of the #NMDevice. - * - * Returns: the interface of the device. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_iface (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->iface; -} - -/** - * nm_device_get_ip_iface: - * @device: a #NMDevice - * - * Gets the IP interface name of the #NMDevice over which IP traffic flows - * when the device is in the ACTIVATED state. - * - * Returns: the IP traffic interface of the device. This is the internal string - * used by the device, and must not be modified. - **/ -const char * -nm_device_get_ip_iface (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->ip_iface; -} - -/** - * nm_device_get_device_type: - * @device: a #NMDevice - * - * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc. - * - * Returns: the device type - **/ -NMDeviceType -nm_device_get_device_type (NMDevice *self) -{ - g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN); - - return NM_DEVICE_GET_PRIVATE (self)->device_type; -} - -/** - * nm_device_get_udi: - * @device: a #NMDevice - * - * Gets the Unique Device Identifier of the #NMDevice. - * - * Returns: the Unique Device Identifier of the device. This identifier may be - * used to gather more information about the device from various operating - * system services like udev or sysfs. - **/ -const char * -nm_device_get_udi (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->udi; -} - -/** - * nm_device_get_driver: - * @device: a #NMDevice - * - * Gets the driver of the #NMDevice. - * - * Returns: the driver of the device. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_driver (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->driver; -} - -/** - * nm_device_get_driver_version: - * @device: a #NMDevice - * - * Gets the driver version of the #NMDevice. - * - * Returns: the version of the device driver. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_driver_version (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->driver_version; -} - -/** - * nm_device_get_firmware_version: - * @device: a #NMDevice - * - * Gets the firmware version of the #NMDevice. - * - * Returns: the firmware version of the device. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_firmware_version (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->firmware_version; -} - -/** - * nm_device_get_type_description: - * @device: a #NMDevice - * - * Gets a (non-localized) description of the type of device that - * @device is. - * - * Returns: the type description of the device. This is the internal - * string used by the device, and must not be modified. - * - * Since: 0.9.10 - **/ -const char * -nm_device_get_type_description (NMDevice *device) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *desc, *typename; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - if (priv->type_description) - return priv->type_description; - - if (NM_DEVICE_GET_CLASS (device)->get_type_description) { - desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device); - if (desc) - return desc; - } - - typename = G_OBJECT_TYPE_NAME (device); - if (g_str_has_prefix (typename, "NMDevice")) - typename += 8; - priv->type_description = g_ascii_strdown (typename, -1); - - return priv->type_description; -} - -/** - * nm_device_get_hw_address: - * @device: a #NMDevice - * - * Gets the current a hardware address (MAC) for the @device. - * - * Returns: the current MAC of the device, or %NULL. - * This is the internal string used by the device, and must not be modified. - * - * Since: 0.9.10 - **/ -const char * -nm_device_get_hw_address (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - if (NM_DEVICE_GET_CLASS (device)->get_hw_address) - return NM_DEVICE_GET_CLASS (device)->get_hw_address (device); - - return NULL; -} - -/** - * nm_device_get_capabilities: - * @device: a #NMDevice - * - * Gets the device' capabilities. - * - * Returns: the capabilities - **/ -NMDeviceCapabilities -nm_device_get_capabilities (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->capabilities; -} - -/** - * nm_device_get_managed: - * @device: a #NMDevice - * - * Whether the #NMDevice is managed by NetworkManager. - * - * Returns: %TRUE if the device is managed by NetworkManager - **/ -gboolean -nm_device_get_managed (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->managed; -} - -/** - * nm_device_set_managed: - * @device: a #NMDevice - * @managed: %TRUE to make the device managed by NetworkManager. - * - * Enables or disables management of #NMDevice by NetworkManager. - * - * Since: 1.2 - **/ -void -nm_device_set_managed (NMDevice *device, gboolean managed) -{ - GValue value = G_VALUE_INIT; - - g_return_if_fail (NM_IS_DEVICE (device)); - - managed = !!managed; - - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, managed); - - NM_DEVICE_GET_PRIVATE (device)->managed = managed; - - _nm_object_set_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Managed", - &value); -} - -/** - * nm_device_get_autoconnect: - * @device: a #NMDevice - * - * Whether the #NMDevice can be autoconnected. - * - * Returns: %TRUE if the device is allowed to be autoconnected - **/ -gboolean -nm_device_get_autoconnect (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->autoconnect; -} - -/** - * nm_device_set_autoconnect: - * @device: a #NMDevice - * @autoconnect: %TRUE to enable autoconnecting - * - * Enables or disables automatic activation of the #NMDevice. - **/ -void -nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect) -{ - GValue value = G_VALUE_INIT; - - g_return_if_fail (NM_IS_DEVICE (device)); - - g_value_init (&value, G_TYPE_BOOLEAN); - g_value_set_boolean (&value, autoconnect); - - NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect; - - _nm_object_set_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE, - "Autoconnect", - &value); -} - -/** - * nm_device_get_firmware_missing: - * @device: a #NMDevice - * - * Indicates that firmware required for the device's operation is likely - * to be missing. - * - * Returns: %TRUE if firmware required for the device's operation is likely - * to be missing. - **/ -gboolean -nm_device_get_firmware_missing (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->firmware_missing; -} - -/** - * nm_device_get_ip4_config: - * @device: a #NMDevice - * - * Gets the current #NMIP4Config associated with the #NMDevice. - * - * Note that as of NetworkManager 0.9.10, you can alternatively use - * nm_active_connection_get_ip4_config(), which also works with VPN - * connections. - * - * Returns: (transfer none): the #NMIP4Config or %NULL if the device is not activated. - **/ -NMIP4Config * -nm_device_get_ip4_config (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->ip4_config; -} - -/** - * nm_device_get_dhcp4_config: - * @device: a #NMDevice - * - * Gets the current #NMDHCP4Config associated with the #NMDevice. - * - * Note that as of NetworkManager 0.9.10, you can alternatively use - * nm_active_connection_get_dhcp4_config(), which also works with VPN - * connections. - * - * Returns: (transfer none): the #NMDHCP4Config or %NULL if the device is not activated or not - * using DHCP. - **/ -NMDHCP4Config * -nm_device_get_dhcp4_config (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config; -} - -/** - * nm_device_get_ip6_config: - * @device: a #NMDevice - * - * Gets the current #NMIP6Config associated with the #NMDevice. - * - * Note that as of NetworkManager 0.9.10, you can alternatively use - * nm_active_connection_get_ip6_config(), which also works with VPN - * connections. - * - * Returns: (transfer none): the #NMIP6Config or %NULL if the device is not activated. - **/ -NMIP6Config * -nm_device_get_ip6_config (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->ip6_config; -} - -/** - * nm_device_get_dhcp6_config: - * @device: a #NMDevice - * - * Gets the current #NMDHCP6Config associated with the #NMDevice. - * - * Note that as of NetworkManager 0.9.10, you can alternatively use - * nm_active_connection_get_dhcp6_config(), which also works with VPN - * connections. - * - * Returns: (transfer none): the #NMDHCP6Config or %NULL if the device is not activated or not - * using DHCP. - **/ -NMDHCP6Config * -nm_device_get_dhcp6_config (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config; -} - -/** - * nm_device_get_state: - * @device: a #NMDevice - * - * Gets the current #NMDevice state. - * - * Returns: the current device state - **/ -NMDeviceState -nm_device_get_state (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->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; -} - -/** - * nm_device_get_active_connection: - * @device: a #NMDevice - * - * Gets the #NMActiveConnection object which owns this device during activation. - * - * Returns: (transfer none): the #NMActiveConnection or %NULL if the device is - * not part of an active connection - **/ -NMActiveConnection * -nm_device_get_active_connection (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->active_connection; -} - -/** - * nm_device_get_available_connections: - * @device: a #NMDevice - * - * Gets the #NMRemoteConnections currently known to the daemon that could - * be activated on @device. - * - * Returns: (element-type NMRemoteConnection): the #GPtrArray - * containing #NMRemoteConnections. This is the internal copy used by - * the connection, and must not be modified. - * - * Since: 0.9.8 - **/ -const GPtrArray * -nm_device_get_available_connections (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return handle_ptr_array_return (NM_DEVICE_GET_PRIVATE (device)->available_connections); -} - -static gboolean -ensure_udev_client (NMDevice *device) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - - if (!priv->udev_client) { - priv->udev_client = nm_udev_client_new ((const char *[]) { "net", "tty", NULL }, - NULL, NULL); - } - return !!priv->udev_client; -} - -static char * -_get_udev_property (NMDevice *device, - const char *enc_prop, /* ID_XXX_ENC */ - const char *db_prop) /* ID_XXX_FROM_DATABASE */ -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - struct udev_device *udev_device, *tmpdev; - const char *ifname; - guint32 count = 0; - char *enc_value = NULL, *db_value = NULL; - - if (!ensure_udev_client (device)) - return NULL; - - ifname = nm_device_get_iface (device); - if (!ifname) - return NULL; - - udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname); - if (!udev_device) { - udev_device = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname); - if (!udev_device) - return NULL; - } - /* Walk up the chain of the device and its parents a few steps to grab - * vendor and device ID information off it. - */ - tmpdev = udev_device; - while ((count++ < 3) && tmpdev && !enc_value) { - if (!enc_value) - enc_value = nm_udev_utils_property_decode_cp (udev_device_get_property_value (tmpdev, enc_prop)); - if (!db_value) - db_value = g_strdup (udev_device_get_property_value (tmpdev, db_prop)); - - tmpdev = udev_device_get_parent (tmpdev); - } - udev_device_unref (udev_device); - - /* Prefer the encoded value which comes directly from the device - * over the hwdata database value. - */ - if (enc_value) { - g_free (db_value); - return enc_value; - } - - return db_value; -} - -/** - * nm_device_get_product: - * @device: a #NMDevice - * - * Gets the product string of the #NMDevice. - * - * Returns: the product name of the device. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_product (NMDevice *device) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->product) { - priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); - if (!priv->product) { - /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ - priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); - } - _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT); - } - return priv->product; -} - -/** - * nm_device_get_vendor: - * @device: a #NMDevice - * - * Gets the vendor string of the #NMDevice. - * - * Returns: the vendor name of the device. This is the internal string used by the - * device, and must not be modified. - **/ -const char * -nm_device_get_vendor (NMDevice *device) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->vendor) { - priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); - _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR); - } - return priv->vendor; -} - -static const char * const ignored_words[] = { - "Semiconductor", - "Components", - "Corporation", - "Communications", - "Company", - "Corp.", - "Corp", - "Co.", - "Inc.", - "Inc", - "Incorporated", - "Ltd.", - "Limited.", - "Intel?", - "chipset", - "adapter", - "[hex]", - "NDIS", - "Module", - NULL -}; - -static const char * const ignored_phrases[] = { - "Multiprotocol MAC/baseband processor", - "Wireless LAN Controller", - "Wireless LAN Adapter", - "Wireless Adapter", - "Network Connection", - "Wireless Cardbus Adapter", - "Wireless CardBus Adapter", - "54 Mbps Wireless PC Card", - "Wireless PC Card", - "Wireless PC", - "PC Card with XJACK(r) Antenna", - "Wireless cardbus", - "Wireless LAN PC Card", - "Technology Group Ltd.", - "Communication S.p.A.", - "Business Mobile Networks BV", - "Mobile Broadband Minicard Composite Device", - "Mobile Communications AB", - "(PC-Suite Mode)", - NULL -}; - -static char * -fixup_desc_string (const char *desc) -{ - char *p, *temp; - char **words, **item; - GString *str; - int i; - - if (!desc) - return NULL; - - p = temp = g_strdup (desc); - while (*p) { - if (*p == '_' || *p == ',') - *p = ' '; - p++; - } - - /* Attempt to shorten ID by ignoring certain phrases */ - for (i = 0; ignored_phrases[i]; i++) { - p = strstr (temp, ignored_phrases[i]); - if (p) { - guint32 ignored_len = strlen (ignored_phrases[i]); - - memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */ - } - } - - /* Attempt to shorten ID by ignoring certain individual words */ - words = g_strsplit (temp, " ", 0); - str = g_string_new_len (NULL, strlen (temp)); - g_free (temp); - - for (item = words; *item; item++) { - gboolean ignore = FALSE; - - if (**item == '\0') - continue; - - for (i = 0; ignored_words[i]; i++) { - if (!strcmp (*item, ignored_words[i])) { - ignore = TRUE; - break; - } - } - - if (!ignore) { - if (str->len) - g_string_append_c (str, ' '); - g_string_append (str, *item); - } - } - g_strfreev (words); - - temp = str->str; - g_string_free (str, FALSE); - - return temp; -} - -static void -get_description (NMDevice *device) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *dev_product; - const char *dev_vendor; - char *pdown; - char *vdown; - GString *str; - GParamSpec *name_prop; - - dev_product = nm_device_get_product (device); - priv->short_product = fixup_desc_string (dev_product); - - dev_vendor = nm_device_get_vendor (device); - priv->short_vendor = fixup_desc_string (dev_vendor); - - /* Grab device's preferred name, if any */ - name_prop = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (device)), "name"); - if (name_prop) { - g_object_get (device, "name", &priv->description, NULL); - if (priv->description && priv->description[0]) - return; - g_clear_pointer (&priv->description, g_free); - } - - if (!dev_product || !dev_vendor) { - priv->description = g_strdup (nm_device_get_iface (device)); - return; - } - - str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1); - - /* Another quick hack; if all of the fixed up vendor string - * is found in product, ignore the vendor. - */ - pdown = g_ascii_strdown (priv->short_product, -1); - vdown = g_ascii_strdown (priv->short_vendor, -1); - if (!strstr (pdown, vdown)) { - g_string_append (str, priv->short_vendor); - g_string_append_c (str, ' '); - } - g_free (pdown); - g_free (vdown); - - g_string_append (str, priv->short_product); - - priv->description = g_string_free (str, FALSE); -} - -static const char * -get_short_vendor (NMDevice *device) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - priv = NM_DEVICE_GET_PRIVATE (device); - - if (!priv->description) - get_description (device); - - return priv->short_vendor; -} - -/** - * nm_device_get_description: - * @device: an #NMDevice - * - * Gets a description of @device, based on its vendor and product names. - * - * Returns: a description of @device. If either the vendor or the - * product name is unknown, this returns the interface name. - * - * Since: 0.9.10 - */ -const char * -nm_device_get_description (NMDevice *device) -{ - NMDevicePrivate *priv; - - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - priv = NM_DEVICE_GET_PRIVATE (device); - - if (!priv->description) - get_description (device); - - return priv->description; -} - -static const char * -get_type_name (NMDevice *device) -{ - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_ETHERNET: - return _("Ethernet"); - case NM_DEVICE_TYPE_WIFI: - return _("Wi-Fi"); - case NM_DEVICE_TYPE_BT: - return _("Bluetooth"); - case NM_DEVICE_TYPE_OLPC_MESH: - return _("OLPC Mesh"); - case NM_DEVICE_TYPE_WIMAX: - return _("WiMAX"); - case NM_DEVICE_TYPE_MODEM: - return _("Mobile Broadband"); - case NM_DEVICE_TYPE_INFINIBAND: - return _("InfiniBand"); - case NM_DEVICE_TYPE_BOND: - return _("Bond"); - case NM_DEVICE_TYPE_TEAM: - return _("Team"); - case NM_DEVICE_TYPE_BRIDGE: - return _("Bridge"); - case NM_DEVICE_TYPE_VLAN: - return _("VLAN"); - case NM_DEVICE_TYPE_ADSL: - return _("ADSL"); - case NM_DEVICE_TYPE_MACVLAN: - return _("MACVLAN"); - case NM_DEVICE_TYPE_VXLAN: - return _("VXLAN"); - case NM_DEVICE_TYPE_IP_TUNNEL: - return _("IPTunnel"); - case NM_DEVICE_TYPE_TUN: - return _("Tun"); - case NM_DEVICE_TYPE_VETH: - return _("Veth"); - case NM_DEVICE_TYPE_GENERIC: - case NM_DEVICE_TYPE_UNUSED1: - case NM_DEVICE_TYPE_UNUSED2: - case NM_DEVICE_TYPE_UNKNOWN: - break; - } - return _("Unknown"); -} - -static char * -get_device_type_name_with_iface (NMDevice *device) -{ - const char *type_name = get_type_name (device); - - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_BOND: - case NM_DEVICE_TYPE_TEAM: - case NM_DEVICE_TYPE_BRIDGE: - case NM_DEVICE_TYPE_VLAN: - return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device)); - default: - return g_strdup (type_name); - } -} - -static char * -get_device_generic_type_name_with_iface (NMDevice *device) -{ - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_ETHERNET: - case NM_DEVICE_TYPE_INFINIBAND: - return g_strdup (_("Wired")); - default: - return get_device_type_name_with_iface (device); - } -} - -static const char * -get_bus_name (NMDevice *device) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - struct udev_device *udevice; - const char *ifname, *bus; - - if (priv->bus_name) - goto out; - - if (!ensure_udev_client (device)) - return NULL; - - ifname = nm_device_get_iface (device); - if (!ifname) - return NULL; - - udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "net", ifname); - if (!udevice) - udevice = udev_device_new_from_subsystem_sysname (nm_udev_client_get_udev (priv->udev_client), "tty", ifname); - if (!udevice) - return NULL; - - bus = udev_device_get_property_value (udevice, "ID_BUS"); - if (!g_strcmp0 (bus, "pci")) - priv->bus_name = g_strdup (_("PCI")); - else if (!g_strcmp0 (bus, "usb")) - priv->bus_name = g_strdup (_("USB")); - else { - /* Use "" instead of NULL so we can tell later that we've - * already tried. - */ - priv->bus_name = g_strdup (""); - } - udev_device_unref (udevice); - -out: - if (*priv->bus_name) - return priv->bus_name; - else - return NULL; -} - -static gboolean -find_duplicates (char **names, - gboolean *duplicates, - int num_devices) -{ - int i, j; - gboolean found_any = FALSE; - - memset (duplicates, 0, num_devices * sizeof (gboolean)); - for (i = 0; i < num_devices; i++) { - if (duplicates[i]) - continue; - for (j = i + 1; j < num_devices; j++) { - if (duplicates[j]) - continue; - if (!strcmp (names[i], names[j])) - duplicates[i] = duplicates[j] = found_any = TRUE; - } - } - - return found_any; -} - -/** - * nm_device_disambiguate_names: - * @devices: (array length=num_devices): an array of #NMDevice - * @num_devices: length of @devices - * - * Generates a list of short-ish unique presentation names for the - * devices in @devices. - * - * Returns: (transfer full) (array zero-terminated=1): the device names - * - * Since: 0.9.10 - */ -char ** -nm_device_disambiguate_names (NMDevice **devices, - int num_devices) -{ - char **names; - gboolean *duplicates; - int i; - - names = g_new (char *, num_devices + 1); - duplicates = g_new (gboolean, num_devices); - - /* Generic device name */ - for (i = 0; i < num_devices; i++) - names[i] = get_device_generic_type_name_with_iface (devices[i]); - if (!find_duplicates (names, duplicates, num_devices)) - goto done; - - /* Try specific names (eg, "Ethernet" and "InfiniBand" rather - * than "Wired") - */ - for (i = 0; i < num_devices; i++) { - if (duplicates[i]) { - g_free (names[i]); - names[i] = get_device_type_name_with_iface (devices[i]); - } - } - if (!find_duplicates (names, duplicates, num_devices)) - goto done; - - /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */ - for (i = 0; i < num_devices; i++) { - if (duplicates[i]) { - const char *bus = get_bus_name (devices[i]); - char *name; - - if (!bus) - continue; - - g_free (names[i]); - name = get_device_type_name_with_iface (devices[i]); - /* TRANSLATORS: the first %s is a bus name (eg, "USB") or - * product name, the second is a device type (eg, - * "Ethernet"). You can change this to something like - * "%2$s (%1$s)" if there's no grammatical way to combine - * the strings otherwise. - */ - names[i] = g_strdup_printf (C_("long device name", "%s %s"), - bus, name); - g_free (name); - } - } - if (!find_duplicates (names, duplicates, num_devices)) - goto done; - - /* Try prefixing vendor name */ - for (i = 0; i < num_devices; i++) { - if (duplicates[i]) { - const char *vendor = get_short_vendor (devices[i]); - char *name; - - if (!vendor) - continue; - - g_free (names[i]); - name = get_device_type_name_with_iface (devices[i]); - names[i] = g_strdup_printf (C_("long device name", "%s %s"), - vendor, - get_type_name (devices[i])); - g_free (name); - } - } - if (!find_duplicates (names, duplicates, num_devices)) - goto done; - - /* We have multiple identical network cards, so we have to differentiate - * them by interface name. - */ - for (i = 0; i < num_devices; i++) { - if (duplicates[i]) { - const char *interface = nm_device_get_iface (devices[i]); - - if (!interface) - continue; - - g_free (names[i]); - names[i] = g_strdup_printf ("%s (%s)", - get_type_name (devices[i]), - interface); - } - } - -done: - g_free (duplicates); - names[num_devices] = NULL; - return names; -} - -/** - * nm_device_get_physical_port_id: - * @device: a #NMDevice - * - * Gets the physical port ID of the #NMDevice. If non-%NULL, this is - * an opaque string that can be used to recognize when - * seemingly-unrelated #NMDevices are actually just different virtual - * ports on a single physical port. (Eg, NPAR / SR-IOV.) - * - * Returns: the physical port ID of the device, or %NULL if the port - * ID is unknown. This is the internal string used by the device and - * must not be modified. - * - * Since: 0.9.10 - **/ -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); - - _nm_object_ensure_inited (NM_OBJECT (device)); - if (priv->physical_port_id && *priv->physical_port_id) - return priv->physical_port_id; - else - return NULL; -} - -/** - * nm_device_get_mtu: - * @device: a #NMDevice - * - * Gets the MTU of the #NMDevice. - * - * Returns: the MTU of the device in bytes. - * - * Since: 0.9.10 - **/ -guint32 -nm_device_get_mtu (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->mtu; -} - -/** - * nm_device_is_real: - * @device: a #NMDevice - * - * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device - * that could be automatically created by NetworkManager if one of its - * #NMDevice:available-connections was activated. - * - * Since: 1.2 - **/ -gboolean -nm_device_is_real (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return NM_DEVICE_GET_PRIVATE (device)->real; -} - -/** - * nm_device_is_software: - * @device: a #NMDevice - * - * Whether the device is a software device. - * - * Returns: %TRUE if @device is a software device, %FALSE if it is a hardware device. - * - * Since: 1.0 - **/ -gboolean -nm_device_is_software (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - _nm_object_ensure_inited (NM_OBJECT (device)); - return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); -} - -typedef struct { - NMDevice *device; - NMDeviceCallbackFn fn; - gpointer user_data; - const char *method; -} DeviceCallbackInfo; - -static void -device_operation_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - DeviceCallbackInfo *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) { - g_warning ("%s: device %s %s failed: %s", - __func__, - nm_object_get_path (NM_OBJECT (info->device)), - info->method, - NM_G_ERROR_MSG (error)); - } - g_clear_error (&error); - - g_object_unref (info->device); - g_slice_free (DeviceCallbackInfo, info); -} - -/** - * nm_device_disconnect: - * @device: a #NMDevice - * @callback: (scope async) (allow-none): callback to be called when disconnect - * operation completes - * @user_data: (closure): caller-specific data passed to @callback - * - * Disconnects the device if currently connected, and prevents the device from - * automatically connecting to networks until the next manual network connection - * request. - **/ -void -nm_device_disconnect (NMDevice *device, - NMDeviceCallbackFn callback, - gpointer user_data) -{ - DeviceCallbackInfo *info; - - g_return_if_fail (NM_IS_DEVICE (device)); - - info = g_slice_new (DeviceCallbackInfo); - info->fn = callback; - info->user_data = user_data; - info->method = "Disconnect"; - info->device = g_object_ref (device); - - dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Disconnect", - device_operation_cb, info, NULL, - G_TYPE_INVALID); -} - -/** - * nm_device_delete: - * @device: a #NMDevice - * @callback: (scope async) (allow-none): callback to be called when delete - * operation completes - * @user_data: (closure): caller-specific data passed to @callback - * - * Deletes the software device. Hardware devices can't be deleted. - * - * Since: 1.0 - **/ -void -nm_device_delete (NMDevice *device, - NMDeviceCallbackFn callback, - gpointer user_data) -{ - DeviceCallbackInfo *info; - - g_return_if_fail (NM_IS_DEVICE (device)); - - info = g_slice_new (DeviceCallbackInfo); - info->fn = callback; - info->user_data = user_data; - info->method = "Delete"; - info->device = g_object_ref (device); - - dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Delete", - device_operation_cb, info, NULL, - G_TYPE_INVALID); -} - -/** - * nm_device_connection_valid: - * @device: an #NMDevice to validate @connection against - * @connection: an #NMConnection to validate against @device - * - * 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 Wi-Fi device that supports only WEP encryption, the connection - * will only be valid if it is a Wi-Fi 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. - * - * 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_valid (NMDevice *device, NMConnection *connection) -{ - return nm_device_connection_compatible (device, connection, NULL); -} - -gboolean -connection_compatible (NMDevice *device, NMConnection *connection, GError **error) -{ - NMSettingConnection *s_con; - const char *config_iface, *device_iface; - - s_con = nm_connection_get_setting_connection (connection); - g_assert (s_con); - - config_iface = nm_setting_connection_get_interface_name (s_con); - device_iface = nm_device_get_iface (device); - if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INTERFACE_MISMATCH, - "The interface names of the device and the connection didn't match."); - return FALSE; - } - - return TRUE; -} - -/** - * 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 Wi-Fi device that supports only WEP encryption, the connection - * will only be valid if it is a Wi-Fi 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) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error); -} - -/** - * nm_device_filter_connections: - * @device: an #NMDevice to filter connections for - * @connections: (element-type NMConnection): a list of #NMConnection objects to filter - * - * Filters a given list of connections for a given #NMDevice object and return - * connections which may be activated with the device. For example if @device - * is a Wi-Fi device that supports only WEP encryption, the returned list will - * contain any Wi-Fi connections in @connections that allow connection to - * unencrypted or WEP-enabled SSIDs. The returned list will not contain - * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is - * incompatible with the device. To get the full list of connections see - * nm_remote_settings_list_connections(). - * - * Returns: (transfer container) (element-type NMConnection): a - * list of #NMConnection objects that could be activated with the given @device. - * The elements of the list are owned by their creator and should not be freed - * by the caller, but the returned list itself is owned by the caller and should - * be freed with g_slist_free() when it is no longer required. - **/ -GSList * -nm_device_filter_connections (NMDevice *device, const GSList *connections) -{ - GSList *filtered = NULL; - const GSList *iter; - - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = NM_CONNECTION (iter->data); - - /* Connection applies to this device */ - if (nm_device_connection_valid (device, candidate)) - filtered = g_slist_prepend (filtered, candidate); - } - - return g_slist_reverse (filtered); -} - -/** - * nm_device_get_setting_type: - * @device: an #NMDevice - * - * Gets the (primary) #NMSetting subtype associated with connections - * that can be used on @device. - * - * Returns: @device's associated #NMSetting type - * - * Since: 0.9.10 - */ -GType -nm_device_get_setting_type (NMDevice *device) -{ - g_return_val_if_fail (NM_IS_DEVICE (device), G_TYPE_INVALID); - g_return_val_if_fail (NM_DEVICE_GET_CLASS (device)->get_setting_type != NULL, G_TYPE_INVALID); - - return NM_DEVICE_GET_CLASS (device)->get_setting_type (device); -} |