From b67783635be0ede5a8fc524b7d66d8a4b4a79142 Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Tue, 8 Mar 2016 12:31:29 -0800 Subject: [PATCH] Sysparam code cleanup --- core/sysparam.c | 345 ++++++++++++++++++++++++++++-------------------- 1 file changed, 202 insertions(+), 143 deletions(-) diff --git a/core/sysparam.c b/core/sysparam.c index d6fd4b1..8f9415d 100644 --- a/core/sysparam.c +++ b/core/sysparam.c @@ -5,28 +5,60 @@ #include //TODO: make this properly threadsafe -//FIXME: reduce stack usage -//TODO: make stderr work for debug output +//TODO: reduce stack usage +//FIXME: CRC calculations/checking + +/* The "magic" values that indicate the start of a sysparam region in flash. + * Note that SYSPARAM_STALE_MAGIC is written over SYSPARAM_ACTIVE_MAGIC, so it + * must not contain any set bits which are not set in SYSPARAM_ACTIVE_MAGIC + * (that is, going from SYSPARAM_ACTIVE_MAGIC to SYSPARAM_STALE_MAGIC must only + * clear bits, not set them) + */ +#define SYSPARAM_ACTIVE_MAGIC 0x70524f45 // "EORp" in little-endian +#define SYSPARAM_STALE_MAGIC 0x40524f45 // "EOR@" in little-endian + +/* The size of the initial buffer created by sysparam_iter_start, etc, to hold + * returned key-value pairs. Setting this too small may result in a lot of + * unnecessary reallocs. Setting it too large will waste memory when iterating + * through entries. + */ +#define DEFAULT_ITER_BUF_SIZE 64 + +/* The size of the buffer (in words) used by `sysparam_create_area` when + * scanning a potential area to make sure it's currently empty. Note that this + * space is taken from the stack, so it should not be too large. + */ +#define SCAN_BUFFER_SIZE 8 // words + +/* Size of region/entry headers. These should not normally need tweaking (and + * will probably require some code changes if they are tweaked). + */ +#define REGION_HEADER_SIZE 4 // NOTE: Must be multiple of 4 +#define ENTRY_HEADER_SIZE 4 // NOTE: Must be multiple of 4 + +/* Maximum value that can be used for a key_id. This is limited by the format + * to 0x7e (0x7f would produce a corresponding value ID of 0xff, which is + * invalid) + */ +#define MAX_KEY_ID 0x7e #ifndef SYSPARAM_DEBUG #define SYSPARAM_DEBUG 0 #endif -#define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); } - -#define SYSPARAM_MAGIC 0x70524f45 // "EORp" in little-endian -#define SYSPARAM_STALEMAGIC 0x40524f45 // "EOR@" in little-endian -#define REGION_HEADER_SIZE 4 // NOTE: Must be multiple of 4 -#define ENTRY_HEADER_SIZE 4 // NOTE: Must be multiple of 4 -#define DEFAULT_ITER_BUF_SIZE 64 -#define MAX_KEY_ID 0x7e -#define SCAN_BUFFER_SIZE 8 // words +/******************************* Useful Macros *******************************/ #define ROUND_TO_WORD_BOUNDARY(x) (((x) + 3) & 0xfffffffc) #define ENTRY_SIZE(payload_len) (ENTRY_HEADER_SIZE + ROUND_TO_WORD_BOUNDARY(payload_len)) +#define max(x, y) ((x) > (y) ? (x) : (y)) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +#define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); } + #define CHECK_FLASH_OP(x) do { int __x = (x); if ((__x) != SPI_FLASH_RESULT_OK) { debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; } } while (0); +/********************* Internal datatypes and structures *********************/ struct entry_header { uint8_t prev_len; @@ -43,21 +75,19 @@ struct sysparam_context { uint8_t max_key_id; }; -/* Internal data structures */ +/*************************** Global variables/data ***************************/ -struct { +static struct { uint32_t cur_base; uint32_t alt_base; uint32_t end_addr; size_t region_size; -} sysparam_info; +} _sysparam_info; -/* Internal routines */ +/***************************** Internal routines *****************************/ -#define max(x, y) ((x) > (y) ? (x) : (y)) -#define min(x, y) ((x) < (y) ? (x) : (y)) - -static sysparam_status_t format_region(uint32_t addr) { +/** Erase the sectors of a region */ +static sysparam_status_t _format_region(uint32_t addr) { uint16_t sector = addr / sdk_flashchip.sector_size; int i; @@ -67,30 +97,38 @@ static sysparam_status_t format_region(uint32_t addr) { return SYSPARAM_OK; } -static inline sysparam_status_t write_region_header(uint32_t addr, bool active) { - uint32_t magic = active ? SYSPARAM_MAGIC : SYSPARAM_STALEMAGIC; +/** Write the magic value at the beginning of a region */ +static inline sysparam_status_t _write_region_header(uint32_t addr, bool active) { + uint32_t magic = active ? SYSPARAM_ACTIVE_MAGIC : SYSPARAM_STALE_MAGIC; debug(3, "write region header (0x%08x) @ 0x%08x", magic, addr); CHECK_FLASH_OP(sdk_spi_flash_write(addr, &magic, 4)); return SYSPARAM_OK; } -static void init_context(struct sysparam_context *ctx) { +/** Initialize a context structure at the beginning of the active region */ +static void _init_context(struct sysparam_context *ctx) { memset(ctx, 0, sizeof(*ctx)); - ctx->addr = sysparam_info.cur_base; + ctx->addr = _sysparam_info.cur_base; } +/** Initialize a context structure at the end of the active region */ static sysparam_status_t init_write_context(struct sysparam_context *ctx) { memset(ctx, 0, sizeof(*ctx)); - ctx->addr = sysparam_info.end_addr; + ctx->addr = _sysparam_info.end_addr; debug(3, "read entry header @ 0x%08x", ctx->addr); CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, &ctx->entry, ENTRY_HEADER_SIZE)); return SYSPARAM_OK; } -static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_id) { +/** Search through the region for an entry matching the specified id + * + * @param match_id The id to match, or 0 to match any key, or 0xff to scan + * to the end. + */ +static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint8_t match_id) { uint8_t prev_len; - while (ctx->addr + ENTRY_SIZE(ctx->entry.len) < sysparam_info.end_addr) { + while (ctx->addr + ENTRY_SIZE(ctx->entry.len) < _sysparam_info.end_addr) { prev_len = ctx->entry.len; ctx->addr += ENTRY_SIZE(ctx->entry.len); @@ -102,7 +140,7 @@ static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_ // been corrupted and we don't even know if we're in the right // place anymore. We have to bail out. debug(1, "prev_len mismatch at 0x%08x (%d != %d)", ctx->addr, ctx->entry.prev_len, prev_len); - ctx->addr = sysparam_info.end_addr; + ctx->addr = _sysparam_info.end_addr; return SYSPARAM_ERR_CORRUPT; } @@ -132,28 +170,28 @@ static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_ return SYSPARAM_NOTFOUND; } -static inline sysparam_status_t read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) { +/** Read the payload from the current entry pointed to by `ctx` */ +static inline sysparam_status_t _read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) { debug(3, "read payload (%d) @ 0x%08x", min(buffer_size, ctx->entry.len), ctx->addr); CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr + ENTRY_HEADER_SIZE, buffer, min(buffer_size, ctx->entry.len))); //FIXME: check crc return SYSPARAM_OK; } -// Scan through the region to find the location of the key entry matching the -// specified name. -static sysparam_status_t find_key(struct sysparam_context *ctx, const char *key, uint8_t key_len, uint8_t *buffer) { +/** Find the entry corresponding to the specified key name */ +static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key, uint8_t key_len, uint8_t *buffer) { sysparam_status_t status; while (true) { // Find the next key entry - status = find_entry(ctx, 0); + status = _find_entry(ctx, 0); if (status != SYSPARAM_OK) return status; if (!key) { // We're looking for the next (any) key, so we're done. break; } if (ctx->entry.len == key_len) { - status = read_payload(ctx, buffer, key_len); + status = _read_payload(ctx, buffer, key_len); if (status < 0) return status; if (!memcmp(key, buffer, key_len)) { // We have a match @@ -165,7 +203,8 @@ static sysparam_status_t find_key(struct sysparam_context *ctx, const char *key, return SYSPARAM_OK; } -static inline sysparam_status_t write_entry(uint32_t addr, uint8_t id, const uint8_t *payload, uint8_t len, uint8_t prev_len) { +/** Write an entry at the specified address */ +static inline sysparam_status_t _write_entry(uint32_t addr, uint8_t id, const uint8_t *payload, uint8_t len, uint8_t prev_len) { struct entry_header entry; debug(2, "Writing entry 0x%02x @ 0x%08x", id, addr); @@ -181,7 +220,10 @@ static inline sysparam_status_t write_entry(uint32_t addr, uint8_t id, const uin return SYSPARAM_OK; } -static inline sysparam_status_t write_entry_tail(uint32_t addr, uint8_t prev_len) { +/** Write the "tail" entry on the end of the region + * (this entry just contains the `prev_len` field with all others set to 0xff) + */ +static inline sysparam_status_t _write_entry_tail(uint32_t addr, uint8_t prev_len) { struct entry_header entry; entry.prev_len = prev_len; @@ -194,7 +236,8 @@ static inline sysparam_status_t write_entry_tail(uint32_t addr, uint8_t prev_len return SYSPARAM_OK; } -static inline sysparam_status_t delete_entry(uint32_t addr) { +/** Mark an entry as "deleted" so it won't be considered in future reads */ +static inline sysparam_status_t _delete_entry(uint32_t addr) { struct entry_header entry; debug(2, "Deleting entry @ 0x%08x", addr); @@ -208,16 +251,28 @@ static inline sysparam_status_t delete_entry(uint32_t addr) { return SYSPARAM_OK; } -static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *key_id) { - uint32_t new_base = sysparam_info.alt_base; +/** Compact the current region, removing all deleted/unused entries, and write + * the result to the alternate region, then make the new alternate region the + * active one. + * + * @param key_id A pointer to the "current" key ID. + * + * NOTE: The value corresponding to the passed key ID will not be written to + * the output (because it is assumed it will be overwritten as the next step + * in `sysparam_set_data` anyway). When compacting, this routine will + * automatically update *key_id to contain the ID of this key in the new + * compacted result as well. + */ +static sysparam_status_t _compact_params(struct sysparam_context *ctx, uint8_t *key_id) { + uint32_t new_base = _sysparam_info.alt_base; sysparam_status_t status; uint32_t addr = new_base + REGION_HEADER_SIZE; uint8_t current_key_id = 0; sysparam_iter_t iter; uint8_t prev_len = 0; - debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", sysparam_info.end_addr - sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys[0] || ctx->unused_keys[1]) ? "+ (unused keys present)" : ""); - status = format_region(new_base); + debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys[0] || ctx->unused_keys[1]) ? "+ (unused keys present)" : ""); + status = _format_region(new_base); if (status < 0) return status; status = sysparam_iter_start(&iter); if (status < 0) return status; @@ -230,7 +285,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k // Write the key to the new region debug(2, "writing %d key @ 0x%08x", current_key_id, addr); - status = write_entry(addr, current_key_id, (uint8_t *)iter.key, iter.key_len, prev_len); + status = _write_entry(addr, current_key_id, (uint8_t *)iter.key, iter.key_len, prev_len); if (status < 0) break; prev_len = iter.key_len; addr += ENTRY_SIZE(iter.key_len); @@ -245,7 +300,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k // Copy the value to the new region debug(2, "writing %d value @ 0x%08x", current_key_id, addr); - status = write_entry(addr, current_key_id | 0x80, iter.value, iter.value_len, prev_len); + status = _write_entry(addr, current_key_id | 0x80, iter.value, iter.value_len, prev_len); if (status < 0) break; prev_len = iter.value_len; addr += ENTRY_SIZE(iter.value_len); @@ -253,7 +308,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k sysparam_iter_end(&iter); if (status >= 0) { - status = write_entry_tail(addr, prev_len); + status = _write_entry_tail(addr, prev_len); } // If we broke out with an error, return the error instead of continuing. @@ -263,14 +318,14 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k } // Switch to officially using the new region. - status = write_region_header(new_base, true); + status = _write_region_header(new_base, true); if (status < 0) return status; - status = write_region_header(sysparam_info.cur_base, false); + status = _write_region_header(_sysparam_info.cur_base, false); if (status < 0) return status; - sysparam_info.alt_base = sysparam_info.cur_base; - sysparam_info.cur_base = new_base; - sysparam_info.end_addr = addr; + _sysparam_info.alt_base = _sysparam_info.cur_base; + _sysparam_info.cur_base = new_base; + _sysparam_info.end_addr = addr; // Fix up ctx so it doesn't point to invalid stuff memset(ctx, 0, sizeof(*ctx)); @@ -278,38 +333,38 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k ctx->entry.prev_len = prev_len; ctx->max_key_id = current_key_id; - debug(1, "done compacting (current size %d)", sysparam_info.end_addr - sysparam_info.cur_base); + debug(1, "done compacting (current size %d)", _sysparam_info.end_addr - _sysparam_info.cur_base); return SYSPARAM_OK; } -/* Public Functions */ +/***************************** Public Functions ******************************/ sysparam_status_t sysparam_init(uint32_t base_addr) { sysparam_status_t status; uint32_t magic0, magic1; struct sysparam_context ctx; - sysparam_info.region_size = SYSPARAM_REGION_SECTORS * sdk_flashchip.sector_size; + _sysparam_info.region_size = SYSPARAM_REGION_SECTORS * sdk_flashchip.sector_size; // First, see if we can find an existing one. debug(3, "read magic @ 0x%08x", base_addr); CHECK_FLASH_OP(sdk_spi_flash_read(base_addr, &magic0, 4)); - debug(3, "read magic @ 0x%08x", base_addr + sysparam_info.region_size); - CHECK_FLASH_OP(sdk_spi_flash_read(base_addr + sysparam_info.region_size, &magic1, 4)); - if (magic0 == SYSPARAM_MAGIC && magic1 == SYSPARAM_STALEMAGIC) { + debug(3, "read magic @ 0x%08x", base_addr + _sysparam_info.region_size); + CHECK_FLASH_OP(sdk_spi_flash_read(base_addr + _sysparam_info.region_size, &magic1, 4)); + if (magic0 == SYSPARAM_ACTIVE_MAGIC && magic1 == SYSPARAM_STALE_MAGIC) { // Sysparam area found, first region is active - sysparam_info.cur_base = base_addr; - sysparam_info.alt_base = base_addr + sysparam_info.region_size; - } else if (magic0 == SYSPARAM_STALEMAGIC && magic1 == SYSPARAM_MAGIC) { + _sysparam_info.cur_base = base_addr; + _sysparam_info.alt_base = base_addr + _sysparam_info.region_size; + } else if (magic0 == SYSPARAM_STALE_MAGIC && magic1 == SYSPARAM_ACTIVE_MAGIC) { // Sysparam area found, second region is active - sysparam_info.cur_base = base_addr + sysparam_info.region_size; - sysparam_info.alt_base = base_addr; - } else if (magic0 == SYSPARAM_MAGIC && magic1 == SYSPARAM_MAGIC) { + _sysparam_info.cur_base = base_addr + _sysparam_info.region_size; + _sysparam_info.alt_base = base_addr; + } else if (magic0 == SYSPARAM_ACTIVE_MAGIC && magic1 == SYSPARAM_ACTIVE_MAGIC) { // Both regions are marked as active. Not sure which to use. // This can theoretically happen if something goes wrong at exactly the // wrong time during compacting. return SYSPARAM_ERR_CORRUPT; - } else if (magic0 == SYSPARAM_STALEMAGIC && magic1 == SYSPARAM_STALEMAGIC) { + } else if (magic0 == SYSPARAM_STALE_MAGIC && magic1 == SYSPARAM_STALE_MAGIC) { // Both regions are marked as inactive. This shouldn't ever happen. return SYSPARAM_ERR_CORRUPT; } else { @@ -318,17 +373,17 @@ sysparam_status_t sysparam_init(uint32_t base_addr) { } // Find the actual end - sysparam_info.end_addr = sysparam_info.cur_base + sysparam_info.region_size; - init_context(&ctx); - status = find_entry(&ctx, 0xff); + _sysparam_info.end_addr = _sysparam_info.cur_base + _sysparam_info.region_size; + _init_context(&ctx); + status = _find_entry(&ctx, 0xff); if (status < 0) { - sysparam_info.cur_base = 0; - sysparam_info.alt_base = 0; - sysparam_info.end_addr = 0; + _sysparam_info.cur_base = 0; + _sysparam_info.alt_base = 0; + _sysparam_info.end_addr = 0; return status; } if (status == SYSPARAM_OK) { - sysparam_info.end_addr = ctx.addr; + _sysparam_info.end_addr = ctx.addr; } return SYSPARAM_OK; @@ -356,21 +411,21 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, bool force) { } } - if (sysparam_info.cur_base == base_addr || sysparam_info.alt_base == base_addr) { + if (_sysparam_info.cur_base == base_addr || _sysparam_info.alt_base == base_addr) { // We're reformating the same region we're already using. // De-initialize everything to force the caller to do a clean // `sysparam_init()` afterwards. - memset(&sysparam_info, 0, sizeof(sysparam_info)); + memset(&_sysparam_info, 0, sizeof(_sysparam_info)); } - status = format_region(base_addr); + status = _format_region(base_addr); if (status < 0) return status; - status = format_region(base_addr + region_size); + status = _format_region(base_addr + region_size); if (status < 0) return status; - status = write_entry_tail(base_addr + REGION_HEADER_SIZE, 0); + status = _write_entry_tail(base_addr + REGION_HEADER_SIZE, 0); if (status < 0) return status; - status = write_region_header(base_addr + region_size, false); + status = _write_region_header(base_addr + region_size, false); if (status < 0) return status; - status = write_region_header(base_addr, true); + status = _write_region_header(base_addr, true); if (status < 0) return status; return SYSPARAM_OK; @@ -382,24 +437,24 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t * size_t key_len = strlen(key); uint8_t *buffer; - if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; + if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; buffer = malloc(key_len + 2); if (!buffer) return SYSPARAM_ERR_NOMEM; do { - init_context(&ctx); - status = find_key(&ctx, key, key_len, buffer); + _init_context(&ctx); + status = _find_key(&ctx, key, key_len, buffer); if (status != SYSPARAM_OK) break; // Find the associated value - status = find_entry(&ctx, ctx.entry.id | 0x80); + status = _find_entry(&ctx, ctx.entry.id | 0x80); if (status != SYSPARAM_OK) break; buffer = realloc(buffer, ctx.entry.len + 1); if (!buffer) { return SYSPARAM_ERR_NOMEM; } - status = read_payload(&ctx, buffer, ctx.entry.len); + status = _read_payload(&ctx, buffer, ctx.entry.len); if (status != SYSPARAM_OK) break; // Zero-terminate the result, just in case (doesn't hurt anything for @@ -413,7 +468,6 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t * } while (false); free(buffer); - *destptr = NULL; if (actual_length) *actual_length = 0; return status; } @@ -423,7 +477,7 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, siz sysparam_status_t status = SYSPARAM_OK; size_t key_len = strlen(key); - if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; + if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; // Supplied buffer must be at least as large as the key, or 2 bytes, // whichever is larger. @@ -431,12 +485,12 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, siz if (actual_length) *actual_length = 0; - init_context(&ctx); - status = find_key(&ctx, key, key_len, buffer); + _init_context(&ctx); + status = _find_key(&ctx, key, key_len, buffer); if (status != SYSPARAM_OK) return status; - status = find_entry(&ctx, ctx.entry.id | 0x80); + status = _find_entry(&ctx, ctx.entry.id | 0x80); if (status != SYSPARAM_OK) return status; - status = read_payload(&ctx, buffer, buffer_size); + status = _read_payload(&ctx, buffer, buffer_size); if (status != SYSPARAM_OK) return status; if (actual_length) *actual_length = ctx.entry.len; @@ -450,54 +504,59 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr) { } sysparam_status_t sysparam_get_int(const char *key, int32_t *result) { - char buffer[32]; - size_t len; + char *buffer; char *endptr; int32_t value; sysparam_status_t status; - status = sysparam_get_data_static(key, (uint8_t *)buffer, 12, &len); + status = sysparam_get_string(key, &buffer); if (status != SYSPARAM_OK) return status; - if (len > 31) return SYSPARAM_PARSEFAILED; - buffer[len] = 0; value = strtol(buffer, &endptr, 0); - if (*endptr) return SYSPARAM_PARSEFAILED; + if (*endptr) { + // There was extra crap at the end of the string. + free(buffer); + return SYSPARAM_PARSEFAILED; + } *result = value; + free(buffer); return SYSPARAM_OK; } sysparam_status_t sysparam_get_bool(const char *key, bool *result) { - char buffer[6]; - size_t len; + char *buffer; int i; sysparam_status_t status; - status = sysparam_get_data_static(key, (uint8_t *)buffer, 12, &len); + status = sysparam_get_string(key, &buffer); if (status != SYSPARAM_OK) return status; - if (len > 5) return SYSPARAM_PARSEFAILED; - buffer[len] = 0; - for (i = 0; i < len; i++) { - // Quick and dirty tolower(). Not perfect, but works for our purposes, - // and avoids needing to pull in additional libc modules. - if (buffer[i] >= 0x41) buffer[i] |= 0x20; - } - if (!strcmp(buffer, "t")) { - *result = true; - } else if (!strcmp(buffer, "f")) { - *result = false; - } else if (!strcmp(buffer, "true")) { - *result = true; - } else if (!strcmp(buffer, "false")) { - *result = false; - } else if (!strcmp(buffer, "0")) { - *result = true; - } else if (!strcmp(buffer, "1")) { - *result = false; - } else { - return SYSPARAM_PARSEFAILED; - } - return SYSPARAM_OK; + do { + for (i = 0; buffer[i]; i++) { + // Quick-and-dirty tolower(). Not perfect, but works for our + // purposes, and avoids needing to pull in additional libc stuff. + if (buffer[i] >= 0x41) buffer[i] |= 0x20; + } + if (!strcmp(buffer, "y") || + !strcmp(buffer, "yes") || + !strcmp(buffer, "t") || + !strcmp(buffer, "true") || + !strcmp(buffer, "1")) { + *result = true; + break; + } + if (!strcmp(buffer, "n") || + !strcmp(buffer, "no") || + !strcmp(buffer, "f") || + !strcmp(buffer, "false") || + !strcmp(buffer, "0")) { + *result = false; + break; + } + status = SYSPARAM_PARSEFAILED; + } while (0); + + free(buffer); + return status; } sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_t value_len) { @@ -512,7 +571,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ uint8_t key_id = 0; uint32_t old_value_addr = 0; - if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; + if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; if (!key_len) return SYSPARAM_ERR_BADVALUE; if (value_len > 0xff) return SYSPARAM_ERR_BADVALUE; @@ -525,7 +584,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ value = buffer; free_value = true; } - // Create a working buffer for `find_key` to use. + // Create a working buffer for `_find_key` to use. buffer = malloc(key_len); if (!buffer) { if (free_value) free((void *)value); @@ -533,12 +592,12 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ } do { - init_context(&ctx); - status = find_key(&ctx, key, key_len, buffer); + _init_context(&ctx); + status = _find_key(&ctx, key, key_len, buffer); if (status == SYSPARAM_OK) { // Key already exists, see if there's a current value. key_id = ctx.entry.id; - status = find_entry(&ctx, key_id | 0x80); + status = _find_entry(&ctx, key_id | 0x80); if (status == SYSPARAM_OK) { old_value_addr = ctx.addr; } @@ -553,7 +612,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ buffer = realloc(buffer, value_len); if (!buffer) return SYSPARAM_ERR_NOMEM; } - status = read_payload(&ctx, buffer, value_len); + status = _read_payload(&ctx, buffer, value_len); if (status == SYSPARAM_ERR_CORRUPT) { // If the CRC check failed, don't worry about it. We're // going to be deleting this entry anyway. @@ -575,7 +634,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ // Append new value to the end, but first make sure we have enough // space. - free_space = sysparam_info.cur_base + sysparam_info.region_size - sysparam_info.end_addr - 4; + free_space = _sysparam_info.cur_base + _sysparam_info.region_size - _sysparam_info.end_addr - 4; needed_space = ENTRY_SIZE(value_len); if (!key_id) { // We did not find a previous key entry matching this key. We @@ -587,10 +646,10 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ // Can we compact things? // First, scan all remaining entries up to the end so we can // get a reasonably accurate "compactable" reading. - find_entry(&ctx, 0xff); + _find_entry(&ctx, 0xff); if (needed_space <= free_space + ctx.compactable) { // We should be able to get enough space by compacting. - status = compact_params(&ctx, &key_id); + status = _compact_params(&ctx, &key_id); if (status < 0) break; old_value_addr = 0; } else if (ctx.unused_keys[0] || ctx.unused_keys[1]) { @@ -598,11 +657,11 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ // there are some keys that can be omitted too, but we // don't know exactly how much that will gain, so all we // can do is give it a try and see if it gives us enough. - status = compact_params(&ctx, &key_id); + status = _compact_params(&ctx, &key_id); if (status < 0) break; old_value_addr = 0; } - free_space = sysparam_info.cur_base + sysparam_info.region_size - sysparam_info.end_addr - 4; + free_space = _sysparam_info.cur_base + _sysparam_info.region_size - _sysparam_info.end_addr - 4; } if (needed_space > free_space) { // Nothing we can do here.. We're full. @@ -617,14 +676,14 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ if (!key_id) { // We need to write a key entry for a new key. - // If we didn't find the key, then we already know find_entry + // If we didn't find the key, then we already know _find_entry // has gone through the entire contents, and thus // ctx.max_key_id has the largest key_id found in the whole // region. key_id = ctx.max_key_id + 1; if (key_id > MAX_KEY_ID) { if (ctx.unused_keys[0] || ctx.unused_keys[1]) { - status = compact_params(&ctx, &key_id); + status = _compact_params(&ctx, &key_id); if (status < 0) break; old_value_addr = 0; } else { @@ -633,24 +692,24 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ break; } } - status = write_entry(write_ctx.addr, key_id, (uint8_t *)key, key_len, write_ctx.entry.prev_len); + status = _write_entry(write_ctx.addr, key_id, (uint8_t *)key, key_len, write_ctx.entry.prev_len); if (status < 0) break; write_ctx.addr += ENTRY_SIZE(key_len); write_ctx.entry.prev_len = key_len; } // Write new value - status = write_entry(write_ctx.addr, key_id | 0x80, value, value_len, write_ctx.entry.prev_len); + status = _write_entry(write_ctx.addr, key_id | 0x80, value, value_len, write_ctx.entry.prev_len); if (status < 0) break; write_ctx.addr += ENTRY_SIZE(value_len); - status = write_entry_tail(write_ctx.addr, value_len); + status = _write_entry_tail(write_ctx.addr, value_len); if (status < 0) break; - sysparam_info.end_addr = write_ctx.addr; + _sysparam_info.end_addr = write_ctx.addr; } // Delete old value (if present) by setting it's id to 0x00 if (old_value_addr) { - status = delete_entry(old_value_addr); + status = _delete_entry(old_value_addr); if (status < 0) break; } } while (false); @@ -675,12 +734,12 @@ sysparam_status_t sysparam_set_int(const char *key, int32_t value) { sysparam_status_t sysparam_set_bool(const char *key, bool value) { uint8_t buf[4] = {0xff, 0xff, 0xff, 0xff}; - buf[0] = value ? 't' : 'f'; + buf[0] = value ? 'y' : 'n'; return sysparam_set_data(key, buf, 1); } sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) { - if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; + if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; iter->bufsize = DEFAULT_ITER_BUF_SIZE; iter->key = malloc(iter->bufsize); @@ -696,7 +755,7 @@ sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) { iter->bufsize = 0; return SYSPARAM_ERR_NOMEM; } - init_context(iter->ctx); + _init_context(iter->ctx); return SYSPARAM_OK; } @@ -710,11 +769,11 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) { size_t key_space; while (true) { - status = find_key(ctx, NULL, 0, buffer); + status = _find_key(ctx, NULL, 0, buffer); if (status != SYSPARAM_OK) return status; memcpy(&value_ctx, ctx, sizeof(value_ctx)); - status = find_entry(&value_ctx, ctx->entry.id | 0x80); + status = _find_entry(&value_ctx, ctx->entry.id | 0x80); if (status < 0) return status; if (status == SYSPARAM_NOTFOUND) continue; @@ -729,14 +788,14 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) { iter->bufsize = required_len; } - status = read_payload(ctx, (uint8_t *)iter->key, iter->bufsize); + status = _read_payload(ctx, (uint8_t *)iter->key, iter->bufsize); if (status < 0) return status; // Null-terminate the key iter->key[ctx->entry.len] = 0; iter->key_len = ctx->entry.len; iter->value = (uint8_t *)(iter->key + key_space); - status = read_payload(&value_ctx, iter->value, iter->bufsize - key_space); + status = _read_payload(&value_ctx, iter->value, iter->bufsize - key_space); if (status < 0) return status; // Null-terminate the value (just in case) iter->value[value_ctx.entry.len] = 0;