diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 0d0a9508a..7a02b73ef 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -52,6 +52,12 @@ Whether or not this device is managed by NetworkManager. + + + If TRUE, indicates the device is likely missing firmware necessary for + its operation. + + The general type of the network device; ie Ethernet, WiFi, etc. diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 8f03b0abd..e230a7c14 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -132,7 +132,7 @@ libnm_glib_la_LIBADD = \ $(GUDEV_LIBS) libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \ - -version-info "4:2:2" + -version-info "5:0:3" noinst_PROGRAMS = libnm-glib-test diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 6d48fb38e..2b84dace1 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -68,6 +68,7 @@ global: nm_device_get_capabilities; nm_device_get_dhcp4_config; nm_device_get_driver; + nm_device_get_firmware_missing; nm_device_get_iface; nm_device_get_ip4_config; nm_device_get_ip6_config; diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index a24eb06ef..b07c9b0dc 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. */ #include @@ -53,6 +53,7 @@ typedef struct { char *driver; guint32 capabilities; gboolean managed; + gboolean firmware_missing; NMIP4Config *ip4_config; gboolean null_ip4_config; NMDHCP4Config *dhcp4_config; @@ -75,6 +76,7 @@ enum { PROP_DRIVER, PROP_CAPABILITIES, PROP_MANAGED, + PROP_FIRMWARE_MISSING, PROP_IP4_CONFIG, PROP_DHCP4_CONFIG, PROP_IP6_CONFIG, @@ -268,15 +270,16 @@ register_for_property_changed (NMDevice *device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); const NMPropertiesChangedInfo property_changed_info[] = { - { NM_DEVICE_UDI, _nm_object_demarshal_generic, &priv->udi }, - { NM_DEVICE_INTERFACE, _nm_object_demarshal_generic, &priv->iface }, - { NM_DEVICE_DRIVER, _nm_object_demarshal_generic, &priv->driver }, - { NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities }, - { NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed }, - { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, - { NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config }, - { NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config }, - { NM_DEVICE_DHCP6_CONFIG, demarshal_dhcp6_config, &priv->dhcp6_config }, + { NM_DEVICE_UDI, _nm_object_demarshal_generic, &priv->udi }, + { NM_DEVICE_INTERFACE, _nm_object_demarshal_generic, &priv->iface }, + { NM_DEVICE_DRIVER, _nm_object_demarshal_generic, &priv->driver }, + { NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities }, + { NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed }, + { NM_DEVICE_FIRMWARE_MISSING, _nm_object_demarshal_generic, &priv->firmware_missing }, + { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, + { NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config }, + { NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config }, + { NM_DEVICE_DHCP6_CONFIG, demarshal_dhcp6_config, &priv->dhcp6_config }, { NULL }, }; @@ -408,6 +411,9 @@ get_property (GObject *object, case PROP_MANAGED: g_value_set_boolean (value, nm_device_get_managed (device)); break; + case PROP_FIRMWARE_MISSING: + g_value_set_boolean (value, nm_device_get_firmware_missing (device)); + break; case PROP_IP4_CONFIG: g_value_set_object (value, nm_device_get_ip4_config (device)); break; @@ -515,6 +521,20 @@ nm_device_class_init (NMDeviceClass *device_class) FALSE, G_PARAM_READABLE)); + /** + * NMDevice:firmware-missing: + * + * When %TRUE indicates the device is likely missing firmware required + * for its operation. + **/ + g_object_class_install_property + (object_class, PROP_FIRMWARE_MISSING, + g_param_spec_boolean (NM_DEVICE_FIRMWARE_MISSING, + "FirmwareMissing", + "Firmware missing", + FALSE, + G_PARAM_READABLE)); + /** * NMDevice:ip4-config: * @@ -829,6 +849,33 @@ nm_device_get_managed (NMDevice *device) return priv->managed; } +/** + * nm_device_get_firmware_missing: + * @device: a #NMDevice + * + * Indicates that firmware required for the device's operation is likely + * to be missing. + * + * Returns: %TRUE if firmware required for the device's operation is likely + * to be missing. + **/ +gboolean +nm_device_get_firmware_missing (NMDevice *device) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (device), 0); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->firmware_missing) { + priv->firmware_missing = _nm_object_get_boolean_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "FirmwareMissing"); + } + + return priv->firmware_missing; +} + /** * nm_device_get_ip4_config: * @device: a #NMDevice diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h index 64694ec83..5a47ff9a6 100644 --- a/libnm-glib/nm-device.h +++ b/libnm-glib/nm-device.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. */ #ifndef NM_DEVICE_H @@ -49,6 +49,7 @@ G_BEGIN_DECLS #define NM_DEVICE_DRIVER "driver" #define NM_DEVICE_CAPABILITIES "capabilities" #define NM_DEVICE_MANAGED "managed" +#define NM_DEVICE_FIRMWARE_MISSING "firmware-missing" #define NM_DEVICE_IP4_CONFIG "ip4-config" #define NM_DEVICE_DHCP4_CONFIG "dhcp4-config" #define NM_DEVICE_IP6_CONFIG "ip6-config" @@ -83,18 +84,19 @@ GType nm_device_get_type (void); GObject * nm_device_new (DBusGConnection *connection, const char *path); -const char * nm_device_get_iface (NMDevice *device); -const char * nm_device_get_udi (NMDevice *device); -const char * nm_device_get_driver (NMDevice *device); -guint32 nm_device_get_capabilities (NMDevice *device); -gboolean nm_device_get_managed (NMDevice *device); -NMIP4Config * nm_device_get_ip4_config (NMDevice *device); -NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device); -NMIP6Config * nm_device_get_ip6_config (NMDevice *device); -NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *device); -NMDeviceState nm_device_get_state (NMDevice *device); -const char * nm_device_get_product (NMDevice *device); -const char * nm_device_get_vendor (NMDevice *device); +const char * nm_device_get_iface (NMDevice *device); +const char * nm_device_get_udi (NMDevice *device); +const char * nm_device_get_driver (NMDevice *device); +guint32 nm_device_get_capabilities (NMDevice *device); +gboolean nm_device_get_managed (NMDevice *device); +gboolean nm_device_get_firmware_missing (NMDevice *device); +NMIP4Config * nm_device_get_ip4_config (NMDevice *device); +NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device); +NMIP6Config * nm_device_get_ip6_config (NMDevice *device); +NMDHCP6Config * nm_device_get_dhcp6_config (NMDevice *device); +NMDeviceState nm_device_get_state (NMDevice *device); +const char * nm_device_get_product (NMDevice *device); +const char * nm_device_get_vendor (NMDevice *device); typedef void (*NMDeviceDeactivateFn) (NMDevice *device, GError *error, gpointer user_data); diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index 85f58d556..bbc54a862 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -169,6 +169,13 @@ nm_device_interface_init (gpointer g_iface) FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_interface_install_property + (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_FIRMWARE_MISSING, + "FirmwareMissing", + "Firmware missing", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_interface_install_property (g_iface, g_param_spec_string (NM_DEVICE_INTERFACE_TYPE_DESC, diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index ec27f6e82..ea152602e 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. */ #ifndef NM_DEVICE_INTERFACE_H @@ -45,21 +45,22 @@ typedef enum #define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ()) #define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ()) -#define NM_DEVICE_INTERFACE_UDI "udi" -#define NM_DEVICE_INTERFACE_IFACE "interface" -#define NM_DEVICE_INTERFACE_DRIVER "driver" -#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" -#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" -#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" -#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" -#define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-config" -#define NM_DEVICE_INTERFACE_DHCP6_CONFIG "dhcp6-config" -#define NM_DEVICE_INTERFACE_STATE "state" -#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ -#define NM_DEVICE_INTERFACE_MANAGED "managed" -#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */ +#define NM_DEVICE_INTERFACE_UDI "udi" +#define NM_DEVICE_INTERFACE_IFACE "interface" +#define NM_DEVICE_INTERFACE_DRIVER "driver" +#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" +#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4-address" +#define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_INTERFACE_DHCP4_CONFIG "dhcp4-config" +#define NM_DEVICE_INTERFACE_IP6_CONFIG "ip6-config" +#define NM_DEVICE_INTERFACE_DHCP6_CONFIG "dhcp6-config" +#define NM_DEVICE_INTERFACE_STATE "state" +#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_INTERFACE_MANAGED "managed" +#define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing" +#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */ typedef enum { NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, @@ -76,6 +77,7 @@ typedef enum { NM_DEVICE_INTERFACE_PROP_STATE, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_PROP_MANAGED, + NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING, NM_DEVICE_INTERFACE_PROP_TYPE_DESC, NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE, NM_DEVICE_INTERFACE_PROP_IFINDEX, diff --git a/src/nm-device.c b/src/nm-device.c index a6ad3be58..fcd312053 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -92,6 +92,7 @@ typedef struct { char * driver; gboolean managed; /* whether managed by NM or not */ RfKillType rfkill_type; + gboolean firmware_missing; guint32 ip4_address; @@ -492,6 +493,11 @@ nm_device_get_act_request (NMDevice *self) gboolean nm_device_is_available (NMDevice *self) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->firmware_missing) + return FALSE; + if (NM_DEVICE_GET_CLASS (self)->is_available) return NM_DEVICE_GET_CLASS (self)->is_available (self); return TRUE; @@ -3384,6 +3390,9 @@ set_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_MANAGED: priv->managed = g_value_get_boolean (value); break; + case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING: + priv->firmware_missing = g_value_get_boolean (value); + break; case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN); priv->type = g_value_get_uint (value); @@ -3471,6 +3480,9 @@ get_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_MANAGED: g_value_set_boolean (value, priv->managed); break; + case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING: + g_value_set_boolean (value, priv->firmware_missing); + break; case NM_DEVICE_INTERFACE_PROP_TYPE_DESC: g_value_set_string (value, priv->type_desc); break; @@ -3563,6 +3575,10 @@ nm_device_class_init (NMDeviceClass *klass) NM_DEVICE_INTERFACE_PROP_MANAGED, NM_DEVICE_INTERFACE_MANAGED); + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING, + NM_DEVICE_INTERFACE_FIRMWARE_MISSING); + g_object_class_override_property (object_class, NM_DEVICE_INTERFACE_PROP_TYPE_DESC, NM_DEVICE_INTERFACE_TYPE_DESC); @@ -3607,6 +3623,17 @@ unavailable_to_disconnected (gpointer user_data) return FALSE; } +static void +set_firmware_missing (NMDevice *self, gboolean new_missing) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->firmware_missing != new_missing) { + priv->firmware_missing = new_missing; + g_object_notify (G_OBJECT (self), NM_DEVICE_INTERFACE_FIRMWARE_MISSING); + } +} + void nm_device_state_changed (NMDevice *device, NMDeviceState state, @@ -3639,6 +3666,7 @@ nm_device_state_changed (NMDevice *device, */ switch (state) { case NM_DEVICE_STATE_UNMANAGED: + set_firmware_missing (device, FALSE); if (old_state > NM_DEVICE_STATE_UNMANAGED) nm_device_take_down (device, TRUE, reason); break; @@ -3646,6 +3674,7 @@ nm_device_state_changed (NMDevice *device, if (old_state == NM_DEVICE_STATE_UNMANAGED) { if (!nm_device_bring_up (device, TRUE, &no_firmware) && no_firmware) { nm_log_warn (LOGD_HW, "%s: firmware may be missing.", nm_device_get_iface (device)); + set_firmware_missing (device, TRUE); } } /* Ensure the device gets deactivated in response to stuff like