libnm-glib: make nm_device_update_description() use libgudev not HAL

You'll want latest udev-extras to get the ID_*_FROM_DATABASE rules.
This commit is contained in:
Dan Williams 2009-06-11 20:49:22 -04:00
parent 139ed09f67
commit d6a3eb003a
2 changed files with 135 additions and 180 deletions

View file

@ -22,19 +22,19 @@ BUILT_SOURCES = \
lib_LTLIBRARIES = libnm_glib.la libnm_glib_vpn.la
libnm_glib_la_CFLAGS = \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
$(GCONF_CFLAGS) \
$(GNOME_KEYRING_CFLAGS)
libnm_glib_la_CFLAGS = \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS) \
$(GCONF_CFLAGS) \
$(GUDEV_CFLAGS)
libnmincludedir = $(includedir)/libnm-glib
libnminclude_HEADERS = \
libnm_glib.h \
nm-object.h \
nm-client.h \
nm-device.h \
libnm_glib.h \
nm-object.h \
nm-client.h \
nm-device.h \
nm-device-ethernet.h \
nm-device-wifi.h \
nm-access-point.h \
@ -54,23 +54,23 @@ libnminclude_HEADERS = \
nm-dhcp4-config.h
libnm_glib_la_SOURCES = \
libnm_glib.c \
nm-object.c \
libnm_glib.c \
nm-object.c \
nm-object-private.h \
nm-client.c \
nm-dbus-utils.c \
nm-dbus-utils.h \
nm-device.c \
nm-device-private.h \
nm-client.c \
nm-dbus-utils.c \
nm-dbus-utils.h \
nm-device.c \
nm-device-private.h \
nm-device-ethernet.c \
nm-device-wifi.c \
nm-access-point.c \
nm-ip4-config.c \
nm-settings.c \
nm-gsm-device.c \
nm-cdma-device.c \
nm-access-point.c \
nm-ip4-config.c \
nm-settings.c \
nm-gsm-device.c \
nm-cdma-device.c \
nm-serial-device.c \
nm-vpn-connection.c \
nm-vpn-connection.c \
nm-types.c \
nm-types-private.h \
nm-object-cache.c \
@ -82,12 +82,12 @@ libnm_glib_la_SOURCES = \
nm-dhcp4-config.c
libnm_glib_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/marshallers/libmarshallers.la \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(GCONF_LIBS) \
$(GNOME_KEYRING_LIBS)
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/marshallers/libmarshallers.la \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(GCONF_LIBS) \
$(GUDEV_LIBS)
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm_glib.ver \
-version-info "1:0:1"

View file

