1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2007 - 2008 Novell, Inc.
19 * Copyright 2007 - 2012 Red Hat, Inc.
22 #include "nm-default.h"
25 #include <gudev/gudev.h>
27 #include "NetworkManager.h"
28 #include "nm-device-ethernet.h"
29 #include "nm-device-adsl.h"
30 #include "nm-device-wifi.h"
31 #include "nm-device-modem.h"
32 #include "nm-device-bt.h"
33 #include "nm-device-olpc-mesh.h"
34 #include "nm-device-wimax.h"
35 #include "nm-device-infiniband.h"
36 #include "nm-device-bond.h"
37 #include "nm-device-team.h"
38 #include "nm-device-bridge.h"
39 #include "nm-device-vlan.h"
40 #include "nm-device-generic.h"
41 #include "nm-device.h"
42 #include "nm-device-private.h"
43 #include "nm-object-private.h"
44 #include "nm-object-cache.h"
45 #include "nm-remote-connection.h"
47 #include "nm-dbus-glib-types.h"
49 #include "nm-dbus-helpers-private.h"
51 static GType _nm_device_gtype_for_path (DBusGConnection *connection,
53 static void _nm_device_gtype_for_path_async (DBusGConnection *connection,
55 NMObjectTypeCallbackFunc callback,
57 gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error);
59 G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT,
60 _nm_object_register_type_func (g_define_type_id, _nm_device_gtype_for_path,
61 _nm_device_gtype_for_path_async);
64 #define DBUS_G_TYPE_UINT_STRUCT (dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID))
66 #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
73 NMDeviceType device_type;
77 char *firmware_version;
78 char *type_description;
79 NMDeviceCapabilities capabilities;
82 gboolean firmware_missing;
84 NMIP4Config *ip4_config;
85 NMDHCP4Config *dhcp4_config;
86 NMIP6Config *ip6_config;
87 NMDHCP6Config *dhcp6_config;
89 NMDeviceState last_seen_state;
90 NMDeviceStateReason reason;
92 NMActiveConnection *active_connection;
93 GPtrArray *available_connections;
96 char *product, *short_product;
97 char *vendor, *short_vendor;
98 char *description, *bus_name;
100 char *physical_port_id;
110 PROP_FIRMWARE_VERSION,
115 PROP_FIRMWARE_MISSING,
126 PROP_ACTIVE_CONNECTION,
127 PROP_AVAILABLE_CONNECTIONS,
128 PROP_PHYSICAL_PORT_ID,
140 static guint signals[LAST_SIGNAL] = { 0 };
143 * nm_device_error_quark:
145 * Registers an error quark for #NMDevice if necessary.
147 * Returns: the error quark used for #NMDevice errors.
152 nm_device_error_quark (void)
154 static GQuark quark = 0;
156 if (G_UNLIKELY (quark == 0))
157 quark = g_quark_from_static_string ("nm-device-error-quark");
162 nm_device_init (NMDevice *device)
164 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
166 priv->state = NM_DEVICE_STATE_UNKNOWN;
167 priv->reason = NM_DEVICE_STATE_REASON_NONE;
171 demarshal_state_reason (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
173 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
175 if (!G_VALUE_HOLDS (value, DBUS_G_TYPE_UINT_STRUCT))
178 dbus_g_type_struct_get (value,
183 _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON);
188 register_properties (NMDevice *device)
190 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
191 const NMPropertiesInfo property_info[] = {
192 { NM_DEVICE_UDI, &priv->udi },
193 { NM_DEVICE_INTERFACE, &priv->iface },
194 { NM_DEVICE_IP_INTERFACE, &priv->ip_iface },
195 { NM_DEVICE_DRIVER, &priv->driver },
196 { NM_DEVICE_DRIVER_VERSION, &priv->driver_version },
197 { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version },
198 { NM_DEVICE_CAPABILITIES, &priv->capabilities },
199 { NM_DEVICE_REAL, &priv->real },
200 { NM_DEVICE_MANAGED, &priv->managed },
201 { NM_DEVICE_AUTOCONNECT, &priv->autoconnect },
202 { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing },
203 { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG },
204 { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
205 { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG },
206 { NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG },
207 { NM_DEVICE_STATE, &priv->state },
208 { NM_DEVICE_STATE_REASON, &priv->state, demarshal_state_reason },
209 { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
210 { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION },
211 { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id },
212 { NM_DEVICE_MTU, &priv->mtu },
214 /* Properties that exist in D-Bus but that we don't track */
215 { "ip4-address", NULL },
216 { "device-type", NULL },
221 _nm_object_register_properties (NM_OBJECT (device),
227 NMDeviceState old_state;
228 NMDeviceState new_state;
229 NMDeviceStateReason reason;
233 device_state_change_reloaded (GObject *object,
234 GAsyncResult *result,
237 NMDevice *self = NM_DEVICE (object);
238 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
239 StateChangeData *data = user_data;
240 NMDeviceState old_state = data->old_state;
241 NMDeviceState new_state = data->new_state;
242 NMDeviceStateReason reason = data->reason;
244 g_slice_free (StateChangeData, data);
246 _nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
248 /* If the device changes state several times in rapid succession, then we'll
249 * queue several reload_properties() calls, and there's no guarantee that
250 * they'll finish in the right order. In that case, only emit the signal
253 if (priv->last_seen_state != new_state)
256 /* Ensure that nm_device_get_state() will return the right value even if
257 * we haven't processed the corresponding PropertiesChanged yet.
259 priv->state = new_state;
261 g_signal_emit (self, signals[STATE_CHANGED], 0,
262 new_state, old_state, reason);
266 device_state_changed (DBusGProxy *proxy,
267 NMDeviceState new_state,
268 NMDeviceState old_state,
269 NMDeviceStateReason reason,
272 NMDevice *self = NM_DEVICE (user_data);
273 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
275 if (old_state != new_state) {
276 StateChangeData *data;
278 /* Our object-valued properties (eg, ip4_config) will still
279 * have their old values at this point, because NMObject is
280 * in the process of asynchronously reading the new values.
281 * Wait for that to finish before emitting the signal.
283 priv->last_seen_state = new_state;
285 data = g_slice_new (StateChangeData);
286 data->old_state = old_state;
287 data->new_state = new_state;
288 data->reason = reason;
289 _nm_object_reload_properties_async (NM_OBJECT (user_data),
290 device_state_change_reloaded,
296 _nm_device_gtype_from_dtype (NMDeviceType dtype)
299 case NM_DEVICE_TYPE_VETH:
300 case NM_DEVICE_TYPE_ETHERNET:
301 return NM_TYPE_DEVICE_ETHERNET;
302 case NM_DEVICE_TYPE_WIFI:
303 return NM_TYPE_DEVICE_WIFI;
304 case NM_DEVICE_TYPE_MODEM:
305 return NM_TYPE_DEVICE_MODEM;
306 case NM_DEVICE_TYPE_BT:
307 return NM_TYPE_DEVICE_BT;
308 case NM_DEVICE_TYPE_ADSL:
309 return NM_TYPE_DEVICE_ADSL;
310 case NM_DEVICE_TYPE_OLPC_MESH:
311 return NM_TYPE_DEVICE_OLPC_MESH;
312 case NM_DEVICE_TYPE_WIMAX:
313 return NM_TYPE_DEVICE_WIMAX;
314 case NM_DEVICE_TYPE_INFINIBAND:
315 return NM_TYPE_DEVICE_INFINIBAND;
316 case NM_DEVICE_TYPE_BOND:
317 return NM_TYPE_DEVICE_BOND;
318 case NM_DEVICE_TYPE_TEAM:
319 return NM_TYPE_DEVICE_TEAM;
320 case NM_DEVICE_TYPE_BRIDGE:
321 return NM_TYPE_DEVICE_BRIDGE;
322 case NM_DEVICE_TYPE_VLAN:
323 return NM_TYPE_DEVICE_VLAN;
324 case NM_DEVICE_TYPE_GENERIC:
325 case NM_DEVICE_TYPE_TUN:
326 case NM_DEVICE_TYPE_IP_TUNNEL:
327 return NM_TYPE_DEVICE_GENERIC;
329 /* Fall back to NMDeviceGeneric for unknown devices */
330 return NM_TYPE_DEVICE_GENERIC;
335 constructed (GObject *object)
337 NMDevicePrivate *priv;
339 G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
341 priv = NM_DEVICE_GET_PRIVATE (object);
342 /* Catch failure of subclasses to call _nm_device_set_device_type() */
343 g_warn_if_fail (priv->device_type != NM_DEVICE_TYPE_UNKNOWN);
344 /* Catch a subclass setting the wrong type */
345 g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type));
347 priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE);
349 register_properties (NM_DEVICE (object));
351 dbus_g_object_register_marshaller (g_cclosure_marshal_generic,
353 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
356 dbus_g_proxy_add_signal (priv->proxy,
358 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
361 dbus_g_proxy_connect_signal (priv->proxy, "StateChanged",
362 G_CALLBACK (device_state_changed),
368 dispose (GObject *object)
370 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
372 g_clear_object (&priv->proxy);
373 g_clear_object (&priv->ip4_config);
374 g_clear_object (&priv->dhcp4_config);
375 g_clear_object (&priv->ip6_config);
376 g_clear_object (&priv->dhcp6_config);
377 g_clear_object (&priv->client);
378 g_clear_object (&priv->active_connection);
380 if (priv->available_connections) {
383 for (i = 0; i < priv->available_connections->len; i++)
384 g_object_unref (priv->available_connections->pdata[i]);
385 g_ptr_array_free (priv->available_connections, TRUE);
386 priv->available_connections = NULL;
389 G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
393 finalize (GObject *object)
395 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
397 g_free (priv->iface);
398 g_free (priv->ip_iface);
400 g_free (priv->driver);
401 g_free (priv->driver_version);
402 g_free (priv->firmware_version);
403 g_free (priv->product);
404 g_free (priv->short_product);
405 g_free (priv->vendor);
406 g_free (priv->short_vendor);
407 g_free (priv->description);
408 g_free (priv->bus_name);
409 g_free (priv->type_description);
410 g_free (priv->physical_port_id);
412 G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
416 get_property (GObject *object,
421 NMDevice *device = NM_DEVICE (object);
422 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
424 _nm_object_ensure_inited (NM_OBJECT (object));
427 case PROP_DEVICE_TYPE:
428 g_value_set_uint (value, nm_device_get_device_type (device));
431 g_value_set_string (value, nm_device_get_udi (device));
434 g_value_set_string (value, nm_device_get_iface (device));
436 case PROP_IP_INTERFACE:
437 g_value_set_string (value, nm_device_get_ip_iface (device));
440 g_value_set_string (value, nm_device_get_driver (device));
442 case PROP_DRIVER_VERSION:
443 g_value_set_string (value, nm_device_get_driver_version (device));
445 case PROP_FIRMWARE_VERSION:
446 g_value_set_string (value, nm_device_get_firmware_version (device));
448 case PROP_CAPABILITIES:
449 g_value_set_uint (value, nm_device_get_capabilities (device));
452 g_value_set_boolean (value, nm_device_is_real (device));
455 g_value_set_boolean (value, nm_device_get_managed (device));
457 case PROP_AUTOCONNECT:
458 g_value_set_boolean (value, nm_device_get_autoconnect (device));
460 case PROP_FIRMWARE_MISSING:
461 g_value_set_boolean (value, nm_device_get_firmware_missing (device));
463 case PROP_IP4_CONFIG:
464 g_value_set_object (value, nm_device_get_ip4_config (device));
466 case PROP_DHCP4_CONFIG:
467 g_value_set_object (value, nm_device_get_dhcp4_config (device));
469 case PROP_IP6_CONFIG:
470 g_value_set_object (value, nm_device_get_ip6_config (device));
472 case PROP_DHCP6_CONFIG:
473 g_value_set_object (value, nm_device_get_dhcp6_config (device));
476 g_value_set_uint (value, nm_device_get_state (device));
478 case PROP_STATE_REASON:
479 g_value_set_boxed (value,
480 dbus_g_type_specialized_construct (DBUS_G_TYPE_UINT_STRUCT));
481 dbus_g_type_struct_set (value,
486 case PROP_ACTIVE_CONNECTION:
487 g_value_set_object (value, nm_device_get_active_connection (device));
489 case PROP_AVAILABLE_CONNECTIONS:
490 g_value_set_boxed (value, nm_device_get_available_connections (device));
493 g_value_set_string (value, nm_device_get_product (device));
496 g_value_set_string (value, nm_device_get_vendor (device));
498 case PROP_PHYSICAL_PORT_ID:
499 g_value_set_string (value, nm_device_get_physical_port_id (device));
502 g_value_set_uint (value, nm_device_get_mtu (device));
505 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
511 set_property (GObject *object,
516 NMDevice *self = NM_DEVICE (object);
517 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
521 case PROP_DEVICE_TYPE:
523 priv->device_type = g_value_get_uint (value);
526 b = g_value_get_boolean (value);
527 if (priv->managed != b)
528 nm_device_set_managed (NM_DEVICE (object), b);
530 case PROP_AUTOCONNECT:
531 b = g_value_get_boolean (value);
532 if (priv->autoconnect != b)
533 nm_device_set_autoconnect (NM_DEVICE (object), b);
536 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
542 nm_device_class_init (NMDeviceClass *device_class)
544 GObjectClass *object_class = G_OBJECT_CLASS (device_class);
546 g_type_class_add_private (device_class, sizeof (NMDevicePrivate));
548 /* virtual methods */
549 object_class->constructed = constructed;
550 object_class->get_property = get_property;
551 object_class->set_property = set_property;
552 object_class->dispose = dispose;
553 object_class->finalize = finalize;
555 device_class->connection_compatible = connection_compatible;
560 * NMDevice:interface:
562 * The interface of the device.
564 g_object_class_install_property
565 (object_class, PROP_INTERFACE,
566 g_param_spec_string (NM_DEVICE_INTERFACE, "", "",
569 G_PARAM_STATIC_STRINGS));
572 * NMDevice:ip-interface:
574 * The IP interface of the device which should be used for all IP-related
575 * operations like addressing and routing.
577 g_object_class_install_property
578 (object_class, PROP_IP_INTERFACE,
579 g_param_spec_string (NM_DEVICE_IP_INTERFACE, "", "",
582 G_PARAM_STATIC_STRINGS));
585 * NMDevice:device-type:
587 * The numeric type of the device.
589 g_object_class_install_property
590 (object_class, PROP_DEVICE_TYPE,
591 g_param_spec_uint (NM_DEVICE_DEVICE_TYPE, "", "",
592 NM_DEVICE_TYPE_UNKNOWN, G_MAXUINT32, NM_DEVICE_TYPE_UNKNOWN,
594 G_PARAM_STATIC_STRINGS));
598 * An operating-system specific device hardware identifier; this is not
599 * unique to a specific hardware device across reboots or hotplugs. It
600 * is an opaque string which for some device types (Bluetooth, Modem)
601 * contains an identifier provided by the underlying hardware service daemon
602 * such as Bluez or ModemManager, and clients can use this property to
603 * request more information about the device from those services.
605 g_object_class_install_property
606 (object_class, PROP_UDI,
607 g_param_spec_string (NM_DEVICE_UDI, "", "",
610 G_PARAM_STATIC_STRINGS));
615 * The driver of the device.
617 g_object_class_install_property
618 (object_class, PROP_DRIVER,
619 g_param_spec_string (NM_DEVICE_DRIVER, "", "",
622 G_PARAM_STATIC_STRINGS));
625 * NMDevice:driver-version:
627 * The version of the device driver.
629 g_object_class_install_property
630 (object_class, PROP_DRIVER_VERSION,
631 g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "",
634 G_PARAM_STATIC_STRINGS));
637 * NMDevice:firmware-version:
639 * The firmware version of the device.
641 g_object_class_install_property
642 (object_class, PROP_FIRMWARE_VERSION,
643 g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "",
646 G_PARAM_STATIC_STRINGS));
649 * NMDevice:capabilities:
651 * The capabilities of the device.
653 g_object_class_install_property
654 (object_class, PROP_CAPABILITIES,
655 g_param_spec_uint (NM_DEVICE_CAPABILITIES, "", "",
658 G_PARAM_STATIC_STRINGS));
663 * Whether the device is real or is a placeholder device that could
664 * be created automatically by NetworkManager if one of its
665 * #NMDevice:available-connections was activated.
669 g_object_class_install_property
670 (object_class, PROP_REAL,
671 g_param_spec_boolean (NM_DEVICE_REAL, "", "",
674 G_PARAM_STATIC_STRINGS));
679 * Whether the device is managed by NetworkManager.
681 g_object_class_install_property
682 (object_class, PROP_MANAGED,
683 g_param_spec_boolean (NM_DEVICE_MANAGED, "", "",
686 G_PARAM_STATIC_STRINGS));
689 * NMDevice:autoconnect:
691 * Whether the device can auto-activate a connection.
693 g_object_class_install_property
694 (object_class, PROP_AUTOCONNECT,
695 g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "",
698 G_PARAM_STATIC_STRINGS));
701 * NMDevice:firmware-missing:
703 * When %TRUE indicates the device is likely missing firmware required
706 g_object_class_install_property
707 (object_class, PROP_FIRMWARE_MISSING,
708 g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "",
711 G_PARAM_STATIC_STRINGS));
714 * NMDevice:ip4-config:
716 * The #NMIP4Config of the device.
718 g_object_class_install_property
719 (object_class, PROP_IP4_CONFIG,
720 g_param_spec_object (NM_DEVICE_IP4_CONFIG, "", "",
723 G_PARAM_STATIC_STRINGS));
726 * NMDevice:dhcp4-config:
728 * The #NMDHCP4Config of the device.
730 g_object_class_install_property
731 (object_class, PROP_DHCP4_CONFIG,
732 g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, "", "",
733 NM_TYPE_DHCP4_CONFIG,
735 G_PARAM_STATIC_STRINGS));
738 * NMDevice:ip6-config:
740 * The #NMIP6Config of the device.
742 g_object_class_install_property
743 (object_class, PROP_IP6_CONFIG,
744 g_param_spec_object (NM_DEVICE_IP6_CONFIG, "", "",
747 G_PARAM_STATIC_STRINGS));
750 * NMDevice:dhcp6-config:
752 * The #NMDHCP6Config of the device.
754 g_object_class_install_property
755 (object_class, PROP_DHCP6_CONFIG,
756 g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, "", "",
757 NM_TYPE_DHCP6_CONFIG,
759 G_PARAM_STATIC_STRINGS));
764 * The state of the device.
766 g_object_class_install_property
767 (object_class, PROP_STATE,
768 g_param_spec_uint (NM_DEVICE_STATE, "", "",
771 G_PARAM_STATIC_STRINGS));
774 * NMDevice:state-reason:
776 * The state and reason of the device.
778 g_object_class_install_property
779 (object_class, PROP_STATE_REASON,
780 g_param_spec_boxed (NM_DEVICE_STATE_REASON, "", "",
781 DBUS_G_TYPE_UINT_STRUCT,
783 G_PARAM_STATIC_STRINGS));
786 * NMDevice:active-connection:
788 * The #NMActiveConnection object that "owns" this device during activation.
790 g_object_class_install_property
791 (object_class, PROP_ACTIVE_CONNECTION,
792 g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION, "", "",
793 NM_TYPE_ACTIVE_CONNECTION,
795 G_PARAM_STATIC_STRINGS));
798 * NMDevice:available-connections:
800 * The available connections (#NMRemoteConnection) of the device
804 g_object_class_install_property
805 (object_class, PROP_AVAILABLE_CONNECTIONS,
806 g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "",
807 NM_TYPE_OBJECT_ARRAY,
809 G_PARAM_STATIC_STRINGS));
814 * The vendor string of the device.
816 g_object_class_install_property
817 (object_class, PROP_VENDOR,
818 g_param_spec_string (NM_DEVICE_VENDOR, "", "",
821 G_PARAM_STATIC_STRINGS));
826 * The product string of the device.
828 g_object_class_install_property
829 (object_class, PROP_PRODUCT,
830 g_param_spec_string (NM_DEVICE_PRODUCT, "", "",
833 G_PARAM_STATIC_STRINGS));
836 * NMDevice:physical-port-id:
838 * The physical port ID of the device. (See
839 * nm_device_get_physical_port_id().)
843 g_object_class_install_property
844 (object_class, PROP_PHYSICAL_PORT_ID,
845 g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "",
848 G_PARAM_STATIC_STRINGS));
853 * The MTU of the device.
857 g_object_class_install_property
858 (object_class, PROP_MTU,
859 g_param_spec_uint (NM_DEVICE_MTU, "", "",
860 0, G_MAXUINT32, 1500,
862 G_PARAM_STATIC_STRINGS));
867 * NMDevice::state-changed:
868 * @device: the device object that received the signal
869 * @new_state: the new state of the device
870 * @old_state: the previous state of the device
871 * @reason: the reason describing the state change
873 * Notifies the state change of a #NMDevice.
875 signals[STATE_CHANGED] =
876 g_signal_new ("state-changed",
877 G_OBJECT_CLASS_TYPE (object_class),
879 G_STRUCT_OFFSET (NMDeviceClass, state_changed),
882 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
886 * _nm_device_set_device_type:
887 * @device: the device
888 * @dtype: the NM device type
890 * Sets the NM device type if it wasn't set during construction. INTERNAL
894 _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype)
896 NMDevicePrivate *priv;
898 g_return_if_fail (device != NULL);
899 g_return_if_fail (dtype != NM_DEVICE_TYPE_UNKNOWN);
901 priv = NM_DEVICE_GET_PRIVATE (device);
902 if (priv->device_type == NM_DEVICE_TYPE_UNKNOWN)
903 priv->device_type = dtype;
905 g_warn_if_fail (dtype == priv->device_type);
909 _nm_device_type_for_path (DBusGConnection *connection, const char *path)
913 GValue value = G_VALUE_INIT;
915 proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
917 g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
918 return G_TYPE_INVALID;
921 if (!dbus_g_proxy_call (proxy,
923 G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
924 G_TYPE_STRING, "DeviceType",
926 G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
927 g_warning ("Error in get_property: %s\n", err->message);
929 g_object_unref (proxy);
930 return G_TYPE_INVALID;
932 g_object_unref (proxy);
934 return g_value_get_uint (&value);
938 _nm_device_gtype_for_path (DBusGConnection *connection,
941 return _nm_device_gtype_from_dtype (_nm_device_type_for_path (connection, path));
946 * @connection: the #DBusGConnection
947 * @path: the DBus object path of the device
949 * Creates a new #NMDevice.
951 * Returns: (transfer full): a new device
954 nm_device_new (DBusGConnection *connection, const char *path)
957 NMDevice *device = NULL;
959 g_return_val_if_fail (connection != NULL, NULL);
960 g_return_val_if_fail (path != NULL, NULL);
962 dtype = _nm_device_gtype_for_path (connection, path);
963 if (dtype == G_TYPE_INVALID)
966 device = (NMDevice *) g_object_new (dtype,
967 NM_OBJECT_DBUS_CONNECTION, connection,
968 NM_OBJECT_DBUS_PATH, path,
970 _nm_object_ensure_inited (NM_OBJECT (device));
971 return G_OBJECT (device);
975 DBusGConnection *connection;
976 NMObjectTypeCallbackFunc callback;
981 async_got_type (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
983 NMDeviceAsyncData *async_data = user_data;
984 GValue value = G_VALUE_INIT;
985 const char *path = dbus_g_proxy_get_path (proxy);
986 GError *error = NULL;
989 if (dbus_g_proxy_end_call (proxy, call, &error,
990 G_TYPE_VALUE, &value,
994 dtype = g_value_get_uint (&value);
995 type = _nm_device_gtype_from_dtype (dtype);
997 g_warning ("%s: could not read properties for %s: %s", __func__, path, error->message);
998 g_error_free (error);
999 type = G_TYPE_INVALID;
1002 async_data->callback (type, async_data->user_data);
1003 g_object_unref (proxy);
1004 g_slice_free (NMDeviceAsyncData, async_data);
1008 _nm_device_gtype_for_path_async (DBusGConnection *connection,
1010 NMObjectTypeCallbackFunc callback,
1013 NMDeviceAsyncData *async_data;
1016 async_data = g_slice_new (NMDeviceAsyncData);
1017 async_data->connection = connection;
1018 async_data->callback = callback;
1019 async_data->user_data = user_data;
1021 proxy = _nm_dbus_new_proxy_for_connection (connection, path, DBUS_INTERFACE_PROPERTIES);
1022 dbus_g_proxy_begin_call (proxy, "Get",
1023 async_got_type, async_data, NULL,
1024 G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE,
1025 G_TYPE_STRING, "DeviceType",
1030 * nm_device_get_iface:
1031 * @device: a #NMDevice
1033 * Gets the interface name of the #NMDevice.
1035 * Returns: the interface of the device. This is the internal string used by the
1036 * device, and must not be modified.
1039 nm_device_get_iface (NMDevice *device)
1041 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1043 _nm_object_ensure_inited (NM_OBJECT (device));
1044 return NM_DEVICE_GET_PRIVATE (device)->iface;
1048 * nm_device_get_ip_iface:
1049 * @device: a #NMDevice
1051 * Gets the IP interface name of the #NMDevice over which IP traffic flows
1052 * when the device is in the ACTIVATED state.
1054 * Returns: the IP traffic interface of the device. This is the internal string
1055 * used by the device, and must not be modified.
1058 nm_device_get_ip_iface (NMDevice *device)
1060 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1062 _nm_object_ensure_inited (NM_OBJECT (device));
1063 return NM_DEVICE_GET_PRIVATE (device)->ip_iface;
1067 * nm_device_get_device_type:
1068 * @device: a #NMDevice
1070 * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc.
1072 * Returns: the device type
1075 nm_device_get_device_type (NMDevice *self)
1077 g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN);
1079 return NM_DEVICE_GET_PRIVATE (self)->device_type;
1083 * nm_device_get_udi:
1084 * @device: a #NMDevice
1086 * Gets the Unique Device Identifier of the #NMDevice.
1088 * Returns: the Unique Device Identifier of the device. This identifier may be
1089 * used to gather more information about the device from various operating
1090 * system services like udev or sysfs.
1093 nm_device_get_udi (NMDevice *device)
1095 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1097 _nm_object_ensure_inited (NM_OBJECT (device));
1098 return NM_DEVICE_GET_PRIVATE (device)->udi;
1102 * nm_device_get_driver:
1103 * @device: a #NMDevice
1105 * Gets the driver of the #NMDevice.
1107 * Returns: the driver of the device. This is the internal string used by the
1108 * device, and must not be modified.
1111 nm_device_get_driver (NMDevice *device)
1113 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1115 _nm_object_ensure_inited (NM_OBJECT (device));
1116 return NM_DEVICE_GET_PRIVATE (device)->driver;
1120 * nm_device_get_driver_version:
1121 * @device: a #NMDevice
1123 * Gets the driver version of the #NMDevice.
1125 * Returns: the version of the device driver. This is the internal string used by the
1126 * device, and must not be modified.
1129 nm_device_get_driver_version (NMDevice *device)
1131 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1133 _nm_object_ensure_inited (NM_OBJECT (device));
1134 return NM_DEVICE_GET_PRIVATE (device)->driver_version;
1138 * nm_device_get_firmware_version:
1139 * @device: a #NMDevice
1141 * Gets the firmware version of the #NMDevice.
1143 * Returns: the firmware version of the device. This is the internal string used by the
1144 * device, and must not be modified.
1147 nm_device_get_firmware_version (NMDevice *device)
1149 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1151 _nm_object_ensure_inited (NM_OBJECT (device));
1152 return NM_DEVICE_GET_PRIVATE (device)->firmware_version;
1156 * nm_device_get_type_description:
1157 * @device: a #NMDevice
1159 * Gets a (non-localized) description of the type of device that
1162 * Returns: the type description of the device. This is the internal
1163 * string used by the device, and must not be modified.
1168 nm_device_get_type_description (NMDevice *device)
1170 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1171 const char *desc, *typename;
1173 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1175 if (priv->type_description)
1176 return priv->type_description;
1178 if (NM_DEVICE_GET_CLASS (device)->get_type_description) {
1179 desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device);
1184 typename = G_OBJECT_TYPE_NAME (device);
1185 if (g_str_has_prefix (typename, "NMDevice"))
1187 priv->type_description = g_ascii_strdown (typename, -1);
1189 return priv->type_description;
1193 * nm_device_get_hw_address:
1194 * @device: a #NMDevice
1196 * Gets the current a hardware address (MAC) for the @device.
1198 * Returns: the current MAC of the device, or %NULL.
1199 * This is the internal string used by the device, and must not be modified.
1204 nm_device_get_hw_address (NMDevice *device)
1206 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1208 if (NM_DEVICE_GET_CLASS (device)->get_hw_address)
1209 return NM_DEVICE_GET_CLASS (device)->get_hw_address (device);
1215 * nm_device_get_capabilities:
1216 * @device: a #NMDevice
1218 * Gets the device' capabilities.
1220 * Returns: the capabilities
1222 NMDeviceCapabilities
1223 nm_device_get_capabilities (NMDevice *device)
1225 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1227 _nm_object_ensure_inited (NM_OBJECT (device));
1228 return NM_DEVICE_GET_PRIVATE (device)->capabilities;
1232 * nm_device_get_managed:
1233 * @device: a #NMDevice
1235 * Whether the #NMDevice is managed by NetworkManager.
1237 * Returns: %TRUE if the device is managed by NetworkManager
1240 nm_device_get_managed (NMDevice *device)
1242 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1244 _nm_object_ensure_inited (NM_OBJECT (device));
1245 return NM_DEVICE_GET_PRIVATE (device)->managed;
1249 * nm_device_set_managed:
1250 * @device: a #NMDevice
1251 * @managed: %TRUE to make the device managed by NetworkManager.
1253 * Enables or disables management of #NMDevice by NetworkManager.
1258 nm_device_set_managed (NMDevice *device, gboolean managed)
1260 GValue value = G_VALUE_INIT;
1262 g_return_if_fail (NM_IS_DEVICE (device));
1264 managed = !!managed;
1266 g_value_init (&value, G_TYPE_BOOLEAN);
1267 g_value_set_boolean (&value, managed);
1269 NM_DEVICE_GET_PRIVATE (device)->managed = managed;
1271 _nm_object_set_property (NM_OBJECT (device),
1272 NM_DBUS_INTERFACE_DEVICE,
1278 * nm_device_get_autoconnect:
1279 * @device: a #NMDevice
1281 * Whether the #NMDevice can be autoconnected.
1283 * Returns: %TRUE if the device is allowed to be autoconnected
1286 nm_device_get_autoconnect (NMDevice *device)
1288 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1290 _nm_object_ensure_inited (NM_OBJECT (device));
1291 return NM_DEVICE_GET_PRIVATE (device)->autoconnect;
1295 * nm_device_set_autoconnect:
1296 * @device: a #NMDevice
1297 * @autoconnect: %TRUE to enable autoconnecting
1299 * Enables or disables automatic activation of the #NMDevice.
1302 nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect)
1304 GValue value = G_VALUE_INIT;
1306 g_return_if_fail (NM_IS_DEVICE (device));
1308 g_value_init (&value, G_TYPE_BOOLEAN);
1309 g_value_set_boolean (&value, autoconnect);
1312 NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect;
1314 _nm_object_set_property (NM_OBJECT (device),
1315 NM_DBUS_INTERFACE_DEVICE,
1321 * nm_device_get_firmware_missing:
1322 * @device: a #NMDevice
1324 * Indicates that firmware required for the device's operation is likely
1327 * Returns: %TRUE if firmware required for the device's operation is likely
1331 nm_device_get_firmware_missing (NMDevice *device)
1333 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1335 _nm_object_ensure_inited (NM_OBJECT (device));
1336 return NM_DEVICE_GET_PRIVATE (device)->firmware_missing;
1340 * nm_device_get_ip4_config:
1341 * @device: a #NMDevice
1343 * Gets the current #NMIP4Config associated with the #NMDevice.
1345 * Note that as of NetworkManager 0.9.10, you can alternatively use
1346 * nm_active_connection_get_ip4_config(), which also works with VPN
1349 * Returns: (transfer none): the #NMIP4Config or %NULL if the device is not activated.
1352 nm_device_get_ip4_config (NMDevice *device)
1354 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1356 _nm_object_ensure_inited (NM_OBJECT (device));
1357 return NM_DEVICE_GET_PRIVATE (device)->ip4_config;
1361 * nm_device_get_dhcp4_config:
1362 * @device: a #NMDevice
1364 * Gets the current #NMDHCP4Config associated with the #NMDevice.
1366 * Note that as of NetworkManager 0.9.10, you can alternatively use
1367 * nm_active_connection_get_dhcp4_config(), which also works with VPN
1370 * Returns: (transfer none): the #NMDHCP4Config or %NULL if the device is not activated or not
1374 nm_device_get_dhcp4_config (NMDevice *device)
1376 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1378 _nm_object_ensure_inited (NM_OBJECT (device));
1379 return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config;
1383 * nm_device_get_ip6_config:
1384 * @device: a #NMDevice
1386 * Gets the current #NMIP6Config associated with the #NMDevice.
1388 * Note that as of NetworkManager 0.9.10, you can alternatively use
1389 * nm_active_connection_get_ip6_config(), which also works with VPN
1392 * Returns: (transfer none): the #NMIP6Config or %NULL if the device is not activated.
1395 nm_device_get_ip6_config (NMDevice *device)
1397 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1399 _nm_object_ensure_inited (NM_OBJECT (device));
1400 return NM_DEVICE_GET_PRIVATE (device)->ip6_config;
1404 * nm_device_get_dhcp6_config:
1405 * @device: a #NMDevice
1407 * Gets the current #NMDHCP6Config associated with the #NMDevice.
1409 * Note that as of NetworkManager 0.9.10, you can alternatively use
1410 * nm_active_connection_get_dhcp6_config(), which also works with VPN
1413 * Returns: (transfer none): the #NMDHCP6Config or %NULL if the device is not activated or not
1417 nm_device_get_dhcp6_config (NMDevice *device)
1419 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1421 _nm_object_ensure_inited (NM_OBJECT (device));
1422 return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config;
1426 * nm_device_get_state:
1427 * @device: a #NMDevice
1429 * Gets the current #NMDevice state.
1431 * Returns: the current device state
1434 nm_device_get_state (NMDevice *device)
1436 g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN);
1438 _nm_object_ensure_inited (NM_OBJECT (device));
1439 return NM_DEVICE_GET_PRIVATE (device)->state;
1443 * nm_device_get_state_reason:
1444 * @device: a #NMDevice
1445 * @reason: (out) (allow-none): location to store reason (#NMDeviceStateReason), or %NULL
1447 * Gets the current #NMDevice state (return value) and the reason for entering
1448 * the state (@reason argument).
1450 * Returns: the current device state
1453 nm_device_get_state_reason (NMDevice *device, NMDeviceStateReason *reason)
1455 g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN);
1457 _nm_object_ensure_inited (NM_OBJECT (device));
1459 *reason = NM_DEVICE_GET_PRIVATE (device)->reason;
1460 return NM_DEVICE_GET_PRIVATE (device)->state;
1464 * nm_device_get_active_connection:
1465 * @device: a #NMDevice
1467 * Gets the #NMActiveConnection object which owns this device during activation.
1469 * Returns: (transfer none): the #NMActiveConnection or %NULL if the device is
1470 * not part of an active connection
1472 NMActiveConnection *
1473 nm_device_get_active_connection (NMDevice *device)
1475 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1477 _nm_object_ensure_inited (NM_OBJECT (device));
1478 return NM_DEVICE_GET_PRIVATE (device)->active_connection;
1482 * nm_device_get_available_connections:
1483 * @device: a #NMDevice
1485 * Gets the #NMRemoteConnections currently known to the daemon that could
1486 * be activated on @device.
1488 * Returns: (element-type NMRemoteConnection): the #GPtrArray
1489 * containing #NMRemoteConnections. This is the internal copy used by
1490 * the connection, and must not be modified.
1495 nm_device_get_available_connections (NMDevice *device)
1497 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1499 _nm_object_ensure_inited (NM_OBJECT (device));
1500 return handle_ptr_array_return (NM_DEVICE_GET_PRIVATE (device)->available_connections);
1504 get_decoded_property (GUdevDevice *device, const char *property)
1506 const char *orig, *p;
1507 char *unescaped, *n;
1510 p = orig = g_udev_device_get_property (device, property);
1514 len = strlen (orig);
1515 n = unescaped = g_malloc0 (len + 1);
1517 if ((len >= 4) && (*p == '\\') && (*(p+1) == 'x')) {
1518 *n++ = (char) nm_utils_hex2byte (p + 2);
1531 ensure_udev_client (NMDevice *device)
1533 static const char *const subsys[3] = { "net", "tty", NULL };
1534 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1537 priv->client = g_udev_client_new (subsys);
1539 return priv->client != NULL;
1543 _get_udev_property (NMDevice *device,
1544 const char *enc_prop, /* ID_XXX_ENC */
1545 const char *db_prop) /* ID_XXX_FROM_DATABASE */
1547 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1548 GUdevDevice *udev_device = NULL, *tmpdev, *olddev;
1551 char *enc_value = NULL, *db_value = NULL;
1553 if (!ensure_udev_client (device))
1556 ifname = nm_device_get_iface (device);
1560 udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
1562 udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
1566 /* Walk up the chain of the device and its parents a few steps to grab
1567 * vendor and device ID information off it.
1570 /* Ref the device again because we have to unref it each iteration,
1571 * as g_udev_device_get_parent() returns a ref-ed object.
1573 tmpdev = g_object_ref (udev_device);
1574 while ((count++ < 3) && tmpdev && !enc_value) {
1576 enc_value = get_decoded_property (tmpdev, enc_prop);
1578 db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop));
1581 tmpdev = g_udev_device_get_parent (tmpdev);
1582 g_object_unref (olddev);
1585 /* Unref the last device if we found what we needed before running out
1589 g_object_unref (tmpdev);
1591 /* Balance the initial g_udev_client_query_by_subsystem_and_name() */
1592 g_object_unref (udev_device);
1594 /* Prefer the encoded value which comes directly from the device
1595 * over the hwdata database value.
1606 * nm_device_get_product:
1607 * @device: a #NMDevice
1609 * Gets the product string of the #NMDevice.
1611 * Returns: the product name of the device. This is the internal string used by the
1612 * device, and must not be modified.
1615 nm_device_get_product (NMDevice *device)
1617 NMDevicePrivate *priv;
1619 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1621 priv = NM_DEVICE_GET_PRIVATE (device);
1622 if (!priv->product) {
1623 priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE");
1624 if (!priv->product) {
1625 /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */
1626 priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE");
1628 _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT);
1630 return priv->product;
1634 * nm_device_get_vendor:
1635 * @device: a #NMDevice
1637 * Gets the vendor string of the #NMDevice.
1639 * Returns: the vendor name of the device. This is the internal string used by the
1640 * device, and must not be modified.
1643 nm_device_get_vendor (NMDevice *device)
1645 NMDevicePrivate *priv;
1647 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1649 priv = NM_DEVICE_GET_PRIVATE (device);
1650 if (!priv->vendor) {
1651 priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE");
1652 _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR);
1654 return priv->vendor;
1657 static const char * const ignored_words[] = {
1680 static const char * const ignored_phrases[] = {
1681 "Multiprotocol MAC/baseband processor",
1682 "Wireless LAN Controller",
1683 "Wireless LAN Adapter",
1685 "Network Connection",
1686 "Wireless Cardbus Adapter",
1687 "Wireless CardBus Adapter",
1688 "54 Mbps Wireless PC Card",
1691 "PC Card with XJACK(r) Antenna",
1693 "Wireless LAN PC Card",
1694 "Technology Group Ltd.",
1695 "Communication S.p.A.",
1696 "Business Mobile Networks BV",
1697 "Mobile Broadband Minicard Composite Device",
1698 "Mobile Communications AB",
1704 fixup_desc_string (const char *desc)
1707 char **words, **item;
1714 p = temp = g_strdup (desc);
1716 if (*p == '_' || *p == ',')
1721 /* Attempt to shorten ID by ignoring certain phrases */
1722 for (i = 0; ignored_phrases[i]; i++) {
1723 p = strstr (temp, ignored_phrases[i]);
1725 guint32 ignored_len = strlen (ignored_phrases[i]);
1727 memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
1731 /* Attempt to shorten ID by ignoring certain individual words */
1732 words = g_strsplit (temp, " ", 0);
1733 str = g_string_new_len (NULL, strlen (temp));
1736 for (item = words; *item; item++) {
1737 gboolean ignore = FALSE;
1742 for (i = 0; ignored_words[i]; i++) {
1743 if (!strcmp (*item, ignored_words[i])) {
1751 g_string_append_c (str, ' ');
1752 g_string_append (str, *item);
1758 g_string_free (str, FALSE);
1764 get_description (NMDevice *device)
1766 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1767 const char *dev_product;
1768 const char *dev_vendor;
1773 dev_product = nm_device_get_product (device);
1774 priv->short_product = fixup_desc_string (dev_product);
1776 dev_vendor = nm_device_get_vendor (device);
1777 priv->short_vendor = fixup_desc_string (dev_vendor);
1779 if (!dev_product || !dev_vendor) {
1780 priv->description = g_strdup (nm_device_get_iface (device));
1784 str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1);
1786 /* Another quick hack; if all of the fixed up vendor string
1787 * is found in product, ignore the vendor.
1789 pdown = g_ascii_strdown (priv->short_product, -1);
1790 vdown = g_ascii_strdown (priv->short_vendor, -1);
1791 if (!strstr (pdown, vdown)) {
1792 g_string_append (str, priv->short_vendor);
1793 g_string_append_c (str, ' ');
1798 g_string_append (str, priv->short_product);
1800 priv->description = g_string_free (str, FALSE);
1804 get_short_vendor (NMDevice *device)
1806 NMDevicePrivate *priv;
1808 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1810 priv = NM_DEVICE_GET_PRIVATE (device);
1812 if (!priv->description)
1813 get_description (device);
1815 return priv->short_vendor;
1819 * nm_device_get_description:
1820 * @device: an #NMDevice
1822 * Gets a description of @device, based on its vendor and product names.
1824 * Returns: a description of @device. If either the vendor or the
1825 * product name is unknown, this returns the interface name.
1830 nm_device_get_description (NMDevice *device)
1832 NMDevicePrivate *priv;
1834 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1836 priv = NM_DEVICE_GET_PRIVATE (device);
1838 if (!priv->description)
1839 get_description (device);
1841 return priv->description;
1845 get_type_name (NMDevice *device)
1847 switch (nm_device_get_device_type (device)) {
1848 case NM_DEVICE_TYPE_ETHERNET:
1849 return _("Ethernet");
1850 case NM_DEVICE_TYPE_WIFI:
1852 case NM_DEVICE_TYPE_BT:
1853 return _("Bluetooth");
1854 case NM_DEVICE_TYPE_OLPC_MESH:
1855 return _("OLPC Mesh");
1856 case NM_DEVICE_TYPE_WIMAX:
1858 case NM_DEVICE_TYPE_MODEM:
1859 return _("Mobile Broadband");
1860 case NM_DEVICE_TYPE_INFINIBAND:
1861 return _("InfiniBand");
1862 case NM_DEVICE_TYPE_BOND:
1864 case NM_DEVICE_TYPE_TEAM:
1866 case NM_DEVICE_TYPE_BRIDGE:
1868 case NM_DEVICE_TYPE_VLAN:
1870 case NM_DEVICE_TYPE_ADSL:
1872 case NM_DEVICE_TYPE_MACVLAN:
1873 return _("MACVLAN");
1874 case NM_DEVICE_TYPE_VXLAN:
1876 case NM_DEVICE_TYPE_IP_TUNNEL:
1877 return _("IPTunnel");
1878 case NM_DEVICE_TYPE_TUN:
1880 case NM_DEVICE_TYPE_VETH:
1882 case NM_DEVICE_TYPE_GENERIC:
1883 case NM_DEVICE_TYPE_UNUSED1:
1884 case NM_DEVICE_TYPE_UNUSED2:
1885 case NM_DEVICE_TYPE_UNKNOWN:
1888 return _("Unknown");
1892 get_device_type_name_with_iface (NMDevice *device)
1894 const char *type_name = get_type_name (device);
1896 switch (nm_device_get_device_type (device)) {
1897 case NM_DEVICE_TYPE_BOND:
1898 case NM_DEVICE_TYPE_TEAM:
1899 case NM_DEVICE_TYPE_BRIDGE:
1900 case NM_DEVICE_TYPE_VLAN:
1901 return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device));
1903 return g_strdup (type_name);
1908 get_device_generic_type_name_with_iface (NMDevice *device)
1910 switch (nm_device_get_device_type (device)) {
1911 case NM_DEVICE_TYPE_ETHERNET:
1912 case NM_DEVICE_TYPE_INFINIBAND:
1913 return g_strdup (_("Wired"));
1915 return get_device_type_name_with_iface (device);
1920 get_bus_name (NMDevice *device)
1922 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1923 GUdevDevice *udevice;
1924 const char *ifname, *bus;
1929 if (!ensure_udev_client (device))
1932 ifname = nm_device_get_iface (device);
1936 udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
1938 udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
1942 bus = g_udev_device_get_property (udevice, "ID_BUS");
1943 if (!g_strcmp0 (bus, "pci"))
1944 priv->bus_name = g_strdup (_("PCI"));
1945 else if (!g_strcmp0 (bus, "usb"))
1946 priv->bus_name = g_strdup (_("USB"));
1948 /* Use "" instead of NULL so we can tell later that we've
1951 priv->bus_name = g_strdup ("");
1955 if (*priv->bus_name)
1956 return priv->bus_name;
1962 find_duplicates (char **names,
1963 gboolean *duplicates,
1967 gboolean found_any = FALSE;
1969 memset (duplicates, 0, num_devices * sizeof (gboolean));
1970 for (i = 0; i < num_devices; i++) {
1973 for (j = i + 1; j < num_devices; j++) {
1976 if (!strcmp (names[i], names[j]))
1977 duplicates[i] = duplicates[j] = found_any = TRUE;
1985 * nm_device_disambiguate_names:
1986 * @devices: (array length=num_devices): an array of #NMDevice
1987 * @num_devices: length of @devices
1989 * Generates a list of short-ish unique presentation names for the
1990 * devices in @devices.
1992 * Returns: (transfer full) (array zero-terminated=1): the device names
1997 nm_device_disambiguate_names (NMDevice **devices,
2001 gboolean *duplicates;
2004 names = g_new (char *, num_devices + 1);
2005 duplicates = g_new (gboolean, num_devices);
2007 /* Generic device name */
2008 for (i = 0; i < num_devices; i++)
2009 names[i] = get_device_generic_type_name_with_iface (devices[i]);
2010 if (!find_duplicates (names, duplicates, num_devices))
2013 /* Try specific names (eg, "Ethernet" and "InfiniBand" rather
2016 for (i = 0; i < num_devices; i++) {
2017 if (duplicates[i]) {
2019 names[i] = get_device_type_name_with_iface (devices[i]);
2022 if (!find_duplicates (names, duplicates, num_devices))
2025 /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */
2026 for (i = 0; i < num_devices; i++) {
2027 if (duplicates[i]) {
2028 const char *bus = get_bus_name (devices[i]);
2035 name = get_device_type_name_with_iface (devices[i]);
2036 /* Translators: the first %s is a bus name (eg, "USB") or
2037 * product name, the second is a device type (eg,
2038 * "Ethernet"). You can change this to something like
2039 * "%2$s (%1$s)" if there's no grammatical way to combine
2040 * the strings otherwise.
2042 names[i] = g_strdup_printf (C_("long device name", "%s %s"),
2047 if (!find_duplicates (names, duplicates, num_devices))
2050 /* Try prefixing vendor name */
2051 for (i = 0; i < num_devices; i++) {
2052 if (duplicates[i]) {
2053 const char *vendor = get_short_vendor (devices[i]);
2060 name = get_device_type_name_with_iface (devices[i]);
2061 names[i] = g_strdup_printf (C_("long device name", "%s %s"),
2063 get_type_name (devices[i]));
2067 if (!find_duplicates (names, duplicates, num_devices))
2070 /* We have multiple identical network cards, so we have to differentiate
2071 * them by interface name.
2073 for (i = 0; i < num_devices; i++) {
2074 if (duplicates[i]) {
2075 const char *interface = nm_device_get_iface (devices[i]);
2081 names[i] = g_strdup_printf ("%s (%s)",
2082 get_type_name (devices[i]),
2088 g_free (duplicates);
2089 names[num_devices] = NULL;
2094 * nm_device_get_physical_port_id:
2095 * @device: a #NMDevice
2097 * Gets the physical port ID of the #NMDevice. If non-%NULL, this is
2098 * an opaque string that can be used to recognize when
2099 * seemingly-unrelated #NMDevices are actually just different virtual
2100 * ports on a single physical port. (Eg, NPAR / SR-IOV.)
2102 * Returns: the physical port ID of the device, or %NULL if the port
2103 * ID is unknown. This is the internal string used by the device and
2104 * must not be modified.
2109 nm_device_get_physical_port_id (NMDevice *device)
2111 NMDevicePrivate *priv;
2113 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2115 priv = NM_DEVICE_GET_PRIVATE (device);
2117 _nm_object_ensure_inited (NM_OBJECT (device));
2118 if (priv->physical_port_id && *priv->physical_port_id)
2119 return priv->physical_port_id;
2125 * nm_device_get_mtu:
2126 * @device: a #NMDevice
2128 * Gets the MTU of the #NMDevice.
2130 * Returns: the MTU of the device.
2135 nm_device_get_mtu (NMDevice *device)
2137 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
2139 _nm_object_ensure_inited (NM_OBJECT (device));
2140 return NM_DEVICE_GET_PRIVATE (device)->mtu;
2144 * nm_device_is_real:
2145 * @device: a #NMDevice
2147 * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device
2148 * that could be automatically created by NetworkManager if one of its
2149 * #NMDevice:available-connections was activated.
2154 nm_device_is_real (NMDevice *device)
2156 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2158 _nm_object_ensure_inited (NM_OBJECT (device));
2159 return NM_DEVICE_GET_PRIVATE (device)->real;
2163 * nm_device_is_software:
2164 * @device: a #NMDevice
2166 * Whether the device is a software device.
2168 * Returns: %TRUE if @device is a software device, %FALSE if it is a hardware device.
2173 nm_device_is_software (NMDevice *device)
2175 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2177 _nm_object_ensure_inited (NM_OBJECT (device));
2178 return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE);
2183 NMDeviceCallbackFn fn;
2186 } DeviceCallbackInfo;
2189 device_operation_cb (DBusGProxy *proxy,
2190 DBusGProxyCall *call,
2193 DeviceCallbackInfo *info = user_data;
2194 GError *error = NULL;
2196 dbus_g_proxy_end_call (proxy, call, &error,
2199 info->fn (info->device, error, info->user_data);
2201 g_warning ("%s: device %s %s failed: %s",
2203 nm_object_get_path (NM_OBJECT (info->device)),
2205 NM_G_ERROR_MSG (error));
2207 g_clear_error (&error);
2209 g_object_unref (info->device);
2210 g_slice_free (DeviceCallbackInfo, info);
2214 * nm_device_disconnect:
2215 * @device: a #NMDevice
2216 * @callback: (scope async) (allow-none): callback to be called when disconnect
2217 * operation completes
2218 * @user_data: (closure): caller-specific data passed to @callback
2220 * Disconnects the device if currently connected, and prevents the device from
2221 * automatically connecting to networks until the next manual network connection
2225 nm_device_disconnect (NMDevice *device,
2226 NMDeviceCallbackFn callback,
2229 DeviceCallbackInfo *info;
2231 g_return_if_fail (NM_IS_DEVICE (device));
2233 info = g_slice_new (DeviceCallbackInfo);
2234 info->fn = callback;
2235 info->user_data = user_data;
2236 info->method = "Disconnect";
2237 info->device = g_object_ref (device);
2239 dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Disconnect",
2240 device_operation_cb, info, NULL,
2246 * @device: a #NMDevice
2247 * @callback: (scope async) (allow-none): callback to be called when delete
2248 * operation completes
2249 * @user_data: (closure): caller-specific data passed to @callback
2251 * Deletes the software device. Hardware devices can't be deleted.
2256 nm_device_delete (NMDevice *device,
2257 NMDeviceCallbackFn callback,
2260 DeviceCallbackInfo *info;
2262 g_return_if_fail (NM_IS_DEVICE (device));
2264 info = g_slice_new (DeviceCallbackInfo);
2265 info->fn = callback;
2266 info->user_data = user_data;
2267 info->method = "Delete";
2268 info->device = g_object_ref (device);
2270 dbus_g_proxy_begin_call (NM_DEVICE_GET_PRIVATE (device)->proxy, "Delete",
2271 device_operation_cb, info, NULL,
2276 * nm_device_connection_valid:
2277 * @device: an #NMDevice to validate @connection against
2278 * @connection: an #NMConnection to validate against @device
2280 * Validates a given connection for a given #NMDevice object and returns
2281 * whether the connection may be activated with the device. For example if
2282 * @device is a Wi-Fi device that supports only WEP encryption, the connection
2283 * will only be valid if it is a Wi-Fi connection which describes a WEP or open
2284 * network, and will not be valid if it describes a WPA network, or if it is
2285 * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the
2288 * Returns: %TRUE if the connection may be activated with this device, %FALSE
2289 * if is incompatible with the device's capabilities and characteristics.
2292 nm_device_connection_valid (NMDevice *device, NMConnection *connection)
2294 return nm_device_connection_compatible (device, connection, NULL);
2298 connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
2300 NMSettingConnection *s_con;
2301 const char *config_iface, *device_iface;
2303 s_con = nm_connection_get_setting_connection (connection);
2306 config_iface = nm_setting_connection_get_interface_name (s_con);
2307 device_iface = nm_device_get_iface (device);
2308 if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) {
2309 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INTERFACE_MISMATCH,
2310 "The interface names of the device and the connection didn't match.");
2318 * nm_device_connection_compatible:
2319 * @device: an #NMDevice to validate @connection against
2320 * @connection: an #NMConnection to validate against @device
2321 * @error: return location for a #GError, or %NULL
2323 * Validates a given connection for a given #NMDevice object and returns
2324 * whether the connection may be activated with the device. For example if
2325 * @device is a Wi-Fi device that supports only WEP encryption, the connection
2326 * will only be valid if it is a Wi-Fi connection which describes a WEP or open
2327 * network, and will not be valid if it describes a WPA network, or if it is
2328 * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the
2331 * This function does the same as nm_device_connection_valid(), i.e. checking
2332 * compatibility of the given device and connection. But, in addition, it sets
2333 * GError when FALSE is returned.
2335 * Returns: %TRUE if the connection may be activated with this device, %FALSE
2336 * if is incompatible with the device's capabilities and characteristics.
2339 nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
2341 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2342 g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
2343 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2345 return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error);
2349 * nm_device_filter_connections:
2350 * @device: an #NMDevice to filter connections for
2351 * @connections: (element-type NMConnection): a list of #NMConnection objects to filter
2353 * Filters a given list of connections for a given #NMDevice object and return
2354 * connections which may be activated with the device. For example if @device
2355 * is a Wi-Fi device that supports only WEP encryption, the returned list will
2356 * contain any Wi-Fi connections in @connections that allow connection to
2357 * unencrypted or WEP-enabled SSIDs. The returned list will not contain
2358 * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is
2359 * incompatible with the device. To get the full list of connections see
2360 * nm_remote_settings_list_connections().
2362 * Returns: (transfer container) (element-type NMConnection): a
2363 * list of #NMConnection objects that could be activated with the given @device.
2364 * The elements of the list are owned by their creator and should not be freed
2365 * by the caller, but the returned list itself is owned by the caller and should
2366 * be freed with g_slist_free() when it is no longer required.
2369 nm_device_filter_connections (NMDevice *device, const GSList *connections)
2371 GSList *filtered = NULL;
2374 for (iter = connections; iter; iter = g_slist_next (iter)) {
2375 NMConnection *candidate = NM_CONNECTION (iter->data);
2377 /* Connection applies to this device */
2378 if (nm_device_connection_valid (device, candidate))
2379 filtered = g_slist_prepend (filtered, candidate);
2382 return g_slist_reverse (filtered);
2386 * nm_device_get_setting_type:
2387 * @device: an #NMDevice
2389 * Gets the (primary) #NMSetting subtype associated with connections
2390 * that can be used on @device.
2392 * Returns: @device's associated #NMSetting type
2397 nm_device_get_setting_type (NMDevice *device)
2399 g_return_val_if_fail (NM_IS_DEVICE (device), G_TYPE_INVALID);
2400 g_return_val_if_fail (NM_DEVICE_GET_CLASS (device)->get_setting_type != NULL, G_TYPE_INVALID);
2402 return NM_DEVICE_GET_CLASS (device)->get_setting_type (device);