blob: 57746ddd742fd488d6e08527728bd5370e1d6e67 [file] [log] [blame]
/* CSE FPT header version 0x21 */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <sys/types.h>
#include "cse_fpt.h"
struct fpt_hdr {
uint8_t marker[4]; /* FPT_MARKER */
uint32_t num_entries;
uint8_t hdr_version; /* FPT_HDR_VERSION_21 */
uint8_t entry_version; /* FPT_ENTRY_VERSION */
uint8_t hdr_length;
uint8_t redundancy;
uint8_t reserved[8];
uint32_t checksum;
struct {
uint16_t major;
uint16_t minor;
uint16_t build;
uint16_t hotfix;
} fit_tool_version;
} __packed;
static bool match_version(struct buffer *buff)
{
const uint8_t *data = buffer_get(buff);
uint8_t version = read_at_le8(data, offsetof(struct fpt_hdr, hdr_version));
return version == FPT_HDR_VERSION_21;
}
static bool validate_fpt_hdr(const struct fpt_hdr *h)
{
if (memcmp(h->marker, FPT_MARKER, sizeof(h->marker))) {
ERROR("Invalid FPT header marker!\n");
return false;
}
if (h->hdr_version != FPT_HDR_VERSION_21) {
ERROR("Invalid FPT header version(0x%x)!\n", h->hdr_version);
return false;
}
if (h->entry_version != FPT_ENTRY_VERSION) {
ERROR("Invalid FPT entry version(0x%x)!\n", h->entry_version);
return false;
}
return true;
}
static fpt_hdr_ptr read_fpt_hdr(struct buffer *buff)
{
struct fpt_hdr *h = malloc(sizeof(*h));
if (!h)
return NULL;
READ_MEMBER(buff, h->marker);
READ_MEMBER(buff, h->num_entries);
READ_MEMBER(buff, h->hdr_version);
READ_MEMBER(buff, h->entry_version);
READ_MEMBER(buff, h->hdr_length);
READ_MEMBER(buff, h->redundancy);
READ_MEMBER(buff, h->reserved);
READ_MEMBER(buff, h->checksum);
READ_MEMBER(buff, h->fit_tool_version);
if (!validate_fpt_hdr(h)) {
free(h);
return NULL;
}
return h;
}
static void print_fpt_hdr(const fpt_hdr_ptr ptr)
{
struct fpt_hdr *h = ptr;
printf(" * FPT header\n");
printf("%-25s: %.4s\n", "Marker", h->marker);
printf("%-25s: %d\n", "Number of entries", h->num_entries);
printf("%-25s: 0x%x\n", "Header version", h->hdr_version);
printf("%-25s: 0x%x\n", "Entry version", h->entry_version);
printf("%-25s: %d\n", "Header length", h->hdr_length);
printf("%-25s: 0x%x\n", "Redundancy", h->redundancy);
printf("%-25s: ", "Reserved");
for (size_t i = 0; i < ARRAY_SIZE(h->reserved); i++)
printf("0x%x ", h->reserved[i]);
printf("\n");
printf("%-25s: 0x%x\n", "Checksum", h->checksum);
printf("%-25s: %d.%d.%d.%d(%.2x.%.2x.%.2x.%.2x)\n", "FIT Tool Version",
h->fit_tool_version.major, h->fit_tool_version.minor,
h->fit_tool_version.build, h->fit_tool_version.hotfix,
h->fit_tool_version.major, h->fit_tool_version.minor,
h->fit_tool_version.build, h->fit_tool_version.hotfix);
}
static size_t get_entry_count(const fpt_hdr_ptr ptr)
{
struct fpt_hdr *h = ptr;
return h->num_entries;
}
const struct fpt_hdr_ops fpt_hdr_21_ops = {
.match_version = match_version,
.read = read_fpt_hdr,
.print = print_fpt_hdr,
.get_entry_count = get_entry_count,
};