aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmi-firmware-update
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-01-13 15:14:09 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 11:24:16 +0100
commit3038951fe085514f6fa4872d0b578756fe22d492 (patch)
treee4d16036e9bac1996ee84a88407644117980465e /src/qmi-firmware-update
parentf8c5c6f48b07fce4d6deeb8c4b10aaf393ca8264 (diff)
downloadexternal_libqmi-3038951fe085514f6fa4872d0b578756fe22d492.zip
external_libqmi-3038951fe085514f6fa4872d0b578756fe22d492.tar.gz
external_libqmi-3038951fe085514f6fa4872d0b578756fe22d492.tar.bz2
qmi-firmware-update: make QMI client allocation a common util
Diffstat (limited to 'src/qmi-firmware-update')
-rw-r--r--src/qmi-firmware-update/Makefile.am9
-rw-r--r--src/qmi-firmware-update/qfu-updater.c148
-rw-r--r--src/qmi-firmware-update/qfu-utils.c179
-rw-r--r--src/qmi-firmware-update/qfu-utils.h12
-rw-r--r--src/qmi-firmware-update/test/Makefile.am4
5 files changed, 222 insertions, 130 deletions
diff --git a/src/qmi-firmware-update/Makefile.am b/src/qmi-firmware-update/Makefile.am
index b165e2a..a9c3583 100644
--- a/src/qmi-firmware-update/Makefile.am
+++ b/src/qmi-firmware-update/Makefile.am
@@ -9,10 +9,15 @@ libutils_la_SOURCES = \
libutils_la_CPPFLAGS = \
$(GLIB_CFLAGS) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated \
$(NULL)
libutils_la_LIBADD = \
- $(GLIB_CFLAGS) \
+ $(top_builddir)/src/libqmi-glib/libqmi-glib.la \
+ $(GLIB_LDFLAGS) \
$(NULL)
bin_PROGRAMS = qmi-firmware-update
@@ -73,7 +78,6 @@ qmi_firmware_update_SOURCES = \
qfu-qdl-device.h qfu-qdl-device.c \
qfu-reseter.h qfu-reseter.c \
qfu-at-device.h qfu-at-device.c \
- qfu-utils.h qfu-utils.c \
$(NULL)
qmi_firmware_update_LDADD = \
@@ -81,7 +85,6 @@ qmi_firmware_update_LDADD = \
$(GUDEV_LIBS) \
$(GLIB_LIBS) \
$(builddir)/libutils.la \
- $(top_builddir)/src/libqmi-glib/libqmi-glib.la \
$(NULL)
# Request to build enum types before anything else
diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c
index 0cdaba4..55cd52b 100644
--- a/src/qmi-firmware-update/qfu-updater.c
+++ b/src/qmi-firmware-update/qfu-updater.c
@@ -60,11 +60,7 @@ struct _QfuUpdaterPrivate {
/******************************************************************************/
/* Run */
-#define QMI_CLIENT_RETRIES 3
-
typedef enum {
- RUN_CONTEXT_STEP_QMI_DEVICE,
- RUN_CONTEXT_STEP_QMI_DEVICE_OPEN,
RUN_CONTEXT_STEP_QMI_CLIENT,
RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE,
RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE,
@@ -97,7 +93,6 @@ typedef struct {
/* QMI device and client */
QmiDevice *qmi_device;
QmiClientDms *qmi_client;
- gint qmi_client_retries;
/* QDL device */
QfuQdlDevice *qdl_device;
@@ -576,7 +571,7 @@ run_context_step_reset (GTask *task)
}
/* Boothold reset */
- reseter = qfu_reseter_new (self->priv->device_selection);
+ reseter = qfu_reseter_new (self->priv->device_selection, ctx->qmi_client);
qfu_reseter_run (reseter,
g_task_get_cancellable (task),
(GAsyncReadyCallback) reseter_run_ready,
@@ -973,152 +968,52 @@ run_context_step_get_firmware_preference (GTask *task)
}
static void
-qmi_client_ready (QmiDevice *device,
- GAsyncResult *res,
- GTask *task)
+new_client_dms_ready (gpointer unused,
+ GAsyncResult *res,
+ GTask *task)
{
RunContext *ctx;
GError *error = NULL;
ctx = (RunContext *) g_task_get_task_data (task);
- ctx->qmi_client = QMI_CLIENT_DMS (qmi_device_allocate_client_finish (device, res, &error));
- if (!ctx->qmi_client) {
- /* If this was the last attempt, error out */
- if (!ctx->qmi_client_retries) {
- g_prefix_error (&error, "couldn't allocate DMS QMI client: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- /* Retry allocation */
- g_debug ("[qfu-updater: DMS QMI client allocation failed: %s", error->message);
- g_error_free (error);
-
- g_debug ("[qfu-updater: retrying...");
- run_context_step_next (task, ctx->step);
- return;
- }
-
- g_debug ("[qfu-updater] DMS QMI client allocated");
-
- /* Go on */
- run_context_step_next (task, ctx->step + 1);
-}
-
-static void
-run_context_step_qmi_client (GTask *task)
-{
- RunContext *ctx;
-
- ctx = (RunContext *) g_task_get_task_data (task);
-
- /* Consume one retry attempt */
- ctx->qmi_client_retries--;
- g_assert (ctx->qmi_client_retries >= 0);
-
- g_debug ("[qfu-updater] allocating new DMS QMI client...");
- qmi_device_allocate_client (ctx->qmi_device,
- QMI_SERVICE_DMS,
- QMI_CID_NONE,
- 10,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) qmi_client_ready,
- task);
-}
-
-static void
-qmi_device_open_ready (QmiDevice *device,
- GAsyncResult *res,
- GTask *task)
-{
- RunContext *ctx;
- GError *error = NULL;
-
- ctx = (RunContext *) g_task_get_task_data (task);
-
- if (!qmi_device_open_finish (device, res, &error)) {
- g_prefix_error (&error, "couldn't open QMI device: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
-
- g_debug ("[qfu-updater] QMI device open");
-
- /* Go on */
- run_context_step_next (task, ctx->step + 1);
-}
-
-static void
-run_context_step_qmi_device_open (GTask *task)
-{
- QfuUpdater *self;
- RunContext *ctx;
- QmiDeviceOpenFlags flags = QMI_DEVICE_OPEN_FLAGS_NONE;
-
- ctx = (RunContext *) g_task_get_task_data (task);
- self = g_task_get_source_object (task);
-
- if (self->priv->device_open_proxy)
- flags |= QMI_DEVICE_OPEN_FLAGS_PROXY;
-
- if (self->priv->device_open_mbim)
- flags |= QMI_DEVICE_OPEN_FLAGS_MBIM;
+ g_assert (!ctx->qmi_device);
+ g_assert (!ctx->qmi_client);
- g_debug ("[qfu-updater] opening QMI device...");
- qmi_device_open (ctx->qmi_device,
- flags,
- 20,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) qmi_device_open_ready,
- task);
-}
-
-static void
-qmi_device_ready (GObject *source,
- GAsyncResult *res,
- GTask *task)
-{
- RunContext *ctx;
- GError *error = NULL;
-
- ctx = (RunContext *) g_task_get_task_data (task);
-
- ctx->qmi_device = qmi_device_new_finish (res, &error);
- if (!ctx->qmi_device) {
- g_prefix_error (&error, "couldn't create QMI device: ");
+ if (!qfu_utils_new_client_dms_finish (res,
+ &ctx->qmi_device,
+ &ctx->qmi_client,
+ &error)) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
- g_debug ("[qfu-updater] QMI device created");
-
/* Go on */
run_context_step_next (task, ctx->step + 1);
}
static void
-run_context_step_qmi_device (GTask *task)
+run_context_step_qmi_client (GTask *task)
{
RunContext *ctx;
+ QfuUpdater *self;
ctx = (RunContext *) g_task_get_task_data (task);
+ self = g_task_get_source_object (task);
- g_debug ("[qfu-updater] creating QMI device...");
+ g_debug ("[qfu-updater] creating QMI DMS client...");
g_assert (ctx->cdc_wdm_file);
- qmi_device_new (ctx->cdc_wdm_file,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) qmi_device_ready,
- task);
+ qfu_utils_new_client_dms (ctx->cdc_wdm_file,
+ self->priv->device_open_proxy,
+ self->priv->device_open_mbim,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) new_client_dms_ready,
+ task);
}
typedef void (* RunContextStepFunc) (GTask *task);
static const RunContextStepFunc run_context_step_func[] = {
- [RUN_CONTEXT_STEP_QMI_DEVICE] = run_context_step_qmi_device,
- [RUN_CONTEXT_STEP_QMI_DEVICE_OPEN] = run_context_step_qmi_device_open,
[RUN_CONTEXT_STEP_QMI_CLIENT] = run_context_step_qmi_client,
[RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE] = run_context_step_get_firmware_preference,
[RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE] = run_context_step_set_firmware_preference,
@@ -1217,8 +1112,7 @@ qfu_updater_run (QfuUpdater *self,
switch (self->priv->type) {
case UPDATER_TYPE_GENERIC:
- ctx->step = RUN_CONTEXT_STEP_QMI_DEVICE;
- ctx->qmi_client_retries = QMI_CLIENT_RETRIES;
+ ctx->step = RUN_CONTEXT_STEP_QMI_CLIENT;
ctx->cdc_wdm_file = qfu_device_selection_get_single_cdc_wdm (self->priv->device_selection);
if (!ctx->cdc_wdm_file) {
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
diff --git a/src/qmi-firmware-update/qfu-utils.c b/src/qmi-firmware-update/qfu-utils.c
index 4e0b6e3..2fe1551 100644
--- a/src/qmi-firmware-update/qfu-utils.c
+++ b/src/qmi-firmware-update/qfu-utils.c
@@ -213,3 +213,182 @@ out:
return result;
}
+
+/******************************************************************************/
+
+#define QMI_CLIENT_RETRIES 3
+
+typedef struct {
+ QmiDevice *qmi_device;
+ gboolean device_open_proxy;
+ gboolean device_open_mbim;
+ gint qmi_client_retries;
+ QmiClientDms *qmi_client;
+} NewClientDmsContext;
+
+static void
+new_client_dms_context_free (NewClientDmsContext *ctx)
+{
+ if (ctx->qmi_client)
+ g_object_unref (ctx->qmi_client);
+ if (ctx->qmi_device)
+ g_object_unref (ctx->qmi_device);
+ g_slice_free (NewClientDmsContext, ctx);
+}
+
+gboolean
+qfu_utils_new_client_dms_finish (GAsyncResult *res,
+ QmiDevice **qmi_device,
+ QmiClientDms **qmi_client,
+ GError **error)
+{
+ NewClientDmsContext *ctx;
+
+ if (!g_task_propagate_boolean (G_TASK (res), error))
+ return FALSE;
+
+ ctx = (NewClientDmsContext *) g_task_get_task_data (G_TASK (res));
+ if (qmi_device)
+ *qmi_device = g_object_ref (ctx->qmi_device);
+ if (qmi_client)
+ *qmi_client = g_object_ref (ctx->qmi_client);
+ return TRUE;
+}
+
+static void retry_allocate_qmi_client (GTask *task);
+
+static void
+qmi_client_ready (QmiDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ NewClientDmsContext *ctx;
+ GError *error = NULL;
+
+ ctx = (NewClientDmsContext *) g_task_get_task_data (task);
+
+ ctx->qmi_client = QMI_CLIENT_DMS (qmi_device_allocate_client_finish (device, res, &error));
+ if (!ctx->qmi_client) {
+ /* If this was the last attempt, error out */
+ if (!ctx->qmi_client_retries) {
+ g_prefix_error (&error, "couldn't allocate DMS QMI client: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ /* Retry allocation */
+ g_debug ("[qfu,utils] DMS QMI client allocation failed: %s", error->message);
+ g_error_free (error);
+
+ g_debug ("[qfu,utils] retrying...");
+ retry_allocate_qmi_client (task);
+ return;
+ }
+
+ g_debug ("[qfu,utils] DMS QMI client allocated");
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+retry_allocate_qmi_client (GTask *task)
+{
+ NewClientDmsContext *ctx;
+
+ ctx = (NewClientDmsContext *) g_task_get_task_data (task);
+
+ /* Consume one retry attempt */
+ ctx->qmi_client_retries--;
+ g_assert (ctx->qmi_client_retries >= 0);
+
+ g_debug ("[qfu,utils] allocating new DMS QMI client...");
+ qmi_device_allocate_client (ctx->qmi_device,
+ QMI_SERVICE_DMS,
+ QMI_CID_NONE,
+ 10,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qmi_client_ready,
+ task);
+}
+
+static void
+qmi_device_open_ready (QmiDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+
+ if (!qmi_device_open_finish (device, res, &error)) {
+ g_prefix_error (&error, "couldn't open QMI device: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ g_debug ("[qfu,utils] QMI device open");
+ retry_allocate_qmi_client (task);
+}
+
+static void
+qmi_device_ready (GObject *source,
+ GAsyncResult *res,
+ GTask *task)
+{
+ NewClientDmsContext *ctx;
+ GError *error = NULL;
+ QmiDeviceOpenFlags flags = QMI_DEVICE_OPEN_FLAGS_NONE;
+
+ ctx = (NewClientDmsContext *) g_task_get_task_data (task);
+
+ ctx->qmi_device = qmi_device_new_finish (res, &error);
+ if (!ctx->qmi_device) {
+ g_prefix_error (&error, "couldn't create QMI device: ");
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ g_debug ("[qfu,utils] QMI device created");
+
+ if (ctx->device_open_proxy)
+ flags |= QMI_DEVICE_OPEN_FLAGS_PROXY;
+ if (ctx->device_open_mbim)
+ flags |= QMI_DEVICE_OPEN_FLAGS_MBIM;
+
+ g_debug ("[qfu,utils] opening QMI device (%s proxy, %s mode)...",
+ ctx->device_open_proxy ? "with" : "without",
+ ctx->device_open_mbim ? "mbim" : "qmi");
+ qmi_device_open (ctx->qmi_device,
+ flags,
+ 20,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qmi_device_open_ready,
+ task);
+}
+
+void
+qfu_utils_new_client_dms (GFile *cdc_wdm_file,
+ gboolean device_open_proxy,
+ gboolean device_open_mbim,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ NewClientDmsContext *ctx;
+
+ ctx = g_slice_new0 (NewClientDmsContext);
+ ctx->device_open_proxy = device_open_proxy;
+ ctx->device_open_mbim = device_open_mbim;
+ ctx->qmi_client_retries = QMI_CLIENT_RETRIES;
+
+ task = g_task_new (NULL, cancellable, callback, user_data);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) new_client_dms_context_free);
+
+ g_debug ("[qfu,utils] creating QMI device...");
+ qmi_device_new (cdc_wdm_file,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) qmi_device_ready,
+ task);
+}
diff --git a/src/qmi-firmware-update/qfu-utils.h b/src/qmi-firmware-update/qfu-utils.h
index 8180a83..076520e 100644
--- a/src/qmi-firmware-update/qfu-utils.h
+++ b/src/qmi-firmware-update/qfu-utils.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include <gio/gio.h>
+#include <libqmi-glib.h>
G_BEGIN_DECLS
@@ -43,6 +44,17 @@ gboolean qfu_utils_parse_cwe_version_string (const gchar *version,
gchar **carrier,
GError **error);
+void qfu_utils_new_client_dms (GFile *cdc_wdm_file,
+ gboolean device_open_proxy,
+ gboolean device_open_mbim,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean qfu_utils_new_client_dms_finish (GAsyncResult *res,
+ QmiDevice **qmi_device,
+ QmiClientDms **qmi_client,
+ GError **error);
+
G_END_DECLS
#endif /* QFU_UTILS_H */
diff --git a/src/qmi-firmware-update/test/Makefile.am b/src/qmi-firmware-update/test/Makefile.am
index 7ef33d3..36cf8ea 100644
--- a/src/qmi-firmware-update/test/Makefile.am
+++ b/src/qmi-firmware-update/test/Makefile.am
@@ -13,6 +13,10 @@ test_utils_SOURCES = \
test_utils_CPPFLAGS = \
$(GLIB_CFLAGS) \
-I$(top_srcdir) \
+ -I$(top_srcdir)/src/libqmi-glib \
+ -I$(top_srcdir)/src/libqmi-glib/generated \
+ -I$(top_builddir)/src/libqmi-glib \
+ -I$(top_builddir)/src/libqmi-glib/generated \
-I$(top_srcdir)/src/qmi-firmware-update \
-I$(top_builddir)/src/qmi-firmware-update \
-DLIBQMI_GLIB_COMPILATION \