summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2017-01-13 14:15:40 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 11:24:16 +0100
commitf8c5c6f48b07fce4d6deeb8c4b10aaf393ca8264 (patch)
tree5290d6e473b2cf5412529c3d76f5272de686c95d
parentbdc0a1e71e18419dd15f8d6865425cb6884e77c0 (diff)
downloadlibqmi-f8c5c6f48b07fce4d6deeb8c4b10aaf393ca8264.tar.gz
qmi-firmware-update: new 'device selection' object
This new object contains the logic to select which device needs to be used as target of the firmware upgrade.
-rw-r--r--src/qmi-firmware-update/Makefile.am1
-rw-r--r--src/qmi-firmware-update/qfu-device-selection.c303
-rw-r--r--src/qmi-firmware-update/qfu-device-selection.h80
-rw-r--r--src/qmi-firmware-update/qfu-main.c213
-rw-r--r--src/qmi-firmware-update/qfu-operation-reset.c19
-rw-r--r--src/qmi-firmware-update/qfu-operation-update.c50
-rw-r--r--src/qmi-firmware-update/qfu-operation.h25
-rw-r--r--src/qmi-firmware-update/qfu-reseter.c27
-rw-r--r--src/qmi-firmware-update/qfu-reseter.h4
-rw-r--r--src/qmi-firmware-update/qfu-udev-helpers.c28
-rw-r--r--src/qmi-firmware-update/qfu-udev-helpers.h19
-rw-r--r--src/qmi-firmware-update/qfu-updater.c159
-rw-r--r--src/qmi-firmware-update/qfu-updater.h6
13 files changed, 587 insertions, 347 deletions
diff --git a/src/qmi-firmware-update/Makefile.am b/src/qmi-firmware-update/Makefile.am
index a54a8c32..b165e2ac 100644
--- a/src/qmi-firmware-update/Makefile.am
+++ b/src/qmi-firmware-update/Makefile.am
@@ -57,6 +57,7 @@ nodist_qmi_firmware_update_SOURCES = \
qmi_firmware_update_SOURCES = \
qfu-main.c \
+ qfu-device-selection.h qfu-device-selection.c \
qfu-operation.h \
qfu-operation-update.c \
qfu-operation-verify.c \
diff --git a/src/qmi-firmware-update/qfu-device-selection.c b/src/qmi-firmware-update/qfu-device-selection.c
new file mode 100644
index 00000000..bc2d9208
--- /dev/null
+++ b/src/qmi-firmware-update/qfu-device-selection.c
@@ -0,0 +1,303 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmi-firmware-update -- Command line tool to update firmware in QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2017 Zodiac Inflight Innovations
+ * Copyright (C) 2017 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <gio/gio.h>
+#include <gudev/gudev.h>
+
+#include <libqmi-glib.h>
+
+#include "qfu-device-selection.h"
+#include "qfu-udev-helpers.h"
+
+G_DEFINE_TYPE (QfuDeviceSelection, qfu_device_selection, G_TYPE_OBJECT)
+
+struct _QfuDeviceSelectionPrivate {
+ /* inputs */
+ gchar *preferred_devices[QFU_UDEV_HELPER_DEVICE_TYPE_LAST];
+ guint16 preferred_vid;
+ guint16 preferred_pid;
+ guint preferred_busnum;
+ guint preferred_devnum;
+ /* sysfs path */
+ gchar *sysfs_path;
+};
+
+/******************************************************************************/
+
+static GFile *
+device_selection_get_single (QfuDeviceSelection *self,
+ QfuUdevHelperDeviceType device_type)
+{
+ GFile *first_selection = NULL;
+ GFile *preferred_selection = NULL;
+ GList *list, *l;
+ gchar *path;
+
+ g_debug ("[qfu,device-selection] single %s device requested in sysfs path '%s'",
+ qfu_udev_helper_device_type_to_string (device_type),
+ self->priv->sysfs_path);
+
+ list = qfu_udev_helper_list_devices (device_type, self->priv->sysfs_path);
+ for (l = list; l; l = g_list_next (l)) {
+ path = g_file_get_path (G_FILE (l->data));
+ g_debug ("[qfu,device-selection] device found: %s", path);
+ if (!first_selection)
+ first_selection = g_object_ref (l->data);
+ if (!preferred_selection && !g_strcmp0 (path, self->priv->preferred_devices[device_type]))
+ preferred_selection = g_object_ref (l->data);
+ g_free (path);
+ }
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ if (preferred_selection) {
+ path = g_file_get_path (preferred_selection);
+ g_debug ("[qfu,device-selection] using preferred device: %s", path);
+ g_free (path);
+ if (first_selection)
+ g_object_unref (first_selection);
+ return preferred_selection;
+ }
+
+ if (first_selection) {
+ path = g_file_get_path (first_selection);
+ g_debug ("[qfu,device-selection] using automatically selected device: %s", path);
+ g_free (path);
+ return first_selection;
+ }
+
+ g_debug ("[qfu,device-selection] couldn't find any device to use");
+ return NULL;
+}
+
+GFile *
+qfu_device_selection_get_single_cdc_wdm (QfuDeviceSelection *self)
+{
+ return device_selection_get_single (self, QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM);
+}
+
+GFile *
+qfu_device_selection_get_single_tty (QfuDeviceSelection *self)
+{
+ return device_selection_get_single (self, QFU_UDEV_HELPER_DEVICE_TYPE_TTY);
+}
+
+/******************************************************************************/
+
+static GList *
+device_selection_get_multiple (QfuDeviceSelection *self,
+ QfuUdevHelperDeviceType device_type)
+{
+ GFile *preferred_selection = NULL;
+ GList *list, *l;
+ gchar *path;
+
+ g_debug ("[qfu,device-selection] multiple %s devices requested in sysfs path '%s'",
+ qfu_udev_helper_device_type_to_string (device_type),
+ self->priv->sysfs_path);
+
+ list = qfu_udev_helper_list_devices (device_type, self->priv->sysfs_path);
+ for (l = list; l; l = g_list_next (l)) {
+ path = g_file_get_path (G_FILE (l->data));
+ g_debug ("[qfu,device-selection] device found: %s", path);
+ if (!preferred_selection && !g_strcmp0 (path, self->priv->preferred_devices[device_type]))
+ preferred_selection = g_object_ref (l->data);
+ g_free (path);
+ }
+
+ /* If we have a preferred device selected, we will only include that one in the output list */
+ if (preferred_selection) {
+ path = g_file_get_path (preferred_selection);
+ g_debug ("[qfu,device-selection] using only preferred device: %s", path);
+ g_free (path);
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+ return g_list_append (NULL, preferred_selection);
+ }
+
+ if (list)
+ return list;
+
+ g_debug ("[qfu,device-selection] couldn't find any device to use");
+ return NULL;
+}
+
+GList *
+qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self)
+{
+ return device_selection_get_multiple (self, QFU_UDEV_HELPER_DEVICE_TYPE_TTY);
+}
+
+/******************************************************************************/
+
+GFile *
+qfu_device_selection_wait_for_cdc_wdm_finish (QfuDeviceSelection *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return G_FILE (g_task_propagate_pointer (G_TASK (res), error));
+}
+
+GFile *
+qfu_device_selection_wait_for_tty_finish (QfuDeviceSelection *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return G_FILE (g_task_propagate_pointer (G_TASK (res), error));
+}
+
+static void
+wait_for_device_ready (gpointer unused,
+ GAsyncResult *res,
+ GTask *task)
+{
+ GError *error = NULL;
+ GFile *file;
+
+ file = qfu_udev_helper_wait_for_device_finish (res, &error);
+ if (!file)
+ g_task_return_error (task, error);
+ else
+ g_task_return_pointer (task, file, (GDestroyNotify) g_object_unref);
+ g_object_unref (task);
+}
+
+void
+qfu_device_selection_wait_for_cdc_wdm (QfuDeviceSelection *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ qfu_udev_helper_wait_for_device (QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM,
+ self->priv->sysfs_path,
+ cancellable,
+ (GAsyncReadyCallback) wait_for_device_ready,
+ task);
+}
+
+void
+qfu_device_selection_wait_for_tty (QfuDeviceSelection *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ qfu_udev_helper_wait_for_device (QFU_UDEV_HELPER_DEVICE_TYPE_TTY,
+ self->priv->sysfs_path,
+ cancellable,
+ (GAsyncReadyCallback) wait_for_device_ready,
+ task);
+}
+
+/******************************************************************************/
+
+QfuDeviceSelection *
+qfu_device_selection_new (const gchar *preferred_cdc_wdm,
+ const gchar *preferred_tty,
+ guint16 preferred_vid,
+ guint16 preferred_pid,
+ guint preferred_busnum,
+ guint preferred_devnum,
+ GError **error)
+{
+ QfuDeviceSelection *self;
+ guint n_selections;
+
+ /* Note: pid and busnum may be zero */
+ n_selections = (!!preferred_cdc_wdm +
+ !!preferred_tty +
+ !!preferred_vid +
+ !!preferred_devnum);
+
+ if (!n_selections) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No device selected");
+ return NULL;
+ }
+
+ if (n_selections > 1) {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Only one device selection option may be provided");
+ return NULL;
+ }
+
+ /* Selection valid, create object */
+
+ self = g_object_new (QFU_TYPE_DEVICE_SELECTION, NULL);
+
+ /* Store inputs */
+ self->priv->preferred_devices[QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM] = g_strdup (preferred_cdc_wdm);
+ self->priv->preferred_devices[QFU_UDEV_HELPER_DEVICE_TYPE_TTY] = g_strdup (preferred_tty);
+ self->priv->preferred_vid = preferred_vid;
+ self->priv->preferred_pid = preferred_pid;
+ self->priv->preferred_busnum = preferred_busnum;
+ self->priv->preferred_devnum = preferred_devnum;
+
+ /* Initialize sysfs path from inputs */
+ if (preferred_vid || preferred_devnum)
+ self->priv->sysfs_path = qfu_udev_helper_find_by_device_info (preferred_vid, preferred_pid, preferred_busnum, preferred_devnum, error);
+ else if (preferred_cdc_wdm || preferred_tty)
+ self->priv->sysfs_path = qfu_udev_helper_find_by_file_path (preferred_cdc_wdm ? preferred_cdc_wdm : preferred_tty, error);
+ else
+ g_assert_not_reached ();
+
+ if (!self->priv->sysfs_path) {
+ g_object_unref (self);
+ return NULL;
+ }
+
+ return self;
+}
+
+static void
+qfu_device_selection_init (QfuDeviceSelection *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, QFU_TYPE_DEVICE_SELECTION, QfuDeviceSelectionPrivate);
+}
+
+static void
+finalize (GObject *object)
+{
+ QfuDeviceSelection *self = QFU_DEVICE_SELECTION (object);
+ guint i;
+
+ for (i = 0; i < QFU_UDEV_HELPER_DEVICE_TYPE_LAST; i++)
+ g_free (self->priv->preferred_devices[i]);
+ g_free (self->priv->sysfs_path);
+
+ G_OBJECT_CLASS (qfu_device_selection_parent_class)->finalize (object);
+}
+
+static void
+qfu_device_selection_class_init (QfuDeviceSelectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (QfuDeviceSelectionPrivate));
+
+ object_class->finalize = finalize;
+}
diff --git a/src/qmi-firmware-update/qfu-device-selection.h b/src/qmi-firmware-update/qfu-device-selection.h
new file mode 100644
index 00000000..9ceb262b
--- /dev/null
+++ b/src/qmi-firmware-update/qfu-device-selection.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * qmi-firmware-update -- Command line tool to update firmware in QMI devices
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2017 Zodiac Inflight Innovations
+ * Copyright (C) 2017 Aleksander Morgado <aleksander@aleksander.es>
+ */
+
+#ifndef QFU_DEVICE_SELECTION_H
+#define QFU_DEVICE_SELECTION_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define QFU_TYPE_DEVICE_SELECTION (qfu_device_selection_get_type ())
+#define QFU_DEVICE_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QFU_TYPE_DEVICE_SELECTION, QfuDeviceSelection))
+#define QFU_DEVICE_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QFU_TYPE_DEVICE_SELECTION, QfuDeviceSelectionClass))
+#define QFU_IS_DEVICE_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QFU_TYPE_DEVICE_SELECTION))
+#define QFU_IS_DEVICE_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QFU_TYPE_DEVICE_SELECTION))
+#define QFU_DEVICE_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QFU_TYPE_DEVICE_SELECTION, QfuDeviceSelectionClass))
+
+typedef struct _QfuDeviceSelection QfuDeviceSelection;
+typedef struct _QfuDeviceSelectionClass QfuDeviceSelectionClass;
+typedef struct _QfuDeviceSelectionPrivate QfuDeviceSelectionPrivate;
+
+struct _QfuDeviceSelection {
+ GObject parent;
+ QfuDeviceSelectionPrivate *priv;
+};
+
+struct _QfuDeviceSelectionClass {
+ GObjectClass parent;
+};
+
+GType qfu_device_selection_get_type (void);
+QfuDeviceSelection *qfu_device_selection_new (const gchar *preferred_cdc_wdm,
+ const gchar *preferred_tty,
+ guint16 preferred_vid,
+ guint16 preferred_pid,
+ guint preferred_busnum,
+ guint preferred_devnum,
+ GError **error);
+
+GFile *qfu_device_selection_get_single_cdc_wdm (QfuDeviceSelection *self);
+void qfu_device_selection_wait_for_cdc_wdm (QfuDeviceSelection *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GFile *qfu_device_selection_wait_for_cdc_wdm_finish (QfuDeviceSelection *self,
+ GAsyncResult *res,
+ GError **error);
+
+GFile *qfu_device_selection_get_single_tty (QfuDeviceSelection *self);
+GList *qfu_device_selection_get_multiple_ttys (QfuDeviceSelection *self);
+void qfu_device_selection_wait_for_tty (QfuDeviceSelection *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GFile *qfu_device_selection_wait_for_tty_finish (QfuDeviceSelection *self,
+ GAsyncResult *res,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* QFU_DEVICE_SELECTION_H */
diff --git a/src/qmi-firmware-update/qfu-main.c b/src/qmi-firmware-update/qfu-main.c
index af831869..df6733d6 100644
--- a/src/qmi-firmware-update/qfu-main.c
+++ b/src/qmi-firmware-update/qfu-main.c
@@ -31,6 +31,7 @@
#include "qfu-log.h"
#include "qfu-operation.h"
+#include "qfu-device-selection.h"
#include "qfu-udev-helpers.h"
#define PROGRAM_NAME "qmi-firmware-update"
@@ -44,10 +45,11 @@ static guint busnum;
static guint devnum;
static guint16 vid;
static guint16 pid;
+static gchar *cdc_wdm_str;
+static gchar *tty_str;
/* Update */
static gboolean action_update_flag;
-static gchar *cdc_wdm_str;
static gchar *firmware_version_str;
static gchar *config_version_str;
static gchar *carrier_str;
@@ -57,11 +59,9 @@ static gboolean force_flag;
/* Reset */
static gboolean action_reset_flag;
-static gchar *at_serial_str;
/* Update (QDL mode) */
static gboolean action_update_qdl_flag;
-static gchar *qdl_serial_str;
/* Verify */
static gboolean action_verify_flag;
@@ -178,6 +178,14 @@ static GOptionEntry context_selection_entries[] = {
"Select device by device vendor and product id (in hexadecimal).",
"VID[:PID]"
},
+ { "cdc-wdm", 'w', 0, G_OPTION_ARG_FILENAME, &cdc_wdm_str,
+ "Select device by QMI/MBIM cdc-wdm device path (e.g. /dev/cdc-wdm0).",
+ "[PATH]"
+ },
+ { "tty", 't', 0, G_OPTION_ARG_FILENAME, &tty_str,
+ "Select device by serial device path (e.g. /dev/ttyUSB2).",
+ "[PATH]"
+ },
{ NULL }
};
@@ -186,10 +194,6 @@ static GOptionEntry context_update_entries[] = {
"Launch firmware update process.",
NULL
},
- { "cdc-wdm", 'w', 0, G_OPTION_ARG_FILENAME, &cdc_wdm_str,
- "Select device by QMI/MBIM cdc-wdm device path (e.g. /dev/cdc-wdm0).",
- "[PATH]"
- },
{ "firmware-version", 'f', 0, G_OPTION_ARG_STRING, &firmware_version_str,
"Firmware version (e.g. '05.05.58.00').",
"[VERSION]",
@@ -222,10 +226,6 @@ static GOptionEntry context_reset_entries[] = {
"Reset device into QDL download mode.",
NULL
},
- { "at-serial", 'a', 0, G_OPTION_ARG_FILENAME, &at_serial_str,
- "Select device by AT serial device path (e.g. /dev/ttyUSB2).",
- "[PATH]"
- },
{ NULL }
};
@@ -234,10 +234,6 @@ static GOptionEntry context_update_qdl_entries[] = {
"Launch firmware update process in QDL mode.",
NULL
},
- { "qdl-serial", 'q', 0, G_OPTION_ARG_FILENAME, &qdl_serial_str,
- "Select device by QDL serial device path (e.g. /dev/ttyUSB0).",
- "[PATH]"
- },
{ NULL }
};
@@ -295,9 +291,9 @@ print_version (void)
g_print ("\n"
PROGRAM_NAME " " PROGRAM_VERSION "\n"
"\n"
- " Copyright (C) 2016 Bjørn Mork\n"
- " Copyright (C) 2016 Zodiac Inflight Innovations\n"
- " Copyright (C) 2016 Aleksander Morgado\n"
+ " Copyright (C) 2016-2017 Bjørn Mork\n"
+ " Copyright (C) 2016-2017 Zodiac Inflight Innovations\n"
+ " Copyright (C) 2016-2017 Aleksander Morgado\n"
"\n"
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\n"
"This is free software: you are free to change and redistribute it.\n"
@@ -445,122 +441,14 @@ print_help_examples (void)
/*****************************************************************************/
-static gboolean
-validate_inputs (const char *manual)
-{
- if (!manual && !vid && !pid && !busnum && !devnum) {
- g_printerr ("error: device not specified\n");
- return FALSE;
- }
- if (manual && (vid != 0 || pid != 0)) {
- g_printerr ("error: cannot specify device path and vid:pid lookup\n");
- return FALSE;
- }
-
- if (manual && (busnum != 0 || devnum != 0)) {
- g_printerr ("error: cannot specify device path and busnum:devnum lookup\n");
- return FALSE;
- }
-
- if ((vid != 0 || pid != 0) && (busnum != 0 || devnum != 0)) {
- g_printerr ("error: cannot specify busnum:devnum and vid:pid lookups\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gchar *
-select_single_path (const char *manual,
- QfuUdevHelperDeviceType type)
-{
- gchar *path = NULL;
- GError *error = NULL;
- gchar *sysfs_path = NULL;
- GList *list = NULL;
-
- if (!validate_inputs (manual))
- goto out;
-
- if (manual) {
- path = g_strdup (manual);
- goto out;
- }
-
- /* lookup sysfs path */
- sysfs_path = qfu_udev_helper_find_by_device_info (vid, pid, busnum, devnum, &error);
- if (!sysfs_path) {
- g_printerr ("error: %s\n", error->message);
- g_error_free (error);
- goto out;
- }
-
- list = qfu_udev_helper_list_devices (type, sysfs_path);
- if (!list) {
- g_printerr ("error: no devices found in sysfs path: %s\n", sysfs_path);
- goto out;
- }
-
- path = g_file_get_path (G_FILE (list->data));
-
-out:
- if (list)
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
-
- return path;
-}
-
-static gchar **
-select_multiple_paths (const char *manual,
- QfuUdevHelperDeviceType type)
-{
- GError *error = NULL;
- gchar *sysfs_path = NULL;
- GList *list = NULL;
- GList *l;
- gchar **paths = NULL;
- guint i;
-
- if (!validate_inputs (manual))
- goto out;
-
- if (manual) {
- paths = g_strsplit (manual, ",", -1);
- goto out;
- }
-
- /* lookup sysfs path */
- sysfs_path = qfu_udev_helper_find_by_device_info (vid, pid, busnum, devnum, &error);
- if (!sysfs_path) {
- g_printerr ("error: %s\n", error->message);
- g_error_free (error);
- goto out;
- }
-
- list = qfu_udev_helper_list_devices (type, sysfs_path);
- if (!list) {
- g_printerr ("error: no devices found in sysfs path: %s\n", sysfs_path);
- goto out;
- }
-
- paths = g_new0 (gchar *, g_list_length (list) + 1);
- for (l = list, i = 0; l; l = g_list_next (l), i++)
- paths[i] = g_file_get_path (G_FILE (l->data));
-
-out:
- if (list)
- g_list_free_full (list, (GDestroyNotify) g_object_unref);
-
- return paths;
-}
-
int main (int argc, char **argv)
{
- GError *error = NULL;
- GOptionContext *context;
- GOptionGroup *group;
- guint n_actions;
- gboolean result = FALSE;
+ GError *error = NULL;
+ GOptionContext *context;
+ GOptionGroup *group;
+ guint n_actions;
+ gboolean result = FALSE;
+ QfuDeviceSelection *device_selection = NULL;
setlocale (LC_ALL, "");
@@ -640,52 +528,41 @@ int main (int argc, char **argv)
goto out;
}
+ /* device selection must be performed for update and reset operations */
+ if (action_update_flag || action_update_qdl_flag || action_reset_flag) {
+ device_selection = qfu_device_selection_new (cdc_wdm_str, tty_str, vid, pid, busnum, devnum, &error);
+ if (!device_selection) {
+ g_printerr ("error: couldn't select device:: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ }
+
/* Run */
if (action_update_flag) {
- gchar *path;
-
- path = select_single_path (cdc_wdm_str, QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM);
- if (path) {
- g_debug ("using cdc-wdm device: %s", path);
- result = qfu_operation_update_run ((const gchar **) image_strv,
- path,
- firmware_version_str,
- config_version_str,
- carrier_str,
- device_open_proxy_flag,
- device_open_mbim_flag,
- force_flag);
- g_free (path);
- }
+ g_assert (QFU_IS_DEVICE_SELECTION (device_selection));
+ result = qfu_operation_update_run ((const gchar **) image_strv,
+ device_selection,
+ firmware_version_str,
+ config_version_str,
+ carrier_str,
+ device_open_proxy_flag,
+ device_open_mbim_flag,
+ force_flag);
goto out;
}
if (action_update_qdl_flag) {
- gchar *path;
-
- path = select_single_path (qdl_serial_str, QFU_UDEV_HELPER_DEVICE_TYPE_TTY);
- if (path) {
- g_debug ("using tty device: %s", path);
- result = qfu_operation_update_qdl_run ((const gchar **) image_strv,
- path);
- g_free (path);
- }
+ g_assert (QFU_IS_DEVICE_SELECTION (device_selection));
+ result = qfu_operation_update_qdl_run ((const gchar **) image_strv,
+ device_selection);
goto out;
}
if (action_reset_flag) {
- gchar **paths;
-
- paths = select_multiple_paths (at_serial_str, QFU_UDEV_HELPER_DEVICE_TYPE_TTY);
- if (paths) {
- guint i;
-
- for (i = 0; paths[i]; i++)
- g_debug ("using tty device #%u: %s", i, paths[i]);
- result = qfu_operation_reset_run ((const gchar **) paths);
- g_strfreev (paths);
- }
+ g_assert (QFU_IS_DEVICE_SELECTION (device_selection));
+ result = qfu_operation_reset_run (device_selection);
goto out;
}
@@ -700,6 +577,8 @@ out:
/* Clean exit for a clean memleak report */
if (context)
g_option_context_free (context);
+ if (device_selection)
+ g_object_unref (device_selection);
return (result ? EXIT_SUCCESS : EXIT_FAILURE);
}
diff --git a/src/qmi-firmware-update/qfu-operation-reset.c b/src/qmi-firmware-update/qfu-operation-reset.c
index 378adae9..402eb1d0 100644
--- a/src/qmi-firmware-update/qfu-operation-reset.c
+++ b/src/qmi-firmware-update/qfu-operation-reset.c
@@ -56,7 +56,7 @@ signal_handler (ReseterOperation *operation)
static void
run_ready (QfuReseter *reseter,
- GAsyncResult *res,
+ GAsyncResult *res,
ReseterOperation *operation)
{
GError *error = NULL;
@@ -105,26 +105,13 @@ operation_reseter_run (QfuReseter *reseter)
}
gboolean
-qfu_operation_reset_run (const gchar **ttys)
+qfu_operation_reset_run (QfuDeviceSelection *device_selection)
{
QfuReseter *reseter = NULL;
gboolean result;
- GList *tty_files = NULL;
- guint i;
- /* No tty path given? */
- if (!ttys) {
- g_printerr ("error: no ttys specified\n");
- return FALSE;
- }
-
- for (i = 0; ttys[i]; i++)
- tty_files = g_list_prepend (tty_files, g_file_new_for_path (ttys[i]));
-
- /* Create reseter */
- reseter = qfu_reseter_new (tty_files);
+ reseter = qfu_reseter_new (device_selection);
result = operation_reseter_run (reseter);
- g_list_free_full (tty_files, (GDestroyNotify) g_object_unref);
g_object_unref (reseter);
return result;
}
diff --git a/src/qmi-firmware-update/qfu-operation-update.c b/src/qmi-firmware-update/qfu-operation-update.c
index 64862d55..708e0a0b 100644
--- a/src/qmi-firmware-update/qfu-operation-update.c
+++ b/src/qmi-firmware-update/qfu-operation-update.c
@@ -116,69 +116,43 @@ operation_update_run (QfuUpdater *updater,
}
gboolean
-qfu_operation_update_run (const gchar **images,
- const gchar *device,
- const gchar *firmware_version,
- const gchar *config_version,
- const gchar *carrier,
- gboolean device_open_proxy,
- gboolean device_open_mbim,
- gboolean force)
+qfu_operation_update_run (const gchar **images,
+ QfuDeviceSelection *device_selection,
+ const gchar *firmware_version,
+ const gchar *config_version,
+ const gchar *carrier,
+ gboolean device_open_proxy,
+ gboolean device_open_mbim,
+ gboolean force)
{
QfuUpdater *updater = NULL;
- GFile *device_file = NULL;
gboolean result;
g_assert (images);
- /* No device path given? */
- if (!device) {
- g_printerr ("error: no device path specified\n");
- return FALSE;
- }
-
- /* Create updater */
- device_file = g_file_new_for_commandline_arg (device);
- updater = qfu_updater_new (device_file,
+ updater = qfu_updater_new (device_selection,
firmware_version,
config_version,
carrier,
device_open_proxy,
device_open_mbim,
force);
- g_object_unref (device_file);
-
- /* Run! */
result = operation_update_run (updater, images);
-
g_object_unref (updater);
return result;
}
gboolean
-qfu_operation_update_qdl_run (const gchar **images,
- const gchar *serial)
+qfu_operation_update_qdl_run (const gchar **images,
+ QfuDeviceSelection *device_selection)
{
QfuUpdater *updater = NULL;
- GFile *serial_file = NULL;
gboolean result;
g_assert (images);
- /* No device path given? */
- if (!serial) {
- g_printerr ("error: no serial path specified\n");
- return FALSE;
- }
-
- /* Create updater */
- serial_file = g_file_new_for_commandline_arg (serial);
- updater = qfu_updater_new_qdl (serial_file);
- g_object_unref (serial_file);
-
- /* Run! */
+ updater = qfu_updater_new_qdl (device_selection);
result = operation_update_run (updater, images);
-
g_object_unref (updater);
return result;
}
diff --git a/src/qmi-firmware-update/qfu-operation.h b/src/qmi-firmware-update/qfu-operation.h
index 8ebce469..b9d40baf 100644
--- a/src/qmi-firmware-update/qfu-operation.h
+++ b/src/qmi-firmware-update/qfu-operation.h
@@ -23,21 +23,22 @@
#define QFU_OPERATION_H
#include <glib.h>
+#include "qfu-device-selection.h"
G_BEGIN_DECLS
-gboolean qfu_operation_update_run (const gchar **images,
- const gchar *device,
- const gchar *firmware_version,
- const gchar *config_version,
- const gchar *carrier,
- gboolean device_open_proxy,
- gboolean device_open_mbim,
- gboolean force);
-gboolean qfu_operation_update_qdl_run (const gchar **images,
- const gchar *serial);
-gboolean qfu_operation_verify_run (const gchar **images);
-gboolean qfu_operation_reset_run (const gchar **ttys);
+gboolean qfu_operation_update_run (const gchar **images,
+ QfuDeviceSelection *device_selection,
+ const gchar *firmware_version,
+ const gchar *config_version,
+ const gchar *carrier,
+ gboolean device_open_proxy,
+ gboolean device_open_mbim,
+ gboolean force);
+gboolean qfu_operation_update_qdl_run (const gchar **images,
+ QfuDeviceSelection *device_selection);
+gboolean qfu_operation_verify_run (const gchar **images);
+gboolean qfu_operation_reset_run (QfuDeviceSelection *device_selection);
G_END_DECLS
diff --git a/src/qmi-firmware-update/qfu-reseter.c b/src/qmi-firmware-update/qfu-reseter.c
index 75dbb1fd..55d6e2a2 100644
--- a/src/qmi-firmware-update/qfu-reseter.c
+++ b/src/qmi-firmware-update/qfu-reseter.c
@@ -33,7 +33,7 @@
G_DEFINE_TYPE (QfuReseter, qfu_reseter, G_TYPE_OBJECT)
struct _QfuReseterPrivate {
- GList *ttys;
+ QfuDeviceSelection *device_selection;
};
/******************************************************************************/
@@ -128,14 +128,14 @@ device_sort_by_name_reversed (QfuAtDevice *a, QfuAtDevice *b)
}
void
-qfu_reseter_run (QfuReseter *self,
+qfu_reseter_run (QfuReseter *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
RunContext *ctx;
GTask *task;
- GList *l;
+ GList *l, *ttys;
ctx = g_slice_new0 (RunContext);
ctx->retries = MAX_RETRIES;
@@ -143,8 +143,17 @@ qfu_reseter_run (QfuReseter *self,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify) run_context_free);
+ /* List TTYs we may use for the reset operation */
+ ttys = qfu_device_selection_get_multiple_ttys (self->priv->device_selection);
+ if (!ttys) {
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "No TTYs found to run reset operation");
+ g_object_unref (task);
+ return;
+ }
+
/* Build QfuAtDevice objects for each TTY given */
- for (l = self->priv->ttys; l; l = g_list_next (l)) {
+ for (l = ttys; l; l = g_list_next (l)) {
GError *error = NULL;
QfuAtDevice *at_device;
@@ -156,6 +165,7 @@ qfu_reseter_run (QfuReseter *self,
}
ctx->at_devices = g_list_append (ctx->at_devices, at_device);
}
+ g_list_free_full (ttys, (GDestroyNotify) g_object_unref);
/* Sort by filename reversed; usually the TTY with biggest number is a
* good AT port */
@@ -169,12 +179,12 @@ qfu_reseter_run (QfuReseter *self,
/******************************************************************************/
QfuReseter *
-qfu_reseter_new (GList *ttys)
+qfu_reseter_new (QfuDeviceSelection *device_selection)
{
QfuReseter *self;
self = g_object_new (QFU_TYPE_RESETER, NULL);
- self->priv->ttys = g_list_copy_deep (ttys, (GCopyFunc) g_object_ref, NULL);
+ self->priv->device_selection = g_object_ref (device_selection);
return self;
}
@@ -190,10 +200,7 @@ dispose (GObject *object)
{
QfuReseter *self = QFU_RESETER (object);
- if (self->priv->ttys) {
- g_list_free_full (self->priv->ttys, (GDestroyNotify) g_object_unref);
- self->priv->ttys = NULL;
- }
+ g_clear_object (&self->priv->device_selection);
G_OBJECT_CLASS (qfu_reseter_parent_class)->dispose (object);
}
diff --git a/src/qmi-firmware-update/qfu-reseter.h b/src/qmi-firmware-update/qfu-reseter.h
index 8fd73b47..46dbabd6 100644
--- a/src/qmi-firmware-update/qfu-reseter.h
+++ b/src/qmi-firmware-update/qfu-reseter.h
@@ -25,6 +25,8 @@
#include <glib-object.h>
#include <gio/gio.h>
+#include "qfu-device-selection.h"
+
G_BEGIN_DECLS
#define QFU_TYPE_RESETER (qfu_reseter_get_type ())
@@ -48,7 +50,7 @@ struct _QfuReseterClass {
};
GType qfu_reseter_get_type (void);
-QfuReseter *qfu_reseter_new (GList *ttys);
+QfuReseter *qfu_reseter_new (QfuDeviceSelection *device_selection);
void qfu_reseter_run (QfuReseter *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
diff --git a/src/qmi-firmware-update/qfu-udev-helpers.c b/src/qmi-firmware-update/qfu-udev-helpers.c
index 47656dbc..c4f2d81f 100644
--- a/src/qmi-firmware-update/qfu-udev-helpers.c
+++ b/src/qmi-firmware-update/qfu-udev-helpers.c
@@ -31,6 +31,21 @@ static const gchar *cdc_wdm_subsys_list[] = { "usbmisc", "usb", NULL };
/******************************************************************************/
+static const gchar *device_type_str[] = {
+ [QFU_UDEV_HELPER_DEVICE_TYPE_TTY] = "tty",
+ [QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM] = "cdc-wdm",
+};
+
+G_STATIC_ASSERT (G_N_ELEMENTS (device_type_str) == QFU_UDEV_HELPER_DEVICE_TYPE_LAST);
+
+const gchar *
+qfu_udev_helper_device_type_to_string (QfuUdevHelperDeviceType type)
+{
+ return device_type_str[type];
+}
+
+/******************************************************************************/
+
static GUdevDevice *
find_udev_device_for_file (GFile *file,
GError **error)
@@ -203,6 +218,19 @@ qfu_udev_helper_find_by_file (GFile *file,
return sysfs_path;
}
+gchar *
+qfu_udev_helper_find_by_file_path (const gchar *path,
+ GError **error)
+{
+ GFile *file;
+ gchar *sysfs_path;
+
+ file = g_file_new_for_path (path);
+ sysfs_path = qfu_udev_helper_find_by_file (file, error);
+ g_object_unref (file);
+ return sysfs_path;
+}
+
/******************************************************************************/
static gboolean
diff --git a/src/qmi-firmware-update/qfu-udev-helpers.h b/src/qmi-firmware-update/qfu-udev-helpers.h
index 9a261202..1d3672e2 100644
--- a/src/qmi-firmware-update/qfu-udev-helpers.h
+++ b/src/qmi-firmware-update/qfu-udev-helpers.h
@@ -27,19 +27,24 @@
G_BEGIN_DECLS
-gchar *qfu_udev_helper_find_by_file (GFile *file,
- GError **error);
-gchar *qfu_udev_helper_find_by_device_info (guint16 vid,
- guint16 pid,
- guint busnum,
- guint devnum,
- GError **error);
+gchar *qfu_udev_helper_find_by_file (GFile *file,
+ GError **error);
+gchar *qfu_udev_helper_find_by_file_path (const gchar *path,
+ GError **error);
+gchar *qfu_udev_helper_find_by_device_info (guint16 vid,
+ guint16 pid,
+ guint busnum,
+ guint devnum,
+ GError **error);
typedef enum {
QFU_UDEV_HELPER_DEVICE_TYPE_TTY,
QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM,
+ QFU_UDEV_HELPER_DEVICE_TYPE_LAST
} QfuUdevHelperDeviceType;
+const gchar *qfu_udev_helper_device_type_to_string (QfuUdevHelperDeviceType type);
+
GList *qfu_udev_helper_list_devices (QfuUdevHelperDeviceType device_type,
const gchar *sysfs_path);
diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c
index 7b9b0d8d..0cdaba48 100644
--- a/src/qmi-firmware-update/qfu-updater.c
+++ b/src/qmi-firmware-update/qfu-updater.c
@@ -47,15 +47,14 @@ typedef enum {
} UpdaterType;
struct _QfuUpdaterPrivate {
- UpdaterType type;
- GFile *cdc_wdm_file;
- GFile *serial_file;
- gchar *firmware_version;
- gchar *config_version;
- gchar *carrier;
- gboolean device_open_proxy;
- gboolean device_open_mbim;
- gboolean force;
+ UpdaterType type;
+ QfuDeviceSelection *device_selection;
+ gchar *firmware_version;
+ gchar *config_version;
+ gchar *carrier;
+ gboolean device_open_proxy;
+ gboolean device_open_mbim;
+ gboolean force;
};
/******************************************************************************/
@@ -64,7 +63,6 @@ struct _QfuUpdaterPrivate {
#define QMI_CLIENT_RETRIES 3
typedef enum {
- RUN_CONTEXT_STEP_USB_INFO = 0,
RUN_CONTEXT_STEP_QMI_DEVICE,
RUN_CONTEXT_STEP_QMI_DEVICE_OPEN,
RUN_CONTEXT_STEP_QMI_CLIENT,
@@ -84,10 +82,9 @@ typedef enum {
} RunContextStep;
typedef struct {
- /* Device files and common USB sysfs path*/
+ /* Device selection */
GFile *cdc_wdm_file;
GFile *serial_file;
- gchar *sysfs_path;
/* Context step */
RunContextStep step;
@@ -137,7 +134,6 @@ run_context_free (RunContext *ctx)
if (ctx->current_image)
g_object_unref (ctx->current_image);
g_list_free_full (ctx->pending_images, (GDestroyNotify) g_object_unref);
- g_free (ctx->sysfs_path);
if (ctx->serial_file)
g_object_unref (ctx->serial_file);
if (ctx->cdc_wdm_file)
@@ -175,9 +171,9 @@ run_context_step_next (GTask *task, RunContextStep next)
}
static void
-wait_for_cdc_wdm_ready (gpointer unused,
- GAsyncResult *res,
- GTask *task)
+wait_for_cdc_wdm_ready (QfuDeviceSelection *device_selection,
+ GAsyncResult *res,
+ GTask *task)
{
GError *error = NULL;
RunContext *ctx;
@@ -186,7 +182,7 @@ wait_for_cdc_wdm_ready (gpointer unused,
ctx = (RunContext *) g_task_get_task_data (task);
g_assert (!ctx->cdc_wdm_file);
- ctx->cdc_wdm_file = qfu_udev_helper_wait_for_device_finish (res, &error);
+ ctx->cdc_wdm_file = qfu_device_selection_wait_for_cdc_wdm_finish (device_selection, res, &error);
if (!ctx->cdc_wdm_file) {
g_prefix_error (&error, "error waiting for cdc-wdm: ");
g_task_return_error (task, error);
@@ -205,16 +201,16 @@ wait_for_cdc_wdm_ready (gpointer unused,
static void
run_context_step_wait_for_cdc_wdm (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] now waiting for cdc-wdm device...");
- qfu_udev_helper_wait_for_device (QFU_UDEV_HELPER_DEVICE_TYPE_CDC_WDM,
- ctx->sysfs_path,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) wait_for_cdc_wdm_ready,
- task);
+
+ qfu_device_selection_wait_for_cdc_wdm (self->priv->device_selection,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) wait_for_cdc_wdm_ready,
+ task);
}
static void
@@ -401,9 +397,9 @@ run_context_step_qdl_device (GTask *task)
}
static void
-wait_for_tty_ready (gpointer unused,
- GAsyncResult *res,
- GTask *task)
+wait_for_tty_ready (QfuDeviceSelection *device_selection,
+ GAsyncResult *res,
+ GTask *task)
{
GError *error = NULL;
RunContext *ctx;
@@ -412,7 +408,7 @@ wait_for_tty_ready (gpointer unused,
ctx = (RunContext *) g_task_get_task_data (task);
g_assert (!ctx->serial_file);
- ctx->serial_file = qfu_udev_helper_wait_for_device_finish (res, &error);
+ ctx->serial_file = qfu_device_selection_wait_for_tty_finish (device_selection, res, &error);
if (!ctx->serial_file) {
g_prefix_error (&error, "error waiting for TTY: ");
g_task_return_error (task, error);
@@ -431,18 +427,17 @@ wait_for_tty_ready (gpointer unused,
static void
run_context_step_wait_for_tty (GTask *task)
{
- RunContext *ctx;
+ QfuUpdater *self;
- ctx = (RunContext *) g_task_get_task_data (task);
+ self = g_task_get_source_object (task);
g_print ("rebooting in download mode...\n");
g_debug ("[qfu-updater] reset requested, now waiting for TTY device...");
- qfu_udev_helper_wait_for_device (QFU_UDEV_HELPER_DEVICE_TYPE_TTY,
- ctx->sysfs_path,
- g_task_get_cancellable (task),
- (GAsyncReadyCallback) wait_for_tty_ready,
- task);
+ qfu_device_selection_wait_for_tty (self->priv->device_selection,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback) wait_for_tty_ready,
+ task);
}
static void
@@ -558,12 +553,13 @@ reseter_run_ready (QfuReseter *reseter,
static void
run_context_step_reset (GTask *task)
{
+ QfuUpdater *self;
RunContext *ctx;
QmiMessageDmsSetOperatingModeInput *input;
- GList *ttys;
QfuReseter *reseter;
ctx = (RunContext *) g_task_get_task_data (task);
+ self = g_task_get_source_object (task);
if (!ctx->boothold_reset) {
g_debug ("[qfu-updater] setting operating mode 'reset'...");
@@ -580,21 +576,12 @@ run_context_step_reset (GTask *task)
}
/* Boothold reset */
- ttys = qfu_udev_helper_list_devices (QFU_UDEV_HELPER_DEVICE_TYPE_TTY, ctx->sysfs_path);
- if (!ttys) {
- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
- "no TTYs found to run boothold reset");
- g_object_unref (task);
- return;
- }
-
- reseter = qfu_reseter_new (ttys);
+ reseter = qfu_reseter_new (self->priv->device_selection);
qfu_reseter_run (reseter,
g_task_get_cancellable (task),
(GAsyncReadyCallback) reseter_run_ready,
task);
g_object_unref (reseter);
- g_list_free_full (ttys, (GDestroyNotify) g_object_unref);
}
@@ -1116,47 +1103,20 @@ qmi_device_ready (GObject *source,
static void
run_context_step_qmi_device (GTask *task)
{
- QfuUpdater *self;
+ RunContext *ctx;
- self = g_task_get_source_object (task);
+ ctx = (RunContext *) g_task_get_task_data (task);
g_debug ("[qfu-updater] creating QMI device...");
- g_assert (self->priv->cdc_wdm_file);
- qmi_device_new (self->priv->cdc_wdm_file,
+ g_assert (ctx->cdc_wdm_file);
+ qmi_device_new (ctx->cdc_wdm_file,
g_task_get_cancellable (task),
(GAsyncReadyCallback) qmi_device_ready,
task);
}
-static void
-run_context_step_usb_info (GTask *task)
-{
- QfuUpdater *self;
- RunContext *ctx;
- GError *error = NULL;
-
- ctx = (RunContext *) g_task_get_task_data (task);
- self = g_task_get_source_object (task);
-
- g_assert (self->priv->cdc_wdm_file);
- g_assert (!ctx->sysfs_path);
-
- g_debug ("[qfu-updater] looking for device sysfs path...");
- ctx->sysfs_path = qfu_udev_helper_find_by_file (self->priv->cdc_wdm_file, &error);
- if (!ctx->sysfs_path) {
- g_prefix_error (&error, "couldn't get cdc-wdm device sysfs path: ");
- g_task_return_error (task, error);
- g_object_unref (task);
- return;
- }
- g_debug ("[qfu-updater] device sysfs path: %s", ctx->sysfs_path);
-
- run_context_step_next (task, ctx->step + 1);
-}
-
typedef void (* RunContextStepFunc) (GTask *task);
static const RunContextStepFunc run_context_step_func[] = {
- [RUN_CONTEXT_STEP_USB_INFO] = run_context_step_usb_info,
[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,
@@ -1257,13 +1217,25 @@ qfu_updater_run (QfuUpdater *self,
switch (self->priv->type) {
case UPDATER_TYPE_GENERIC:
- ctx->step = RUN_CONTEXT_STEP_USB_INFO;
+ ctx->step = RUN_CONTEXT_STEP_QMI_DEVICE;
ctx->qmi_client_retries = QMI_CLIENT_RETRIES;
- ctx->cdc_wdm_file = g_object_ref (self->priv->cdc_wdm_file);
+ 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,
+ "No cdc-wdm device found to run update operation");
+ g_object_unref (task);
+ return;
+ }
break;
case UPDATER_TYPE_QDL:
ctx->step = RUN_CONTEXT_STEP_QDL_DEVICE;
- ctx->serial_file = g_object_ref (self->priv->serial_file);
+ ctx->serial_file = qfu_device_selection_get_single_tty (self->priv->device_selection);
+ if (!ctx->serial_file) {
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "No serial device found to run QDL update operation");
+ g_object_unref (task);
+ return;
+ }
break;
default:
g_assert_not_reached ();
@@ -1275,21 +1247,21 @@ qfu_updater_run (QfuUpdater *self,
/******************************************************************************/
QfuUpdater *
-qfu_updater_new (GFile *cdc_wdm_file,
- const gchar *firmware_version,
- const gchar *config_version,
- const gchar *carrier,
- gboolean device_open_proxy,
- gboolean device_open_mbim,
- gboolean force)
+qfu_updater_new (QfuDeviceSelection *device_selection,
+ const gchar *firmware_version,
+ const gchar *config_version,
+ const gchar *carrier,
+ gboolean device_open_proxy,
+ gboolean device_open_mbim,
+ gboolean force)
{
QfuUpdater *self;
- g_assert (G_IS_FILE (cdc_wdm_file));
+ g_assert (QFU_IS_DEVICE_SELECTION (device_selection));
self = g_object_new (QFU_TYPE_UPDATER, NULL);
self->priv->type = UPDATER_TYPE_GENERIC;
- self->priv->cdc_wdm_file = g_object_ref (cdc_wdm_file);
+ self->priv->device_selection = g_object_ref (device_selection);
self->priv->device_open_proxy = device_open_proxy;
self->priv->device_open_mbim = device_open_mbim;
self->priv->firmware_version = (firmware_version ? g_strdup (firmware_version) : NULL);
@@ -1301,15 +1273,15 @@ qfu_updater_new (GFile *cdc_wdm_file,
}
QfuUpdater *
-qfu_updater_new_qdl (GFile *serial_file)
+qfu_updater_new_qdl (QfuDeviceSelection *device_selection)
{
QfuUpdater *self;
- g_assert (G_IS_FILE (serial_file));
+ g_assert (QFU_IS_DEVICE_SELECTION (device_selection));
self = g_object_new (QFU_TYPE_UPDATER, NULL);
self->priv->type = UPDATER_TYPE_QDL;
- self->priv->serial_file = g_object_ref (serial_file);
+ self->priv->device_selection = g_object_ref (device_selection);
return self;
}
@@ -1326,8 +1298,7 @@ dispose (GObject *object)
{
QfuUpdater *self = QFU_UPDATER (object);
- g_clear_object (&self->priv->serial_file);
- g_clear_object (&self->priv->cdc_wdm_file);
+ g_clear_object (&self->priv->device_selection);
G_OBJECT_CLASS (qfu_updater_parent_class)->dispose (object);
}
diff --git a/src/qmi-firmware-update/qfu-updater.h b/src/qmi-firmware-update/qfu-updater.h
index 230be0fd..8aa1a004 100644
--- a/src/qmi-firmware-update/qfu-updater.h
+++ b/src/qmi-firmware-update/qfu-updater.h
@@ -25,6 +25,8 @@
#include <glib-object.h>
#include <gio/gio.h>
+#include "qfu-device-selection.h"
+
G_BEGIN_DECLS
#define QFU_TYPE_UPDATER (qfu_updater_get_type ())
@@ -48,14 +50,14 @@ struct _QfuUpdaterClass {
};
GType qfu_updater_get_type (void);
-QfuUpdater *qfu_updater_new (GFile *cdc_wdm_file,
+QfuUpdater *qfu_updater_new (QfuDeviceSelection *device_selection,
const gchar *firmware_version,
const gchar *config_version,
const gchar *carrier,
gboolean device_open_proxy,
gboolean device_open_mbim,
gboolean force);
-QfuUpdater *qfu_updater_new_qdl (GFile *serial_file);
+QfuUpdater *qfu_updater_new_qdl (QfuDeviceSelection *device_selection);
void qfu_updater_run (QfuUpdater *self,
GList *image_file_list,
GCancellable *cancellable,