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"
24 #include "nm-device.h"
27 #include <gudev/gudev.h>
29 #include "nm-dbus-interface.h"
30 #include "nm-active-connection.h"
31 #include "nm-device-ethernet.h"
32 #include "nm-device-adsl.h"
33 #include "nm-device-wifi.h"
34 #include "nm-device-modem.h"
35 #include "nm-device-bt.h"
36 #include "nm-device-olpc-mesh.h"
37 #include "nm-device-wimax.h"
38 #include "nm-device-infiniband.h"
39 #include "nm-device-bond.h"
40 #include "nm-device-team.h"
41 #include "nm-device-bridge.h"
42 #include "nm-device-vlan.h"
43 #include "nm-device-vxlan.h"
44 #include "nm-device-generic.h"
45 #include "nm-device-ip-tunnel.h"
46 #include "nm-device-macvlan.h"
47 #include "nm-device-private.h"
48 #include "nm-dhcp4-config.h"
49 #include "nm-dhcp6-config.h"
50 #include "nm-ip4-config.h"
51 #include "nm-ip6-config.h"
52 #include "nm-object-private.h"
53 #include "nm-object-cache.h"
54 #include "nm-remote-connection.h"
55 #include "nm-core-internal.h"
57 #include "nm-dbus-helpers.h"
58 #include "nm-device-tun.h"
59 #include "nm-setting-connection.h"
61 #include "nmdbus-device.h"
63 static GType _nm_device_decide_type (GVariant *value);
64 static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error);
65 static NMLldpNeighbor *nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor);
67 G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT,
68 _nm_object_register_type_func (g_define_type_id,
69 _nm_device_decide_type,
70 NM_DBUS_INTERFACE_DEVICE,
74 #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
81 NMDeviceType device_type;
85 char *firmware_version;
86 char *type_description;
88 NMDeviceCapabilities capabilities;
91 gboolean firmware_missing;
92 gboolean nm_plugin_missing;
94 NMIPConfig *ip4_config;
95 NMDhcpConfig *dhcp4_config;
96 NMIPConfig *ip6_config;
97 NMDhcpConfig *dhcp6_config;
99 NMDeviceState last_seen_state;
100 NMDeviceStateReason reason;
102 NMActiveConnection *active_connection;
103 GPtrArray *available_connections;
106 char *product, *short_product;
107 char *vendor, *short_vendor;
108 char *description, *bus_name;
110 char *physical_port_id;
112 GPtrArray *lldp_neighbors;
121 PROP_FIRMWARE_VERSION,
126 PROP_FIRMWARE_MISSING,
127 PROP_NM_PLUGIN_MISSING,
138 PROP_ACTIVE_CONNECTION,
139 PROP_AVAILABLE_CONNECTIONS,
140 PROP_PHYSICAL_PORT_ID,
154 static guint signals[LAST_SIGNAL] = { 0 };
156 struct _NMLldpNeighbor {
161 G_DEFINE_BOXED_TYPE (NMLldpNeighbor, nm_lldp_neighbor, nm_lldp_neighbor_dup, nm_lldp_neighbor_unref)
164 nm_device_init (NMDevice *device)
166 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
168 priv->state = NM_DEVICE_STATE_UNKNOWN;
169 priv->reason = NM_DEVICE_STATE_REASON_NONE;
170 priv->lldp_neighbors = g_ptr_array_new ();
174 demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
176 guint32 *reason_field = field;
178 g_variant_get (value, "(uu)", NULL, reason_field);
179 _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON);
184 demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
186 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
187 GVariantIter iter, attrs_iter;
188 GVariant *variant, *attr_variant;
189 const char *attr_name;
191 g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
193 g_ptr_array_unref (priv->lldp_neighbors);
194 priv->lldp_neighbors = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref);
195 g_variant_iter_init (&iter, value);
197 while (g_variant_iter_next (&iter, "@a{sv}", &variant)) {
198 NMLldpNeighbor *neigh;
200 neigh = nm_lldp_neighbor_new ();
201 g_variant_iter_init (&attrs_iter, variant);
203 while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_variant))
204 g_hash_table_insert (neigh->attrs, g_strdup (attr_name), attr_variant);
206 g_variant_unref (variant);
207 g_ptr_array_add (priv->lldp_neighbors, neigh);
210 _nm_object_queue_notify (object, NM_DEVICE_LLDP_NEIGHBORS);
216 device_state_changed (NMDBusDevice *proxy,
223 init_dbus (NMObject *object)
225 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
226 const NMPropertiesInfo property_info[] = {
227 { NM_DEVICE_UDI, &priv->udi },
228 { NM_DEVICE_INTERFACE, &priv->iface },
229 { NM_DEVICE_IP_INTERFACE, &priv->ip_iface },
230 { NM_DEVICE_DRIVER, &priv->driver },
231 { NM_DEVICE_DRIVER_VERSION, &priv->driver_version },
232 { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version },
233 { NM_DEVICE_CAPABILITIES, &priv->capabilities },
234 { NM_DEVICE_REAL, &priv->real },
235 { NM_DEVICE_MANAGED, &priv->managed },
236 { NM_DEVICE_AUTOCONNECT, &priv->autoconnect },
237 { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing },
238 { NM_DEVICE_NM_PLUGIN_MISSING, &priv->nm_plugin_missing },
239 { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG },
240 { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
241 { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG },
242 { NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG },
243 { NM_DEVICE_STATE, &priv->state },
244 { NM_DEVICE_STATE_REASON, &priv->reason, demarshal_state_reason },
245 { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
246 { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION },
247 { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id },
248 { NM_DEVICE_MTU, &priv->mtu },
249 { NM_DEVICE_METERED, &priv->metered },
250 { NM_DEVICE_LLDP_NEIGHBORS, &priv->lldp_neighbors, demarshal_lldp_neighbors },
252 /* Properties that exist in D-Bus but that we don't track */
253 { "ip4-address", NULL },
254 { "device-type", NULL },
259 NM_OBJECT_CLASS (nm_device_parent_class)->init_dbus (object);
261 priv->proxy = NMDBUS_DEVICE (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE));
262 _nm_object_register_properties (object,
263 NM_DBUS_INTERFACE_DEVICE,
266 g_signal_connect (priv->proxy, "state-changed",
267 G_CALLBACK (device_state_changed), object);
271 NMDeviceState old_state;
272 NMDeviceState new_state;
273 NMDeviceStateReason reason;
277 device_state_change_reloaded (GObject *object,
278 GAsyncResult *result,
281 NMDevice *self = NM_DEVICE (object);
282 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
283 StateChangeData *data = user_data;
284 NMDeviceState old_state = data->old_state;
285 NMDeviceState new_state = data->new_state;
286 NMDeviceStateReason reason = data->reason;
288 g_slice_free (StateChangeData, data);
290 _nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL);
292 /* If the device changes state several times in rapid succession, then we'll
293 * queue several reload_properties() calls, and there's no guarantee that
294 * they'll finish in the right order. In that case, only emit the signal
297 if (priv->last_seen_state != new_state)
300 /* Ensure that nm_device_get_state() will return the right value even if
301 * we haven't processed the corresponding PropertiesChanged yet.
303 priv->state = new_state;
305 g_signal_emit (self, signals[STATE_CHANGED], 0,
306 new_state, old_state, reason);
310 device_state_changed (NMDBusDevice *proxy,
316 NMDevice *self = NM_DEVICE (user_data);
317 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
318 StateChangeData *data;
320 if (old_state == new_state)
323 /* Our object-valued properties (eg, ip4_config) will still
324 * have their old values at this point, because NMObject is
325 * in the process of asynchronously reading the new values.
326 * Wait for that to finish before emitting the signal.
328 priv->last_seen_state = new_state;
330 data = g_slice_new (StateChangeData);
331 data->old_state = old_state;
332 data->new_state = new_state;
333 data->reason = reason;
334 _nm_object_reload_properties_async (NM_OBJECT (user_data),
336 device_state_change_reloaded,
341 _nm_device_gtype_from_dtype (NMDeviceType dtype)
344 case NM_DEVICE_TYPE_VETH:
345 case NM_DEVICE_TYPE_ETHERNET:
346 return NM_TYPE_DEVICE_ETHERNET;
347 case NM_DEVICE_TYPE_WIFI:
348 return NM_TYPE_DEVICE_WIFI;
349 case NM_DEVICE_TYPE_MODEM:
350 return NM_TYPE_DEVICE_MODEM;
351 case NM_DEVICE_TYPE_BT:
352 return NM_TYPE_DEVICE_BT;
353 case NM_DEVICE_TYPE_ADSL:
354 return NM_TYPE_DEVICE_ADSL;
355 case NM_DEVICE_TYPE_OLPC_MESH:
356 return NM_TYPE_DEVICE_OLPC_MESH;
357 case NM_DEVICE_TYPE_WIMAX:
358 return NM_TYPE_DEVICE_WIMAX;
359 case NM_DEVICE_TYPE_INFINIBAND:
360 return NM_TYPE_DEVICE_INFINIBAND;
361 case NM_DEVICE_TYPE_BOND:
362 return NM_TYPE_DEVICE_BOND;
363 case NM_DEVICE_TYPE_TEAM:
364 return NM_TYPE_DEVICE_TEAM;
365 case NM_DEVICE_TYPE_BRIDGE:
366 return NM_TYPE_DEVICE_BRIDGE;
367 case NM_DEVICE_TYPE_VLAN:
368 return NM_TYPE_DEVICE_VLAN;
369 case NM_DEVICE_TYPE_GENERIC:
370 return NM_TYPE_DEVICE_GENERIC;
371 case NM_DEVICE_TYPE_TUN:
372 return NM_TYPE_DEVICE_TUN;
373 case NM_DEVICE_TYPE_IP_TUNNEL:
374 return NM_TYPE_DEVICE_IP_TUNNEL;
375 case NM_DEVICE_TYPE_MACVLAN:
376 return NM_TYPE_DEVICE_MACVLAN;
377 case NM_DEVICE_TYPE_VXLAN:
378 return NM_TYPE_DEVICE_VXLAN;
380 g_warning ("Unknown device type %d", dtype);
381 return G_TYPE_INVALID;
386 constructed (GObject *object)
388 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
390 G_OBJECT_CLASS (nm_device_parent_class)->constructed (object);
392 /* Catch failure of subclasses to call _nm_device_set_device_type() */
393 g_warn_if_fail (priv->device_type != NM_DEVICE_TYPE_UNKNOWN);
394 /* Catch a subclass setting the wrong type */
395 g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type));
399 dispose (GObject *object)
401 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
403 g_clear_object (&priv->ip4_config);
404 g_clear_object (&priv->dhcp4_config);
405 g_clear_object (&priv->ip6_config);
406 g_clear_object (&priv->dhcp6_config);
407 g_clear_object (&priv->client);
408 g_clear_object (&priv->active_connection);
410 g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
411 g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
413 G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
417 finalize (GObject *object)
419 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
421 g_free (priv->iface);
422 g_free (priv->ip_iface);
424 g_free (priv->driver);
425 g_free (priv->driver_version);
426 g_free (priv->firmware_version);
427 g_free (priv->product);
428 g_free (priv->short_product);
429 g_free (priv->vendor);
430 g_free (priv->short_vendor);
431 g_free (priv->description);
432 g_free (priv->bus_name);
433 g_free (priv->type_description);
434 g_free (priv->physical_port_id);
436 G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
440 get_property (GObject *object,
445 NMDevice *device = NM_DEVICE (object);
448 case PROP_DEVICE_TYPE:
449 g_value_set_enum (value, nm_device_get_device_type (device));
452 g_value_set_string (value, nm_device_get_udi (device));
455 g_value_set_string (value, nm_device_get_iface (device));
457 case PROP_IP_INTERFACE:
458 g_value_set_string (value, nm_device_get_ip_iface (device));
461 g_value_set_string (value, nm_device_get_driver (device));
463 case PROP_DRIVER_VERSION:
464 g_value_set_string (value, nm_device_get_driver_version (device));
466 case PROP_FIRMWARE_VERSION:
467 g_value_set_string (value, nm_device_get_firmware_version (device));
469 case PROP_CAPABILITIES:
470 g_value_set_flags (value, nm_device_get_capabilities (device));
473 g_value_set_boolean (value, nm_device_is_real (device));
476 g_value_set_boolean (value, nm_device_get_managed (device));
478 case PROP_AUTOCONNECT:
479 g_value_set_boolean (value, nm_device_get_autoconnect (device));
481 case PROP_FIRMWARE_MISSING:
482 g_value_set_boolean (value, nm_device_get_firmware_missing (device));
484 case PROP_NM_PLUGIN_MISSING:
485 g_value_set_boolean (value, nm_device_get_nm_plugin_missing (device));
487 case PROP_IP4_CONFIG:
488 g_value_set_object (value, nm_device_get_ip4_config (device));
490 case PROP_DHCP4_CONFIG:
491 g_value_set_object (value, nm_device_get_dhcp4_config (device));
493 case PROP_IP6_CONFIG:
494 g_value_set_object (value, nm_device_get_ip6_config (device));
496 case PROP_DHCP6_CONFIG:
497 g_value_set_object (value, nm_device_get_dhcp6_config (device));
500 g_value_set_enum (value, nm_device_get_state (device));
502 case PROP_STATE_REASON:
503 g_value_set_uint (value, nm_device_get_state_reason (device));
505 case PROP_ACTIVE_CONNECTION:
506 g_value_set_object (value, nm_device_get_active_connection (device));
508 case PROP_AVAILABLE_CONNECTIONS:
509 g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_get_available_connections (device)));
512 g_value_set_string (value, nm_device_get_product (device));
515 g_value_set_string (value, nm_device_get_vendor (device));
517 case PROP_PHYSICAL_PORT_ID:
518 g_value_set_string (value, nm_device_get_physical_port_id (device));
521 g_value_set_uint (value, nm_device_get_mtu (device));
524 g_value_set_uint (value, nm_device_get_metered (device));
526 case PROP_LLDP_NEIGHBORS:
527 g_value_set_boxed (value, nm_device_get_lldp_neighbors (device));
530 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
536 set_property (GObject *object,
541 NMDevice *self = NM_DEVICE (object);
542 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
546 case PROP_DEVICE_TYPE:
548 priv->device_type = g_value_get_enum (value);
551 b = g_value_get_boolean (value);
552 if (priv->managed != b)
553 nm_device_set_managed (NM_DEVICE (object), b);
555 case PROP_AUTOCONNECT:
556 b = g_value_get_boolean (value);
557 if (priv->autoconnect != b)
558 nm_device_set_autoconnect (NM_DEVICE (object), b);
561 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
567 nm_device_class_init (NMDeviceClass *device_class)
569 GObjectClass *object_class = G_OBJECT_CLASS (device_class);
570 NMObjectClass *nm_object_class = NM_OBJECT_CLASS (device_class);
572 g_type_class_add_private (device_class, sizeof (NMDevicePrivate));
574 _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE);
575 _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE, NMDBUS_TYPE_DEVICE_PROXY);
577 /* virtual methods */
578 object_class->constructed = constructed;
579 object_class->get_property = get_property;
580 object_class->set_property = set_property;
581 object_class->dispose = dispose;
582 object_class->finalize = finalize;
584 nm_object_class->init_dbus = init_dbus;
586 device_class->connection_compatible = connection_compatible;
591 * NMDevice:interface:
593 * The interface of the device.
595 g_object_class_install_property
596 (object_class, PROP_INTERFACE,
597 g_param_spec_string (NM_DEVICE_INTERFACE, "", "",
600 G_PARAM_STATIC_STRINGS));
603 * NMDevice:ip-interface:
605 * The IP interface of the device which should be used for all IP-related
606 * operations like addressing and routing.
608 g_object_class_install_property
609 (object_class, PROP_IP_INTERFACE,
610 g_param_spec_string (NM_DEVICE_IP_INTERFACE, "", "",
613 G_PARAM_STATIC_STRINGS));
616 * NMDevice:device-type:
618 * The numeric type of the device.
620 g_object_class_install_property
621 (object_class, PROP_DEVICE_TYPE,
622 g_param_spec_enum (NM_DEVICE_DEVICE_TYPE, "", "",
624 NM_DEVICE_TYPE_UNKNOWN,
626 G_PARAM_STATIC_STRINGS));
630 * An operating-system specific device hardware identifier; this is not
631 * unique to a specific hardware device across reboots or hotplugs. It
632 * is an opaque string which for some device types (Bluetooth, Modem)
633 * contains an identifier provided by the underlying hardware service daemon
634 * such as Bluez or ModemManager, and clients can use this property to
635 * request more information about the device from those services.
637 g_object_class_install_property
638 (object_class, PROP_UDI,
639 g_param_spec_string (NM_DEVICE_UDI, "", "",
642 G_PARAM_STATIC_STRINGS));
647 * The driver of the device.
649 g_object_class_install_property
650 (object_class, PROP_DRIVER,
651 g_param_spec_string (NM_DEVICE_DRIVER, "", "",
654 G_PARAM_STATIC_STRINGS));
657 * NMDevice:driver-version:
659 * The version of the device driver.
661 g_object_class_install_property
662 (object_class, PROP_DRIVER_VERSION,
663 g_param_spec_string (NM_DEVICE_DRIVER_VERSION, "", "",
666 G_PARAM_STATIC_STRINGS));
669 * NMDevice:firmware-version:
671 * The firmware version of the device.
673 g_object_class_install_property
674 (object_class, PROP_FIRMWARE_VERSION,
675 g_param_spec_string (NM_DEVICE_FIRMWARE_VERSION, "", "",
678 G_PARAM_STATIC_STRINGS));
681 * NMDevice:capabilities:
683 * The capabilities of the device.
685 g_object_class_install_property
686 (object_class, PROP_CAPABILITIES,
687 g_param_spec_flags (NM_DEVICE_CAPABILITIES, "", "",
688 NM_TYPE_DEVICE_CAPABILITIES,
691 G_PARAM_STATIC_STRINGS));
696 * Whether the device is real or is a placeholder device that could
697 * be created automatically by NetworkManager if one of its
698 * #NMDevice:available-connections was activated.
702 g_object_class_install_property
703 (object_class, PROP_REAL,
704 g_param_spec_boolean (NM_DEVICE_REAL, "", "",
707 G_PARAM_STATIC_STRINGS));
712 * Whether the device is managed by NetworkManager.
714 g_object_class_install_property
715 (object_class, PROP_MANAGED,
716 g_param_spec_boolean (NM_DEVICE_MANAGED, "", "",
719 G_PARAM_STATIC_STRINGS));
722 * NMDevice:autoconnect:
724 * Whether the device can auto-activate a connection.
726 g_object_class_install_property
727 (object_class, PROP_AUTOCONNECT,
728 g_param_spec_boolean (NM_DEVICE_AUTOCONNECT, "", "",
731 G_PARAM_STATIC_STRINGS));
734 * NMDevice:firmware-missing:
736 * When %TRUE indicates the device is likely missing firmware required
739 g_object_class_install_property
740 (object_class, PROP_FIRMWARE_MISSING,
741 g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, "", "",
744 G_PARAM_STATIC_STRINGS));
747 * NMDevice:nm-plugin-missing:
749 * When %TRUE indicates that the NetworkManager plugin for the device
754 g_object_class_install_property
755 (object_class, PROP_NM_PLUGIN_MISSING,
756 g_param_spec_boolean (NM_DEVICE_NM_PLUGIN_MISSING, "", "",
759 G_PARAM_STATIC_STRINGS));
762 * NMDevice:ip4-config:
764 * The #NMIP4Config of the device.
766 g_object_class_install_property
767 (object_class, PROP_IP4_CONFIG,
768 g_param_spec_object (NM_DEVICE_IP4_CONFIG, "", "",
771 G_PARAM_STATIC_STRINGS));
774 * NMDevice:dhcp4-config:
776 * The IPv4 #NMDhcpConfig of the device.
778 g_object_class_install_property
779 (object_class, PROP_DHCP4_CONFIG,
780 g_param_spec_object (NM_DEVICE_DHCP4_CONFIG, "", "",
783 G_PARAM_STATIC_STRINGS));
786 * NMDevice:ip6-config:
788 * The IPv6 #NMIPConfig of the device.
790 g_object_class_install_property
791 (object_class, PROP_IP6_CONFIG,
792 g_param_spec_object (NM_DEVICE_IP6_CONFIG, "", "",
795 G_PARAM_STATIC_STRINGS));
798 * NMDevice:dhcp6-config:
800 * The IPv6 #NMDhcpConfig of the device.
802 g_object_class_install_property
803 (object_class, PROP_DHCP6_CONFIG,
804 g_param_spec_object (NM_DEVICE_DHCP6_CONFIG, "", "",
807 G_PARAM_STATIC_STRINGS));
812 * The state of the device.
814 g_object_class_install_property
815 (object_class, PROP_STATE,
816 g_param_spec_enum (NM_DEVICE_STATE, "", "",
817 NM_TYPE_DEVICE_STATE,
818 NM_DEVICE_STATE_UNKNOWN,
820 G_PARAM_STATIC_STRINGS));
823 * NMDevice:state-reason:
825 * The reason for the device state.
827 g_object_class_install_property
828 (object_class, PROP_STATE_REASON,
829 g_param_spec_uint (NM_DEVICE_STATE_REASON, "", "",
832 G_PARAM_STATIC_STRINGS));
835 * NMDevice:active-connection:
837 * The #NMActiveConnection object that "owns" this device during activation.
839 g_object_class_install_property
840 (object_class, PROP_ACTIVE_CONNECTION,
841 g_param_spec_object (NM_DEVICE_ACTIVE_CONNECTION, "", "",
842 NM_TYPE_ACTIVE_CONNECTION,
844 G_PARAM_STATIC_STRINGS));
847 * NMDevice:available-connections:
849 * The available connections of the device
851 * Element-type: NMRemoteConnection
853 g_object_class_install_property
854 (object_class, PROP_AVAILABLE_CONNECTIONS,
855 g_param_spec_boxed (NM_DEVICE_AVAILABLE_CONNECTIONS, "", "",
858 G_PARAM_STATIC_STRINGS));
863 * The vendor string of the device.
865 g_object_class_install_property
866 (object_class, PROP_VENDOR,
867 g_param_spec_string (NM_DEVICE_VENDOR, "", "",
870 G_PARAM_STATIC_STRINGS));
875 * The product string of the device.
877 g_object_class_install_property
878 (object_class, PROP_PRODUCT,
879 g_param_spec_string (NM_DEVICE_PRODUCT, "", "",
882 G_PARAM_STATIC_STRINGS));
885 * NMDevice:physical-port-id:
887 * The physical port ID of the device. (See
888 * nm_device_get_physical_port_id().)
890 g_object_class_install_property
891 (object_class, PROP_PHYSICAL_PORT_ID,
892 g_param_spec_string (NM_DEVICE_PHYSICAL_PORT_ID, "", "",
895 G_PARAM_STATIC_STRINGS));
900 * The MTU of the device.
902 g_object_class_install_property
903 (object_class, PROP_MTU,
904 g_param_spec_uint (NM_DEVICE_MTU, "", "",
905 0, G_MAXUINT32, 1500,
907 G_PARAM_STATIC_STRINGS));
912 * Whether the device is metered.
916 g_object_class_install_property
917 (object_class, PROP_METERED,
918 g_param_spec_uint (NM_DEVICE_METERED, "", "",
919 0, G_MAXUINT32, NM_METERED_UNKNOWN,
921 G_PARAM_STATIC_STRINGS));
924 * NMDevice:lldp-neighbors:
926 * The LLDP neighbors.
928 g_object_class_install_property
929 (object_class, PROP_LLDP_NEIGHBORS,
930 g_param_spec_boxed (NM_DEVICE_LLDP_NEIGHBORS, "", "",
933 G_PARAM_STATIC_STRINGS));
938 * NMDevice::state-changed:
939 * @device: the device object that received the signal
940 * @new_state: the new state of the device
941 * @old_state: the previous state of the device
942 * @reason: the reason describing the state change
944 * Notifies the state change of a #NMDevice.
946 signals[STATE_CHANGED] =
947 g_signal_new ("state-changed",
948 G_OBJECT_CLASS_TYPE (object_class),
950 G_STRUCT_OFFSET (NMDeviceClass, state_changed),
953 G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
957 * _nm_device_set_device_type:
958 * @device: the device
959 * @dtype: the NM device type
961 * Sets the NM device type if it wasn't set during construction. INTERNAL
965 _nm_device_set_device_type (NMDevice *device, NMDeviceType dtype)
967 NMDevicePrivate *priv;
969 g_return_if_fail (device != NULL);
970 g_return_if_fail (dtype != NM_DEVICE_TYPE_UNKNOWN);
972 priv = NM_DEVICE_GET_PRIVATE (device);
973 if (priv->device_type == NM_DEVICE_TYPE_UNKNOWN)
974 priv->device_type = dtype;
976 g_warn_if_fail (dtype == priv->device_type);
980 _nm_device_decide_type (GVariant *value)
982 return _nm_device_gtype_from_dtype (g_variant_get_uint32 (value));
986 * nm_device_get_iface:
987 * @device: a #NMDevice
989 * Gets the interface name of the #NMDevice.
991 * Returns: the interface of the device. This is the internal string used by the
992 * device, and must not be modified.
995 nm_device_get_iface (NMDevice *device)
997 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
999 return NM_DEVICE_GET_PRIVATE (device)->iface;
1003 * nm_device_get_ip_iface:
1004 * @device: a #NMDevice
1006 * Gets the IP interface name of the #NMDevice over which IP traffic flows
1007 * when the device is in the ACTIVATED state.
1009 * Returns: the IP traffic interface of the device. This is the internal string
1010 * used by the device, and must not be modified.
1013 nm_device_get_ip_iface (NMDevice *device)
1015 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1017 return NM_DEVICE_GET_PRIVATE (device)->ip_iface;
1021 * nm_device_get_device_type:
1022 * @device: a #NMDevice
1024 * Returns the numeric type of the #NMDevice, ie Ethernet, Wi-Fi, etc.
1026 * Returns: the device type
1029 nm_device_get_device_type (NMDevice *self)
1031 g_return_val_if_fail (NM_IS_DEVICE (self), NM_DEVICE_TYPE_UNKNOWN);
1033 return NM_DEVICE_GET_PRIVATE (self)->device_type;
1037 * nm_device_get_udi:
1038 * @device: a #NMDevice
1040 * Gets the Unique Device Identifier of the #NMDevice.
1042 * Returns: the Unique Device Identifier of the device. This identifier may be
1043 * used to gather more information about the device from various operating
1044 * system services like udev or sysfs.
1047 nm_device_get_udi (NMDevice *device)
1049 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1051 return NM_DEVICE_GET_PRIVATE (device)->udi;
1055 * nm_device_get_driver:
1056 * @device: a #NMDevice
1058 * Gets the driver of the #NMDevice.
1060 * Returns: the driver of the device. This is the internal string used by the
1061 * device, and must not be modified.
1064 nm_device_get_driver (NMDevice *device)
1066 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1068 return NM_DEVICE_GET_PRIVATE (device)->driver;
1072 * nm_device_get_driver_version:
1073 * @device: a #NMDevice
1075 * Gets the driver version of the #NMDevice.
1077 * Returns: the version of the device driver. This is the internal string used by the
1078 * device, and must not be modified.
1081 nm_device_get_driver_version (NMDevice *device)
1083 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1085 return NM_DEVICE_GET_PRIVATE (device)->driver_version;
1089 * nm_device_get_firmware_version:
1090 * @device: a #NMDevice
1092 * Gets the firmware version of the #NMDevice.
1094 * Returns: the firmware version of the device. This is the internal string used by the
1095 * device, and must not be modified.
1098 nm_device_get_firmware_version (NMDevice *device)
1100 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1102 return NM_DEVICE_GET_PRIVATE (device)->firmware_version;
1106 * nm_device_get_type_description:
1107 * @device: a #NMDevice
1109 * Gets a (non-localized) description of the type of device that
1112 * Returns: the type description of the device. This is the internal
1113 * string used by the device, and must not be modified.
1116 nm_device_get_type_description (NMDevice *device)
1118 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1119 const char *desc, *typename;
1121 /* BEWARE: this function should return the same value
1122 * as nm_device_get_type_description() in nm-core. */
1124 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1126 if (priv->type_description)
1127 return priv->type_description;
1129 if (NM_DEVICE_GET_CLASS (device)->get_type_description) {
1130 desc = NM_DEVICE_GET_CLASS (device)->get_type_description (device);
1135 typename = G_OBJECT_TYPE_NAME (device);
1136 if (g_str_has_prefix (typename, "NMDevice"))
1138 priv->type_description = g_ascii_strdown (typename, -1);
1140 return priv->type_description;
1144 * nm_device_get_hw_address:
1145 * @device: a #NMDevice
1147 * Gets the current a hardware address (MAC) for the @device.
1149 * Returns: the current MAC of the device, or %NULL.
1150 * This is the internal string used by the device, and must not be modified.
1153 nm_device_get_hw_address (NMDevice *device)
1155 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1157 if (NM_DEVICE_GET_CLASS (device)->get_hw_address)
1158 return NM_DEVICE_GET_CLASS (device)->get_hw_address (device);
1164 * nm_device_get_capabilities:
1165 * @device: a #NMDevice
1167 * Gets the device' capabilities.
1169 * Returns: the capabilities
1171 NMDeviceCapabilities
1172 nm_device_get_capabilities (NMDevice *device)
1174 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1176 return NM_DEVICE_GET_PRIVATE (device)->capabilities;
1180 * nm_device_get_managed:
1181 * @device: a #NMDevice
1183 * Whether the #NMDevice is managed by NetworkManager.
1185 * Returns: %TRUE if the device is managed by NetworkManager
1188 nm_device_get_managed (NMDevice *device)
1190 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1192 return NM_DEVICE_GET_PRIVATE (device)->managed;
1196 * nm_device_set_managed:
1197 * @device: a #NMDevice
1198 * @managed: %TRUE to make the device managed by NetworkManager.
1200 * Enables or disables management of #NMDevice by NetworkManager.
1205 nm_device_set_managed (NMDevice *device, gboolean managed)
1207 g_return_if_fail (NM_IS_DEVICE (device));
1209 managed = !!managed;
1211 NM_DEVICE_GET_PRIVATE (device)->managed = managed;
1213 _nm_object_set_property (NM_OBJECT (device),
1214 NM_DBUS_INTERFACE_DEVICE,
1220 * nm_device_get_autoconnect:
1221 * @device: a #NMDevice
1223 * Whether the #NMDevice can be autoconnected.
1225 * Returns: %TRUE if the device is allowed to be autoconnected
1228 nm_device_get_autoconnect (NMDevice *device)
1230 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1232 return NM_DEVICE_GET_PRIVATE (device)->autoconnect;
1236 * nm_device_set_autoconnect:
1237 * @device: a #NMDevice
1238 * @autoconnect: %TRUE to enable autoconnecting
1240 * Enables or disables automatic activation of the #NMDevice.
1243 nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect)
1245 g_return_if_fail (NM_IS_DEVICE (device));
1247 NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect;
1249 _nm_object_set_property (NM_OBJECT (device),
1250 NM_DBUS_INTERFACE_DEVICE,
1256 * nm_device_get_firmware_missing:
1257 * @device: a #NMDevice
1259 * Indicates that firmware required for the device's operation is likely
1262 * Returns: %TRUE if firmware required for the device's operation is likely
1266 nm_device_get_firmware_missing (NMDevice *device)
1268 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
1270 return NM_DEVICE_GET_PRIVATE (device)->firmware_missing;
1274 * nm_device_get_nm_plugin_missing:
1275 * @device: a #NMDevice
1277 * Indicates that the NetworkManager plugin for the device is not installed.
1279 * Returns: %TRUE if the device plugin not installed.
1284 nm_device_get_nm_plugin_missing (NMDevice *device)
1286 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
1288 return NM_DEVICE_GET_PRIVATE (device)->nm_plugin_missing;
1292 * nm_device_get_ip4_config:
1293 * @device: a #NMDevice
1295 * Gets the current IPv4 #NMIPConfig associated with the #NMDevice.
1297 * You can alternatively use nm_active_connection_get_ip4_config(), which also
1298 * works with VPN connections.
1300 * Returns: (transfer none): the IPv4 #NMIPConfig, or %NULL if the device is not
1304 nm_device_get_ip4_config (NMDevice *device)
1306 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1308 return NM_DEVICE_GET_PRIVATE (device)->ip4_config;
1312 * nm_device_get_dhcp4_config:
1313 * @device: a #NMDevice
1315 * Gets the current IPv4 #NMDhcpConfig associated with the #NMDevice.
1317 * You can alternatively use nm_active_connection_get_dhcp4_config(), which also
1318 * works with VPN connections.
1320 * Returns: (transfer none): the IPv4 #NMDhcpConfig, or %NULL if the device is
1321 * not activated or not using DHCP.
1324 nm_device_get_dhcp4_config (NMDevice *device)
1326 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1328 return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config;
1332 * nm_device_get_ip6_config:
1333 * @device: a #NMDevice
1335 * Gets the current IPv6 #NMIPConfig associated with the #NMDevice.
1337 * You can alternatively use nm_active_connection_get_ip6_config(), which also
1338 * works with VPN connections.
1340 * Returns: (transfer none): the IPv6 #NMIPConfig or %NULL if the device is not activated.
1343 nm_device_get_ip6_config (NMDevice *device)
1345 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1347 return NM_DEVICE_GET_PRIVATE (device)->ip6_config;
1351 * nm_device_get_dhcp6_config:
1352 * @device: a #NMDevice
1354 * Gets the current IPv6 #NMDhcpConfig associated with the #NMDevice.
1356 * You can alternatively use nm_active_connection_get_dhcp6_config(), which also
1357 * works with VPN connections.
1359 * Returns: (transfer none): the IPv6 #NMDhcpConfig, or %NULL if the device is
1360 * not activated or not using DHCPv6.
1363 nm_device_get_dhcp6_config (NMDevice *device)
1365 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1367 return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config;
1371 * nm_device_get_state:
1372 * @device: a #NMDevice
1374 * Gets the current #NMDevice state.
1376 * Returns: the current device state
1379 nm_device_get_state (NMDevice *device)
1381 g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN);
1383 return NM_DEVICE_GET_PRIVATE (device)->state;
1387 * nm_device_get_state_reason:
1388 * @device: a #NMDevice
1390 * Gets the reason for entering the current #NMDevice state.
1392 * Returns: the reason for entering the current device state
1395 nm_device_get_state_reason (NMDevice *device)
1397 g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_REASON_UNKNOWN);
1399 return NM_DEVICE_GET_PRIVATE (device)->reason;
1403 * nm_device_get_active_connection:
1404 * @device: a #NMDevice
1406 * Gets the #NMActiveConnection object which owns this device during activation.
1408 * Returns: (transfer none): the #NMActiveConnection or %NULL if the device is
1409 * not part of an active connection
1411 NMActiveConnection *
1412 nm_device_get_active_connection (NMDevice *device)
1414 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1416 return NM_DEVICE_GET_PRIVATE (device)->active_connection;
1420 * nm_device_get_available_connections:
1421 * @device: a #NMDevice
1423 * Gets the #NMRemoteConnections currently known to the daemon that could
1424 * be activated on @device.
1426 * Returns: (element-type NMRemoteConnection): the #GPtrArray
1427 * containing #NMRemoteConnections. This is the internal copy used by
1428 * the connection, and must not be modified.
1431 nm_device_get_available_connections (NMDevice *device)
1433 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1435 return NM_DEVICE_GET_PRIVATE (device)->available_connections;
1438 static inline guint8
1439 hex2byte (const char *hex)
1442 a = g_ascii_xdigit_value (*hex++);
1445 b = g_ascii_xdigit_value (*hex++);
1448 return (a << 4) | b;
1452 get_decoded_property (GUdevDevice *device, const char *property)
1454 const char *orig, *p;
1455 char *unescaped, *n;
1458 p = orig = g_udev_device_get_property (device, property);
1462 len = strlen (orig);
1463 n = unescaped = g_malloc0 (len + 1);
1465 if ((len >= 4) && (*p == '\\') && (*(p+1) == 'x')) {
1466 *n++ = (char) hex2byte (p + 2);
1479 ensure_udev_client (NMDevice *device)
1481 static const char *const subsys[3] = { "net", "tty", NULL };
1482 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1485 priv->client = g_udev_client_new (subsys);
1487 return priv->client != NULL;
1491 _get_udev_property (NMDevice *device,
1492 const char *enc_prop, /* ID_XXX_ENC */
1493 const char *db_prop) /* ID_XXX_FROM_DATABASE */
1495 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1496 GUdevDevice *udev_device = NULL, *tmpdev, *olddev;
1499 char *enc_value = NULL, *db_value = NULL;
1501 if (!ensure_udev_client (device))
1504 ifname = nm_device_get_iface (device);
1508 udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
1510 udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
1514 /* Walk up the chain of the device and its parents a few steps to grab
1515 * vendor and device ID information off it.
1518 /* Ref the device again because we have to unref it each iteration,
1519 * as g_udev_device_get_parent() returns a ref-ed object.
1521 tmpdev = g_object_ref (udev_device);
1522 while ((count++ < 3) && tmpdev && !enc_value) {
1524 enc_value = get_decoded_property (tmpdev, enc_prop);
1526 db_value = g_strdup (g_udev_device_get_property (tmpdev, db_prop));
1529 tmpdev = g_udev_device_get_parent (tmpdev);
1530 g_object_unref (olddev);
1533 /* Unref the last device if we found what we needed before running out
1537 g_object_unref (tmpdev);
1539 /* Balance the initial g_udev_client_query_by_subsystem_and_name() */
1540 g_object_unref (udev_device);
1542 /* Prefer the encoded value which comes directly from the device
1543 * over the hwdata database value.
1554 * nm_device_get_product:
1555 * @device: a #NMDevice
1557 * Gets the product string of the #NMDevice.
1559 * Returns: the product name of the device. This is the internal string used by the
1560 * device, and must not be modified.
1563 nm_device_get_product (NMDevice *device)
1565 NMDevicePrivate *priv;
1567 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1569 priv = NM_DEVICE_GET_PRIVATE (device);
1571 priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE");
1573 /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */
1575 priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE");
1578 priv->product = g_strdup ("");
1580 return priv->product;
1584 * nm_device_get_vendor:
1585 * @device: a #NMDevice
1587 * Gets the vendor string of the #NMDevice.
1589 * Returns: the vendor name of the device. This is the internal string used by the
1590 * device, and must not be modified.
1593 nm_device_get_vendor (NMDevice *device)
1595 NMDevicePrivate *priv;
1597 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1599 priv = NM_DEVICE_GET_PRIVATE (device);
1602 priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE");
1605 priv->vendor = g_strdup ("");
1607 return priv->vendor;
1610 static const char * const ignored_words[] = {
1633 static const char * const ignored_phrases[] = {
1634 "Multiprotocol MAC/baseband processor",
1635 "Wireless LAN Controller",
1636 "Wireless LAN Adapter",
1638 "Network Connection",
1639 "Wireless Cardbus Adapter",
1640 "Wireless CardBus Adapter",
1641 "54 Mbps Wireless PC Card",
1644 "PC Card with XJACK(r) Antenna",
1646 "Wireless LAN PC Card",
1647 "Technology Group Ltd.",
1648 "Communication S.p.A.",
1649 "Business Mobile Networks BV",
1650 "Mobile Broadband Minicard Composite Device",
1651 "Mobile Communications AB",
1657 fixup_desc_string (const char *desc)
1660 char **words, **item;
1667 p = temp = g_strdup (desc);
1669 if (*p == '_' || *p == ',')
1674 /* Attempt to shorten ID by ignoring certain phrases */
1675 for (i = 0; ignored_phrases[i]; i++) {
1676 p = strstr (temp, ignored_phrases[i]);
1678 guint32 ignored_len = strlen (ignored_phrases[i]);
1680 memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
1684 /* Attempt to shorten ID by ignoring certain individual words */
1685 words = g_strsplit (temp, " ", 0);
1686 str = g_string_new_len (NULL, strlen (temp));
1689 for (item = words; *item; item++) {
1690 gboolean ignore = FALSE;
1695 for (i = 0; ignored_words[i]; i++) {
1696 if (!strcmp (*item, ignored_words[i])) {
1704 g_string_append_c (str, ' ');
1705 g_string_append (str, *item);
1711 g_string_free (str, FALSE);
1717 get_description (NMDevice *device)
1719 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1720 const char *dev_product;
1721 const char *dev_vendor;
1726 dev_product = nm_device_get_product (device);
1727 priv->short_product = fixup_desc_string (dev_product);
1729 dev_vendor = nm_device_get_vendor (device);
1730 priv->short_vendor = fixup_desc_string (dev_vendor);
1732 if (!dev_product || !dev_vendor) {
1733 priv->description = g_strdup (nm_device_get_iface (device));
1737 str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1);
1739 /* Another quick hack; if all of the fixed up vendor string
1740 * is found in product, ignore the vendor.
1742 pdown = g_ascii_strdown (priv->short_product, -1);
1743 vdown = g_ascii_strdown (priv->short_vendor, -1);
1744 if (!strstr (pdown, vdown)) {
1745 g_string_append (str, priv->short_vendor);
1746 g_string_append_c (str, ' ');
1751 g_string_append (str, priv->short_product);
1753 priv->description = g_string_free (str, FALSE);
1757 get_short_vendor (NMDevice *device)
1759 NMDevicePrivate *priv;
1761 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1763 priv = NM_DEVICE_GET_PRIVATE (device);
1765 if (!priv->description)
1766 get_description (device);
1768 return priv->short_vendor;
1772 * nm_device_get_description:
1773 * @device: an #NMDevice
1775 * Gets a description of @device, based on its vendor and product names.
1777 * Returns: a description of @device. If either the vendor or the
1778 * product name is unknown, this returns the interface name.
1781 nm_device_get_description (NMDevice *device)
1783 NMDevicePrivate *priv;
1785 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
1787 priv = NM_DEVICE_GET_PRIVATE (device);
1789 if (!priv->description)
1790 get_description (device);
1792 return priv->description;
1796 get_type_name (NMDevice *device)
1798 switch (nm_device_get_device_type (device)) {
1799 case NM_DEVICE_TYPE_ETHERNET:
1800 return _("Ethernet");
1801 case NM_DEVICE_TYPE_WIFI:
1803 case NM_DEVICE_TYPE_BT:
1804 return _("Bluetooth");
1805 case NM_DEVICE_TYPE_OLPC_MESH:
1806 return _("OLPC Mesh");
1807 case NM_DEVICE_TYPE_WIMAX:
1809 case NM_DEVICE_TYPE_MODEM:
1810 return _("Mobile Broadband");
1811 case NM_DEVICE_TYPE_INFINIBAND:
1812 return _("InfiniBand");
1813 case NM_DEVICE_TYPE_BOND:
1815 case NM_DEVICE_TYPE_TEAM:
1817 case NM_DEVICE_TYPE_BRIDGE:
1819 case NM_DEVICE_TYPE_VLAN:
1821 case NM_DEVICE_TYPE_ADSL:
1823 case NM_DEVICE_TYPE_MACVLAN:
1824 return _("MACVLAN");
1825 case NM_DEVICE_TYPE_VXLAN:
1827 case NM_DEVICE_TYPE_IP_TUNNEL:
1828 return _("IPTunnel");
1829 case NM_DEVICE_TYPE_TUN:
1831 case NM_DEVICE_TYPE_VETH:
1833 case NM_DEVICE_TYPE_GENERIC:
1834 case NM_DEVICE_TYPE_UNUSED1:
1835 case NM_DEVICE_TYPE_UNUSED2:
1836 case NM_DEVICE_TYPE_UNKNOWN:
1839 return _("Unknown");
1843 get_device_type_name_with_iface (NMDevice *device)
1845 const char *type_name = get_type_name (device);
1847 switch (nm_device_get_device_type (device)) {
1848 case NM_DEVICE_TYPE_BOND:
1849 case NM_DEVICE_TYPE_TEAM:
1850 case NM_DEVICE_TYPE_BRIDGE:
1851 case NM_DEVICE_TYPE_VLAN:
1852 return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device));
1854 return g_strdup (type_name);
1859 get_device_generic_type_name_with_iface (NMDevice *device)
1861 switch (nm_device_get_device_type (device)) {
1862 case NM_DEVICE_TYPE_ETHERNET:
1863 case NM_DEVICE_TYPE_INFINIBAND:
1864 return g_strdup (_("Wired"));
1866 return get_device_type_name_with_iface (device);
1871 get_bus_name (NMDevice *device)
1873 NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
1874 GUdevDevice *udevice;
1875 const char *ifname, *bus;
1880 if (!ensure_udev_client (device))
1883 ifname = nm_device_get_iface (device);
1887 udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
1889 udevice = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
1893 bus = g_udev_device_get_property (udevice, "ID_BUS");
1894 if (!g_strcmp0 (bus, "pci"))
1895 priv->bus_name = g_strdup (_("PCI"));
1896 else if (!g_strcmp0 (bus, "usb"))
1897 priv->bus_name = g_strdup (_("USB"));
1899 /* Use "" instead of NULL so we can tell later that we've
1902 priv->bus_name = g_strdup ("");
1906 if (*priv->bus_name)
1907 return priv->bus_name;
1913 find_duplicates (char **names,
1914 gboolean *duplicates,
1918 gboolean found_any = FALSE;
1920 memset (duplicates, 0, num_devices * sizeof (gboolean));
1921 for (i = 0; i < num_devices; i++) {
1924 for (j = i + 1; j < num_devices; j++) {
1927 if (!strcmp (names[i], names[j]))
1928 duplicates[i] = duplicates[j] = found_any = TRUE;
1936 * nm_device_disambiguate_names:
1937 * @devices: (array length=num_devices): an array of #NMDevice
1938 * @num_devices: length of @devices
1940 * Generates a list of short-ish unique presentation names for the
1941 * devices in @devices.
1943 * Returns: (transfer full) (array zero-terminated=1): the device names
1946 nm_device_disambiguate_names (NMDevice **devices,
1950 gboolean *duplicates;
1953 names = g_new (char *, num_devices + 1);
1954 duplicates = g_new (gboolean, num_devices);
1956 /* Generic device name */
1957 for (i = 0; i < num_devices; i++)
1958 names[i] = get_device_generic_type_name_with_iface (devices[i]);
1959 if (!find_duplicates (names, duplicates, num_devices))
1962 /* Try specific names (eg, "Ethernet" and "InfiniBand" rather
1965 for (i = 0; i < num_devices; i++) {
1966 if (duplicates[i]) {
1968 names[i] = get_device_type_name_with_iface (devices[i]);
1971 if (!find_duplicates (names, duplicates, num_devices))
1974 /* Try prefixing bus name (eg, "PCI Ethernet" vs "USB Ethernet") */
1975 for (i = 0; i < num_devices; i++) {
1976 if (duplicates[i]) {
1977 const char *bus = get_bus_name (devices[i]);
1984 name = get_device_type_name_with_iface (devices[i]);
1985 /* Translators: the first %s is a bus name (eg, "USB") or
1986 * product name, the second is a device type (eg,
1987 * "Ethernet"). You can change this to something like
1988 * "%2$s (%1$s)" if there's no grammatical way to combine
1989 * the strings otherwise.
1991 names[i] = g_strdup_printf (C_("long device name", "%s %s"),
1996 if (!find_duplicates (names, duplicates, num_devices))
1999 /* Try prefixing vendor name */
2000 for (i = 0; i < num_devices; i++) {
2001 if (duplicates[i]) {
2002 const char *vendor = get_short_vendor (devices[i]);
2009 name = get_device_type_name_with_iface (devices[i]);
2010 names[i] = g_strdup_printf (C_("long device name", "%s %s"),
2012 get_type_name (devices[i]));
2016 if (!find_duplicates (names, duplicates, num_devices))
2019 /* If dealing with Bluetooth devices, try to distinguish them by
2022 for (i = 0; i < num_devices; i++) {
2023 if (duplicates[i] && NM_IS_DEVICE_BT (devices[i])) {
2024 const char *devname = nm_device_bt_get_name (NM_DEVICE_BT (devices[i]));
2030 names[i] = g_strdup_printf ("%s (%s)",
2031 get_device_type_name_with_iface (devices[i]),
2035 if (!find_duplicates (names, duplicates, num_devices))
2038 /* We have multiple identical network cards, so we have to differentiate
2039 * them by interface name.
2041 for (i = 0; i < num_devices; i++) {
2042 if (duplicates[i]) {
2043 const char *interface = nm_device_get_iface (devices[i]);
2049 names[i] = g_strdup_printf ("%s (%s)",
2050 get_type_name (devices[i]),
2056 g_free (duplicates);
2057 names[num_devices] = NULL;
2062 * nm_device_get_physical_port_id:
2063 * @device: a #NMDevice
2065 * Gets the physical port ID of the #NMDevice. If non-%NULL, this is
2066 * an opaque string that can be used to recognize when
2067 * seemingly-unrelated #NMDevices are actually just different virtual
2068 * ports on a single physical port. (Eg, NPAR / SR-IOV.)
2070 * Returns: the physical port ID of the device, or %NULL if the port
2071 * ID is unknown. This is the internal string used by the device and
2072 * must not be modified.
2075 nm_device_get_physical_port_id (NMDevice *device)
2077 NMDevicePrivate *priv;
2079 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2081 priv = NM_DEVICE_GET_PRIVATE (device);
2083 if (priv->physical_port_id && *priv->physical_port_id)
2084 return priv->physical_port_id;
2090 * nm_device_get_mtu:
2091 * @device: a #NMDevice
2093 * Gets the MTU of the #NMDevice.
2095 * Returns: the MTU of the device.
2098 nm_device_get_mtu (NMDevice *device)
2100 g_return_val_if_fail (NM_IS_DEVICE (device), 0);
2102 return NM_DEVICE_GET_PRIVATE (device)->mtu;
2106 * nm_device_get_metered:
2107 * @device: a #NMDevice
2109 * Gets the metered setting of a #NMDevice.
2111 * Returns: the metered setting.
2116 nm_device_get_metered (NMDevice *device)
2118 g_return_val_if_fail (NM_IS_DEVICE (device), NM_METERED_UNKNOWN);
2120 return NM_DEVICE_GET_PRIVATE (device)->metered;
2123 NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_device_get_metered, (NMDevice *device), (device));
2126 * nm_device_get_lldp_neighbors:
2127 * @device: a #NMDevice
2129 * Gets the list of neighbors discovered through LLDP.
2131 * Returns: (element-type NMLldpNeighbor) (transfer none): the #GPtrArray
2132 * containing #NMLldpNeighbor<!-- -->s. This is the internal copy used by the
2133 * device and must not be modified. The library never modifies the returned
2134 * array and thus it is safe for callers to reference and keep using it.
2139 nm_device_get_lldp_neighbors (NMDevice *device)
2141 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2143 return NM_DEVICE_GET_PRIVATE (device)->lldp_neighbors;
2147 * nm_device_is_real:
2148 * @device: a #NMDevice
2150 * Returns: %TRUE if the device exists, or %FALSE if it is a placeholder device
2151 * that could be automatically created by NetworkManager if one of its
2152 * #NMDevice:available-connections was activated.
2157 nm_device_is_real (NMDevice *device)
2159 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2161 return NM_DEVICE_GET_PRIVATE (device)->real;
2165 * nm_device_is_software:
2166 * @device: a #NMDevice
2168 * Whether the device is a software device.
2170 * 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 return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE);
2181 * nm_device_reapply:
2182 * @device: a #NMDevice
2183 * @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
2184 * @version_id: zero or the expected version id of the applied connection. If specified
2185 * and the version id mismatches, the call fails without modification. This allows to
2186 * catch concurrent accesses.
2187 * @flags: always set this to zero
2188 * @cancellable: a #GCancellable, or %NULL
2189 * @error: location for a #GError, or %NULL
2191 * Attempts to update device with changes to the currently active connection
2192 * made since it was last applied.
2194 * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
2199 nm_device_reapply (NMDevice *device,
2200 NMConnection *connection,
2203 GCancellable *cancellable,
2206 GVariant *dict = NULL;
2209 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2212 dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
2214 dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
2217 ret = nmdbus_device_call_reapply_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
2218 dict, version_id, flags, cancellable, error);
2219 if (error && *error)
2220 g_dbus_error_strip_remote_error (*error);
2225 device_reapply_cb (GObject *proxy,
2226 GAsyncResult *result,
2229 GSimpleAsyncResult *simple = user_data;
2230 GError *error = NULL;
2232 if (nmdbus_device_call_reapply_finish (NMDBUS_DEVICE (proxy), result, &error))
2233 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
2235 g_dbus_error_strip_remote_error (error);
2236 g_simple_async_result_take_error (simple, error);
2239 g_simple_async_result_complete (simple);
2240 g_object_unref (simple);
2244 * nm_device_reapply_async:
2245 * @device: a #NMDevice
2246 * @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
2247 * @version_id: zero or the expected version id of the applied connection. If specified
2248 * and the version id mismatches, the call fails without modification. This allows to
2249 * catch concurrent accesses.
2250 * @flags: always set this to zero
2251 * @cancellable: a #GCancellable, or %NULL
2252 * @callback: callback to be called when the reapply operation completes
2253 * @user_data: caller-specific data passed to @callback
2255 * Asynchronously begins an attempt to update device with changes to the
2256 * currently active connection made since it was last applied.
2261 nm_device_reapply_async (NMDevice *device,
2262 NMConnection *connection,
2265 GCancellable *cancellable,
2266 GAsyncReadyCallback callback,
2269 GVariant *dict = NULL;
2270 GSimpleAsyncResult *simple;
2272 g_return_if_fail (NM_IS_DEVICE (device));
2275 dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
2277 dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
2279 simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
2280 nm_device_reapply_async);
2282 nmdbus_device_call_reapply (NM_DEVICE_GET_PRIVATE (device)->proxy,
2283 dict, version_id, flags, cancellable,
2284 device_reapply_cb, simple);
2288 * nm_device_reapply_finish:
2289 * @device: a #NMDevice
2290 * @result: the result passed to the #GAsyncReadyCallback
2291 * @error: location for a #GError, or %NULL
2293 * Gets the result of a call to nm_device_reapply_async().
2295 * Returns: %TRUE on success, %FALSE on error, in which case @error
2301 nm_device_reapply_finish (NMDevice *device,
2302 GAsyncResult *result,
2305 GSimpleAsyncResult *simple;
2307 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_reapply_async), FALSE);
2309 simple = G_SIMPLE_ASYNC_RESULT (result);
2310 if (g_simple_async_result_propagate_error (simple, error))
2313 return g_simple_async_result_get_op_res_gboolean (simple);
2316 /*****************************************************************************/
2319 * nm_device_get_applied_connection:
2320 * @device: a #NMDevice
2321 * @flags: the flags argument. Currently this value must always be zero.
2322 * @version_id: (out): (allow-none): returns the current version id of
2323 * the applied connection
2324 * @cancellable: a #GCancellable, or %NULL
2325 * @error: location for a #GError, or %NULL
2327 * Fetch the currently applied connection on the device.
2329 * Returns: (transfer full): a %NMConnection with the currently applied settings
2330 * or %NULL on error.
2335 nm_device_get_applied_connection (NMDevice *device,
2337 guint64 *version_id,
2338 GCancellable *cancellable,
2341 gs_unref_variant GVariant *dict = NULL;
2342 guint64 my_version_id;
2344 NMConnection *connection;
2346 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2347 g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
2348 g_return_val_if_fail (!error || !*error, NULL);
2350 success = nmdbus_device_call_get_applied_connection_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
2351 flags, &dict, &my_version_id, cancellable, error);
2353 if (error && *error)
2354 g_dbus_error_strip_remote_error (*error);
2358 connection = _nm_simple_connection_new_from_dbus (dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, error);
2362 NM_SET_OUT (version_id, my_version_id);
2367 NMConnection *connection;
2369 } GetAppliedConnectionData;
2372 device_get_applied_connection_data_free (gpointer user_data)
2374 GetAppliedConnectionData *data = user_data;
2376 g_return_if_fail (data);
2378 g_object_unref (data->connection);
2379 g_slice_free (GetAppliedConnectionData, data);
2383 device_get_applied_connection_cb (GObject *proxy,
2384 GAsyncResult *result,
2387 gs_unref_object GSimpleAsyncResult *simple = user_data;
2388 gs_unref_variant GVariant *dict = NULL;
2389 guint64 my_version_id;
2390 GError *error = NULL;
2391 NMConnection *connection;
2392 GetAppliedConnectionData *data;
2394 if (!nmdbus_device_call_get_applied_connection_finish (NMDBUS_DEVICE (proxy), &dict, &my_version_id, result, &error)) {
2395 g_dbus_error_strip_remote_error (error);
2396 g_simple_async_result_take_error (simple, error);
2400 connection = _nm_simple_connection_new_from_dbus (dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error);
2402 g_simple_async_result_take_error (simple, error);
2406 data = g_slice_new (GetAppliedConnectionData);
2407 data->connection = connection;
2408 data->version_id = my_version_id;
2409 g_simple_async_result_set_op_res_gpointer (simple, data, device_get_applied_connection_data_free);
2412 g_simple_async_result_complete (simple);
2416 * nm_device_get_applied_connection_async:
2417 * @device: a #NMDevice
2418 * @flags: the flags argument. Currently this value must always be zero.
2419 * @cancellable: a #GCancellable, or %NULL
2420 * @callback: callback to be called when the reapply operation completes
2421 * @user_data: caller-specific data passed to @callback
2423 * Asynchronously begins an get the a currently applied connection.
2428 nm_device_get_applied_connection_async (NMDevice *device,
2430 GCancellable *cancellable,
2431 GAsyncReadyCallback callback,
2434 GSimpleAsyncResult *simple;
2436 g_return_if_fail (NM_IS_DEVICE (device));
2437 g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
2439 simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
2440 nm_device_get_applied_connection_async);
2442 nmdbus_device_call_get_applied_connection (NM_DEVICE_GET_PRIVATE (device)->proxy,
2444 device_get_applied_connection_cb, simple);
2448 * nm_device_get_applied_connection_finish:
2449 * @device: a #NMDevice
2450 * @result: the result passed to the #GAsyncReadyCallback
2451 * @version_id: (out): (allow-none): the current version id of the applied
2453 * @error: location for a #GError, or %NULL
2455 * Gets the result of a call to nm_device_get_applied_connection_async().
2457 * Returns: (transfer full): a currently applied %NMConnection or %NULL in case
2463 nm_device_get_applied_connection_finish (NMDevice *device,
2464 GAsyncResult *result,
2465 guint64 *version_id,
2468 GSimpleAsyncResult *simple;
2469 GetAppliedConnectionData *data;
2471 g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
2472 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_get_applied_connection_async), NULL);
2473 g_return_val_if_fail (!error || !*error, NULL);
2475 simple = G_SIMPLE_ASYNC_RESULT (result);
2476 if (g_simple_async_result_propagate_error (simple, error))
2479 data = g_simple_async_result_get_op_res_gpointer (simple);
2480 g_return_val_if_fail (data, NULL);
2481 g_return_val_if_fail (NM_IS_CONNECTION (data->connection), NULL);
2483 NM_SET_OUT (version_id, data->version_id);
2484 return g_object_ref (data->connection);
2487 /*****************************************************************************/
2490 * nm_device_disconnect:
2491 * @device: a #NMDevice
2492 * @cancellable: a #GCancellable, or %NULL
2493 * @error: location for a #GError, or %NULL
2495 * Disconnects the device if currently connected, and prevents the device from
2496 * automatically connecting to networks until the next manual network connection
2499 * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
2502 nm_device_disconnect (NMDevice *device,
2503 GCancellable *cancellable,
2508 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2510 ret = nmdbus_device_call_disconnect_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
2511 cancellable, error);
2512 if (error && *error)
2513 g_dbus_error_strip_remote_error (*error);
2518 device_disconnect_cb (GObject *proxy,
2519 GAsyncResult *result,
2522 GSimpleAsyncResult *simple = user_data;
2523 GError *error = NULL;
2525 if (nmdbus_device_call_disconnect_finish (NMDBUS_DEVICE (proxy), result, &error))
2526 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
2528 g_dbus_error_strip_remote_error (error);
2529 g_simple_async_result_take_error (simple, error);
2532 g_simple_async_result_complete (simple);
2533 g_object_unref (simple);
2537 * nm_device_disconnect_async:
2538 * @device: a #NMDevice
2539 * @cancellable: a #GCancellable, or %NULL
2540 * @callback: callback to be called when the disconnect operation completes
2541 * @user_data: caller-specific data passed to @callback
2543 * Asynchronously begins disconnecting the device if currently connected, and
2544 * prevents the device from automatically connecting to networks until the next
2545 * manual network connection request.
2548 nm_device_disconnect_async (NMDevice *device,
2549 GCancellable *cancellable,
2550 GAsyncReadyCallback callback,
2553 GSimpleAsyncResult *simple;
2555 g_return_if_fail (NM_IS_DEVICE (device));
2557 simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
2558 nm_device_disconnect_async);
2560 nmdbus_device_call_disconnect (NM_DEVICE_GET_PRIVATE (device)->proxy,
2562 device_disconnect_cb, simple);
2566 * nm_device_disconnect_finish:
2567 * @device: a #NMDevice
2568 * @result: the result passed to the #GAsyncReadyCallback
2569 * @error: location for a #GError, or %NULL
2571 * Gets the result of a call to nm_device_disconnect_async().
2573 * Returns: %TRUE on success, %FALSE on error, in which case @error
2577 nm_device_disconnect_finish (NMDevice *device,
2578 GAsyncResult *result,
2581 GSimpleAsyncResult *simple;
2583 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_disconnect_async), FALSE);
2585 simple = G_SIMPLE_ASYNC_RESULT (result);
2586 if (g_simple_async_result_propagate_error (simple, error))
2589 return g_simple_async_result_get_op_res_gboolean (simple);
2594 * @device: a #NMDevice
2595 * @cancellable: a #GCancellable, or %NULL
2596 * @error: location for a #GError, or %NULL
2598 * Deletes the software device. Hardware devices can't be deleted.
2600 * Returns: %TRUE on success, %FALSE on error, in which case @error
2604 nm_device_delete (NMDevice *device,
2605 GCancellable *cancellable,
2610 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2612 ret = nmdbus_device_call_delete_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
2613 cancellable, error);
2614 if (error && *error)
2615 g_dbus_error_strip_remote_error (*error);
2620 device_delete_cb (GObject *proxy,
2621 GAsyncResult *result,
2624 GSimpleAsyncResult *simple = user_data;
2625 GError *error = NULL;
2627 if (nmdbus_device_call_delete_finish (NMDBUS_DEVICE (proxy), result, &error))
2628 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
2630 g_dbus_error_strip_remote_error (error);
2631 g_simple_async_result_take_error (simple, error);
2634 g_simple_async_result_complete (simple);
2635 g_object_unref (simple);
2639 * nm_device_delete_async:
2640 * @device: a #NMDevice
2641 * @cancellable: a #GCancellable, or %NULL
2642 * @callback: callback to be called when delete operation completes
2643 * @user_data: caller-specific data passed to @callback
2645 * Asynchronously begins deleteing the software device. Hardware devices can't
2649 nm_device_delete_async (NMDevice *device,
2650 GCancellable *cancellable,
2651 GAsyncReadyCallback callback,
2654 GSimpleAsyncResult *simple;
2656 g_return_if_fail (NM_IS_DEVICE (device));
2658 simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
2659 nm_device_delete_async);
2661 nmdbus_device_call_delete (NM_DEVICE_GET_PRIVATE (device)->proxy,
2663 device_delete_cb, simple);
2667 * nm_device_delete_finish:
2668 * @device: a #NMDevice
2669 * @result: the result passed to the #GAsyncReadyCallback
2670 * @error: location for a #GError, or %NULL
2672 * Gets the result of a call to nm_device_delete_async().
2674 * Returns: %TRUE on success, %FALSE on error, in which case @error
2678 nm_device_delete_finish (NMDevice *device,
2679 GAsyncResult *result,
2682 GSimpleAsyncResult *simple;
2684 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_delete_async), FALSE);
2686 simple = G_SIMPLE_ASYNC_RESULT (result);
2687 if (g_simple_async_result_propagate_error (simple, error))
2690 return g_simple_async_result_get_op_res_gboolean (simple);
2694 * nm_device_connection_valid:
2695 * @device: an #NMDevice to validate @connection against
2696 * @connection: an #NMConnection to validate against @device
2698 * Validates a given connection for a given #NMDevice object and returns
2699 * whether the connection may be activated with the device. For example if
2700 * @device is a Wi-Fi device that supports only WEP encryption, the connection
2701 * will only be valid if it is a Wi-Fi connection which describes a WEP or open
2702 * network, and will not be valid if it describes a WPA network, or if it is
2703 * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the
2706 * Returns: %TRUE if the connection may be activated with this device, %FALSE
2707 * if is incompatible with the device's capabilities and characteristics.
2710 nm_device_connection_valid (NMDevice *device, NMConnection *connection)
2712 return nm_device_connection_compatible (device, connection, NULL);
2716 connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
2718 const char *config_iface, *device_iface;
2719 GError *local = NULL;
2721 if (!nm_connection_verify (connection, &local)) {
2722 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
2723 _("The connection was not valid: %s"), local->message);
2724 g_error_free (local);
2728 config_iface = nm_connection_get_interface_name (connection);
2729 device_iface = nm_device_get_iface (device);
2730 if (config_iface && g_strcmp0 (config_iface, device_iface) != 0) {
2731 g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
2732 _("The interface names of the device and the connection didn't match."));
2740 * nm_device_connection_compatible:
2741 * @device: an #NMDevice to validate @connection against
2742 * @connection: an #NMConnection to validate against @device
2743 * @error: return location for a #GError, or %NULL
2745 * Validates a given connection for a given #NMDevice object and returns
2746 * whether the connection may be activated with the device. For example if
2747 * @device is a Wi-Fi device that supports only WEP encryption, the connection
2748 * will only be valid if it is a Wi-Fi connection which describes a WEP or open
2749 * network, and will not be valid if it describes a WPA network, or if it is
2750 * an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the
2753 * This function does the same as nm_device_connection_valid(), i.e. checking
2754 * compatibility of the given device and connection. But, in addition, it sets
2755 * GError when FALSE is returned.
2757 * Returns: %TRUE if the connection may be activated with this device, %FALSE
2758 * if is incompatible with the device's capabilities and characteristics.
2761 nm_device_connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
2763 g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
2764 g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
2765 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2767 return NM_DEVICE_GET_CLASS (device)->connection_compatible (device, connection, error);
2771 * nm_device_filter_connections:
2772 * @device: an #NMDevice to filter connections for
2773 * @connections: (element-type NMConnection): an array of #NMConnections to filter
2775 * Filters a given array of connections for a given #NMDevice object and returns
2776 * connections which may be activated with the device. For example if @device
2777 * is a Wi-Fi device that supports only WEP encryption, the returned array will
2778 * contain any Wi-Fi connections in @connections that allow connection to
2779 * unencrypted or WEP-enabled SSIDs. The returned array will not contain
2780 * Ethernet, Bluetooth, Wi-Fi WPA connections, or any other connection that is
2781 * incompatible with the device. To get the full list of connections see
2782 * nm_client_get_connections().
2784 * Returns: (transfer container) (element-type NMConnection): an array of
2785 * #NMConnections that could be activated with the given @device. The array
2786 * should be freed with g_ptr_array_unref() when it is no longer required.
2789 nm_device_filter_connections (NMDevice *device, const GPtrArray *connections)
2791 GPtrArray *filtered;
2794 filtered = g_ptr_array_new_with_free_func (g_object_unref);
2795 for (i = 0; i < connections->len; i++) {
2796 NMConnection *candidate = connections->pdata[i];
2798 /* Connection applies to this device */
2799 if (nm_device_connection_valid (device, candidate))
2800 g_ptr_array_add (filtered, g_object_ref (candidate));
2807 * nm_device_get_setting_type:
2808 * @device: an #NMDevice
2810 * Gets the (primary) #NMSetting subtype associated with connections
2811 * that can be used on @device.
2813 * Returns: @device's associated #NMSetting type
2816 nm_device_get_setting_type (NMDevice *device)
2818 g_return_val_if_fail (NM_IS_DEVICE (device), G_TYPE_INVALID);
2819 g_return_val_if_fail (NM_DEVICE_GET_CLASS (device)->get_setting_type != NULL, G_TYPE_INVALID);
2821 return NM_DEVICE_GET_CLASS (device)->get_setting_type (device);
2825 * nm_lldp_neighbor_new:
2827 * Creates a new #NMLldpNeighbor object.
2829 * Returns: (transfer full): the new #NMLldpNeighbor object.
2834 nm_lldp_neighbor_new (void)
2836 NMLldpNeighbor *neigh;
2838 neigh = g_new0 (NMLldpNeighbor, 1);
2839 neigh->refcount = 1;
2840 neigh->attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
2841 (GDestroyNotify) g_variant_unref);
2846 static NMLldpNeighbor *
2847 nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor)
2849 NMLldpNeighbor *copy;
2851 copy = nm_lldp_neighbor_new ();
2852 copy->attrs = g_hash_table_ref (neighbor->attrs);
2858 * nm_lldp_neighbor_ref:
2859 * @neighbor: the #NMLldpNeighbor
2861 * Increases the reference count of the object.
2866 nm_lldp_neighbor_ref (NMLldpNeighbor *neighbor)
2868 g_return_if_fail (neighbor);
2869 g_return_if_fail (neighbor->refcount > 0);
2871 neighbor->refcount++;
2875 * nm_lldp_neighbor_unref:
2876 * @neighbor: the #NMLldpNeighbor
2878 * Decreases the reference count of the object. If the reference count
2879 * reaches zero, the object will be destroyed.
2884 nm_lldp_neighbor_unref (NMLldpNeighbor *neighbor)
2886 g_return_if_fail (neighbor);
2887 g_return_if_fail (neighbor->refcount > 0);
2889 if (--neighbor->refcount == 0) {
2890 g_return_if_fail (neighbor->attrs);
2891 g_hash_table_unref (neighbor->attrs);
2897 * nm_lldp_neighbor_get_attr_names:
2898 * @neighbor: the #NMLldpNeighbor
2900 * Gets an array of attribute names available for @neighbor.
2902 * Returns: (transfer full): a %NULL-terminated array of attribute names.
2907 nm_lldp_neighbor_get_attr_names (NMLldpNeighbor *neighbor)
2909 GHashTableIter iter;
2913 g_return_val_if_fail (neighbor, NULL);
2914 g_return_val_if_fail (neighbor->attrs, NULL);
2916 names = g_ptr_array_new ();
2918 g_hash_table_iter_init (&iter, neighbor->attrs);
2919 while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
2920 g_ptr_array_add (names, g_strdup (key));
2922 g_ptr_array_add (names, NULL);
2924 return (char **) g_ptr_array_free (names, FALSE);
2928 * nm_lldp_neighbor_get_attr_string_value:
2929 * @neighbor: the #NMLldpNeighbor
2930 * @name: the attribute name
2931 * @out_value: (out) (allow-none) (transfer none): on return, the attribute value
2933 * Gets the string value of attribute with name @name on @neighbor
2935 * Returns: %TRUE if a string attribute with name @name was found, %FALSE otherwise
2940 nm_lldp_neighbor_get_attr_string_value (NMLldpNeighbor *neighbor, char *name,
2941 const char **out_value)
2945 g_return_val_if_fail (neighbor, FALSE);
2946 g_return_val_if_fail (name && name[0], FALSE);
2948 variant = g_hash_table_lookup (neighbor->attrs, name);
2949 if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
2951 *out_value = g_variant_get_string (variant, NULL);
2958 * nm_lldp_neighbor_get_attr_uint_value:
2959 * @neighbor: the #NMLldpNeighbor
2960 * @name: the attribute name
2961 * @out_value: (out) (allow-none): on return, the attribute value
2963 * Gets the uint value of attribute with name @name on @neighbor
2965 * Returns: %TRUE if a uint attribute with name @name was found, %FALSE otherwise
2970 nm_lldp_neighbor_get_attr_uint_value (NMLldpNeighbor *neighbor, char *name,
2975 g_return_val_if_fail (neighbor, FALSE);
2976 g_return_val_if_fail (name && name[0], FALSE);
2978 variant = g_hash_table_lookup (neighbor->attrs, name);
2979 if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) {
2981 *out_value = g_variant_get_uint32 (variant);
2988 * nm_lldp_neighbor_get_attr_type:
2989 * @neighbor: the #NMLldpNeighbor
2990 * @name: the attribute name
2992 * Get the type of an attribute.
2994 * Returns: the #GVariantType of the attribute with name @name
2998 const GVariantType *
2999 nm_lldp_neighbor_get_attr_type (NMLldpNeighbor *neighbor, char *name)
3003 g_return_val_if_fail (neighbor, NULL);
3004 g_return_val_if_fail (name && name[0], NULL);
3006 variant = g_hash_table_lookup (neighbor->attrs, name);
3008 return g_variant_get_type (variant);