0001-release-bump-version-to-1.14.0.patch0000664000175100017510000000224313117471773015172 0ustar uuFrom 9e2fc52d057476cbd65d73b63b1331a8c8b8f250 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 17 Mar 2016 14:12:56 +0100 Subject: [PATCH 01/17] release: bump version to 1.14.0 Conflicts: configure.ac --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a7a5de5..c52c4b6 100644 --- a/configure.ac +++ b/configure.ac @@ -3,8 +3,8 @@ AC_PREREQ([2.68]) dnl The QMI version number m4_define([qmi_major_version], [1]) -m4_define([qmi_minor_version], [12]) -m4_define([qmi_micro_version], [11]) +m4_define([qmi_minor_version], [14]) +m4_define([qmi_micro_version], [0]) m4_define([qmi_version], [qmi_major_version.qmi_minor_version.qmi_micro_version]) @@ -18,7 +18,7 @@ dnl If the interface has changed in an incompatible way (that is, dnl functions have changed or been removed), then zero a. m4_define([qmi_glib_lt_current], [5]) m4_define([qmi_glib_lt_revision], [0]) -m4_define([qmi_glib_lt_age], [4]) +m4_define([qmi_glib_lt_age], [0]) AC_INIT([libqmi], [qmi_version], [libqmi-devel@lists.freedesktop.org]) -- 2.7.4 0002-libqmi-support-MBIM-EXT_QMUX-service.patch0000664000175100017510000002615113117471773016453 0ustar uuFrom 1f4a102e9b4d1d1a3bed1faf16469e42d3e65c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Mon, 4 Apr 2016 14:44:01 +0200 Subject: [PATCH 02/17] libqmi: support MBIM EXT_QMUX service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- configure.ac | 13 ++++ src/libqmi-glib/Makefile.am | 4 +- src/libqmi-glib/qmi-device.c | 155 ++++++++++++++++++++++++++++++++++++++++++- src/libqmi-glib/qmi-device.h | 4 +- 4 files changed, 171 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index c52c4b6..e370c48 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,18 @@ fi AM_CONDITIONAL([QMI_USERNAME_ENABLED], [test "x$QMI_USERNAME_ENABLED" = "xyes"]) +# MBIM QMUX service support +AC_ARG_ENABLE(mbim-qmux, + AS_HELP_STRING([--enable-mbim-qmux], [support QMI over MBIM QMUX service])) +if test -n "$enable_mbim_qmux"; then + PKG_CHECK_MODULES(MBIM, mbim-glib >= 1.13) + MBIM_CFLAGS="$MBIM_CFLAGS -DMBIM_QMUX" + AC_SUBST(MBIM_CFLAGS) + AC_SUBST(MBIM_LIBS) +fi + +AM_CONDITIONAL(MBIM_QMUX, [test -n "$MBIM_CFLAGS"]) + # 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 @@ -146,4 +158,5 @@ echo " udev base directory: ${UDEV_BASE_DIR} Documentation: ${enable_gtk_doc} QMI username: ${QMI_USERNAME_ENABLED} (${QMI_USERNAME}) + QMUX over MBIM: ${enable_mbim_qmux} " diff --git a/src/libqmi-glib/Makefile.am b/src/libqmi-glib/Makefile.am index 78d93f3..25ad914 100644 --- a/src/libqmi-glib/Makefile.am +++ b/src/libqmi-glib/Makefile.am @@ -5,6 +5,7 @@ lib_LTLIBRARIES = libqmi-glib.la libqmi_glib_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ + $(MBIM_CFLAGS) \ -I$(top_srcdir) \ -I$(top_builddir) \ -I$(top_srcdir)/src/libqmi-glib \ @@ -38,7 +39,8 @@ libqmi_glib_la_SOURCES = \ libqmi_glib_la_LIBADD = \ ${top_builddir}/src/libqmi-glib/generated/libqmi-glib-generated.la \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + $(MBIM_LIBS) libqmi_glib_la_LDFLAGS = \ -version-info $(QMI_GLIB_LT_CURRENT):$(QMI_GLIB_LT_REVISION):$(QMI_GLIB_LT_AGE) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index c0b494b..0ff3769 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -31,6 +31,10 @@ #include #include +#ifdef MBIM_QMUX +#include +#endif + #include "qmi-device.h" #include "qmi-message.h" #include "qmi-ctl.h" @@ -89,6 +93,10 @@ struct _QmiDevicePrivate { gchar *path_display; gboolean no_file_check; gchar *proxy_path; + gboolean mbim_qmux; +#ifdef MBIM_QMUX + MbimDevice *mbimdev; +#endif /* Implicit CTL client */ QmiClientCtl *client_ctl; @@ -1415,7 +1423,6 @@ input_ready_cb (GInputStream *istream, self->priv->buffer = g_byte_array_sized_new (r); g_byte_array_append (self->priv->buffer, buffer, r); - /* Try to parse input messages */ parse_response (self); return TRUE; @@ -1860,6 +1867,56 @@ internal_proxy_open_ready (QmiClientCtl *client_ctl, device_open_context_step (ctx); } +#ifdef MBIM_QMUX +static void +mbim_device_open_ready (MbimDevice *dev, + GAsyncResult *res, + DeviceOpenContext *ctx) +{ + GError *error = NULL; + + if (!mbim_device_open_finish (dev, res, &error)) { + g_simple_async_result_take_error (ctx->result, error); + device_open_context_complete_and_free (ctx); + return; + } + g_debug ("[%s] MBIM device Open..", + ctx->self->priv->path_display); + + /* Go on */ + ctx->step++; + device_open_context_step (ctx); + return; +} + +static void +mbim_device_new_ready (GObject *source, + GAsyncResult *res, + DeviceOpenContext *ctx) +{ + MbimDeviceOpenFlags open_flags = MBIM_DEVICE_OPEN_FLAGS_NONE; + GError *error = NULL; + MbimDevice *device; + + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY) + open_flags |= MBIM_DEVICE_OPEN_FLAGS_PROXY; + device = mbim_device_new_finish (res, &error); + if (!device) { + g_simple_async_result_take_error (ctx->result, error); + device_open_context_complete_and_free (ctx); + return; + } + ctx->self->priv->mbimdev = device; + + mbim_device_open_full(device, + open_flags, + 30, + ctx->cancellable, + (GAsyncReadyCallback)mbim_device_open_ready, + ctx); +} +#endif + static void create_iostream_ready (QmiDevice *self, GAsyncResult *res, @@ -1892,6 +1949,20 @@ device_open_context_step (DeviceOpenContext *ctx) /* Fall down */ case DEVICE_OPEN_CONTEXT_STEP_CREATE_IOSTREAM: +#ifdef MBIM_QMUX + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { + GFile *file; + + ctx->self->priv->mbim_qmux = TRUE; + file = g_file_new_for_path (ctx->self->priv->path); + mbim_device_new (file, + ctx->cancellable, + (GAsyncReadyCallback)mbim_device_new_ready, + ctx); + g_object_unref (file); + return; + } +#endif create_iostream (ctx->self, !!(ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY), (GAsyncReadyCallback)create_iostream_ready, @@ -1900,7 +1971,8 @@ device_open_context_step (DeviceOpenContext *ctx) case DEVICE_OPEN_CONTEXT_STEP_FLAGS_PROXY: /* Initialize communication with proxy? */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY) { + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY && + !(ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM)) { QmiMessageCtlInternalProxyOpenInput *input; input = qmi_message_ctl_internal_proxy_open_input_new (); @@ -2095,6 +2167,21 @@ destroy_iostream (QmiDevice *self, return TRUE; } +#ifdef MBIM_QMUX +static void +mbim_device_close_ready (MbimDevice *dev, + GAsyncResult *res) +{ + GError *error = NULL; + + if (!mbim_device_close_finish (dev, res, &error)) { + g_printerr ("error: couldn't close device: %s", error->message); + g_error_free (error); + } else + g_debug ("Device closed"); +} +#endif + /** * qmi_device_close: * @self: a #QmiDevice @@ -2112,6 +2199,15 @@ qmi_device_close (QmiDevice *self, { g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); +#ifdef MBIM_QMUX + if (self->priv->mbim_qmux) + mbim_device_close (self->priv->mbimdev, + 15, + NULL, + (GAsyncReadyCallback) mbim_device_close_ready, + NULL); + else +#endif if (!destroy_iostream (self, error)) { g_prefix_error (error, "Cannot close QMI device: "); return FALSE; @@ -2120,6 +2216,41 @@ qmi_device_close (QmiDevice *self, return TRUE; } +#ifdef MBIM_QMUX +static void +mbim_device_command_ready (MbimDevice *dev, + GAsyncResult *res, + QmiDevice *qmidev) +{ + MbimMessage *response; + GError *error = NULL; + const guint8 *buf; + guint32 len; + + response = mbim_device_command_finish (dev, res, &error); + if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { + g_prefix_error (&error, "MBIM error: "); + // transaction_complete_and_free (tr, NULL, error); + g_error_free (error); + mbim_message_unref (response); + return; + } + + g_debug ("[%s] Received MBIM message\n", qmidev->priv->path_display); + + /* get the information buffer */ + buf = mbim_message_command_done_get_raw_information_buffer (response, &len); + if (!G_UNLIKELY (qmidev->priv->buffer)) + qmidev->priv->buffer = g_byte_array_sized_new (len); + g_byte_array_append (qmidev->priv->buffer, buf, len); + + /* and parse it as QMI */ + parse_response(qmidev); + mbim_message_unref (response); + return; +} +#endif + /*****************************************************************************/ /* Command */ @@ -2188,7 +2319,7 @@ qmi_device_command (QmiDevice *self, tr = transaction_new (self, message, cancellable, callback, user_data); /* Device must be open */ - if (!self->priv->istream || !self->priv->ostream) { + if ((!self->priv->istream || !self->priv->ostream) && !self->priv->mbim_qmux) { error = g_error_new (QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, "Device must be open to send commands"); @@ -2257,6 +2388,24 @@ qmi_device_command (QmiDevice *self, g_free (printable); } +#ifdef MBIM_QMUX + /* wrap QMUX in MBIM? */ + if (self->priv->mbim_qmux) { + MbimMessage *mbim; + + mbim = (mbim_message_qmi_msg_set_new (raw_message_len, raw_message, &error)); + mbim_device_command (self->priv->mbimdev, + mbim, + 30, + NULL, /* cancellable */ + (GAsyncReadyCallback)mbim_device_command_ready, + self); + g_debug ("[%s] Message sent as MBIM\n", self->priv->path_display); + + /* FIXME: check errors, set proper MBIM TID */ + return; + } +#endif if (!g_output_stream_write_all (self->priv->ostream, raw_message, raw_message_len, diff --git a/src/libqmi-glib/qmi-device.h b/src/libqmi-glib/qmi-device.h index cef7c50..81e88f5 100644 --- a/src/libqmi-glib/qmi-device.h +++ b/src/libqmi-glib/qmi-device.h @@ -95,6 +95,7 @@ gboolean qmi_device_is_open (QmiDevice *self); * @QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER: set network port to transmit/receive QoS headers; mutually exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER * @QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER: set network port to not transmit/receive QoS headers; mutually exclusive with @QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER * @QMI_DEVICE_OPEN_FLAGS_PROXY: Try to open the port through the 'qmi-proxy'. + * @QMI_DEVICE_OPEN_FLAGS_MBIM: open an MBIM port with QMUX tunneling service * * Flags to specify which actions to be performed when the device is open. */ @@ -106,7 +107,8 @@ typedef enum { QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP = 1 << 3, QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER = 1 << 4, QMI_DEVICE_OPEN_FLAGS_NET_NO_QOS_HEADER = 1 << 5, - QMI_DEVICE_OPEN_FLAGS_PROXY = 1 << 6 + QMI_DEVICE_OPEN_FLAGS_PROXY = 1 << 6, + QMI_DEVICE_OPEN_FLAGS_MBIM = 1 << 7 } QmiDeviceOpenFlags; void qmi_device_open (QmiDevice *self, -- 2.7.4 0003-qmicli-support-MBIM-EXT_QMUX-devices.patch0000664000175100017510000000341713117471773016437 0ustar uuFrom 4f05365a11935bd91138e4e34c3cfd2807faba83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Mon, 4 Apr 2016 14:47:01 +0200 Subject: [PATCH 03/17] qmicli: support MBIM EXT_QMUX devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- src/qmicli/qmicli.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/qmicli/qmicli.c b/src/qmicli/qmicli.c index e947ed5..7c949ce 100644 --- a/src/qmicli/qmicli.c +++ b/src/qmicli/qmicli.c @@ -53,6 +53,7 @@ static gboolean device_open_version_info_flag; static gboolean device_open_sync_flag; static gchar *device_open_net_str; static gboolean device_open_proxy_flag; +static gboolean device_open_mbim_flag; static gchar *client_cid_str; static gboolean client_no_release_cid_flag; static gboolean verbose_flag; @@ -84,6 +85,10 @@ static GOptionEntry main_entries[] = { "Request to use the 'qmi-proxy' proxy", NULL }, + { "device-open-mbim", 0, 0, G_OPTION_ARG_NONE, &device_open_mbim_flag, + "Open an MBIM device with EXT_QMUX support", + NULL + }, { "device-open-net", 0, 0, G_OPTION_ARG_STRING, &device_open_net_str, "Open device with specific link protocol and QoS flags", "[net-802-3|net-raw-ip|net-qos-header|net-no-qos-header]" @@ -490,6 +495,8 @@ device_new_ready (GObject *unused, open_flags |= QMI_DEVICE_OPEN_FLAGS_SYNC; if (device_open_proxy_flag) open_flags |= QMI_DEVICE_OPEN_FLAGS_PROXY; + if (device_open_mbim_flag) + open_flags |= QMI_DEVICE_OPEN_FLAGS_MBIM; if (device_open_net_str) if (!qmicli_read_net_open_flags_from_string (device_open_net_str, &open_flags)) exit (EXIT_FAILURE); -- 2.7.4 0004-build-update-enable-mbim-qmux-rules.patch0000664000175100017510000001030613117471773016636 0ustar uuFrom e4d8af4885db49c2b1811d885a4bd266cee6a75e Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 15:38:48 +0200 Subject: [PATCH 04/17] build: update `--enable-mbim-qmux' rules If libmbim 1.14.0 found, enable QMI over MBIM support. --- configure.ac | 21 +++++++++++++++------ src/libqmi-glib/qmi-device.c | 19 +++++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index e370c48..5eb4d5d 100644 --- a/configure.ac +++ b/configure.ac @@ -96,17 +96,26 @@ fi AM_CONDITIONAL([QMI_USERNAME_ENABLED], [test "x$QMI_USERNAME_ENABLED" = "xyes"]) # MBIM QMUX service support +MBIM_GLIB_VERSION=1.14.0 +PKG_CHECK_MODULES([MBIM], [mbim-glib >= ${MBIM_GLIB_VERSION}], [have_mbim=yes], [have_mbim=no]) AC_ARG_ENABLE(mbim-qmux, - AS_HELP_STRING([--enable-mbim-qmux], [support QMI over MBIM QMUX service])) -if test -n "$enable_mbim_qmux"; then - PKG_CHECK_MODULES(MBIM, mbim-glib >= 1.13) - MBIM_CFLAGS="$MBIM_CFLAGS -DMBIM_QMUX" + AS_HELP_STRING([--enable-mbim-qmux], [Enable support for QMI over MBIM QMUX service [default=auto]]), + [enable_mbim_qmux=$enableval], + [enable_mbim_qmux=auto]) + +if test "x$enable_mbim_qmux" = "xauto"; then + enable_mbim_qmux=$have_mbim +fi + +if test "x$enable_mbim_qmux" = "xyes"; then + if test "xhave_mbim" = "xno"; then + AC_MSG_ERROR([Couldn't find `libmbim-glib` >= ${MBIM_GLIB_VERSION}. Install it, or otherwise configure using --disable-mbim-qmux to disable the QMI over MBIM QMUX service.]) + fi + AC_DEFINE(MBIM_QMUX_ENABLED, 1, [Define if MBIM QMUX support enabled]) AC_SUBST(MBIM_CFLAGS) AC_SUBST(MBIM_LIBS) fi -AM_CONDITIONAL(MBIM_QMUX, [test -n "$MBIM_CFLAGS"]) - # 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 diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 0ff3769..b511b39 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -21,6 +21,9 @@ * Copyright (C) 2012 - 2014 Aleksander Morgado */ +#include + +#include #include #include #include @@ -31,7 +34,7 @@ #include #include -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED #include #endif @@ -94,7 +97,7 @@ struct _QmiDevicePrivate { gboolean no_file_check; gchar *proxy_path; gboolean mbim_qmux; -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED MbimDevice *mbimdev; #endif @@ -1867,7 +1870,7 @@ internal_proxy_open_ready (QmiClientCtl *client_ctl, device_open_context_step (ctx); } -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED static void mbim_device_open_ready (MbimDevice *dev, GAsyncResult *res, @@ -1949,7 +1952,7 @@ device_open_context_step (DeviceOpenContext *ctx) /* Fall down */ case DEVICE_OPEN_CONTEXT_STEP_CREATE_IOSTREAM: -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { GFile *file; @@ -2167,7 +2170,7 @@ destroy_iostream (QmiDevice *self, return TRUE; } -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED static void mbim_device_close_ready (MbimDevice *dev, GAsyncResult *res) @@ -2199,7 +2202,7 @@ qmi_device_close (QmiDevice *self, { g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED if (self->priv->mbim_qmux) mbim_device_close (self->priv->mbimdev, 15, @@ -2216,7 +2219,7 @@ qmi_device_close (QmiDevice *self, return TRUE; } -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED static void mbim_device_command_ready (MbimDevice *dev, GAsyncResult *res, @@ -2388,7 +2391,7 @@ qmi_device_command (QmiDevice *self, g_free (printable); } -#ifdef MBIM_QMUX +#if defined MBIM_QMUX_ENABLED /* wrap QMUX in MBIM? */ if (self->priv->mbim_qmux) { MbimMessage *mbim; -- 2.7.4 0005-libqmi-glib-device-fix-indentation.patch0000664000175100017510000000275613117471773016527 0ustar uuFrom 083f58f84185e6aa41e35c3406efa09d0b274318 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 15:55:08 +0200 Subject: [PATCH 05/17] libqmi-glib,device: fix indentation --- src/libqmi-glib/qmi-device.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index b511b39..81bf761 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1876,20 +1876,20 @@ mbim_device_open_ready (MbimDevice *dev, GAsyncResult *res, DeviceOpenContext *ctx) { - GError *error = NULL; - - if (!mbim_device_open_finish (dev, res, &error)) { - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - return; - } - g_debug ("[%s] MBIM device Open..", - ctx->self->priv->path_display); + GError *error = NULL; - /* Go on */ - ctx->step++; - device_open_context_step (ctx); + if (!mbim_device_open_finish (dev, res, &error)) { + g_simple_async_result_take_error (ctx->result, error); + device_open_context_complete_and_free (ctx); return; + } + + g_debug ("[%s] MBIM device Open..", + ctx->self->priv->path_display); + + /* Go on */ + ctx->step++; + device_open_context_step (ctx); } static void -- 2.7.4 0006-libqmi-glib-device-include-steps-for-mbim-device-cre.patch0000664000175100017510000001527613117471773021722 0ustar uuFrom 820b272798966974cc39e32cdf0e66ced160c228 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 18:04:13 +0200 Subject: [PATCH 06/17] libqmi-glib,device: include steps for mbim device create/open --- src/libqmi-glib/qmi-device.c | 117 ++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 39 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 81bf761..c31943d 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1639,6 +1639,10 @@ create_iostream (QmiDevice *self, typedef enum { DEVICE_OPEN_CONTEXT_STEP_FIRST = 0, +#if defined MBIM_QMUX_ENABLED + DEVICE_OPEN_CONTEXT_STEP_DEVICE_MBIM, + DEVICE_OPEN_CONTEXT_STEP_OPEN_DEVICE_MBIM, +#endif DEVICE_OPEN_CONTEXT_STEP_CREATE_IOSTREAM, DEVICE_OPEN_CONTEXT_STEP_FLAGS_PROXY, DEVICE_OPEN_CONTEXT_STEP_FLAGS_VERSION_INFO, @@ -1870,7 +1874,26 @@ internal_proxy_open_ready (QmiClientCtl *client_ctl, device_open_context_step (ctx); } +static void +create_iostream_ready (QmiDevice *self, + GAsyncResult *res, + DeviceOpenContext *ctx) +{ + GError *error = NULL; + + if (!create_iostream_finish (self, res, &error)) { + g_simple_async_result_take_error (ctx->result, error); + device_open_context_complete_and_free (ctx); + return; + } + + /* Go on */ + ctx->step++; + device_open_context_step (ctx); +} + #if defined MBIM_QMUX_ENABLED + static void mbim_device_open_ready (MbimDevice *dev, GAsyncResult *res, @@ -1884,8 +1907,7 @@ mbim_device_open_ready (MbimDevice *dev, return; } - g_debug ("[%s] MBIM device Open..", - ctx->self->priv->path_display); + g_debug ("[%s] MBIM device open", ctx->self->priv->path_display); /* Go on */ ctx->step++; @@ -1893,51 +1915,61 @@ mbim_device_open_ready (MbimDevice *dev, } static void -mbim_device_new_ready (GObject *source, - GAsyncResult *res, - DeviceOpenContext *ctx) +open_mbim_device (DeviceOpenContext *ctx) { MbimDeviceOpenFlags open_flags = MBIM_DEVICE_OPEN_FLAGS_NONE; - GError *error = NULL; - MbimDevice *device; + /* If QMI proxy was requested, use MBIM proxy instead */ if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY) open_flags |= MBIM_DEVICE_OPEN_FLAGS_PROXY; - device = mbim_device_new_finish (res, &error); - if (!device) { - g_simple_async_result_take_error (ctx->result, error); - device_open_context_complete_and_free (ctx); - return; - } - ctx->self->priv->mbimdev = device; - mbim_device_open_full(device, - open_flags, - 30, - ctx->cancellable, - (GAsyncReadyCallback)mbim_device_open_ready, - ctx); + /* We pass the original timeout of the request to the open operation */ + g_debug ("[%s] opening MBIM device...", ctx->self->priv->path_display); + mbim_device_open_full (ctx->self->priv->mbimdev, + open_flags, + ctx->timeout, + ctx->cancellable, + (GAsyncReadyCallback) mbim_device_open_ready, + ctx); } -#endif static void -create_iostream_ready (QmiDevice *self, +mbim_device_new_ready (GObject *source, GAsyncResult *res, DeviceOpenContext *ctx) { GError *error = NULL; - if (!create_iostream_finish (self, res, &error)) { + ctx->self->priv->mbimdev = mbim_device_new_finish (res, &error); + if (!ctx->self->priv->mbimdev) { g_simple_async_result_take_error (ctx->result, error); device_open_context_complete_and_free (ctx); return; } + g_debug ("[%s] MBIM device created", ctx->self->priv->path_display); + /* Go on */ ctx->step++; device_open_context_step (ctx); } +static void +create_mbim_device (DeviceOpenContext *ctx) +{ + GFile *file; + + g_debug ("[%s] creating MBIM device...", ctx->self->priv->path_display); + file = g_file_new_for_path (ctx->self->priv->path); + mbim_device_new (file, + ctx->cancellable, + (GAsyncReadyCallback) mbim_device_new_ready, + ctx); + g_object_unref (file); +} + +#endif + #define NETPORT_FLAGS (QMI_DEVICE_OPEN_FLAGS_NET_802_3 | \ QMI_DEVICE_OPEN_FLAGS_NET_RAW_IP | \ QMI_DEVICE_OPEN_FLAGS_NET_QOS_HEADER | \ @@ -1951,31 +1983,38 @@ device_open_context_step (DeviceOpenContext *ctx) ctx->step++; /* Fall down */ - case DEVICE_OPEN_CONTEXT_STEP_CREATE_IOSTREAM: #if defined MBIM_QMUX_ENABLED + case DEVICE_OPEN_CONTEXT_STEP_DEVICE_MBIM: + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { + create_mbim_device (ctx); + return; + } + ctx->step++; + /* Fall down */ + + case DEVICE_OPEN_CONTEXT_STEP_OPEN_DEVICE_MBIM: if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM) { - GFile *file; + open_mbim_device (ctx); + return; + } + ctx->step++; + /* Fall down */ +#endif - ctx->self->priv->mbim_qmux = TRUE; - file = g_file_new_for_path (ctx->self->priv->path); - mbim_device_new (file, - ctx->cancellable, - (GAsyncReadyCallback)mbim_device_new_ready, + case DEVICE_OPEN_CONTEXT_STEP_CREATE_IOSTREAM: + if (!(ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM)) { + create_iostream (ctx->self, + !!(ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY), + (GAsyncReadyCallback)create_iostream_ready, ctx); - g_object_unref (file); return; } -#endif - create_iostream (ctx->self, - !!(ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY), - (GAsyncReadyCallback)create_iostream_ready, - ctx); - return; + ctx->step++; + /* Fall down */ case DEVICE_OPEN_CONTEXT_STEP_FLAGS_PROXY: /* Initialize communication with proxy? */ - if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY && - !(ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM)) { + if (ctx->flags & QMI_DEVICE_OPEN_FLAGS_PROXY && !(ctx->flags & QMI_DEVICE_OPEN_FLAGS_MBIM)) { QmiMessageCtlInternalProxyOpenInput *input; input = qmi_message_ctl_internal_proxy_open_input_new (); -- 2.7.4 0007-libqmi-glib-mbim-destroy-mbim-device-on-port-close.patch0000664000175100017510000000457013117471773021461 0ustar uuFrom b43346cb2bd46577f938216beecd6ca03a7decbb Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 18:09:31 +0200 Subject: [PATCH 07/17] libqmi-glib,mbim: destroy mbim device on port close --- src/libqmi-glib/qmi-device.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index c31943d..4de6afa 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -2210,18 +2210,38 @@ destroy_iostream (QmiDevice *self, } #if defined MBIM_QMUX_ENABLED + static void mbim_device_close_ready (MbimDevice *dev, - GAsyncResult *res) + GAsyncResult *res, + QmiDevice *self) { GError *error = NULL; if (!mbim_device_close_finish (dev, res, &error)) { - g_printerr ("error: couldn't close device: %s", error->message); + g_warning ("[%s] error: couldn't close device: %s", + self->priv->path_display, error->message); g_error_free (error); } else - g_debug ("Device closed"); + g_debug ("[%s] MBIM device closed", self->priv->path_display); + g_object_unref (self); +} + +static void +destroy_mbim_device (QmiDevice *self) +{ + /* TODO: make this sync */ + mbim_device_close (self->priv->mbimdev, + 15, + NULL, + (GAsyncReadyCallback) mbim_device_close_ready, + g_object_ref (self)); + + /* Cleanup right away, we don't want multiple close attempts on the + * device */ + g_clear_object (&self->priv->mbimdev); } + #endif /** @@ -2242,14 +2262,12 @@ qmi_device_close (QmiDevice *self, g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); #if defined MBIM_QMUX_ENABLED - if (self->priv->mbim_qmux) - mbim_device_close (self->priv->mbimdev, - 15, - NULL, - (GAsyncReadyCallback) mbim_device_close_ready, - NULL); - else + if (self->priv->mbimdev) { + destroy_mbim_device (self); + return TRUE; + } #endif + if (!destroy_iostream (self, error)) { g_prefix_error (error, "Cannot close QMI device: "); return FALSE; -- 2.7.4 0008-libqmi-glib-mbim-rework-transaction-management-on-mb.patch0000664000175100017510000003214413117471773022065 0ustar uuFrom d1cc5fcb280a8a3566d6294cf304c7e9fe9a7e73 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 20:10:05 +0200 Subject: [PATCH 08/17] libqmi-glib,mbim: rework transaction management on mbim backend The lifecycle for transactions going through the MBIM backend is a bit different w.r.t. the default one: * Given that libmbim has its own timeout management for the commands sent, we will rely on it instead of having our own. This means that we always assume that mbim_command() finishes, as it should be. * Instead of using the response QMI message to match a transaction, when using MBIM we use the transaction key given in the context passed to mbim_command() and by doing this we make sure that the transaction is always removed from the tracking table, regardless of whether the QMI message inside matched or not. --- src/libqmi-glib/qmi-device.c | 195 ++++++++++++++++++++++++++++++++----------- src/libqmi-glib/qmi-errors.h | 20 +++-- 2 files changed, 159 insertions(+), 56 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 4de6afa..1c81960 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -96,7 +96,7 @@ struct _QmiDevicePrivate { gchar *path_display; gboolean no_file_check; gchar *proxy_path; - gboolean mbim_qmux; + #if defined MBIM_QMUX_ENABLED MbimDevice *mbimdev; #endif @@ -217,7 +217,7 @@ build_transaction_key (QmiMessage *message) static Transaction * device_release_transaction (QmiDevice *self, - gpointer key) + gconstpointer key) { Transaction *tr = NULL; @@ -294,10 +294,13 @@ device_store_transaction (QmiDevice *self, tr->wait_ctx->self = self; tr->wait_ctx->key = key; /* valid as long as the transaction is in the HT */ - tr->timeout_source = g_timeout_source_new_seconds (timeout); - g_source_set_callback (tr->timeout_source, (GSourceFunc)transaction_timed_out, tr->wait_ctx, NULL); - g_source_attach (tr->timeout_source, g_main_context_get_thread_default ()); - g_source_unref (tr->timeout_source); + /* Timeout is optional (e.g. disabled when MBIM is used) */ + if (timeout > 0) { + tr->timeout_source = g_timeout_source_new_seconds (timeout); + g_source_set_callback (tr->timeout_source, (GSourceFunc)transaction_timed_out, tr->wait_ctx, NULL); + g_source_attach (tr->timeout_source, g_main_context_get_thread_default ()); + g_source_unref (tr->timeout_source); + } if (tr->cancellable) { /* Note: transaction_cancelled() will also be called directly if the @@ -2277,38 +2280,127 @@ qmi_device_close (QmiDevice *self, } #if defined MBIM_QMUX_ENABLED -static void -mbim_device_command_ready (MbimDevice *dev, - GAsyncResult *res, - QmiDevice *qmidev) + +typedef struct { + QmiDevice *self; + gconstpointer transaction_key; +} MbimTransactionContext; + +static MbimTransactionContext * +mbim_transaction_context_new (QmiDevice *self, + gconstpointer transaction_key) { - MbimMessage *response; - GError *error = NULL; - const guint8 *buf; - guint32 len; + MbimTransactionContext *ctx; - response = mbim_device_command_finish (dev, res, &error); - if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { - g_prefix_error (&error, "MBIM error: "); - // transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - mbim_message_unref (response); - return; - } + ctx = g_slice_new (MbimTransactionContext); + ctx->self = g_object_ref (self); + ctx->transaction_key = transaction_key; + return ctx; +} + +static void +mbim_transaction_context_free (MbimTransactionContext *ctx) +{ + g_object_unref (ctx->self); + g_slice_free (MbimTransactionContext, ctx); +} - g_debug ("[%s] Received MBIM message\n", qmidev->priv->path_display); +static void +mbim_device_command_ready (MbimDevice *dev, + GAsyncResult *res, + MbimTransactionContext *ctx) +{ + MbimMessage *response; + GError *error = NULL; + const guint8 *buf; + guint32 len; + Transaction *tr; - /* get the information buffer */ - buf = mbim_message_command_done_get_raw_information_buffer (response, &len); - if (!G_UNLIKELY (qmidev->priv->buffer)) - qmidev->priv->buffer = g_byte_array_sized_new (len); - g_byte_array_append (qmidev->priv->buffer, buf, len); + /* It is possible that the transaction doesn't exist, when it gets cancelled + * by the user before the response arrives. In such a case, we just return + * without processing the response */ + tr = g_hash_table_lookup (ctx->self->priv->transactions, ctx->transaction_key); + if (!tr) { + mbim_device_command_finish (dev, res, NULL); + mbim_transaction_context_free (ctx); + return; + } - /* and parse it as QMI */ - parse_response(qmidev); + response = mbim_device_command_finish (dev, res, &error); + if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { + g_prefix_error (&error, "MBIM error: "); + transaction_complete_and_free (tr, NULL, error); mbim_message_unref (response); + mbim_transaction_context_free (ctx); return; + } + + g_debug ("[%s] Received MBIM message", ctx->self->priv->path_display); + + /* Store the raw information buffer in the internal reception buffer, + * as if we had read from a iochannel. */ + buf = mbim_message_command_done_get_raw_information_buffer (response, &len); + if (!G_UNLIKELY (ctx->self->priv->buffer)) + ctx->self->priv->buffer = g_byte_array_sized_new (len); + g_byte_array_append (ctx->self->priv->buffer, buf, len); + + /* And parse it as QMI; it should remove and cleanup the transaction */ + parse_response (ctx->self); + mbim_message_unref (response); + + /* After processing the QMI message, we check whether the transaction id was + * removed from our tables, and if it wasn't (e.g. the QMI message embedded + * in MBIM wasn't the proper one), we remove it ourselves. This is so that + * we don't leave unused transactions in the HT, given that we've disabled + * the transaction timeout for MBIM based ones */ + tr = device_release_transaction (ctx->self, ctx->transaction_key); + if (tr) { + /* Complete transaction with a timeout error */ + error = g_error_new (QMI_CORE_ERROR, + QMI_CORE_ERROR_UNEXPECTED_MESSAGE, + "Transaction received unexpected message"); + transaction_complete_and_free (tr, NULL, error); + g_error_free (error); + } + + mbim_transaction_context_free (ctx); } + +static gboolean +mbim_command (QmiDevice *self, + gconstpointer raw_message, + gsize raw_message_len, + gconstpointer transaction_key, + guint timeout, + GCancellable *cancellable, + GError **error) +{ + MbimMessage *mbim_message; + + g_debug ("[%s] sending message as MBIM...", self->priv->path_display); + + mbim_message = (mbim_message_qmi_msg_set_new (raw_message_len, raw_message, error)); + if (!mbim_message) + return FALSE; + + /* Note: + * + * Pass a full reference to the original QMI device to the MBIM command + * operation, so that we make sure the parent object is valid regardless + * of when the underlying device is fully disposed. This is required + * because device close is async(). + */ + mbim_device_command (self->priv->mbimdev, + mbim_message, + timeout, + cancellable, + (GAsyncReadyCallback) mbim_device_command_ready, + mbim_transaction_context_new (self, transaction_key)); + + mbim_message_unref (mbim_message); + return TRUE; +} + #endif /*****************************************************************************/ @@ -2362,9 +2454,11 @@ qmi_device_command (QmiDevice *self, Transaction *tr; gconstpointer raw_message; gsize raw_message_len; + guint transaction_timeout; g_return_if_fail (QMI_IS_DEVICE (self)); g_return_if_fail (message != NULL); + g_return_if_fail (timeout > 0); /* Use a proper transaction id for CTL messages if they don't have one */ if (qmi_message_get_service (message) == QMI_SERVICE_CTL && @@ -2379,7 +2473,7 @@ qmi_device_command (QmiDevice *self, tr = transaction_new (self, message, cancellable, callback, user_data); /* Device must be open */ - if ((!self->priv->istream || !self->priv->ostream) && !self->priv->mbim_qmux) { + if ((!self->priv->istream || !self->priv->ostream) && !self->priv->mbimdev) { error = g_error_new (QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, "Device must be open to send commands"); @@ -2418,8 +2512,16 @@ qmi_device_command (QmiDevice *self, return; } + /* For transactions using the MBIM backend, no explicit timeout is set. + * Instead, we rely on the timeout management in libmbim. */ + transaction_timeout = timeout; +#if defined MBIM_QMUX_ENABLED + if (self->priv->mbimdev) + transaction_timeout = 0; +#endif + /* Setup context to match response */ - if (!device_store_transaction (self, tr, timeout, &error)) { + if (!device_store_transaction (self, tr, transaction_timeout, &error)) { g_prefix_error (&error, "Cannot store transaction: "); transaction_complete_and_free (tr, NULL, error); g_error_free (error); @@ -2449,23 +2551,22 @@ qmi_device_command (QmiDevice *self, } #if defined MBIM_QMUX_ENABLED - /* wrap QMUX in MBIM? */ - if (self->priv->mbim_qmux) { - MbimMessage *mbim; - - mbim = (mbim_message_qmi_msg_set_new (raw_message_len, raw_message, &error)); - mbim_device_command (self->priv->mbimdev, - mbim, - 30, - NULL, /* cancellable */ - (GAsyncReadyCallback)mbim_device_command_ready, - self); - g_debug ("[%s] Message sent as MBIM\n", self->priv->path_display); - - /* FIXME: check errors, set proper MBIM TID */ + if (self->priv->mbimdev) { + if (!mbim_command (self, + raw_message, + raw_message_len, + build_transaction_key (message), + timeout, + cancellable, + &error)) { + g_prefix_error (&error, "Cannot create MBIM command: "); + transaction_complete_and_free (tr, NULL, error); + g_error_free (error); + } return; - } + } #endif + if (!g_output_stream_write_all (self->priv->ostream, raw_message, raw_message_len, diff --git a/src/libqmi-glib/qmi-errors.h b/src/libqmi-glib/qmi-errors.h index 9c73d27..e8e5588 100644 --- a/src/libqmi-glib/qmi-errors.h +++ b/src/libqmi-glib/qmi-errors.h @@ -50,19 +50,21 @@ * @QMI_CORE_ERROR_TLV_TOO_LONG: TLV is too long. * @QMI_CORE_ERROR_UNSUPPORTED: Not supported. * @QMI_CORE_ERROR_TLV_EMPTY: TLV has no value. + * @QMI_CORE_ERROR_UNEXPECTED_MESSAGE: QMI message is unexpected. * * Common errors that may be reported by libqmi-glib. */ typedef enum { /*< underscore_name=qmi_core_error >*/ - QMI_CORE_ERROR_FAILED = 0, /*< nick=Failed >*/ - QMI_CORE_ERROR_WRONG_STATE = 1, /*< nick=WrongState >*/ - QMI_CORE_ERROR_TIMEOUT = 2, /*< nick=Timeout >*/ - QMI_CORE_ERROR_INVALID_ARGS = 3, /*< nick=InvalidArgs >*/ - QMI_CORE_ERROR_INVALID_MESSAGE = 4, /*< nick=InvalidMessage >*/ - QMI_CORE_ERROR_TLV_NOT_FOUND = 5, /*< nick=TlvNotFound >*/ - QMI_CORE_ERROR_TLV_TOO_LONG = 6, /*< nick=TlvTooLong >*/ - QMI_CORE_ERROR_UNSUPPORTED = 7, /*< nick=Unsupported >*/ - QMI_CORE_ERROR_TLV_EMPTY = 8, /*< nick=TlvEmpty >*/ + QMI_CORE_ERROR_FAILED = 0, /*< nick=Failed >*/ + QMI_CORE_ERROR_WRONG_STATE = 1, /*< nick=WrongState >*/ + QMI_CORE_ERROR_TIMEOUT = 2, /*< nick=Timeout >*/ + QMI_CORE_ERROR_INVALID_ARGS = 3, /*< nick=InvalidArgs >*/ + QMI_CORE_ERROR_INVALID_MESSAGE = 4, /*< nick=InvalidMessage >*/ + QMI_CORE_ERROR_TLV_NOT_FOUND = 5, /*< nick=TlvNotFound >*/ + QMI_CORE_ERROR_TLV_TOO_LONG = 6, /*< nick=TlvTooLong >*/ + QMI_CORE_ERROR_UNSUPPORTED = 7, /*< nick=Unsupported >*/ + QMI_CORE_ERROR_TLV_EMPTY = 8, /*< nick=TlvEmpty >*/ + QMI_CORE_ERROR_UNEXPECTED_MESSAGE = 9, /*< nick=UnexpectedMessage >*/ } QmiCoreError; /** -- 2.7.4 0009-libqmi-glib-mbim-don-t-create-mbim-device-multiple-t.patch0000664000175100017510000000214113117471773021637 0ustar uuFrom ee3e4b3682ba843ef6a829528d48d47683b5b4c2 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 20:42:20 +0200 Subject: [PATCH 09/17] libqmi-glib,mbim: don't create mbim device multiple times --- src/libqmi-glib/qmi-device.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 1c81960..d905623 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -1962,6 +1962,15 @@ create_mbim_device (DeviceOpenContext *ctx) { GFile *file; + if (ctx->self->priv->mbimdev) { + g_simple_async_result_set_error (ctx->result, + QMI_CORE_ERROR, + QMI_CORE_ERROR_WRONG_STATE, + "Already open"); + device_open_context_complete_and_free (ctx); + return; + } + g_debug ("[%s] creating MBIM device...", ctx->self->priv->path_display); file = g_file_new_for_path (ctx->self->priv->path); mbim_device_new (file, -- 2.7.4 0010-libqmi-glib-mbim-run-the-mbim-close-operation-synchr.patch0000664000175100017510000000574313117471773022020 0ustar uuFrom 44fa2d8c903bb5b7608896298ffa35696731f98a Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 20:42:55 +0200 Subject: [PATCH 10/17] libqmi-glib,mbim: run the mbim close operation synchronously --- src/libqmi-glib/qmi-device.c | 60 +++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index d905623..9f79327 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -2223,35 +2223,57 @@ destroy_iostream (QmiDevice *self, #if defined MBIM_QMUX_ENABLED +typedef struct { + GError *error; + GMainLoop *loop; +} SyncMbimClose; + static void -mbim_device_close_ready (MbimDevice *dev, - GAsyncResult *res, - QmiDevice *self) +mbim_device_close_ready (MbimDevice *dev, + GAsyncResult *res, + SyncMbimClose *ctx) { - GError *error = NULL; - - if (!mbim_device_close_finish (dev, res, &error)) { - g_warning ("[%s] error: couldn't close device: %s", - self->priv->path_display, error->message); - g_error_free (error); - } else - g_debug ("[%s] MBIM device closed", self->priv->path_display); - g_object_unref (self); + mbim_device_close_finish (dev, res, &ctx->error); + g_main_loop_quit (ctx->loop); } -static void -destroy_mbim_device (QmiDevice *self) +static gboolean +destroy_mbim_device (QmiDevice *self, + GError **error) { - /* TODO: make this sync */ + GMainContext *main_ctx; + SyncMbimClose ctx; + + main_ctx = g_main_context_new (); + g_main_context_push_thread_default (main_ctx); + + ctx.loop = g_main_loop_new (main_ctx, FALSE); + ctx.error = NULL; + + /* Schedule in new main context */ mbim_device_close (self->priv->mbimdev, 15, NULL, (GAsyncReadyCallback) mbim_device_close_ready, - g_object_ref (self)); + &ctx); /* Cleanup right away, we don't want multiple close attempts on the * device */ g_clear_object (&self->priv->mbimdev); + + /* Run */ + g_main_loop_run (ctx.loop); + g_main_loop_unref (ctx.loop); + g_main_context_pop_thread_default (main_ctx); + g_main_context_unref (main_ctx); + + /* Report error, if any found */ + if (error) { + g_propagate_error (error, ctx.error); + return FALSE; + } + + return TRUE; } #endif @@ -2274,10 +2296,8 @@ qmi_device_close (QmiDevice *self, g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE); #if defined MBIM_QMUX_ENABLED - if (self->priv->mbimdev) { - destroy_mbim_device (self); - return TRUE; - } + if (self->priv->mbimdev) + return destroy_mbim_device (self, error); #endif if (!destroy_iostream (self, error)) { -- 2.7.4 0011-libqmi-glib-version-new-symbol-to-flag-qmi-over-mbim.patch0000664000175100017510000000445413117471773021751 0ustar uuFrom 97d26079ef2e6cf39d6274d05e6472a7089be78c Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 6 Jun 2016 15:50:18 +0200 Subject: [PATCH 11/17] libqmi-glib,version: new symbol to flag qmi-over-mbim support --- configure.ac | 4 ++++ docs/reference/libqmi-glib/libqmi-glib-common.sections | 3 ++- src/libqmi-glib/qmi-version.h.in | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5eb4d5d..4e7f7d9 100644 --- a/configure.ac +++ b/configure.ac @@ -114,7 +114,11 @@ if test "x$enable_mbim_qmux" = "xyes"; then AC_DEFINE(MBIM_QMUX_ENABLED, 1, [Define if MBIM QMUX support enabled]) AC_SUBST(MBIM_CFLAGS) AC_SUBST(MBIM_LIBS) + QMI_MBIM_QMUX_SUPPORTED=1 +else + QMI_MBIM_QMUX_SUPPORTED=0 fi +AC_SUBST(QMI_MBIM_QMUX_SUPPORTED) # udev base directory AC_ARG_WITH(udev-base-dir, AS_HELP_STRING([--with-udev-base-dir=DIR], [where udev base directory is])) diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections index a34226d..5d37ebd 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-common.sections +++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections @@ -1,10 +1,11 @@
qmi-version -Version checks +Version and feature checks QMI_MAJOR_VERSION QMI_MINOR_VERSION QMI_MICRO_VERSION QMI_CHECK_VERSION +QMI_MBIM_QMUX_SUPPORTED
diff --git a/src/libqmi-glib/qmi-version.h.in b/src/libqmi-glib/qmi-version.h.in index 22dda01..3369d2e 100644 --- a/src/libqmi-glib/qmi-version.h.in +++ b/src/libqmi-glib/qmi-version.h.in @@ -66,4 +66,21 @@ (QMI_MAJOR_VERSION == (major) && QMI_MINOR_VERSION > (minor)) || \ (QMI_MAJOR_VERSION == (major) && QMI_MINOR_VERSION == (minor) && QMI_MICRO_VERSION >= (micro))) +/** + * QMI_MBIM_QMUX_SUPPORTED: + * + * Symbol to expose wether QMI over MBIM is supported. The symbol is always + * defined and set to either or 1 or 0. + * + * E.g.: + * |[ + * #if QMI_MBIM_QMUX_SUPPORTED + * // do something + * #endif + * ]| + * + * Since: 1.16 + */ +#define QMI_MBIM_QMUX_SUPPORTED @QMI_MBIM_QMUX_SUPPORTED@ + #endif /* _QMI_VERSION_H_ */ -- 2.7.4 0012-libqmi-glib-device-fix-build-with-mbim-qmux-disabled.patch0000664000175100017510000000306213117471773021727 0ustar uuFrom 59a18f8624dffc1a58a188dc5559ba93733a5d59 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Wed, 8 Jun 2016 07:28:05 +0200 Subject: [PATCH 12/17] libqmi-glib,device: fix build with mbim-qmux disabled --- src/libqmi-glib/qmi-device.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 9f79327..81ca98b 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -2502,13 +2502,18 @@ qmi_device_command (QmiDevice *self, tr = transaction_new (self, message, cancellable, callback, user_data); /* Device must be open */ - if ((!self->priv->istream || !self->priv->ostream) && !self->priv->mbimdev) { - error = g_error_new (QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "Device must be open to send commands"); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; + if (!self->priv->istream || !self->priv->ostream) { +#if defined MBIM_QMUX_ENABLED + if (!self->priv->mbimdev) +#endif + { + error = g_error_new (QMI_CORE_ERROR, + QMI_CORE_ERROR_WRONG_STATE, + "Device must be open to send commands"); + transaction_complete_and_free (tr, NULL, error); + g_error_free (error); + return; + } } /* Non-CTL services should use a proper CID */ -- 2.7.4 0013-libqmi-glib-device-avoid-unref-ing-MBIM-message-if-n.patch0000664000175100017510000000175013117471773021404 0ustar uuFrom fd9076d1a82144e9af86d3e166c648157b546571 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 27 Jun 2016 07:42:37 +0200 Subject: [PATCH 13/17] libqmi-glib,device: avoid unref-ing MBIM message if none received --- src/libqmi-glib/qmi-device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index 81ca98b..c12cb95 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -2359,7 +2359,8 @@ mbim_device_command_ready (MbimDevice *dev, if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { g_prefix_error (&error, "MBIM error: "); transaction_complete_and_free (tr, NULL, error); - mbim_message_unref (response); + if (response) + mbim_message_unref (response); mbim_transaction_context_free (ctx); return; } -- 2.7.4 0014-build-distcheck-always-uses-qmi-over-mbim-support.patch0000664000175100017510000000121413117471773021472 0ustar uuFrom dbcba9de05e21346739dbe340189430abecbff3b Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 7 Jul 2016 19:37:13 +0200 Subject: [PATCH 14/17] build: distcheck always uses qmi-over-mbim support --- Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 7970fbe..4d2ce1a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,7 +5,9 @@ ACLOCAL_AMFLAGS = -I m4 DISTCHECK_CONFIGURE_FLAGS = \ --with-udev-base-dir="$$dc_install_base" \ - --enable-gtk-doc + --enable-gtk-doc \ + --enable-mbim-qmux \ + $(NULL) EXTRA_DIST = \ gtester.make \ -- 2.7.4 0015-build-fix-a-typo-in-mbim-check.patch0000664000175100017510000000153313117471773015470 0ustar uuFrom 959a293d3684138729cf992e41308c18cf91a5e6 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 8 Jul 2016 16:57:25 +0200 Subject: [PATCH 15/17] build: fix a typo in mbim check --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4e7f7d9..763b254 100644 --- a/configure.ac +++ b/configure.ac @@ -108,7 +108,7 @@ if test "x$enable_mbim_qmux" = "xauto"; then fi if test "x$enable_mbim_qmux" = "xyes"; then - if test "xhave_mbim" = "xno"; then + if test "x$have_mbim" = "xno"; then AC_MSG_ERROR([Couldn't find `libmbim-glib` >= ${MBIM_GLIB_VERSION}. Install it, or otherwise configure using --disable-mbim-qmux to disable the QMI over MBIM QMUX service.]) fi AC_DEFINE(MBIM_QMUX_ENABLED, 1, [Define if MBIM QMUX support enabled]) -- 2.7.4 0016-build-post-release-version-bump-to-1.16.5.patch0000664000175100017510000000140413117471773017265 0ustar uuFrom a9a502ce845545d05ee72b62eba0e1019e1c9192 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Tue, 21 Mar 2017 12:37:33 +0100 Subject: [PATCH 16/17] build: post release version bump to 1.16.5 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 763b254..d3b651c 100644 --- a/configure.ac +++ b/configure.ac @@ -3,8 +3,8 @@ AC_PREREQ([2.68]) dnl The QMI version number m4_define([qmi_major_version], [1]) -m4_define([qmi_minor_version], [14]) -m4_define([qmi_micro_version], [0]) +m4_define([qmi_minor_version], [16]) +m4_define([qmi_micro_version], [5]) m4_define([qmi_version], [qmi_major_version.qmi_minor_version.qmi_micro_version]) -- 2.7.4 0017-backport-qmi-over-mbim-to-libmbim-glib4-1.12.2-and-l.patch0000664000175100017510000000153513117471773021025 0ustar uuFrom 4fe9c3db6618c6fa4d45233e61646a128d971eab Mon Sep 17 00:00:00 2001 From: Alex Tu Date: Tue, 6 Jun 2017 15:30:41 +0800 Subject: [PATCH 17/17] backport qmi over mbim to libmbim-glib4 1.12.2 and libqmi-glib1 1.12.6 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index d3b651c..fb9fb66 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,7 @@ fi AM_CONDITIONAL([QMI_USERNAME_ENABLED], [test "x$QMI_USERNAME_ENABLED" = "xyes"]) # MBIM QMUX service support -MBIM_GLIB_VERSION=1.14.0 +MBIM_GLIB_VERSION=1.12.0 PKG_CHECK_MODULES([MBIM], [mbim-glib >= ${MBIM_GLIB_VERSION}], [have_mbim=yes], [have_mbim=no]) AC_ARG_ENABLE(mbim-qmux, AS_HELP_STRING([--enable-mbim-qmux], [Enable support for QMI over MBIM QMUX service [default=auto]]), -- 2.7.4