aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmi-firmware-update
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-12-06 17:12:35 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 11:24:14 +0100
commit9a033681f2bb81e1033804f5e626838b6c1a20a2 (patch)
tree142153a11116358341411c09daa473fdfe0d4209 /src/qmi-firmware-update
parentfe09c2cbc53c752358c429a0b907966ee145e78d (diff)
downloadexternal_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.c108
-rw-r--r--src/qmi-firmware-update/qfu-utils.c51
-rw-r--r--src/qmi-firmware-update/qfu-utils.h2
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);