diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-12-06 17:12:35 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-01-16 11:24:14 +0100 |
commit | 9a033681f2bb81e1033804f5e626838b6c1a20a2 (patch) | |
tree | 142153a11116358341411c09daa473fdfe0d4209 /src/qmi-firmware-update | |
parent | fe09c2cbc53c752358c429a0b907966ee145e78d (diff) | |
download | external_libqmi-9a033681f2bb81e1033804f5e626838b6c1a20a2.zip external_libqmi-9a033681f2bb81e1033804f5e626838b6c1a20a2.tar.gz external_libqmi-9a033681f2bb81e1033804f5e626838b6c1a20a2.tar.bz2 |
qmi-firmware-update: get firmware preference during update operation
Diffstat (limited to 'src/qmi-firmware-update')
-rw-r--r-- | src/qmi-firmware-update/qfu-updater.c | 108 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-utils.c | 51 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-utils.h | 2 |
3 files changed, 144 insertions, 17 deletions
diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c index a50862c..7fcfa73 100644 --- a/src/qmi-firmware-update/qfu-updater.c +++ b/src/qmi-firmware-update/qfu-updater.c @@ -29,6 +29,7 @@ #include "qfu-image-factory.h" #include "qfu-updater.h" +#include "qfu-utils.h" #include "qfu-udev-helpers.h" #include "qfu-qdl-device.h" #include "qfu-enum-types.h" @@ -62,7 +63,8 @@ typedef enum { RUN_CONTEXT_STEP_QMI_DEVICE, RUN_CONTEXT_STEP_QMI_DEVICE_OPEN, RUN_CONTEXT_STEP_QMI_CLIENT, - RUN_CONTEXT_STEP_FIRMWARE_PREFERENCE, + RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE, + RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE, RUN_CONTEXT_STEP_OFFLINE, RUN_CONTEXT_STEP_RESET, RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE, @@ -589,7 +591,7 @@ set_firmware_preference_ready (QmiClientDms *client, } static void -run_context_step_firmware_preference (GTask *task) +run_context_step_set_firmware_preference (GTask *task) { QfuUpdater *self; RunContext *ctx; @@ -643,6 +645,77 @@ run_context_step_firmware_preference (GTask *task) } static void +get_firmware_preference_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + RunContext *ctx; + GError *error = NULL; + QmiMessageDmsGetFirmwarePreferenceOutput *output; + GArray *array; + guint i; + + ctx = (RunContext *) g_task_get_task_data (task); + + output = qmi_client_dms_get_firmware_preference_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed, couldn't get firmware preference: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + if (!qmi_message_dms_get_firmware_preference_output_get_result (output, &error)) { + g_prefix_error (&error, "couldn't get firmware preference: "); + g_task_return_error (task, error); + g_object_unref (task); + qmi_message_dms_get_firmware_preference_output_unref (output); + return; + } + + qmi_message_dms_get_firmware_preference_output_get_list (output, &array, NULL); + + if (array->len > 0) { + for (i = 0; i < array->len; i++) { + QmiMessageDmsGetFirmwarePreferenceOutputListImage *image; + gchar *unique_id_str; + + image = &g_array_index (array, QmiMessageDmsGetFirmwarePreferenceOutputListImage, i); + unique_id_str = qfu_utils_get_firmware_image_unique_id_printable (image->unique_id); + + g_debug ("[qfu-updater] [image %u]", i); + g_debug ("[qfu-updater] \tImage type: '%s'", qmi_dms_firmware_image_type_get_string (image->type)); + g_debug ("[qfu-updater] \tUnique ID: '%s'", unique_id_str); + g_debug ("[qfu-updater] \tBuild ID: '%s'", image->build_id); + + g_free (unique_id_str); + } + } else + g_debug ("[qfu-updater] no images specified"); + + qmi_message_dms_get_firmware_preference_output_unref (output); + + /* Go on */ + run_context_step_next (task, ctx->step + 1); +} + +static void +run_context_step_get_firmware_preference (GTask *task) +{ + RunContext *ctx; + + ctx = (RunContext *) g_task_get_task_data (task); + + g_debug ("[qfu-updater] getting firmware preference..."); + qmi_client_dms_get_firmware_preference (ctx->qmi_client, + NULL, + 10, + g_task_get_cancellable (task), + (GAsyncReadyCallback) get_firmware_preference_ready, + task); +} + +static void qmi_client_ready (QmiDevice *device, GAsyncResult *res, GTask *task) @@ -813,21 +886,22 @@ run_context_step_usb_info (GTask *task) 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, - [RUN_CONTEXT_STEP_FIRMWARE_PREFERENCE] = run_context_step_firmware_preference, - [RUN_CONTEXT_STEP_OFFLINE] = run_context_step_offline, - [RUN_CONTEXT_STEP_RESET] = run_context_step_reset, - [RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE] = run_context_step_cleanup_qmi_device, - [RUN_CONTEXT_STEP_WAIT_FOR_TTY] = run_context_step_wait_for_tty, - [RUN_CONTEXT_STEP_QDL_DEVICE] = run_context_step_qdl_device, - [RUN_CONTEXT_STEP_SELECT_IMAGE] = run_context_step_select_image, - [RUN_CONTEXT_STEP_DOWNLOAD_IMAGE] = run_context_step_download_image, - [RUN_CONTEXT_STEP_CLEANUP_IMAGE] = run_context_step_cleanup_image, - [RUN_CONTEXT_STEP_CLEANUP_QDL_DEVICE] = run_context_step_cleanup_qdl_device, - [RUN_CONTEXT_STEP_WAIT_FOR_CDC_WDM] = run_context_step_wait_for_cdc_wdm, + [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, + [RUN_CONTEXT_STEP_GET_FIRMWARE_PREFERENCE] = run_context_step_get_firmware_preference, + [RUN_CONTEXT_STEP_SET_FIRMWARE_PREFERENCE] = run_context_step_set_firmware_preference, + [RUN_CONTEXT_STEP_OFFLINE] = run_context_step_offline, + [RUN_CONTEXT_STEP_RESET] = run_context_step_reset, + [RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE] = run_context_step_cleanup_qmi_device, + [RUN_CONTEXT_STEP_WAIT_FOR_TTY] = run_context_step_wait_for_tty, + [RUN_CONTEXT_STEP_QDL_DEVICE] = run_context_step_qdl_device, + [RUN_CONTEXT_STEP_SELECT_IMAGE] = run_context_step_select_image, + [RUN_CONTEXT_STEP_DOWNLOAD_IMAGE] = run_context_step_download_image, + [RUN_CONTEXT_STEP_CLEANUP_IMAGE] = run_context_step_cleanup_image, + [RUN_CONTEXT_STEP_CLEANUP_QDL_DEVICE] = run_context_step_cleanup_qdl_device, + [RUN_CONTEXT_STEP_WAIT_FOR_CDC_WDM] = run_context_step_wait_for_cdc_wdm, }; G_STATIC_ASSERT (G_N_ELEMENTS (run_context_step_func) == RUN_CONTEXT_STEP_LAST); diff --git a/src/qmi-firmware-update/qfu-utils.c b/src/qmi-firmware-update/qfu-utils.c index 4cf9d89..905e328 100644 --- a/src/qmi-firmware-update/qfu-utils.c +++ b/src/qmi-firmware-update/qfu-utils.c @@ -24,6 +24,7 @@ */ #include <stdio.h> +#include <string.h> #include <glib.h> @@ -67,6 +68,56 @@ qfu_utils_str_hex (gconstpointer mem, /******************************************************************************/ +gchar * +qfu_utils_get_firmware_image_unique_id_printable (const GArray *unique_id) +{ + gchar *unique_id_str; + guint i; + guint n_ascii = 0; + gboolean end = FALSE; + +#define UNIQUE_ID_LEN 16 + + g_warn_if_fail (unique_id->len <= UNIQUE_ID_LEN); + unique_id_str = g_malloc0 (UNIQUE_ID_LEN + 1); + memcpy (unique_id_str, unique_id->data, UNIQUE_ID_LEN); + + /* We want an ASCII string that, if finished before the 16 bytes, + * is suffixed with NUL bytes. */ + for (i = 0; i < UNIQUE_ID_LEN; i++) { + /* If a byte isn't ASCII, stop */ + if (unique_id_str[i] & 0x80) + break; + /* If string isn't finished yet... */ + if (!end) { + /* String finished now */ + if (unique_id_str[i] == '\0') + end = TRUE; + else + n_ascii++; + } else { + /* String finished but we then got + * another ASCII byte? not possible */ + if (unique_id_str[i] != '\0') + break; + } + } + + if (i == UNIQUE_ID_LEN && n_ascii > 0) + return unique_id_str; + +#undef UNIQUE_ID_LEN + + g_free (unique_id_str); + + /* Get a raw hex string otherwise */ + unique_id_str = qfu_utils_str_hex (unique_id->data, unique_id->len, ':'); + + return unique_id_str; +} + +/******************************************************************************/ + /* Table of CRCs for each possible byte, with a generator polynomial of 0x8408 */ static const guint16 crc_table[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, diff --git a/src/qmi-firmware-update/qfu-utils.h b/src/qmi-firmware-update/qfu-utils.h index 2460434..2c66aad 100644 --- a/src/qmi-firmware-update/qfu-utils.h +++ b/src/qmi-firmware-update/qfu-utils.h @@ -31,6 +31,8 @@ gchar *qfu_utils_str_hex (gconstpointer mem, gsize size, gchar delimiter); +gchar *qfu_utils_get_firmware_image_unique_id_printable (const GArray *unique_id); + guint16 qfu_utils_crc16 (const guint8 *buffer, gsize len); |