diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2017-01-13 22:57:04 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-01-16 11:24:16 +0100 |
commit | 3bc72338fa30f83d1618eb47d8d69821c81a1948 (patch) | |
tree | 9ad63265b68bb23865c8c215ff90e7c97ea3c14b | |
parent | 4c37ab59f05cbff952b085d6b187b366dc3772eb (diff) | |
download | external_libqmi-3bc72338fa30f83d1618eb47d8d69821c81a1948.zip external_libqmi-3bc72338fa30f83d1618eb47d8d69821c81a1948.tar.gz external_libqmi-3bc72338fa30f83d1618eb47d8d69821c81a1948.tar.bz2 |
qmi-firmware-update: load capabilities of the modem early
Only for the update operation, though.
-rw-r--r-- | src/qmi-firmware-update/qfu-reseter.c | 2 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-updater.c | 102 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-utils.c | 154 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-utils.h | 4 |
4 files changed, 201 insertions, 61 deletions
diff --git a/src/qmi-firmware-update/qfu-reseter.c b/src/qmi-firmware-update/qfu-reseter.c index 17f7913..fedd85e 100644 --- a/src/qmi-firmware-update/qfu-reseter.c +++ b/src/qmi-firmware-update/qfu-reseter.c @@ -248,6 +248,7 @@ new_client_dms_ready (gpointer unused, if (!qfu_utils_new_client_dms_finish (res, &ctx->qmi_device, &ctx->qmi_client, + NULL, NULL, NULL, &error)) { /* Jump to AT-based boothold */ g_debug ("[qfu-reseter] error: couldn't allocate QMI client: %s", error->message); @@ -304,6 +305,7 @@ qfu_reseter_run (QfuReseter *self, qfu_utils_new_client_dms (ctx->cdc_wdm, self->priv->device_open_proxy, self->priv->device_open_mbim, + FALSE, cancellable, (GAsyncReadyCallback) new_client_dms_ready, task); diff --git a/src/qmi-firmware-update/qfu-updater.c b/src/qmi-firmware-update/qfu-updater.c index c7a34ae..ea4c13f 100644 --- a/src/qmi-firmware-update/qfu-updater.c +++ b/src/qmi-firmware-update/qfu-updater.c @@ -85,6 +85,11 @@ typedef struct { /* Context step */ RunContextStep step; + /* Before/after info and capabilities */ + gchar *revision; + gboolean supports_stored_image_management; + gboolean supports_firmware_preference_management; + /* List of pending QfuImages to download, and the current one being * processed. */ GList *pending_images; @@ -109,6 +114,7 @@ typedef struct { static void run_context_free (RunContext *ctx) { + g_free (ctx->revision); g_free (ctx->firmware_version); g_free (ctx->config_version); g_free (ctx->carrier); @@ -617,7 +623,7 @@ set_firmware_preference_ready (QmiClientDms *client, /* list images we need to download? */ if (qmi_message_dms_set_firmware_preference_output_get_image_download_list (output, &array, &error)) { if (!array->len) { - g_print ("device already reports the given firmware/config version: nothing to do\n"); + g_print ("device already contains the given firmware/config version: nothing to do\n"); g_list_free_full (ctx->pending_images, (GDestroyNotify) g_object_unref); ctx->pending_images = NULL; next_step = RUN_CONTEXT_STEP_CLEANUP_QMI_DEVICE; @@ -862,30 +868,16 @@ validate_firmware_config_carrier (QfuUpdater *self, } static void -get_firmware_preference_ready (QmiClientDms *client, - GAsyncResult *res, - GTask *task) +run_context_step_get_firmware_preference (GTask *task) { - QfuUpdater *self; - RunContext *ctx; - GError *error = NULL; - QmiMessageDmsGetFirmwarePreferenceOutput *output; - GArray *array; - guint i; + RunContext *ctx; + QfuUpdater *self; + GError *error = NULL; ctx = (RunContext *) g_task_get_task_data (task); self = g_task_get_source_object (task); - output = qmi_client_dms_get_firmware_preference_finish (client, res, &error); - if (!output) { - g_prefix_error (&error, "QMI operation failed: couldn't set operating mode: "); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - if (!qmi_message_dms_get_firmware_preference_output_get_result (output, NULL)) { - qmi_message_dms_get_firmware_preference_output_unref (output); + if (!ctx->supports_firmware_preference_management) { /* Firmware preference setting not supported; fail if we got those settings explicitly */ if (self->priv->firmware_version || self->priv->config_version || self->priv->carrier) { g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -900,28 +892,6 @@ get_firmware_preference_ready (QmiClientDms *client, 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); - /* Firmware preference setting is supported so we require firmware/config/carrier */ if (!validate_firmware_config_carrier (self, ctx, &error)) { g_task_return_error (task, error); @@ -934,22 +904,6 @@ get_firmware_preference_ready (QmiClientDms *client, } 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 new_client_dms_ready (gpointer unused, GAsyncResult *res, GTask *task) @@ -965,6 +919,9 @@ new_client_dms_ready (gpointer unused, if (!qfu_utils_new_client_dms_finish (res, &ctx->qmi_device, &ctx->qmi_client, + &ctx->revision, + &ctx->supports_stored_image_management, + &ctx->supports_firmware_preference_management, &error)) { g_task_return_error (task, error); g_object_unref (task); @@ -989,6 +946,7 @@ run_context_step_qmi_client (GTask *task) qfu_utils_new_client_dms (ctx->cdc_wdm_file, self->priv->device_open_proxy, self->priv->device_open_mbim, + TRUE, g_task_get_cancellable (task), (GAsyncReadyCallback) new_client_dms_ready, task); @@ -1032,6 +990,34 @@ run_context_step (GTask *task) } g_debug ("[qfu-updater] operation finished"); + + /* Dump output report */ + g_print ("\n" + "--------------------------------------------------\n"); + + g_print ("\n" + " original revision was:\n" + " %s\n", ctx->revision); + + if (ctx->supports_stored_image_management) + g_print ("\n" + " NOTE: this device supports stored image management\n" + " with qmicli operations:\n" + " --dms-list-stored-images\n" + " --dms-select-stored-image\n" + " --dms-delete-stored-image\n"); + + if (ctx->supports_firmware_preference_management) + g_print ("\n" + " NOTE: this device supports firmware preference management\n" + " with qmicli operations:\n" + " --dms-get-firmware-preference\n" + " --dms-set-firmware-preference\n"); + + g_print ("\n" + "--------------------------------------------------\n" + "\n"); + g_task_return_boolean (task, TRUE); g_object_unref (task); } diff --git a/src/qmi-firmware-update/qfu-utils.c b/src/qmi-firmware-update/qfu-utils.c index 2fe1551..de47ee3 100644 --- a/src/qmi-firmware-update/qfu-utils.c +++ b/src/qmi-firmware-update/qfu-utils.c @@ -224,6 +224,14 @@ typedef struct { gboolean device_open_mbim; gint qmi_client_retries; QmiClientDms *qmi_client; + + gboolean load_capabilities; + gchar *revision; + gboolean revision_done; + gboolean supports_stored_image_management; + gboolean supports_stored_image_management_done; + gboolean supports_firmware_preference_management; + gboolean supports_firmware_preference_management_done; } NewClientDmsContext; static void @@ -233,6 +241,7 @@ new_client_dms_context_free (NewClientDmsContext *ctx) g_object_unref (ctx->qmi_client); if (ctx->qmi_device) g_object_unref (ctx->qmi_device); + g_free (ctx->revision); g_slice_free (NewClientDmsContext, ctx); } @@ -240,6 +249,9 @@ gboolean qfu_utils_new_client_dms_finish (GAsyncResult *res, QmiDevice **qmi_device, QmiClientDms **qmi_client, + gchar **revision, + gboolean *supports_stored_image_management, + gboolean *supports_firmware_preference_management, GError **error) { NewClientDmsContext *ctx; @@ -247,14 +259,132 @@ qfu_utils_new_client_dms_finish (GAsyncResult *res, if (!g_task_propagate_boolean (G_TASK (res), error)) return FALSE; - ctx = (NewClientDmsContext *) g_task_get_task_data (G_TASK (res)); + ctx = g_task_get_task_data (G_TASK (res)); if (qmi_device) *qmi_device = g_object_ref (ctx->qmi_device); if (qmi_client) *qmi_client = g_object_ref (ctx->qmi_client); + if (revision) + *revision = (ctx->revision ? g_strdup (ctx->revision) : NULL); + if (supports_stored_image_management) + *supports_stored_image_management = ctx->supports_stored_image_management; + if (supports_firmware_preference_management) + *supports_firmware_preference_management = ctx->supports_firmware_preference_management; return TRUE; } +static void +check_capabilities_done (GTask *task) +{ + NewClientDmsContext *ctx; + + ctx = g_task_get_task_data (task); + + if (!ctx->revision_done || + !ctx->supports_stored_image_management_done || + !ctx->supports_firmware_preference_management_done) + return; + + /* All done! */ + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +dms_get_revision_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageDmsGetRevisionOutput *output; + const gchar *str = NULL; + NewClientDmsContext *ctx; + + ctx = g_task_get_task_data (task); + + output = qmi_client_dms_get_revision_finish (client, res, NULL); + if (output && qmi_message_dms_get_revision_output_get_result (output, NULL)) + qmi_message_dms_get_revision_output_get_revision (output, &str, NULL); + + if (str) { + g_debug ("[qfu,utils] current revision loaded: %s", str); + ctx->revision = g_strdup (str); + } + + if (output) + qmi_message_dms_get_revision_output_unref (output); + + ctx->revision_done = TRUE; + check_capabilities_done (task); +} + +static void +dms_list_stored_images_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageDmsListStoredImagesOutput *output; + NewClientDmsContext *ctx; + + ctx = g_task_get_task_data (task); + + output = qmi_client_dms_list_stored_images_finish (client, res, NULL); + ctx->supports_stored_image_management = (output && qmi_message_dms_list_stored_images_output_get_result (output, NULL)); + + if (output) + qmi_message_dms_list_stored_images_output_unref (output); + + ctx->supports_stored_image_management_done = TRUE; + check_capabilities_done (task); +} + +static void +dms_get_firmware_preference_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageDmsGetFirmwarePreferenceOutput *output; + NewClientDmsContext *ctx; + + ctx = g_task_get_task_data (task); + + output = qmi_client_dms_get_firmware_preference_finish (client, res, NULL); + ctx->supports_firmware_preference_management = (output && qmi_message_dms_get_firmware_preference_output_get_result (output, NULL)); + + /* Log the current firmware preference */ + if (ctx->supports_firmware_preference_management) { + GArray *array; + guint i; + + g_debug ("[qfu,utils] current firmware preference loaded:"); + + 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,utils] [image %u]", i); + g_debug ("[qfu,utils] \tImage type: '%s'", qmi_dms_firmware_image_type_get_string (image->type)); + g_debug ("[qfu,utils] \tUnique ID: '%s'", unique_id_str); + g_debug ("[qfu,utils] \tBuild ID: '%s'", image->build_id); + + g_free (unique_id_str); + } + } else + g_debug ("[qfu,utils] no images specified"); + } + + if (output) + qmi_message_dms_get_firmware_preference_output_unref (output); + + ctx->supports_firmware_preference_management_done = TRUE; + check_capabilities_done (task); +} + static void retry_allocate_qmi_client (GTask *task); static void @@ -287,8 +417,24 @@ qmi_client_ready (QmiDevice *device, } g_debug ("[qfu,utils] DMS QMI client allocated"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); + + /* If loading capabilities not required, we're done */ + if (!ctx->load_capabilities) { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + /* Query capabilities */ + qmi_client_dms_get_revision (ctx->qmi_client, + NULL, 10, g_task_get_cancellable (task), + (GAsyncReadyCallback) dms_get_revision_ready, task); + qmi_client_dms_list_stored_images (ctx->qmi_client, + NULL, 10, g_task_get_cancellable (task), + (GAsyncReadyCallback) dms_list_stored_images_ready, task); + qmi_client_dms_get_firmware_preference (ctx->qmi_client, + NULL, 10, g_task_get_cancellable (task), + (GAsyncReadyCallback) dms_get_firmware_preference_ready, task); } static void @@ -371,6 +517,7 @@ void qfu_utils_new_client_dms (GFile *cdc_wdm_file, gboolean device_open_proxy, gboolean device_open_mbim, + gboolean load_capabilities, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -381,6 +528,7 @@ qfu_utils_new_client_dms (GFile *cdc_wdm_file, ctx = g_slice_new0 (NewClientDmsContext); ctx->device_open_proxy = device_open_proxy; ctx->device_open_mbim = device_open_mbim; + ctx->load_capabilities = load_capabilities; ctx->qmi_client_retries = QMI_CLIENT_RETRIES; task = g_task_new (NULL, cancellable, callback, user_data); diff --git a/src/qmi-firmware-update/qfu-utils.h b/src/qmi-firmware-update/qfu-utils.h index 076520e..95e7c2f 100644 --- a/src/qmi-firmware-update/qfu-utils.h +++ b/src/qmi-firmware-update/qfu-utils.h @@ -47,12 +47,16 @@ gboolean qfu_utils_parse_cwe_version_string (const gchar *version, void qfu_utils_new_client_dms (GFile *cdc_wdm_file, gboolean device_open_proxy, gboolean device_open_mbim, + gboolean load_capabilities, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean qfu_utils_new_client_dms_finish (GAsyncResult *res, QmiDevice **qmi_device, QmiClientDms **qmi_client, + gchar **revision, + gboolean *supports_stored_image_management, + gboolean *supports_firmware_preference_management, GError **error); G_END_DECLS |