@ -23,6 +23,9 @@
#include <string.h>
#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include "NetworkManager.h"
#include "nm-device-ethernet.h"
#include "nm-device-wifi.h"
@ -54,6 +57,8 @@ typedef struct {
NMDHCP4Config *dhcp4_config;
gboolean null_dhcp4_config;
NMDeviceState state;
GUdevClient *client;
char *product;
char *vendor;
} NMDevicePrivate;
@ -89,7 +94,6 @@ nm_device_init (NMDevice *device)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
priv->state = NM_DEVICE_STATE_UNKNOWN;
priv->disposed = FALSE;
}
static gboolean
@ -267,6 +271,8 @@ dispose (GObject *object)
g_object_unref (priv->ip4_config);
if (priv->dhcp4_config)
g_object_unref (priv->dhcp4_config);
if (priv->client)
g_object_unref (priv->client);
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
}
@ -361,13 +367,13 @@ nm_device_class_init (NMDeviceClass *device_class)
/**
* NMDevice:udi:
*
* The HAL UDI of the device.
* The Unique Device Identifier of the device.
**/
g_object_class_install_property
(object_class, PROP_UDI,
g_param_spec_string (NM_DEVICE_UDI,
"UDI",
"HAL UDI",
"Unique Device Identifier",
NULL,
G_PARAM_READABLE));
@ -596,10 +602,11 @@ nm_device_get_iface (NMDevice *device)
* nm_device_get_udi:
* @device: a #NMDevice
*
* Gets the HAL UDI of the #NMDevice.
* Gets the Unique Device Identifier of the #NMDevice.
*
* Returns: the HAL UDI of the device. This is the internal string used by the
* device, and must not be modified.
* Returns: the Unique Device Identifier of the device. This identifier may be
* used to gather more information about the device from various operating
* system services like udev or sysfs.
**/
const char *
nm_device_get_udi (NMDevice *device)
@ -788,179 +795,127 @@ nm_device_get_state (NMDevice *device)
return priv->state;
}
static char *
get_ancestor_device (NMDevice *device,
DBusGConnection *connection,
const char *udi,
gboolean want_origdev)
/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
static int hex2num (char c)
{
DBusGProxy *proxy;
GError *err = NULL;
char *parent = NULL;
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (udi != NULL, NULL);
static int hex2byte (const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.Hal", udi, "org.freedesktop.Hal.Device");
if (!proxy)
/* End from hostap */
static char *
get_decoded_property (GUdevDevice *device, const char *property)
{
const char *orig, *p;
char *unescaped, *n;
guint len;
p = orig = g_udev_device_get_property (device, property);
if (!orig)
return NULL;
if (want_origdev) {
gboolean serial = FALSE;
if (NM_IS_GSM_DEVICE (device) || NM_IS_CDMA_DEVICE (device))
serial = TRUE;
dbus_g_proxy_call (proxy, "GetPropertyString", NULL,
G_TYPE_STRING, serial ? "serial.originating_device" : "net.originating_device",
G_TYPE_INVALID,
G_TYPE_STRING, &parent,
G_TYPE_INVALID);
if (!parent) {
/* Older HAL uses 'physical_device' */
dbus_g_proxy_call (proxy, "GetPropertyString", &err,
G_TYPE_STRING, serial ? "serial.physical_device" : "net.physical_device",
G_TYPE_INVALID,
G_TYPE_STRING, &parent,
G_TYPE_INVALID);
len = strlen (orig);
n = unescaped = g_malloc0 (len + 1);
while (*p) {
if ((len >= 4) && (*p == '\\') && (*(p+1) == 'x')) {
*n++ = (char) hex2byte (p + 2);
p += 4;
len -= 4;
} else {
*n++ = *p++;
len--;
}
if (err || !parent) {
g_warning ("Error getting originating device info from HAL: %s",
err ? err->message : "unknown error");
if (err)
g_error_free (err);
}
} else {
if (!dbus_g_proxy_call (proxy, "GetPropertyString", &err,
G_TYPE_STRING, "info.parent",
G_TYPE_INVALID,
G_TYPE_STRING, &parent,
G_TYPE_INVALID)) {
g_warning ("Error getting parent device info from HAL: %s", err->message);
g_error_free (err);
}
}
g_object_unref (proxy);
return parent;
}
static char *
proxy_get_string (DBusGProxy *proxy,
const char *property,
gboolean warn)
{
GError *error = NULL;
char *result = NULL;
g_return_val_if_fail (proxy != NULL, NULL);
g_return_val_if_fail (property != NULL, NULL);
if (dbus_g_proxy_call (proxy, "GetPropertyString", &error,
G_TYPE_STRING, property, G_TYPE_INVALID,
G_TYPE_STRING, &result, G_TYPE_INVALID))
return result;
if (warn) {
g_warning ("Error getting HAL property '%s' from device '%s': %s",
property, dbus_g_proxy_get_path (proxy),
error ? error->message : "unknown");
}
g_error_free (error);
return NULL;
}
static gboolean
get_product_and_vendor (DBusGConnection *connection,
const char *udi,
char **product,
char **vendor)
{
DBusGProxy *proxy;
char *tmp_product = NULL;
char *tmp_vendor = NULL;
char *subsys = NULL;
gboolean product_fallback = TRUE, vendor_fallback = TRUE;
gboolean warn = FALSE;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (udi != NULL, FALSE);
g_return_val_if_fail (product != NULL, FALSE);
g_return_val_if_fail (*product == NULL, FALSE);
g_return_val_if_fail (vendor != NULL, FALSE);
g_return_val_if_fail (*vendor == NULL, FALSE);
proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.Hal", udi, "org.freedesktop.Hal.Device");
if (!proxy)
return FALSE;
subsys = proxy_get_string (proxy, "info.subsystem", warn);
if (subsys && !strcmp (subsys, "pci")) {
tmp_product = proxy_get_string (proxy, "pci.subsys_product", warn);
if (tmp_product)
product_fallback = FALSE;
tmp_vendor = proxy_get_string (proxy, "pci.subsys_vendor", warn);
if (tmp_vendor)
vendor_fallback = FALSE;
}
g_free (subsys);
if (product_fallback)
tmp_product = proxy_get_string (proxy, "info.product", warn);
if (vendor_fallback)
tmp_vendor = proxy_get_string (proxy, "info.vendor", warn);
if (tmp_product && tmp_vendor) {
*product = tmp_product;
*vendor = tmp_vendor;
} else {
g_free (tmp_product);
g_free (tmp_vendor);
}
g_object_unref (proxy);
return (*product && *vendor) ? TRUE : FALSE;
return unescaped;
}
static void
nm_device_update_description (NMDevice *device)
{
NMDevicePrivate *priv;
DBusGConnection *connection;
const char *udi;
char *orig_dev_udi = NULL;
char *parent_udi = NULL;
const char *subsys[3] = { "net", "tty", NULL };
GUdevDevice *udev_device = NULL, *tmpdev;
const char *ifname;
guint32 count = 0;
const char *vendor, *model;
g_return_if_fail (NM_IS_DEVICE (device));
priv = NM_DEVICE_GET_PRIVATE (device);
if (!priv->client) {
priv->client = g_udev_client_new (subsys);
if (!priv->client)
return;
}
ifname = nm_device_get_iface (device);
if (!ifname)
return;
if (NM_IS_DEVICE_ETHERNET (device) || NM_IS_DEVICE_WIFI (device))
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "net", ifname);
else if (NM_IS_GSM_DEVICE (device) || NM_IS_CDMA_DEVICE (device))
udev_device = g_udev_client_query_by_subsystem_and_name (priv->client, "tty", ifname);
if (!udev_device)
return;
g_free (priv->product);
priv->product = NULL;
g_free (priv->vendor);
priv->vendor = NULL;
connection = nm_object_get_connection (NM_OBJECT (device));
g_return_if_fail (connection != NULL);
/* Walk up the chain of the device and its parents a few steps to grab
* vendor and device ID information off it.
*/
tmpdev = udev_device;
while ((count++ < 3) && tmpdev && (!priv->vendor || !priv->product)) {
if (!priv->vendor)
priv->vendor = get_decoded_property (tmpdev, "ID_VENDOR_ENC");
/* First, get the udi of the originating device */
udi = nm_device_get_udi (device);
orig_dev_udi = get_ancestor_device (device, connection, udi, TRUE);
if (!priv->product)
priv->product = get_decoded_property (tmpdev, "ID_MODEL_ENC");
/* Get product and vendor off the originating device if possible */
if (!get_product_and_vendor (connection, orig_dev_udi, &priv->product, &priv->vendor)) {
/* Try the parent of the originating device */
parent_udi = get_ancestor_device (device, connection, orig_dev_udi, FALSE);
if (parent_udi)
get_product_and_vendor (connection, parent_udi, &priv->product, &priv->vendor);
g_free (parent_udi);
tmpdev = g_udev_device_get_parent (tmpdev);
}
g_free (orig_dev_udi);
/* If we didn't get strings directly from the device, try database strings */
tmpdev = udev_device;
count = 0;
while ((count++ < 3) && tmpdev && (!priv->vendor || !priv->product)) {
if (!priv->vendor) {
vendor = g_udev_device_get_property (tmpdev, "ID_VENDOR_FROM_DATABASE");
if (vendor)
priv->vendor = g_strdup (vendor);
}
if (!priv->product) {
model = g_udev_device_get_property (tmpdev, "ID_MODEL_FROM_DATABASE");
if (model)
priv->product = g_strdup (model);
}
tmpdev = g_udev_device_get_parent (tmpdev);
}
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_VENDOR);
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_PRODUCT);