broadband-modem-qmi: fix listing images when 'Get Stored Image Info' is unsupported

This commit is contained in:
Aleksander Morgado
2019-09-16 13:19:10 +02:00
parent 1b29f7524c
commit a55543d11e

View File

@@ -7055,12 +7055,16 @@ firmware_pair_free (FirmwarePair *pair)
typedef struct {
QmiClientDms *client;
GList *pairs;
GList *l;
FirmwarePair *current_pair;
MMFirmwareProperties *current_firmware;
gboolean skip_image_info;
} FirmwareListPreloadContext;
static void
firmware_list_preload_context_free (FirmwareListPreloadContext *ctx)
{
g_clear_object (&ctx->current_firmware);
g_clear_pointer (&ctx->current_pair, (GDestroyNotify)firmware_pair_free);
g_list_free_full (ctx->pairs, (GDestroyNotify)firmware_pair_free);
g_object_unref (ctx->client);
g_slice_free (FirmwareListPreloadContext, ctx);
@@ -7074,6 +7078,24 @@ firmware_list_preload_finish (MMBroadbandModemQmi *self,
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
store_preloaded_firmware_image_info (MMBroadbandModemQmi *self,
MMFirmwareProperties *firmware,
gboolean running)
{
self->priv->firmware_list = g_list_append (self->priv->firmware_list, g_object_ref (firmware));
/* If this is is also the running image, keep an extra reference to it */
if (running) {
if (self->priv->current_firmware)
mm_warn ("A running firmware is already set (%s), not setting '%s'",
mm_firmware_properties_get_unique_id (self->priv->current_firmware),
mm_firmware_properties_get_unique_id (firmware));
else
self->priv->current_firmware = g_object_ref (firmware);
}
}
static void get_next_image_info (GTask *task);
static void
@@ -7085,35 +7107,23 @@ get_pri_image_info_ready (QmiClientDms *client,
FirmwareListPreloadContext *ctx;
QmiMessageDmsGetStoredImageInfoOutput *output;
GError *error = NULL;
FirmwarePair *current;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
current = (FirmwarePair *)ctx->l->data;
g_assert (ctx->current_pair);
g_assert (ctx->current_firmware);
output = qmi_client_dms_get_stored_image_info_finish (client, res, &error);
if (!output ||
!qmi_message_dms_get_stored_image_info_output_get_result (output, &error)) {
mm_warn ("Couldn't get detailed info for PRI image with build ID '%s': %s",
current->build_id,
error->message);
if (!output || !qmi_message_dms_get_stored_image_info_output_get_result (output, &error)) {
if (g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND))
ctx->skip_image_info = TRUE;
else
mm_dbg ("couldn't get detailed info for PRI image with build ID '%s': %s",
ctx->current_pair->build_id, error->message);
g_error_free (error);
} else {
gchar *unique_id_str;
MMFirmwareProperties *firmware;
firmware = mm_firmware_properties_new (MM_FIRMWARE_IMAGE_TYPE_GOBI,
current->build_id);
unique_id_str = mm_utils_bin2hexstr ((const guint8 *)current->pri_unique_id->data,
current->pri_unique_id->len);
mm_firmware_properties_set_gobi_pri_unique_id (firmware, unique_id_str);
g_free (unique_id_str);
unique_id_str = mm_utils_bin2hexstr ((const guint8 *)current->modem_unique_id->data,
current->modem_unique_id->len);
mm_firmware_properties_set_gobi_modem_unique_id (firmware, unique_id_str);
g_free (unique_id_str);
goto out;
}
/* Boot version (optional) */
{
@@ -7128,7 +7138,7 @@ get_pri_image_info_ready (QmiClientDms *client,
gchar *aux;
aux = g_strdup_printf ("%u.%u", boot_major_version, boot_minor_version);
mm_firmware_properties_set_gobi_boot_version (firmware, aux);
mm_firmware_properties_set_gobi_boot_version (ctx->current_firmware, aux);
g_free (aux);
}
}
@@ -7146,35 +7156,44 @@ get_pri_image_info_ready (QmiClientDms *client,
gchar *aux;
aux = g_strdup_printf ("%u", pri_version);
mm_firmware_properties_set_gobi_pri_version (firmware, aux);
mm_firmware_properties_set_gobi_pri_version (ctx->current_firmware, aux);
g_free (aux);
mm_firmware_properties_set_gobi_pri_info (firmware, pri_info);
mm_firmware_properties_set_gobi_pri_info (ctx->current_firmware, pri_info);
}
}
/* Add firmware image to our internal list */
self->priv->firmware_list = g_list_append (self->priv->firmware_list,
firmware);
out:
/* If this is is also the current image running, keep it */
if (current->current) {
if (self->priv->current_firmware)
mm_warn ("A current firmware is already set (%s), not setting '%s' as current",
mm_firmware_properties_get_unique_id (self->priv->current_firmware),
current->build_id);
else
self->priv->current_firmware = g_object_ref (firmware);
/* We're done with this image */
store_preloaded_firmware_image_info (self, ctx->current_firmware, ctx->current_pair->current);
g_clear_object (&ctx->current_firmware);
g_clear_pointer (&ctx->current_pair, (GDestroyNotify)firmware_pair_free);
}
}
/* Go on to the next one */
get_next_image_info (task);
if (output)
qmi_message_dms_get_stored_image_info_output_unref (output);
}
/* Go on to the next one */
ctx->l = g_list_next (ctx->l);
get_next_image_info (task);
static MMFirmwareProperties *
create_firmware_properties_from_pair (FirmwarePair *pair)
{
gchar *unique_id_str;
MMFirmwareProperties *firmware;
firmware = mm_firmware_properties_new (MM_FIRMWARE_IMAGE_TYPE_GOBI, pair->build_id);
unique_id_str = mm_utils_bin2hexstr ((const guint8 *)pair->pri_unique_id->data, pair->pri_unique_id->len);
mm_firmware_properties_set_gobi_pri_unique_id (firmware, unique_id_str);
g_free (unique_id_str);
unique_id_str = mm_utils_bin2hexstr ((const guint8 *)pair->modem_unique_id->data, pair->modem_unique_id->len);
mm_firmware_properties_set_gobi_modem_unique_id (firmware, unique_id_str);
g_free (unique_id_str);
return firmware;
}
static void
@@ -7182,33 +7201,31 @@ get_next_image_info (GTask *task)
{
MMBroadbandModemQmi *self;
FirmwareListPreloadContext *ctx;
QmiMessageDmsGetStoredImageInfoInputImage image_id;
QmiMessageDmsGetStoredImageInfoInput *input;
FirmwarePair *current;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
if (!ctx->l) {
/* We're done */
if (!self->priv->firmware_list) {
mm_warn ("No valid firmware images listed. "
"Assuming firmware unsupported.");
g_task_return_boolean (task, FALSE);
} else
if (!ctx->pairs) {
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
current = (FirmwarePair *)ctx->l->data;
/* Take next pair to process from list head */
ctx->current_pair = (FirmwarePair *)ctx->pairs->data;
ctx->pairs = g_list_delete_link (ctx->pairs, ctx->pairs);
/* Build firmware properties */
ctx->current_firmware = create_firmware_properties_from_pair (ctx->current_pair);
/* Now, load additional optional information for the PRI image */
if (!ctx->skip_image_info) {
QmiMessageDmsGetStoredImageInfoInputImage image_id;
QmiMessageDmsGetStoredImageInfoInput *input;
/* Query PRI image info */
image_id.type = QMI_DMS_FIRMWARE_IMAGE_TYPE_PRI;
image_id.unique_id = current->pri_unique_id;
image_id.build_id = current->build_id;
image_id.unique_id = ctx->current_pair->pri_unique_id;
image_id.build_id = ctx->current_pair->build_id;
input = qmi_message_dms_get_stored_image_info_input_new ();
qmi_message_dms_get_stored_image_info_input_set_image (input, &image_id, NULL);
qmi_client_dms_get_stored_image_info (ctx->client,
@@ -7218,6 +7235,16 @@ get_next_image_info (GTask *task)
(GAsyncReadyCallback)get_pri_image_info_ready,
task);
qmi_message_dms_get_stored_image_info_input_unref (input);
return;
}
/* If we shouldn't be loading additional image info, we're done with this image */
store_preloaded_firmware_image_info (self, ctx->current_firmware, ctx->current_pair->current);
g_clear_object (&ctx->current_firmware);
g_clear_pointer (&ctx->current_pair, (GDestroyNotify)firmware_pair_free);
/* Go on to the next one */
get_next_image_info (task);
}
static gboolean
@@ -7387,7 +7414,6 @@ list_stored_images_ready (QmiClientDms *client,
}
/* Now keep on loading info for each image and cache it */
ctx->l = ctx->pairs;
get_next_image_info (task);
out: