diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-12-08 12:46:32 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-01-16 11:24:14 +0100 |
commit | 7a98aba9e3000c3d24e29134386db89600700b19 (patch) | |
tree | e1f00d09f91222c3a0f3e80ee122ccd18b699d70 /src/qmi-firmware-update | |
parent | 899fd165ff02bc240c618ad39f6ad66957f69740 (diff) | |
download | external_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.zip external_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.tar.gz external_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.tar.bz2 |
qmi-firmware-update: try to parse firmware/config/carrier in CWE
Diffstat (limited to 'src/qmi-firmware-update')
-rw-r--r-- | src/qmi-firmware-update/qfu-image-cwe.c | 134 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-image-cwe.h | 6 | ||||
-rw-r--r-- | src/qmi-firmware-update/qfu-operation-verify.c | 24 |
3 files changed, 158 insertions, 6 deletions
diff --git a/src/qmi-firmware-update/qfu-image-cwe.c b/src/qmi-firmware-update/qfu-image-cwe.c index 6202e04..463d6bc 100644 --- a/src/qmi-firmware-update/qfu-image-cwe.c +++ b/src/qmi-firmware-update/qfu-image-cwe.c @@ -23,6 +23,7 @@ #include <string.h> #include "qfu-image-cwe.h" +#include "qfu-utils.h" static GInitableIface *iface_initable_parent; static void initable_iface_init (GInitableIface *iface); @@ -58,6 +59,11 @@ typedef struct { struct _QfuImageCwePrivate { GArray *images; + + /* Parsed */ + gchar *firmware_version; + gchar *config_version; + gchar *carrier; }; /******************************************************************************/ @@ -189,6 +195,128 @@ qfu_image_cwe_header_get_image_size (QfuImageCwe *self) /******************************************************************************/ +static void +parse_firmware_config_carrier (QfuImageCwe *self) +{ + GError *inner_error = NULL; + guint i; + + g_assert (!self->priv->firmware_version); + g_assert (!self->priv->config_version); + g_assert (!self->priv->carrier); + + /* Try using the internal version first */ + if (!qfu_utils_parse_cwe_version_string ( + qfu_image_cwe_header_get_version (self), + &self->priv->firmware_version, + &self->priv->config_version, + &self->priv->carrier, + &inner_error)) { + /* Just log the error message */ + g_debug ("[qfu-image-cwe] couldn't parse internal version string '%s': %s", + qfu_image_cwe_header_get_version (self), + inner_error->message); + g_clear_error (&inner_error); + } + + /* If all retrieved with the internal version string, we're done */ + if (self->priv->firmware_version && self->priv->config_version && self->priv->carrier) + goto done; + + /* Try using the filename to gather more info */ + if (!qfu_utils_parse_cwe_version_string ( + qfu_image_get_display_name (QFU_IMAGE (self)), + self->priv->firmware_version ? NULL : &self->priv->firmware_version, + self->priv->config_version ? NULL : &self->priv->config_version, + self->priv->carrier ? NULL : &self->priv->carrier, + &inner_error)) { + /* Just log the error message */ + g_debug ("[qfu-image-cwe] couldn't parse filename '%s': %s", + qfu_image_get_display_name (QFU_IMAGE (self)), + inner_error->message); + g_clear_error (&inner_error); + } + + /* If all retrieved with the filename, we're done */ + if (self->priv->firmware_version && self->priv->config_version && self->priv->carrier) + goto done; + + /* Try with embedded images of type BOOT or NVU */ + for (i = 0; i < self->priv->images->len; i++) { + ImageInfo *info; + + info = &g_array_index (self->priv->images, ImageInfo, i); + + /* BOOT partition in system images won't likely contain anything else + * than firmware version */ + if (!g_strcmp0 (info->type, "BOOT") && !self->priv->firmware_version) { + if (!qfu_utils_parse_cwe_version_string ( + info->hdr.version, + &self->priv->firmware_version, + NULL, + NULL, + &inner_error)) { + /* Just log the error message */ + g_debug ("[qfu-image-cwe] couldn't parse BOOT version '%s': %s", + qfu_image_get_display_name (QFU_IMAGE (self)), + inner_error->message); + g_clear_error (&inner_error); + } + } + + /* NVUP partition in nvu images are usually carrier-specific */ + if (!g_strcmp0 (info->type, "NVUP")) { + if (!qfu_utils_parse_cwe_version_string ( + info->hdr.version, + self->priv->firmware_version ? NULL : &self->priv->firmware_version, + self->priv->config_version ? NULL : &self->priv->config_version, + self->priv->carrier ? NULL : &self->priv->carrier, + &inner_error)) { + /* Just log the error message */ + g_debug ("[qfu-image-cwe] couldn't parse NVUP version '%s': %s", + qfu_image_get_display_name (QFU_IMAGE (self)), + inner_error->message); + g_clear_error (&inner_error); + } + } + + /* As soon as all retrieved, we're done */ + if (self->priv->firmware_version && self->priv->config_version && self->priv->carrier) + goto done; + } + +done: + g_debug ("[qfu-image-cwe] firmware version: %s", self->priv->firmware_version ? self->priv->firmware_version : "unknown"); + g_debug ("[qfu-image-cwe] config version: %s", self->priv->config_version ? self->priv->config_version : "unknown"); + g_debug ("[qfu-image-cwe] carrier: %s", self->priv->carrier ? self->priv->carrier : "unknown"); +} + +const gchar * +qfu_image_cwe_get_parsed_firmware_version (QfuImageCwe *self) +{ + g_return_val_if_fail (QFU_IS_IMAGE_CWE (self), NULL); + + return self->priv->firmware_version; +} + +const gchar * +qfu_image_cwe_get_parsed_config_version (QfuImageCwe *self) +{ + g_return_val_if_fail (QFU_IS_IMAGE_CWE (self), NULL); + + return self->priv->config_version; +} + +const gchar * +qfu_image_cwe_get_parsed_carrier (QfuImageCwe *self) +{ + g_return_val_if_fail (QFU_IS_IMAGE_CWE (self), NULL); + + return self->priv->carrier; +} + +/******************************************************************************/ + static goffset get_header_size (QfuImage *self) { @@ -382,6 +510,9 @@ initable_init (GInitable *initable, goto out; } + g_debug ("[qfu-image-cwe] preloading firmware/config/carrier..."); + parse_firmware_config_carrier (self); + /* Success! */ result = TRUE; @@ -421,6 +552,9 @@ finalize (GObject *object) { QfuImageCwe *self = QFU_IMAGE_CWE (object); + g_free (self->priv->firmware_version); + g_free (self->priv->config_version); + g_free (self->priv->carrier); g_array_unref (self->priv->images); G_OBJECT_CLASS (qfu_image_cwe_parent_class)->finalize (object); diff --git a/src/qmi-firmware-update/qfu-image-cwe.h b/src/qmi-firmware-update/qfu-image-cwe.h index eeb2f23..1ed8bd5 100644 --- a/src/qmi-firmware-update/qfu-image-cwe.h +++ b/src/qmi-firmware-update/qfu-image-cwe.h @@ -54,11 +54,17 @@ GType qfu_image_cwe_get_type (void); QfuImage *qfu_image_cwe_new (GFile *file, GCancellable *cancellable, GError **error); + const gchar *qfu_image_cwe_header_get_type (QfuImageCwe *self); const gchar *qfu_image_cwe_header_get_product (QfuImageCwe *self); const gchar *qfu_image_cwe_header_get_version (QfuImageCwe *self); const gchar *qfu_image_cwe_header_get_date (QfuImageCwe *self); guint32 qfu_image_cwe_header_get_image_size (QfuImageCwe *self); + +const gchar *qfu_image_cwe_get_parsed_firmware_version (QfuImageCwe *self); +const gchar *qfu_image_cwe_get_parsed_config_version (QfuImageCwe *self); +const gchar *qfu_image_cwe_get_parsed_carrier (QfuImageCwe *self); + guint qfu_image_cwe_get_n_embedded_headers (QfuImageCwe *self); gint qfu_image_cwe_embedded_header_get_parent_index (QfuImageCwe *self, guint embedded_i); diff --git a/src/qmi-firmware-update/qfu-operation-verify.c b/src/qmi-firmware-update/qfu-operation-verify.c index 518a6e6..31cbbf4 100644 --- a/src/qmi-firmware-update/qfu-operation-verify.c +++ b/src/qmi-firmware-update/qfu-operation-verify.c @@ -28,6 +28,8 @@ #include "qfu-image-factory.h" #include "qfu-enum-types.h" +#define VALIDATE_STR_NA(str) (str && str[0] ? str : "n/a") + static void print_image_cwe (QfuImageCwe *image, const gchar *indent_prefix, @@ -39,13 +41,13 @@ print_image_cwe (QfuImageCwe *image, g_print ("%s-------------------------------------\n", indent_prefix); g_print ("%s[cwe %s] type: %s\n", - indent_prefix, id_str, qfu_image_cwe_embedded_header_get_type (image, idx)); + indent_prefix, id_str, VALIDATE_STR_NA (qfu_image_cwe_embedded_header_get_type (image, idx))); g_print ("%s[cwe %s] product: %s\n", - indent_prefix, id_str, qfu_image_cwe_embedded_header_get_product (image, idx)); + indent_prefix, id_str, VALIDATE_STR_NA (qfu_image_cwe_embedded_header_get_product (image, idx))); g_print ("%s[cwe %s] version: %s\n", - indent_prefix, id_str, qfu_image_cwe_embedded_header_get_version (image, idx)); + indent_prefix, id_str, VALIDATE_STR_NA (qfu_image_cwe_embedded_header_get_version (image, idx))); g_print ("%s[cwe %s] date: %s\n", - indent_prefix, id_str, qfu_image_cwe_embedded_header_get_date (image, idx)); + indent_prefix, id_str, VALIDATE_STR_NA (qfu_image_cwe_embedded_header_get_date (image, idx))); g_print ("%s[cwe %s] size: %" G_GUINT32_FORMAT "\n", indent_prefix, id_str, qfu_image_cwe_embedded_header_get_image_size (image, idx)); @@ -92,8 +94,18 @@ operation_verify_run_single (const gchar *image_path) g_print (" data: %" G_GOFFSET_FORMAT " bytes\n", qfu_image_get_data_size (image)); g_print (" data chunks: %" G_GUINT16_FORMAT " (%lu bytes/chunk)\n", qfu_image_get_n_data_chunks (image), (gulong) QFU_IMAGE_CHUNK_SIZE); - if (QFU_IS_IMAGE_CWE (image)) - print_image_cwe (QFU_IMAGE_CWE (image), " ", "0", 0); + if (QFU_IS_IMAGE_CWE (image)) { + QfuImageCwe *image_cwe = QFU_IMAGE_CWE (image); + + g_print (" [cwe] detected firmware version: %s\n", + VALIDATE_STR_NA (qfu_image_cwe_get_parsed_firmware_version (image_cwe))); + g_print (" [cwe] detected config version: %s\n", + VALIDATE_STR_NA (qfu_image_cwe_get_parsed_config_version (image_cwe))); + g_print (" [cwe] detected carrier: %s\n", + VALIDATE_STR_NA (qfu_image_cwe_get_parsed_carrier (image_cwe))); + + print_image_cwe (image_cwe, " ", "0", 0); + } result = TRUE; |