/*
 * Simple tool to dump the AP_Var contents from an EEPROM dump
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uint8_t eeprom[0x1000];

#pragma pack(1)

struct EEPROM_header {
    uint16_t magic;
    uint8_t revision;
    uint8_t spare;
};

static const uint16_t k_EEPROM_magic      = 0x5041;
static const uint16_t k_EEPROM_revision   = 2;

struct Var_header {
    uint8_t size : 6;
    uint8_t spare : 2;
    uint8_t key;
};

static const uint8_t k_key_sentinel = 0xff;

void
fail(const char *why)
{
    fprintf(stderr, "ERROR: %s\n", why);
    exit(1);
}

int
main(int argc, char *argv[])
{
    FILE                  *fp;
    struct EEPROM_header  *header;
    struct Var_header     *var;
    unsigned index;
    unsigned i;

    if (argc != 2) {
        fail("missing EEPROM file name");
    }
    if (NULL == (fp = fopen(argv[1], "rb"))) {
        fail("can't open EEPROM file");
    }
    if (1 != fread(eeprom, sizeof(eeprom), 1, fp)) {
        fail("can't read EEPROM file");
    }
    fclose(fp);

    header = (struct EEPROM_header *)&eeprom[0];
    if (header->magic != k_EEPROM_magic) {
        fail("bad magic in EEPROM file");
    }
    if (header->revision != 2) {
        fail("unsupported EEPROM format revision");
    }
    printf("Header OK\n");

    index = sizeof(*header);
    for (;; ) {
        var = (struct Var_header *)&eeprom[index];
        if (var->key == k_key_sentinel) {
            printf("end sentinel at %u\n", index);
            break;
        }
        printf("%04x: key %u size %d\n ", index, var->key, var->size + 1);
        index += sizeof(*var);
        for (i = 0; i <= var->size; i++) {
            printf(" %02x", eeprom[index + i]);
        }
        printf("\n");
        index += var->size + 1;
        if (index >= sizeof(eeprom)) {
            fflush(stdout);
            fail("missing end sentinel");
        }
    }
}