From cbab0ef37331702feb9a9eeca3f33395cba76e57 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 10 Apr 2016 13:11:56 +0200 Subject: build: make gudev optional There's really not much benefit on a hard build-dependency on gudev if we're just using it to get the path of the descriptors path, so provide an alternate implementation for now just using sysfs paths, and make gudev selection auto. --- configure.ac | 33 ++++++++++++ src/libmbim-glib/mbim-device.c | 119 ++++++++++++++++++++++++++++++++++------- 2 files changed, 133 insertions(+), 19 deletions(-) diff --git a/configure.ac b/configure.ac index df8dab7..c4ac9f9 100644 --- a/configure.ac +++ b/configure.ac @@ -112,6 +112,38 @@ fi AM_CONDITIONAL([MBIM_USERNAME_ENABLED], [test "x$MBIM_USERNAME_ENABLED" = "xyes"]) +# udev support (auto) +GUDEV_VERSION=147 + +PKG_CHECK_MODULES(GUDEV, [gudev-1.0 >= $GUDEV_VERSION], [have_gudev=yes],[have_gudev=no]) + +AC_ARG_WITH(udev, + AS_HELP_STRING([--with-udev], [Build with udev support [[default=auto]]]),, [with_udev=auto]) + +if test "x$with_udev" = "xauto"; then + if test "x$have_gudev" = "xno"; then + with_udev="no" + else + with_udev="yes" + fi +fi + +case $with_udev in + yes) + if test "x$have_gudev" = "xno"; then + AC_MSG_ERROR([Couldn't find gudev >= $GUDEV_VERSION. Install it, or otherwise configure using --without-udev to disable udev support.]) + else + AC_DEFINE(WITH_UDEV, 1, [Define if you want udev support]) + AC_SUBST(GUDEV_CFLAGS) + AC_SUBST(GUDEV_LIBS) + fi + ;; + *) + AC_DEFINE(WITH_UDEV, 0, [Define if you want udev support]) + with_udev=no + ;; +esac + # udev base directory AC_ARG_WITH(udev-base-dir, AS_HELP_STRING([--with-udev-base-dir=DIR], [where udev base directory is])) if test -n "$with_udev_base_dir" ; then @@ -168,5 +200,6 @@ echo " udev base directory: ${UDEV_BASE_DIR} Features: + udev support: ${with_udev} MBIM username: ${MBIM_USERNAME_ENABLED} (${MBIM_USERNAME}) " diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c index c0bb5da..a001940 100644 --- a/src/libmbim-glib/mbim-device.c +++ b/src/libmbim-glib/mbim-device.c @@ -23,6 +23,11 @@ * Implementation based on the 'QmiDevice' GObject from libqmi-glib. */ +#include + +#define _GNU_SOURCE +#include +#include #include #include #include @@ -30,11 +35,14 @@ #include #include #include -#include #include #define IOCTL_WDM_MAX_COMMAND _IOR('H', 0xA0, guint16) #define RETRY_TIMEOUT_SECS 5 +#if WITH_UDEV +# include +#endif + #include "mbim-utils.h" #include "mbim-device.h" #include "mbim-message.h" @@ -762,21 +770,17 @@ struct usb_cdc_mbim_desc { guint8 bmNetworkCapabilities; } __attribute__ ((packed)); -static guint16 -read_max_control_transfer (MbimDevice *self) +#if WITH_UDEV + +static gchar * +get_descriptors_filepath (MbimDevice *self) { - static const guint8 mbim_signature[4] = { 0x0c, 0x24, 0x1b, 0x00 }; - guint16 max = MAX_CONTROL_TRANSFER; GUdevClient *client; GUdevDevice *device = NULL; GUdevDevice *parent_device = NULL; GUdevDevice *grandparent_device = NULL; gchar *descriptors_path = NULL; gchar *device_basename = NULL; - GError *error = NULL; - gchar *contents = NULL; - gsize length = 0; - guint i; client = g_udev_client_new (NULL); if (!G_UDEV_IS_CLIENT (client)) { @@ -826,6 +830,93 @@ read_max_control_transfer (MbimDevice *self) g_udev_device_get_sysfs_path (grandparent_device), "descriptors", NULL); + +out: + g_free (device_basename); + if (parent_device) + g_object_unref (parent_device); + if (grandparent_device) + g_object_unref (grandparent_device); + if (device) + g_object_unref (device); + if (client) + g_object_unref (client); + + return descriptors_path; +} + +#else + +static gchar * +get_descriptors_filepath (MbimDevice *self) +{ + static const gchar *subsystems[] = { "usbmisc", "usb" }; + guint i; + gchar *device_basename; + gchar *descriptors_path = NULL; + + device_basename = g_path_get_basename (self->priv->path); + + for (i = 0; !descriptors_path && i < G_N_ELEMENTS (subsystems); i++) { + gchar *tmp; + gchar *path; + + /* parent sysfs can be built directly using subsystem and name; e.g. for subsystem + * usbmisc and name cdc-wdm0: + * $ realpath /sys/class/usbmisc/cdc-wdm0/device + * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.5/2-1.5:2.0 + */ + tmp = g_strdup_printf ("/sys/class/%s/%s/device", subsystems[i], device_basename); + path = canonicalize_file_name (tmp); + g_free (tmp); + + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + /* Now look for the parent dir with descriptors file. */ + gchar *dirname; + + dirname = g_path_get_dirname (path); + descriptors_path = g_build_path (G_DIR_SEPARATOR_S, + dirname, + "descriptors", + NULL); + g_free (dirname); + } + g_free (path); + } + + g_free (device_basename); + + if (descriptors_path && !g_file_test (descriptors_path, G_FILE_TEST_EXISTS)) { + g_warning ("[%s] Descriptors file doesn't exist", + self->priv->path_display); + g_free (descriptors_path); + descriptors_path = NULL; + } + + return descriptors_path; +} + +#endif + +static guint16 +read_max_control_transfer (MbimDevice *self) +{ + static const guint8 mbim_signature[4] = { 0x0c, 0x24, 0x1b, 0x00 }; + guint16 max = MAX_CONTROL_TRANSFER; + gchar *descriptors_path; + GError *error = NULL; + gchar *contents = NULL; + gsize length = 0; + guint i; + + /* Build descriptors filepath */ + descriptors_path = get_descriptors_filepath (self); + if (!descriptors_path) { + g_warning ("[%s] Couldn't get descriptors file path", + self->priv->path_display); + goto out; + } + if (!g_file_get_contents (descriptors_path, &contents, &length, @@ -859,16 +950,6 @@ read_max_control_transfer (MbimDevice *self) out: g_free (contents); - g_free (device_basename); - g_free (descriptors_path); - if (parent_device) - g_object_unref (parent_device); - if (grandparent_device) - g_object_unref (grandparent_device); - if (device) - g_object_unref (device); - if (client) - g_object_unref (client); return max; } -- cgit v1.2.1