summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-04-10 13:11:56 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-04-10 13:16:29 +0200
commitcbab0ef37331702feb9a9eeca3f33395cba76e57 (patch)
tree150e91aa2d7c8b8903c1ffc26ce1e2b0b575c017
parentf1c3a97ab9e6577ec2bfd0aa4572800589b747fb (diff)
downloadlibmbim-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.ac33
-rw-r--r--src/libmbim-glib/mbim-device.c119
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;
}