aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-12-08 12:46:32 +0100
committerAleksander Morgado <aleksander@aleksander.es>2017-01-16 11:24:14 +0100
commit7a98aba9e3000c3d24e29134386db89600700b19 (patch)
treee1f00d09f91222c3a0f3e80ee122ccd18b699d70
parent899fd165ff02bc240c618ad39f6ad66957f69740 (diff)
downloadexternal_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.zip
external_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.tar.gz
external_libqmi-7a98aba9e3000c3d24e29134386db89600700b19.tar.bz2
qmi-firmware-update: try to parse firmware/config/carrier in CWE
-rw-r--r--src/qmi-firmware-update/qfu-image-cwe.c134
-rw-r--r--src/qmi-firmware-update/qfu-image-cwe.h6
-rw-r--r--src/qmi-firmware-update/qfu-operation-verify.c24
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;