diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qmi-firmware-update/Makefile.am | 1 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-device-selection.c | 303 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-device-selection.h | 80 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-main.c | 213 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-operation-reset.c | 19 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-operation-update.c | 50 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-operation.h | 25 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-reseter.c | 27 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-reseter.h | 4 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-udev-helpers.c | 28 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-udev-helpers.h | 19 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-updater.c | 159 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-updater.h | 6 |
13 files changed, 587 insertions, 347 deletions
diff --git a/src/qmi-firmware-update/Makefile.am b/src/qmi-firmware-update/Makefile.am index a54a8c3..b165e2a 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 0000000..bc2d920 --- /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 0000000..9ceb262 --- /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 af83186..df6733d 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 378adae..402eb1d 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 64862d5..708e0a0 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 8ebce46..b9d40ba 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 75dbb1f..55d6e2a 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 8fd73b4..46dbabd 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 47656db..c4f2d81 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 9a26120..1d3672e 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 7b9b0d8..0cdaba4 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 230be0f..8aa1a00 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, |