/* CSE FPT header version 0x21 */ /* SPDX-License-Identifier: GPL-2.0-only */ #include #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, };