diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-04-10 13:11:56 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-04-10 13:16:29 +0200 |
commit | cbab0ef37331702feb9a9eeca3f33395cba76e57 (patch) | |
tree | 150e91aa2d7c8b8903c1ffc26ce1e2b0b575c017 | |
parent | f1c3a97ab9e6577ec2bfd0aa4572800589b747fb (diff) | |
download | libmbim-cbab0ef37331702feb9a9eeca3f33395cba76e57.tar.gz |
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.
-rw-r--r-- | configure.ac | 33 | ||||
-rw-r--r-- | 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 <config.h> + +#define _GNU_SOURCE +#include <stdlib.h> +#include <unistd.h> #include <errno.h> #include <string.h> #include <fcntl.h> @@ -30,11 +35,14 @@ #include <unistd.h> #include <gio/gio.h> #include <gio/gunixsocketaddress.h> -#include <gudev/gudev.h> #include <sys/ioctl.h> #define IOCTL_WDM_MAX_COMMAND _IOR('H', 0xA0, guint16) #define RETRY_TIMEOUT_SECS 5 +#if WITH_UDEV +# include <gudev/gudev.h> +#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; } |