/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * qmi-firmware-update -- Command line tool to update firmware in QMI devices * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Copyright (C) 2016 Zodiac Inflight Innovations * Copyright (C) 2016 Aleksander Morgado */ #include #include #include "qfu-operation.h" #include "qfu-image.h" #include "qfu-image-cwe.h" #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, const gchar *id_str, guint idx) { guint i; guint j; g_print ("%s-------------------------------------\n", indent_prefix); g_print ("%s[cwe %s] type: %s\n", 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, VALIDATE_STR_NA (qfu_image_cwe_embedded_header_get_product (image, idx))); g_print ("%s[cwe %s] version: %s\n", 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, 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)); for (i = idx + 1, j = 0; i < qfu_image_cwe_get_n_embedded_headers (image); i++) { gchar *sub_id_str; gchar *sub_indent_prefix; /* As soon as we find one which doesn't have the expected parent index, break */ if (qfu_image_cwe_embedded_header_get_parent_index (image, i) != idx) continue; sub_id_str = g_strdup_printf ("%s.%u", id_str, j++); sub_indent_prefix = g_strdup_printf ("%s ", indent_prefix); print_image_cwe (image, sub_indent_prefix, sub_id_str, i); g_free (sub_id_str); g_free (sub_indent_prefix); } } static gboolean operation_verify_run_single (const gchar *image_path) { QfuImage *image; GFile *file; GError *error = NULL; gboolean result = FALSE; file = g_file_new_for_commandline_arg (image_path); image = qfu_image_factory_build (file, NULL, &error); if (!image) { g_printerr ("error: couldn't detect image type: %s\n", error->message); g_error_free (error); goto out; } g_print ("\n"); g_print ("Firmware image:\n"); g_print (" filename: %s\n", qfu_image_get_display_name (image)); g_print (" detected type: %s\n", qfu_image_type_get_string (qfu_image_get_image_type (image))); g_print (" size: %" G_GOFFSET_FORMAT " bytes\n", qfu_image_get_size (image)); g_print (" header: %" G_GOFFSET_FORMAT " bytes\n", qfu_image_get_header_size (image)); 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)) { 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; out: if (image) g_object_unref (image); return result; } gboolean qfu_operation_verify_run (const gchar **images) { guint invalid_images = 0; guint i; for (i = 0; images[i] ; i++) invalid_images += !operation_verify_run_single (images[i]); return !invalid_images; }