diff --git a/core/include/sysparam.h b/core/include/sysparam.h index 130bd05..fcb9351 100644 --- a/core/include/sysparam.h +++ b/core/include/sysparam.h @@ -51,11 +51,12 @@ typedef enum { * sysparam_iter_end(). */ typedef struct { - char *key; + char *ns; + char *name; uint8_t *value; - size_t key_len; size_t value_len; bool binary; + uint8_t *buffer; size_t bufsize; struct sysparam_context *ctx; } sysparam_iter_t; @@ -178,7 +179,7 @@ sysparam_status_t sysparam_compact(); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary); +sysparam_status_t sysparam_get_data(const char *ns, const char *name, uint8_t **destptr, size_t *actual_length, bool *is_binary); /** Get the value associated with a key (static value buffer) * @@ -206,7 +207,7 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t * * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary); +sysparam_status_t sysparam_get_data_static(const char *ns, const char *name, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary); /** Get the string value associated with a key * @@ -233,7 +234,7 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_ * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_string(const char *key, char **destptr); +sysparam_status_t sysparam_get_string(const char *ns, const char *name, char **destptr); /** Get the int32_t value associated with a key * @@ -258,7 +259,7 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_int32(const char *key, int32_t *result); +sysparam_status_t sysparam_get_int32(const char *ns, const char *name, int32_t *result); /** Get the int8_t value associated with a key * @@ -283,7 +284,7 @@ sysparam_status_t sysparam_get_int32(const char *key, int32_t *result); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_int8(const char *key, int8_t *result); +sysparam_status_t sysparam_get_int8(const char *ns, const char *name, int8_t *result); /** Get the boolean value associated with a key * @@ -312,7 +313,7 @@ sysparam_status_t sysparam_get_int8(const char *key, int8_t *result); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_get_bool(const char *key, bool *result); +sysparam_status_t sysparam_get_bool(const char *ns, const char *name, bool *result); /** Set the value associated with a key * @@ -342,7 +343,7 @@ sysparam_status_t sysparam_get_bool(const char *key, bool *result); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_t value_len, bool binary); +sysparam_status_t sysparam_set_data(const char *ns, const char *name, const uint8_t *value, size_t value_len, bool binary); /** Set a key's value from a string * @@ -361,7 +362,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_set_string(const char *key, const char *value); +sysparam_status_t sysparam_set_string(const char *ns, const char *name, const char *value); /** Set a key's value as a number * @@ -380,7 +381,7 @@ sysparam_status_t sysparam_set_string(const char *key, const char *value); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_set_int32(const char *key, int32_t value); +sysparam_status_t sysparam_set_int32(const char *ns, const char *name, int32_t value); /** Set a key's value as a number * @@ -399,7 +400,7 @@ sysparam_status_t sysparam_set_int32(const char *key, int32_t value); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_set_int8(const char *key, int8_t value); +sysparam_status_t sysparam_set_int8(const char *ns, const char *name, int8_t value); /** Set a key's value as a boolean (yes/no) string * @@ -418,7 +419,7 @@ sysparam_status_t sysparam_set_int8(const char *key, int8_t value); * @retval ::SYSPARAM_ERR_CORRUPT Sysparam region has bad/corrupted data * @retval ::SYSPARAM_ERR_IO I/O error reading/writing flash */ -sysparam_status_t sysparam_set_bool(const char *key, bool value); +sysparam_status_t sysparam_set_bool(const char *ns, const char *name, bool value); /** Begin iterating through all key/value pairs * diff --git a/core/sysparam.c b/core/sysparam.c index 19e5ada..a1401c0 100644 --- a/core/sysparam.c +++ b/core/sysparam.c @@ -63,7 +63,7 @@ #define ENTRY_FLAG_ALIVE 0x8000 // Deleted (0) or active (1) #define ENTRY_FLAG_INVALID 0x4000 // Valid (0) or invalid (1) entry #define ENTRY_FLAG_VALUE 0x2000 // Key (0) or value (1) -#define ENTRY_FLAG_BINARY 0x1000 // Text (0) or binary (1) data +#define ENTRY_FLAG_BINARY 0x1000 // Value text (0) or binary (1) data #define ENTRY_MASK_ID 0xfff @@ -290,6 +290,46 @@ static inline sysparam_status_t _read_payload(struct sysparam_context *ctx, uint return SYSPARAM_OK; } +static inline sysparam_status_t _compare_key(struct sysparam_context *ctx, const char *ns, size_t ns_len, const char *name, size_t name_len) { + debug(3, "compare key (%u %u) @ 0x%08x", ns_len, name_len, ctx->addr); + size_t key_len = name_len; + if (ns) key_len += ns_len + 1; + if (ctx->entry.len != key_len) return SYSPARAM_NOTFOUND; + uint32_t bounce[BOUNCE_BUFFER_WORDS]; + uint32_t addr = ctx->addr + ENTRY_HEADER_SIZE; + + if (ns) { + for (int i = 0; i < ns_len; i += BOUNCE_BUFFER_SIZE) { + int len = min(ns_len - i, BOUNCE_BUFFER_SIZE); + CHECK_FLASH_OP(spiflash_read(addr, (void*)bounce, len)); + if (memcmp(ns + i, bounce, len)) { + // Mismatch. + return SYSPARAM_NOTFOUND; + } + addr += len; + } + + CHECK_FLASH_OP(spiflash_read(addr, (void*)bounce, 1)); + if (((char *)bounce)[0] != ':') { + // Mismatch. + return SYSPARAM_NOTFOUND; + } + addr++; + } + + for (int i = 0; i < name_len; i += BOUNCE_BUFFER_SIZE) { + int len = min(name_len - i, BOUNCE_BUFFER_SIZE); + CHECK_FLASH_OP(spiflash_read(addr, (void*)bounce, len)); + if (memcmp(name + i, bounce, len)) { + // Mismatch. + return SYSPARAM_NOTFOUND; + } + addr += len; + } + + return SYSPARAM_OK; +} + static inline sysparam_status_t _compare_payload(struct sysparam_context *ctx, uint8_t *value, size_t size) { debug(3, "compare payload (%d) @ 0x%08x", size, ctx->addr); if (ctx->entry.len != size) return SYSPARAM_NOTFOUND; @@ -307,31 +347,42 @@ static inline sysparam_status_t _compare_payload(struct sysparam_context *ctx, u return SYSPARAM_OK; } -/** Find the entry corresponding to the specified key name */ -static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key, uint16_t key_len) { +/** Find the entry corresponding to the specified key namespace and name. + * + * If the name is NULL then find the next key. + * + * The namespace and name length are passed as arguments as the caller can often + * hoist the search for their length. + */ +static sysparam_status_t _find_key(struct sysparam_context *ctx, + const char *ns, uint16_t ns_len, + const char *name, uint16_t name_len) { sysparam_status_t status; + size_t key_len = name_len; + if (ns) key_len += ns_len + 1; - debug(3, "find key len %d: %s", key_len, key ? key : "(null)"); + debug(3, "find key, ns '%s' len %u, name '%s' len %u", ns ? ns : "(null)", ns_len, name ? name : "(null)", name_len); while (true) { // Find the next key entry status = _find_entry(ctx, ENTRY_ID_ANY, false); if (status != SYSPARAM_OK) return status; debug(3, "found a key entry @ 0x%08x", ctx->addr); - if (!key) { + if (!name) { // We're looking for the next (any) key, so we're done. break; } if (ctx->entry.len == key_len) { - status = _compare_payload(ctx, (uint8_t *)key, key_len); + status = _compare_key(ctx, ns, ns_len, name, name_len); if (status == SYSPARAM_OK) { // We have a match break; } if (status != SYSPARAM_NOTFOUND) return status; debug(3, "entry payload does not match"); - } else { - debug(3, "key length (%d) does not match (%d)", ctx->entry.len, key_len); + continue; } + + debug(3, "key length (%d) does not match (%d)", ctx->entry.len, key_len); } debug(3, "key match @ 0x%08x (idflags = 0x%04x)", ctx->addr, ctx->entry.idflags); @@ -344,6 +395,71 @@ static inline sysparam_status_t _find_value(struct sysparam_context *ctx, uint16 return _find_entry(ctx, id_field & ENTRY_MASK_ID, true); } +/** Write a key entry at the specified address */ +static inline sysparam_status_t _write_key_entry(uint32_t addr, uint16_t id, const char *ns, const char *name) { + struct entry_header entry; + sysparam_status_t status; + size_t ns_len = ns ? strlen(ns) : 0; + size_t name_len = strlen(name); + size_t key_len = name_len; + if (ns) key_len += ns_len + 1; + + debug(2, "Writing key entry 0x%02x @ 0x%08x len 0x%x", id, addr, key_len); + entry.idflags = id | ENTRY_FLAG_ALIVE | ENTRY_FLAG_INVALID; + entry.len = key_len; + debug(3, "write initial entry header @ 0x%08x", addr); + status = _write_and_verify(addr, &entry, ENTRY_HEADER_SIZE); + if (status == SYSPARAM_ERR_IO) { + // Uh-oh.. Either the flash call failed in some way or we didn't get + // back what we wrote. This could be a problem because depending on + // how it went wrong it could screw up all reads/writes from this point + // forward. Try to salvage the on-flash structure by overwriting the + // failed header with all zeros, which (if successful) will be + // interpreted on later reads as a deleted empty-payload entry (and it + // will just skip to the next spot). + memset(&entry, 0, ENTRY_HEADER_SIZE); + debug(3, "zeroing entry header @ 0x%08x", addr); + status = _write_and_verify(addr, &entry, ENTRY_HEADER_SIZE); + if (status != SYSPARAM_OK) return status; + + // Make sure future writes skip past this zeroed bit + if (_sysparam_info.end_addr == addr) { + _sysparam_info.end_addr += ENTRY_HEADER_SIZE; + } + // We could just skip to the next space and try again, but + // unfortunately now we can't be sure there's enough space remaining to + // fit the entry, so we just have to fail this operation. Hopefully, + // at least, future requests will still succeed, though. + status = SYSPARAM_ERR_IO; + } + if (status != SYSPARAM_OK) return status; + + // If we've gotten this far, we've committed to writing the full entry. + if (_sysparam_info.end_addr == addr) { + _sysparam_info.end_addr += ENTRY_SIZE(key_len); + } + size_t offset = ENTRY_HEADER_SIZE; + if (ns) { + debug(3, "write key ns (%d) @ 0x%08x", ns_len, addr + offset); + status = _write_and_verify(addr + offset, ns, ns_len); + if (status != SYSPARAM_OK) return status; + offset += ns_len; + char separator = ':'; + status = _write_and_verify(addr + offset, &separator, 1); + if (status != SYSPARAM_OK) return status; + offset += 1; + } + debug(3, "write key name (%d) @ 0x%08x", name_len, addr + offset); + status = _write_and_verify(addr + offset, name, name_len); + if (status != SYSPARAM_OK) return status; + + debug(3, "set entry valid @ 0x%08x", addr); + entry.idflags &= ~ENTRY_FLAG_INVALID; + status = _write_and_verify(addr, &entry, ENTRY_HEADER_SIZE); + + return status; +} + /** Write an entry at the specified address */ static inline sysparam_status_t _write_entry(uint32_t addr, uint16_t id, const uint8_t *payload, uint16_t len) { struct entry_header entry; @@ -446,9 +562,11 @@ static sysparam_status_t _compact_params(struct sysparam_context *ctx, int *key_ // 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); + status = _write_key_entry(addr, current_key_id, iter.ns, iter.name); if (status < 0) break; - addr += ENTRY_SIZE(iter.key_len); + size_t key_len = strlen(iter.name); + if (iter.ns) key_len += strlen(iter.ns) + 1; + addr += ENTRY_SIZE(key_len); if (key_id && (iter.ctx->entry.idflags & ENTRY_MASK_ID) == *key_id) { // Update key_id to have the correct id for the compacted result @@ -658,10 +776,11 @@ sysparam_status_t sysparam_compact() { return status; } -sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *actual_length, bool *is_binary) { +sysparam_status_t sysparam_get_data(const char *ns, const char *name, uint8_t **destptr, size_t *actual_length, bool *is_binary) { struct sysparam_context ctx; sysparam_status_t status; - size_t key_len = strlen(key); + size_t ns_len = ns ? strlen(ns) : 0; + size_t name_len = strlen(name); uint8_t *buffer; xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY); @@ -674,7 +793,7 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t * } _init_context(&ctx); - status = _find_key(&ctx, key, key_len); + status = _find_key(&ctx, ns, ns_len, name, name_len); if (status != SYSPARAM_OK) goto done; // Find the associated value @@ -708,10 +827,11 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t * return status; } -sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary) { +sysparam_status_t sysparam_get_data_static(const char *ns, const char *name, uint8_t *dest, size_t dest_size, size_t *actual_length, bool *is_binary) { struct sysparam_context ctx; sysparam_status_t status = SYSPARAM_OK; - size_t key_len = strlen(key); + size_t ns_len = ns ? strlen(ns) : 0; + size_t name_len = strlen(name); xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY); @@ -723,7 +843,7 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_ } _init_context(&ctx); - status = _find_key(&ctx, key, key_len); + status = _find_key(&ctx, ns, ns_len, name, name_len); if (status != SYSPARAM_OK) goto done; status = _find_value(&ctx, ctx.entry.idflags); if (status != SYSPARAM_OK) goto done; @@ -738,12 +858,12 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *dest, size_ return status; } -sysparam_status_t sysparam_get_string(const char *key, char **destptr) { +sysparam_status_t sysparam_get_string(const char *ns, const char *name, char **destptr) { bool is_binary; sysparam_status_t status; uint8_t *buf; - status = sysparam_get_data(key, &buf, NULL, &is_binary); + status = sysparam_get_data(ns, name, &buf, NULL, &is_binary); if (status != SYSPARAM_OK) return status; if (is_binary) { // Value was saved as binary data, which means we shouldn't try to @@ -757,13 +877,13 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr) { return SYSPARAM_OK; } -sysparam_status_t sysparam_get_int32(const char *key, int32_t *result) { +sysparam_status_t sysparam_get_int32(const char *ns, const char *name, int32_t *result) { int32_t value; size_t actual_length; bool is_binary; sysparam_status_t status; - status = sysparam_get_data_static(key, (uint8_t *)&value, sizeof(int32_t), + status = sysparam_get_data_static(ns, name, (uint8_t *)&value, sizeof(int32_t), &actual_length, &is_binary); if (status != SYSPARAM_OK) return status; if (!is_binary || actual_length != sizeof(int32_t)) @@ -772,13 +892,13 @@ sysparam_status_t sysparam_get_int32(const char *key, int32_t *result) { return status; } -sysparam_status_t sysparam_get_int8(const char *key, int8_t *result) { +sysparam_status_t sysparam_get_int8(const char *ns, const char *name, int8_t *result) { int8_t value; size_t actual_length; bool is_binary; sysparam_status_t status; - status = sysparam_get_data_static(key, (uint8_t *)&value, sizeof(int8_t), + status = sysparam_get_data_static(ns, name, (uint8_t *)&value, sizeof(int8_t), &actual_length, &is_binary); if (status != SYSPARAM_OK) return status; if (!is_binary || actual_length != sizeof(int8_t)) @@ -787,14 +907,14 @@ sysparam_status_t sysparam_get_int8(const char *key, int8_t *result) { return status; } -sysparam_status_t sysparam_get_bool(const char *key, bool *result) { +sysparam_status_t sysparam_get_bool(const char *ns, const char *name, bool *result) { const size_t buf_size = 8; char buf[buf_size + 1]; // extra byte for zero termination size_t data_len = 0; bool binary = false; sysparam_status_t status; - status = sysparam_get_data_static(key, (uint8_t*)buf, + status = sysparam_get_data_static(ns, name, (uint8_t*)buf, buf_size, &data_len, &binary); if (status != SYSPARAM_OK) return status; @@ -837,24 +957,27 @@ sysparam_status_t sysparam_get_bool(const char *key, bool *result) { return status; } -sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_t value_len, bool is_binary) { +sysparam_status_t sysparam_set_data(const char *ns, const char *name, const uint8_t *value, size_t value_len, bool is_binary) { struct sysparam_context ctx; struct sysparam_context write_ctx; sysparam_status_t status = SYSPARAM_OK; - uint16_t key_len = strlen(key); + size_t ns_len = ns ? strlen(ns) : 0; + size_t name_len = strlen(name); size_t free_space; size_t needed_space; int key_id = -1; uint32_t old_value_addr = 0; uint16_t binary_flag; - if (!key_len) return SYSPARAM_ERR_BADVALUE; + if (!name_len) return SYSPARAM_ERR_BADVALUE; + size_t key_len = name_len; + if (ns) key_len += ns_len + 1; if (key_len > MAX_KEY_LEN) return SYSPARAM_ERR_BADVALUE; if (value_len > MAX_VALUE_LEN) return SYSPARAM_ERR_BADVALUE; if (!value) value_len = 0; - debug(1, "updating value for '%s' (%d bytes)", key, value_len); + debug(1, "updating value for '%s' : '%s' (%d bytes)", ns ? ns : "(null)", name, value_len); xSemaphoreTake(_sysparam_info.sem, portMAX_DELAY); @@ -865,7 +988,7 @@ 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); + status = _find_key(&ctx, ns, ns_len, name, name_len); if (status == SYSPARAM_OK) { // Key already exists, see if there's a current value. key_id = ctx.entry.idflags & ENTRY_MASK_ID; @@ -905,8 +1028,8 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ needed_space = ENTRY_SIZE(value_len); if (key_id < 0) { // We did not find a previous key entry matching this key. We - // will need to add a key entry as well. - key_len = strlen(key); + // will need to add a key entry as well. Assume a ns might + // also need to be added, but could actually check that. needed_space += ENTRY_SIZE(key_len); } if (needed_space > free_space) { @@ -971,7 +1094,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ if (key_id < 0) { // Write a new key entry key_id = ctx.max_key_id + 1; - status = _write_entry(write_ctx.addr, key_id, (uint8_t *)key, key_len); + status = _write_key_entry(write_ctx.addr, key_id, ns, name); if (status < 0) break; write_ctx.addr += ENTRY_SIZE(key_len); } @@ -998,46 +1121,45 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_ return status; } -sysparam_status_t sysparam_set_string(const char *key, const char *value) { - return sysparam_set_data(key, (const uint8_t *)value, strlen(value), false); +sysparam_status_t sysparam_set_string(const char *ns, const char *name, const char *value) { + return sysparam_set_data(ns, name, (const uint8_t *)value, strlen(value), false); } -sysparam_status_t sysparam_set_int32(const char *key, int32_t value) { - return sysparam_set_data(key, (const uint8_t *)&value, sizeof(value), true); +sysparam_status_t sysparam_set_int32(const char *ns, const char *name, int32_t value) { + return sysparam_set_data(ns, name, (const uint8_t *)&value, sizeof(value), true); } -sysparam_status_t sysparam_set_int8(const char *key, int8_t value) { - return sysparam_set_data(key, (const uint8_t *)&value, sizeof(value), true); +sysparam_status_t sysparam_set_int8(const char *ns, const char *name, int8_t value) { + return sysparam_set_data(ns, name, (const uint8_t *)&value, sizeof(value), true); } -sysparam_status_t sysparam_set_bool(const char *key, bool value) { +sysparam_status_t sysparam_set_bool(const char *ns, const char *name, bool value) { uint8_t buf[4] = {0xff, 0xff, 0xff, 0xff}; bool old_value; // Don't write anything if the current setting already evaluates to the // same thing. - if (sysparam_get_bool(key, &old_value) == SYSPARAM_OK) { + if (sysparam_get_bool(ns, name, &old_value) == SYSPARAM_OK) { if (old_value == value) return SYSPARAM_OK; } buf[0] = value ? 'y' : 'n'; - return sysparam_set_data(key, buf, 1, false); + return sysparam_set_data(ns, name, buf, 1, false); } sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) { if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT; iter->bufsize = DEFAULT_ITER_BUF_SIZE; - iter->key = malloc(iter->bufsize); - if (!iter->key) { + iter->buffer = malloc(iter->bufsize); + if (!iter->buffer) { iter->bufsize = 0; return SYSPARAM_ERR_NOMEM; } - iter->key_len = 0; iter->value_len = 0; iter->ctx = malloc(sizeof(struct sysparam_context)); if (!iter->ctx) { - free(iter->key); + free(iter->buffer); iter->bufsize = 0; return SYSPARAM_ERR_NOMEM; } @@ -1051,11 +1173,11 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) { size_t required_len; struct sysparam_context *ctx = iter->ctx; struct sysparam_context value_ctx; - size_t key_space; - char *newbuf; + size_t key_len, value_len; + uint8_t *newbuf; while (true) { - status = _find_key(ctx, NULL, 0); + status = _find_key(ctx, NULL, 0, NULL, 0); if (status != SYSPARAM_OK) return status; memcpy(&value_ctx, ctx, sizeof(value_ctx)); @@ -1063,35 +1185,47 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) { if (status < 0) return status; if (status == SYSPARAM_NOTFOUND) continue; - key_space = ctx->entry.len + 1; - required_len = key_space + value_ctx.entry.len + 1; + key_len = ctx->entry.len; + value_len = value_ctx.entry.len; + // Add one null byte to the value, in case of a string. + required_len = key_len + 1 + value_len + 1; if (required_len > iter->bufsize) { - newbuf = realloc(iter->key, required_len); + newbuf = realloc(iter->buffer, required_len); if (!newbuf) { return SYSPARAM_ERR_NOMEM; } - iter->key = newbuf; + iter->buffer = newbuf; iter->bufsize = required_len; } - status = _read_payload(ctx, (uint8_t *)iter->key, iter->bufsize); + status = _read_payload(ctx, iter->buffer, 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); + // Null-terminate the key name + iter->buffer[key_len] = 0; + // Find the name space separator. + char *ns_end = strchr((char *)iter->buffer, ':'); + if (ns_end) { + // Null-terminate the namespace. + *ns_end = 0; + iter->ns = (char *)iter->buffer; + iter->name = ns_end + 1; + } else { + // No namespace. + iter->ns = NULL; + iter->name = (char *)iter->buffer; + } + iter->value = (uint8_t *)(iter->buffer + key_len + 1); + status = _read_payload(&value_ctx, iter->value, iter->bufsize - key_len - 1 - 1); if (status < 0) return status; // Null-terminate the value (just in case) - iter->value[value_ctx.entry.len] = 0; - iter->value_len = value_ctx.entry.len; + iter->value[value_len] = 0; + iter->value_len = value_len; if (value_ctx.entry.idflags & ENTRY_FLAG_BINARY) { iter->binary = true; - debug(2, "iter_next: (0x%08x) '%s' = (0x%08x) (%d)", ctx->addr, iter->key, value_ctx.addr, iter->value_len); + debug(2, "iter_next: (0x%08x) '%s' : '%s' = (0x%08x) (%d)", ctx->addr, iter->ns ? iter->ns : "(null)", iter->name, value_ctx.addr, value_len); } else { iter->binary = false; - debug(2, "iter_next: (0x%08x) '%s' = (0x%08x) '%s' (%d)", ctx->addr, iter->key, value_ctx.addr, iter->value, iter->value_len); + debug(2, "iter_next: (0x%08x) '%s' : '%s' = (0x%08x) '%s' (%d)", ctx->addr, iter->ns ? iter->ns : "(null)", iter->name, value_ctx.addr, iter->value, value_len); } return SYSPARAM_OK; @@ -1099,7 +1233,7 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) { } void sysparam_iter_end(sysparam_iter_t *iter) { - if (iter->key) free(iter->key); + if (iter->buffer) free(iter->buffer); if (iter->ctx) free(iter->ctx); } diff --git a/examples/sysparam_editor/sysparam_editor.c b/examples/sysparam_editor/sysparam_editor.c index df31593..1ec80cb 100644 --- a/examples/sysparam_editor/sysparam_editor.c +++ b/examples/sysparam_editor/sysparam_editor.c @@ -29,7 +29,7 @@ void usage(void) { "Available commands:\n" " ? -- Query the value of \n" " = -- Set to text \n" - " : -- Set to binary value represented as hex\n" + " %% -- Set to binary value represented as hex\n" " dump -- Show all currently set keys/values\n" " compact -- Compact the sysparam area\n" " reformat -- Reinitialize (clear) the sysparam area\n" @@ -76,14 +76,39 @@ size_t tty_readline(char *buffer, size_t buf_size, bool echo) { return i; } -void print_text_value(char *key, char *value) { - printf(" '%s' = '%s'\n", key, value); +static void parse_key(char *buffer, char **ns, char **name) { + char *ns_end = strchr(buffer, ':'); + if (ns_end) { + *ns_end = 0; + *ns = buffer; + *name = ns_end + 1; + } else { + *ns = NULL; + *name = buffer; + } } -void print_binary_value(char *key, uint8_t *value, size_t len) { +static void print_key(const char *ns, const char *name) { + if (ns) { + printf("%s:%s", ns, name); + } else { + printf("%s", name); + } +} + +void print_text_value(const char *ns, const char *name, char *value) { + printf(" '"); + print_key(ns, name); + printf("' = '%s'\n", value); +} + +void print_binary_value(const char *ns, const char *name, uint8_t *value, size_t len) { size_t i; - printf(" %s:", key); + printf(" '"); + print_key(ns, name); + printf("' = "); + for (i = 0; i < len; i++) { if (!(i & 0x0f)) { printf("\n "); @@ -103,9 +128,9 @@ sysparam_status_t dump_params(void) { status = sysparam_iter_next(&iter); if (status != SYSPARAM_OK) break; if (!iter.binary) { - print_text_value(iter.key, (char *)iter.value); + print_text_value(iter.ns, iter.name, (char *)iter.value); } else { - print_binary_value(iter.key, iter.value, iter.value_len); + print_binary_value(iter.ns, iter.name, iter.value, iter.value_len); } } sysparam_iter_end(&iter); @@ -192,29 +217,41 @@ void sysparam_editor_task(void *pvParameters) { if (!len) continue; if (cmd_buffer[len - 1] == '?') { cmd_buffer[len - 1] = 0; - printf("Querying '%s'...\n", cmd_buffer); - status = sysparam_get_string(cmd_buffer, &value); + char *ns, *name; + parse_key(cmd_buffer, &ns, &name); + printf("Querying '"); + print_key(ns, name); + printf("'...\n"); + status = sysparam_get_string(ns, name, &value); if (status == SYSPARAM_OK) { - print_text_value(cmd_buffer, value); + print_text_value(ns, name, value); free(value); } else if (status == SYSPARAM_PARSEFAILED) { // This means it's actually a binary value - status = sysparam_get_data(cmd_buffer, &bin_value, &len, NULL); + status = sysparam_get_data(ns, name, &bin_value, &len, NULL); if (status == SYSPARAM_OK) { - print_binary_value(cmd_buffer, bin_value, len); - free(value); + print_binary_value(ns, name, bin_value, len); + free(bin_value); } } } else if ((value = strchr(cmd_buffer, '='))) { *value++ = 0; - printf("Setting '%s' to '%s'...\n", cmd_buffer, value); - status = sysparam_set_string(cmd_buffer, value); - } else if ((value = strchr(cmd_buffer, ':'))) { + char *ns, *name; + parse_key(cmd_buffer, &ns, &name); + printf("Setting '"); + print_key(ns, name); + printf("' to '%s'...\n", value); + status = sysparam_set_string(ns, name, value); + } else if ((value = strchr(cmd_buffer, '%'))) { *value++ = 0; + char *ns, *name; + parse_key(cmd_buffer, &ns, &name); data = parse_hexdata(value, &len); if (value) { - printf("Setting '%s' to binary data...\n", cmd_buffer); - status = sysparam_set_data(cmd_buffer, data, len, true); + printf("Setting '"); + print_key(ns, name); + printf("' to binary data...\n"); + status = sysparam_set_data(ns, name, data, len, true); free(data); } else { printf("Error: Unable to parse hex data\n"); diff --git a/examples/wificfg/wificfg.c b/examples/wificfg/wificfg.c index 33e70c0..fd3ccd3 100644 --- a/examples/wificfg/wificfg.c +++ b/examples/wificfg/wificfg.c @@ -32,8 +32,6 @@ #include "wificfg/wificfg.h" -#include "sysparam.h" - static const char http_success_header[] = "HTTP/1.1 200 \r\n" "Content-Type: text/html; charset=utf-8\r\n" "Cache-Control: no-store\r\n" diff --git a/extras/wificfg/wificfg.c b/extras/wificfg/wificfg.c index 1e4c5d2..2ac2a3e 100644 --- a/extras/wificfg/wificfg.c +++ b/extras/wificfg/wificfg.c @@ -170,7 +170,7 @@ void wificfg_form_url_decode(char *string) } /* HTML escaping. */ -void wificfg_html_escape(char *string, char *buf, size_t len) +void wificfg_html_escape(const char *string, char *buf, size_t len) { size_t i; size_t out = 0; @@ -578,9 +578,9 @@ int wificfg_write_html_title(int s, char *buf, size_t len, const char *str) { /* Use the hostname or AP SSID as the title prefix. */ char *hostname = NULL; - sysparam_get_string("hostname", &hostname); + sysparam_get_string("wificfg", "hostname", &hostname); if (!hostname) { - sysparam_get_string("wifi_ap_ssid", &hostname); + sysparam_get_string("wificfg", "ap_ssid", &hostname); } if (hostname) { wificfg_html_escape(hostname, buf, len); @@ -612,7 +612,7 @@ static int handle_wificfg_index(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wificfg_content[1], buf, len) < 0) return -1; char *hostname = NULL; - sysparam_get_string("hostname", &hostname); + sysparam_get_string("wificfg", "hostname", &hostname); if (hostname) { if (wificfg_write_string_chunk(s, "
Hostname
", buf, len) < 0) { free(hostname); @@ -810,7 +810,7 @@ static int handle_wificfg_index(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wificfg_content[2], buf, len) < 0) return -1; char *password = NULL; - sysparam_get_string("cfg_password", &password); + sysparam_get_string("wificfg", "cfg_password", &password); if (password) { wificfg_html_escape(password, buf, len); free(password); @@ -861,11 +861,11 @@ static int handle_wificfg_index_post(int s, wificfg_method method, switch (name) { case FORM_NAME_CFG_ENABLE: { uint8_t enable = strtoul(buf, NULL, 10) != 0; - sysparam_set_int8("cfg_enable", enable); + sysparam_set_int8("wificfg", "cfg_enable", enable); break; } case FORM_NAME_CFG_PASSWORD: - sysparam_set_string("cfg_password", buf); + sysparam_set_string("wificfg", "cfg_password", buf); break; default: break; @@ -893,18 +893,18 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[1], buf, len) < 0) return -1; int8_t wifi_sta_enable = 1; - sysparam_get_int8("wifi_sta_enable", &wifi_sta_enable); + sysparam_get_int8("wificfg", "sta_enable", &wifi_sta_enable); if (wifi_sta_enable && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_station_content[2], buf, len) < 0) return -1; int8_t wifi_sta_disabled_restarts = 0; - sysparam_get_int8("wifi_sta_disabled_restarts", &wifi_sta_disabled_restarts); + sysparam_get_int8("wificfg", "sta_dis_restart", &wifi_sta_disabled_restarts); snprintf(buf, len, "%u", wifi_sta_disabled_restarts); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_station_content[3], buf, len) < 0) return -1; char *wifi_sta_ssid = NULL; - sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid); + sysparam_get_string("wificfg", "sta_ssid", &wifi_sta_ssid); if (wifi_sta_ssid) { wificfg_html_escape(wifi_sta_ssid, buf, len); free(wifi_sta_ssid); @@ -914,7 +914,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[4], buf, len) < 0) return -1; char *wifi_sta_password = NULL; - sysparam_get_string("wifi_sta_password", &wifi_sta_password); + sysparam_get_string("wificfg", "sta_password", &wifi_sta_password); if (wifi_sta_password) { wificfg_html_escape(wifi_sta_password, buf, len); free(wifi_sta_password); @@ -924,7 +924,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[5], buf, len) < 0) return -1; char *hostname = NULL; - sysparam_get_string("hostname", &hostname); + sysparam_get_string("wificfg", "hostname", &hostname); if (hostname) { wificfg_html_escape(hostname, buf, len); free(hostname); @@ -934,7 +934,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[6], buf, len) < 0) return -1; int8_t wifi_sta_dhcp = 1; - sysparam_get_int8("wifi_sta_dhcp", &wifi_sta_dhcp); + sysparam_get_int8("wificfg", "sta_dhcp", &wifi_sta_dhcp); if (wifi_sta_dhcp && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_station_content[7], buf, len) < 0) return -1; if (!wifi_sta_dhcp && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; @@ -942,7 +942,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[8], buf, len) < 0) return -1; char *wifi_sta_ip_addr = NULL; - sysparam_get_string("wifi_sta_ip_addr", &wifi_sta_ip_addr); + sysparam_get_string("wificfg", "sta_ip_addr", &wifi_sta_ip_addr); if (wifi_sta_ip_addr) { wificfg_html_escape(wifi_sta_ip_addr, buf, len); free(wifi_sta_ip_addr); @@ -952,7 +952,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[9], buf, len) < 0) return -1; char *wifi_sta_netmask = NULL; - sysparam_get_string("wifi_sta_netmask", &wifi_sta_netmask); + sysparam_get_string("wificfg", "sta_netmask", &wifi_sta_netmask); if (wifi_sta_netmask) { wificfg_html_escape(wifi_sta_netmask, buf, len); free(wifi_sta_netmask); @@ -962,7 +962,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[10], buf, len) < 0) return -1; char *wifi_sta_gateway = NULL; - sysparam_get_string("wifi_sta_gateway", &wifi_sta_gateway); + sysparam_get_string("wificfg", "sta_gateway", &wifi_sta_gateway); if (wifi_sta_gateway) { wificfg_html_escape(wifi_sta_gateway, buf, len); free(wifi_sta_gateway); @@ -972,7 +972,7 @@ static int handle_wifi_station(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_station_content[11], buf, len) < 0) return -1; int8_t wifi_sta_mdns = 1; - sysparam_get_int8("wifi_sta_mdns", &wifi_sta_mdns); + sysparam_get_int8("wificfg", "sta_mdns", &wifi_sta_mdns); if (wifi_sta_mdns && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_station_content[12], buf, len) < 0) return -1; @@ -1028,32 +1028,33 @@ static int handle_wifi_station_post(int s, wificfg_method method, } case FORM_NAME_STA_DISABLED_RESTARTS: { uint32_t restarts = strtoul(buf, NULL, 10); - if (restarts <= 255) - sysparam_set_int8("wifi_sta_disabled_restarts", restarts); + if (restarts <= 255) { + sysparam_set_int8("wificfg", "sta_dis_restart", restarts); + } break; } case FORM_NAME_STA_SSID: - sysparam_set_string("wifi_sta_ssid", buf); + sysparam_set_string("wificfg", "sta_ssid", buf); break; case FORM_NAME_STA_PASSWORD: - sysparam_set_string("wifi_sta_password", buf); + sysparam_set_string("wificfg", "sta_password", buf); break; case FORM_NAME_HOSTNAME: - sysparam_set_string("hostname", buf); + sysparam_set_string("wificfg", "hostname", buf); break; case FORM_NAME_STA_DHCP: { uint8_t enable = strtoul(buf, NULL, 10) != 0; - sysparam_set_int8("wifi_sta_dhcp", enable); + sysparam_set_int8("wificfg", "sta_dhcp", enable); break; } case FORM_NAME_STA_IP_ADDR: - sysparam_set_string("wifi_sta_ip_addr", buf); + sysparam_set_string("wificfg", "sta_ip_addr", buf); break; case FORM_NAME_STA_NETMASK: - sysparam_set_string("wifi_sta_netmask", buf); + sysparam_set_string("wificfg", "sta_netmask", buf); break; case FORM_NAME_STA_GATEWAY: - sysparam_set_string("wifi_sta_gateway", buf); + sysparam_set_string("wificfg", "sta_gateway", buf); break; case FORM_NAME_STA_MDNS: { mdns_enable = strtoul(buf, NULL, 10) != 0; @@ -1069,8 +1070,8 @@ static int handle_wifi_station_post(int s, wificfg_method method, } if (done) { - sysparam_set_int8("wifi_sta_enable", sta_enable); - sysparam_set_int8("wifi_sta_mdns", mdns_enable); + sysparam_set_int8("wificfg", "sta_enable", sta_enable); + sysparam_set_int8("wificfg", "sta_mdns", mdns_enable); } return wificfg_write_string(s, http_redirect_header); @@ -1093,26 +1094,26 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[1], buf, len) < 0) return -1; int8_t wifi_ap_enable = 1; - sysparam_get_int8("wifi_ap_enable", &wifi_ap_enable); + sysparam_get_int8("wificfg", "ap_enable", &wifi_ap_enable); if (wifi_ap_enable && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[2], buf, len) < 0) return -1; int8_t wifi_ap_disable_if_sta = 1; - sysparam_get_int8("wifi_ap_disable_if_sta", &wifi_ap_disable_if_sta); + sysparam_get_int8("wificfg", "ap_dis_if_sta", &wifi_ap_disable_if_sta); if (wifi_ap_disable_if_sta && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[3], buf, len) < 0) return -1; int8_t wifi_ap_disabled_restarts = 0; - sysparam_get_int8("wifi_ap_disabled_restarts", &wifi_ap_disabled_restarts); + sysparam_get_int8("wificfg", "ap_dis_restart", &wifi_ap_disabled_restarts); snprintf(buf, len, "%u", wifi_ap_disabled_restarts); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[4], buf, len) < 0) return -1; char *wifi_ap_ssid = NULL; - sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); + sysparam_get_string("wificfg", "ap_ssid", &wifi_ap_ssid); if (wifi_ap_ssid) { wificfg_html_escape(wifi_ap_ssid, buf, len); free(wifi_ap_ssid); @@ -1122,7 +1123,7 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[5], buf, len) < 0) return -1; char *wifi_ap_password = NULL; - sysparam_get_string("wifi_ap_password", &wifi_ap_password); + sysparam_get_string("wificfg", "ap_password", &wifi_ap_password); if (wifi_ap_password) { wificfg_html_escape(wifi_ap_password, buf, len); free(wifi_ap_password); @@ -1132,20 +1133,20 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[6], buf, len) < 0) return -1; int8_t wifi_ap_ssid_hidden = 0; - sysparam_get_int8("wifi_ap_ssid_hidden", &wifi_ap_ssid_hidden); + sysparam_get_int8("wificfg", "ap_ssid_hidden", &wifi_ap_ssid_hidden); if (wifi_ap_ssid_hidden && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[7], buf, len) < 0) return -1; int8_t wifi_ap_channel = 6; - sysparam_get_int8("wifi_ap_channel", &wifi_ap_channel); + sysparam_get_int8("wificfg", "ap_channel", &wifi_ap_channel); snprintf(buf, len, "%u", wifi_ap_channel); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[8], buf, len) < 0) return -1; int8_t wifi_ap_authmode = AUTH_WPA_WPA2_PSK; - sysparam_get_int8("wifi_ap_authmode", &wifi_ap_authmode); + sysparam_get_int8("wificfg", "ap_authmode", &wifi_ap_authmode); if (wifi_ap_authmode == AUTH_OPEN && wificfg_write_string_chunk(s, " selected", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[9], buf, len) < 0) return -1; if (wifi_ap_authmode == AUTH_WPA_PSK && wificfg_write_string_chunk(s, " selected", buf, len) < 0) return -1; @@ -1157,21 +1158,21 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[12], buf, len) < 0) return -1; int8_t wifi_ap_max_conn = 3; - sysparam_get_int8("wifi_ap_max_conn", &wifi_ap_max_conn); + sysparam_get_int8("wificfg", "ap_max_conn", &wifi_ap_max_conn); snprintf(buf, len, "%u", wifi_ap_max_conn); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[13], buf, len) < 0) return -1; int32_t wifi_ap_beacon_interval = 100; - sysparam_get_int32("wifi_ap_beacon_interval", &wifi_ap_beacon_interval); + sysparam_get_int32("wificfg", "ap_bcn_interval", &wifi_ap_beacon_interval); snprintf(buf, len, "%u", wifi_ap_beacon_interval); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[14], buf, len) < 0) return -1; char *wifi_ap_ip_addr = NULL; - sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); + sysparam_get_string("wificfg", "ap_ip_addr", &wifi_ap_ip_addr); if (wifi_ap_ip_addr) { wificfg_html_escape(wifi_ap_ip_addr, buf, len); free(wifi_ap_ip_addr); @@ -1181,7 +1182,7 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[15], buf, len) < 0) return -1; char *wifi_ap_netmask = NULL; - sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); + sysparam_get_string("wificfg", "ap_netmask", &wifi_ap_netmask); if (wifi_ap_netmask) { wificfg_html_escape(wifi_ap_netmask, buf, len); free(wifi_ap_netmask); @@ -1191,20 +1192,20 @@ static int handle_wifi_ap(int s, wificfg_method method, if (wificfg_write_string_chunk(s, http_wifi_ap_content[16], buf, len) < 0) return -1; int8_t wifi_ap_dhcp_leases = 4; - sysparam_get_int8("wifi_ap_dhcp_leases", &wifi_ap_dhcp_leases); + sysparam_get_int8("wificfg", "ap_dhcp_leases", &wifi_ap_dhcp_leases); snprintf(buf, len, "%u", wifi_ap_dhcp_leases); if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[17], buf, len) < 0) return -1; int8_t wifi_ap_dns = 1; - sysparam_get_int8("wifi_ap_dns", &wifi_ap_dns); + sysparam_get_int8("wificfg", "ap_dns", &wifi_ap_dns); if (wifi_ap_dns && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[18], buf, len) < 0) return -1; int8_t wifi_ap_mdns = 1; - sysparam_get_int8("wifi_ap_mdns", &wifi_ap_mdns); + sysparam_get_int8("wificfg", "ap_mdns", &wifi_ap_mdns); if (wifi_ap_mdns && wificfg_write_string_chunk(s, "checked", buf, len) < 0) return -1; if (wificfg_write_string_chunk(s, http_wifi_ap_content[19], buf, len) < 0) return -1; @@ -1268,14 +1269,14 @@ static int handle_wifi_ap_post(int s, wificfg_method method, case FORM_NAME_AP_DISABLED_RESTARTS: { uint32_t restarts = strtoul(buf, NULL, 10); if (restarts <= 255) - sysparam_set_int8("wifi_ap_disabled_restarts", restarts); + sysparam_set_int8("wificfg", "ap_dis_restart", restarts); break; } case FORM_NAME_AP_SSID: - sysparam_set_string("wifi_ap_ssid", buf); + sysparam_set_string("wificfg", "ap_ssid", buf); break; case FORM_NAME_AP_PASSWORD: - sysparam_set_string("wifi_ap_password", buf); + sysparam_set_string("wificfg", "ap_password", buf); break; case FORM_NAME_AP_SSID_HIDDEN: { ssid_hidden = strtoul(buf, NULL, 10) != 0; @@ -1284,39 +1285,39 @@ static int handle_wifi_ap_post(int s, wificfg_method method, case FORM_NAME_AP_CHANNEL: { uint32_t channel = strtoul(buf, NULL, 10); if (channel >= 1 && channel <= 14) - sysparam_set_int8("wifi_ap_channel", channel); + sysparam_set_int8("wificfg", "ap_channel", channel); break; } case FORM_NAME_AP_AUTHMODE: { uint32_t mode = strtoul(buf, NULL, 10); if (mode == AUTH_OPEN || mode == AUTH_WPA_PSK || mode == AUTH_WPA2_PSK || mode == AUTH_WPA_WPA2_PSK) { - sysparam_set_int8("wifi_ap_authmode", mode); + sysparam_set_int8("wificfg", "ap_authmode", mode); } break; } case FORM_NAME_AP_MAX_CONN: { uint32_t max_conn = strtoul(buf, NULL, 10); if (max_conn <= 8) - sysparam_set_int8("wifi_ap_max_conn", max_conn); + sysparam_set_int8("wificfg", "ap_max_conn", max_conn); break; } case FORM_NAME_AP_BEACON_INTERVAL: { uint32_t interval = strtoul(buf, NULL, 10); if (interval <= 10000) - sysparam_set_int32("wifi_ap_beacon_interval", interval); + sysparam_set_int32("wificfg", "ap_bcn_interval", interval); break; } case FORM_NAME_AP_IP_ADDR: - sysparam_set_string("wifi_ap_ip_addr", buf); + sysparam_set_string("wificfg", "ap_ip_addr", buf); break; case FORM_NAME_AP_NETMASK: - sysparam_set_string("wifi_ap_netmask", buf); + sysparam_set_string("wificfg", "ap_netmask", buf); break; case FORM_NAME_AP_DHCP_LEASES: { uint32_t leases = strtoul(buf, NULL, 10); if (leases <= 16) - sysparam_set_int8("wifi_ap_dhcp_leases", leases); + sysparam_set_int8("wificfg", "ap_dhcp_leases", leases); break; } case FORM_NAME_AP_DNS: { @@ -1337,11 +1338,11 @@ static int handle_wifi_ap_post(int s, wificfg_method method, } if (done) { - sysparam_set_int8("wifi_ap_enable", ap_enable); - sysparam_set_int8("wifi_ap_disable_if_sta", ap_disable_if_sta); - sysparam_set_int8("wifi_ap_ssid_hidden", ssid_hidden); - sysparam_set_int8("wifi_ap_dns", dns_enable); - sysparam_set_int8("wifi_ap_mdns", mdns_enable); + sysparam_set_int8("wificfg", "ap_enable", ap_enable); + sysparam_set_int8("wificfg", "ap_dis_if_sta", ap_disable_if_sta); + sysparam_set_int8("wificfg", "ap_ssid_hidden", ssid_hidden); + sysparam_set_int8("wificfg", "ap_dns", dns_enable); + sysparam_set_int8("wificfg", "ap_mdns", mdns_enable); } return wificfg_write_string(s, http_redirect_header); @@ -1358,19 +1359,19 @@ void wificfg_got_sta_connect() /* Skip if AP not even enabled. */ int8_t wifi_ap_enable = 1; - sysparam_get_int8("wifi_ap_enable", &wifi_ap_enable); + sysparam_get_int8("wificfg", "ap_enable", &wifi_ap_enable); if (!wifi_ap_enable) { return; } int8_t wifi_ap_disable_if_sta = 1; - sysparam_get_int8("wifi_ap_disable_if_sta", &wifi_ap_disable_if_sta); + sysparam_get_int8("wificfg", "ap_dis_if_sta", &wifi_ap_disable_if_sta); if (wifi_ap_disable_if_sta) { int8_t wifi_ap_disabled_restarts = 0; - sysparam_get_int8("wifi_ap_disabled_restarts", &wifi_ap_disabled_restarts); + sysparam_get_int8("wificfg", "ap_dis_restart", &wifi_ap_disabled_restarts); if (wifi_ap_disabled_restarts == 0) { - sysparam_set_int8("wifi_ap_disabled_restarts", 1); + sysparam_set_int8("wificfg", "ap_dis_restart", 1); } } } @@ -1498,9 +1499,9 @@ static int handle_wificfg_challenge_post(int s, wificfg_method method, bool valp = false; int8_t enable = 1; - sysparam_get_int8("cfg_enable", &enable); + sysparam_get_int8("wificfg", "cfg_enable", &enable); char *password = NULL; - sysparam_get_string("cfg_password", &password); + sysparam_get_string("wificfg", "cfg_password", &password); if (!enable && password && strlen(password)) { while (rem > 0) { @@ -1525,7 +1526,7 @@ static int handle_wificfg_challenge_post(int s, wificfg_method method, switch (name) { case FORM_NAME_CFG_PASSWORD: if (strcmp(password, buf) == 0) - sysparam_set_int8("cfg_enable", 1); + sysparam_set_int8("wificfg", "cfg_enable", 1); break; default: break; @@ -1642,7 +1643,7 @@ static const wificfg_dispatch wificfg_dispatch_list[] = { {"/tasks", HTTP_METHOD_GET, handle_tasks, false}, {"/tasks.html", HTTP_METHOD_GET, handle_tasks, false}, #endif /* configUSE_TRACE_FACILITY */ - {NULL, HTTP_METHOD_ANY, NULL} + {NULL, HTTP_METHOD_ANY, NULL, false} }; static const wificfg_dispatch wificfg_challenge_dispatch = {"/challenge.html", HTTP_METHOD_GET, handle_wificfg_challenge, false}; @@ -1715,7 +1716,7 @@ static void server_task(void *pvParameters) char *hostname_local = NULL; char *hostname = NULL; - sysparam_get_string("hostname", &hostname); + sysparam_get_string("wificfg", "hostname", &hostname); if (hostname) { size_t len = strlen(hostname) + 6 + 1; hostname_local = (char *)malloc(len); @@ -1725,8 +1726,8 @@ static void server_task(void *pvParameters) int8_t wifi_sta_mdns = 1; int8_t wifi_ap_mdns = 1; - sysparam_get_int8("wifi_sta_mdns", &wifi_sta_mdns); - sysparam_get_int8("wifi_ap_mdns", &wifi_ap_mdns); + sysparam_get_int8("wificfg", "sta_mdns", &wifi_sta_mdns); + sysparam_get_int8("wificfg", "ap_mdns", &wifi_ap_mdns); struct netif *station_netif = sdk_system_get_netif(STATION_IF); struct netif *softap_netif = sdk_system_get_netif(SOFTAP_IF); @@ -1845,11 +1846,11 @@ static void server_task(void *pvParameters) if (match && match->secure) { /* A secure url so check if enabled. */ int8_t enable = 1; - sysparam_get_int8("cfg_enable", &enable); + sysparam_get_int8("wificfg", "cfg_enable", &enable); if (!enable) { /* Is there a recovery password? */ char *password = NULL; - sysparam_get_string("cfg_password", &password); + sysparam_get_string("wificfg", "cfg_password", &password); if (password && strlen(password) > 0) { match = &wificfg_challenge_dispatch; } else { @@ -1955,7 +1956,7 @@ static void server_task(void *pvParameters) static void dns_task(void *pvParameters) { char *wifi_ap_ip_addr = NULL; - sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); + sysparam_get_string("wificfg", "ap_ip_addr", &wifi_ap_ip_addr); if (!wifi_ap_ip_addr) { printf("dns: no ip address\n"); vTaskDelete(NULL); @@ -2054,43 +2055,43 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) /* Default a hostname. */ char *hostname = NULL; - sysparam_get_string("hostname", &hostname); + sysparam_get_string("wificfg", "hostname", &hostname); if (!hostname && wificfg_default_hostname) { uint8_t macaddr[6]; char name[32]; sdk_wifi_get_macaddr(1, macaddr); snprintf(name, sizeof(name), wificfg_default_hostname, macaddr[3], macaddr[4], macaddr[5]); - sysparam_set_string("hostname", name); + sysparam_set_string("wificfg", "hostname", name); } if (hostname) { free(hostname); } - sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); - sysparam_get_string("wifi_ap_password", &wifi_ap_password); - sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid); - sysparam_get_string("wifi_sta_password", &wifi_sta_password); + sysparam_get_string("wificfg", "ap_ssid", &wifi_ap_ssid); + sysparam_get_string("wificfg", "ap_password", &wifi_ap_password); + sysparam_get_string("wificfg", "sta_ssid", &wifi_sta_ssid); + sysparam_get_string("wificfg", "sta_password", &wifi_sta_password); int8_t wifi_sta_enable = 1; int8_t wifi_ap_enable = 1; - sysparam_get_int8("wifi_sta_enable", &wifi_sta_enable); - sysparam_get_int8("wifi_ap_enable", &wifi_ap_enable); + sysparam_get_int8("wificfg", "sta_enable", &wifi_sta_enable); + sysparam_get_int8("wificfg", "ap_enable", &wifi_ap_enable); int8_t wifi_sta_disabled_restarts = 0; - sysparam_get_int8("wifi_sta_disabled_restarts", &wifi_sta_disabled_restarts); + sysparam_get_int8("wificfg", "sta_dis_restart", &wifi_sta_disabled_restarts); if (wifi_sta_disabled_restarts > 0) { wifi_sta_enable = 0; wifi_sta_disabled_restarts--; - sysparam_set_int8("wifi_sta_disabled_restarts", wifi_sta_disabled_restarts); + sysparam_set_int8("wificfg", "sta_dis_restart", wifi_sta_disabled_restarts); } int8_t wifi_ap_disabled_restarts = 0; - sysparam_get_int8("wifi_ap_disabled_restarts", &wifi_ap_disabled_restarts); + sysparam_get_int8("wificfg", "ap_dis_restart", &wifi_ap_disabled_restarts); if (wifi_ap_disabled_restarts > 0) { wifi_ap_enable = 0; wifi_ap_disabled_restarts--; - sysparam_set_int8("wifi_ap_disabled_restarts", wifi_ap_disabled_restarts); + sysparam_set_int8("wificfg", "ap_dis_restart", wifi_ap_disabled_restarts); } /* Validate the configuration. */ @@ -2112,12 +2113,12 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) sdk_wifi_get_macaddr(1, macaddr); snprintf(ssid, sizeof(ssid), wificfg_default_ssid, macaddr[3], macaddr[4], macaddr[5]); - sysparam_set_string("wifi_ap_ssid", ssid); - sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); + sysparam_set_string("wificfg", "ap_ssid", ssid); + sysparam_get_string("wificfg", "ap_ssid", &wifi_ap_ssid); if (!wifi_ap_password && wificfg_default_password) { - sysparam_set_string("wifi_ap_password", wificfg_default_password); - sysparam_get_string("wifi_ap_password", &wifi_ap_password); + sysparam_set_string("wificfg", "ap_password", wificfg_default_password); + sysparam_get_string("wificfg", "ap_password", &wifi_ap_password); } } @@ -2139,20 +2140,20 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) if (wifi_sta_enable) { struct sdk_station_config config; - strcpy((char *)config.ssid, wifi_sta_ssid); - strcpy((char *)config.password, wifi_sta_password); + strncpy((char *)config.ssid, wifi_sta_ssid, sizeof(config.ssid)); + strncpy((char *)config.password, wifi_sta_password, sizeof(config.password)); config.bssid_set = 0; int8_t wifi_sta_dhcp = 1; - sysparam_get_int8("wifi_sta_dhcp", &wifi_sta_dhcp); + sysparam_get_int8("wificfg", "sta_dhcp", &wifi_sta_dhcp); if (!wifi_sta_dhcp) { char *wifi_sta_ip_addr = NULL; char *wifi_sta_netmask = NULL; char *wifi_sta_gateway = NULL; - sysparam_get_string("wifi_sta_ip_addr", &wifi_sta_ip_addr); - sysparam_get_string("wifi_sta_netmask", &wifi_sta_netmask); - sysparam_get_string("wifi_sta_gateway", &wifi_sta_gateway); + sysparam_get_string("wificfg", "sta_ip_addr", &wifi_sta_ip_addr); + sysparam_get_string("wificfg", "sta_netmask", &wifi_sta_netmask); + sysparam_get_string("wificfg", "sta_gateway", &wifi_sta_gateway); if (wifi_sta_ip_addr && strlen(wifi_sta_ip_addr) > 4 && wifi_sta_netmask && strlen(wifi_sta_netmask) > 4 && @@ -2176,13 +2177,13 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) if (wifi_ap_enable) { /* Read and validate paramenters. */ int8_t wifi_ap_ssid_hidden = 0; - sysparam_get_int8("wifi_ap_ssid_hidden", &wifi_ap_ssid_hidden); + sysparam_get_int8("wificfg", "ap_ssid_hidden", &wifi_ap_ssid_hidden); if (wifi_ap_ssid_hidden < 0 || wifi_ap_ssid_hidden > 1) { wifi_ap_ssid_hidden = 1; } int8_t wifi_ap_channel = 6; - sysparam_get_int8("wifi_ap_channel", &wifi_ap_channel); + sysparam_get_int8("wificfg", "ap_channel", &wifi_ap_channel); /* AU does not allow channels above 13, although 14 works. */ if (wifi_ap_channel > 13) { @@ -2199,36 +2200,36 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) } int8_t wifi_ap_authmode = AUTH_WPA_WPA2_PSK; - sysparam_get_int8("wifi_ap_authmode", &wifi_ap_authmode); + sysparam_get_int8("wificfg", "ap_authmode", &wifi_ap_authmode); if (wifi_ap_authmode != AUTH_OPEN && wifi_ap_authmode != AUTH_WPA_PSK && wifi_ap_authmode != AUTH_WPA2_PSK && wifi_ap_authmode != AUTH_WPA_WPA2_PSK) { wifi_ap_authmode = AUTH_WPA_WPA2_PSK; } int8_t wifi_ap_max_conn = 3; - sysparam_get_int8("wifi_ap_max_conn", &wifi_ap_max_conn); + sysparam_get_int8("wificfg", "ap_max_conn", &wifi_ap_max_conn); if (wifi_ap_max_conn < 1 || wifi_ap_max_conn > 8) { wifi_ap_max_conn = 3; } int32_t wifi_ap_beacon_interval = 100; - sysparam_get_int32("wifi_ap_beacon_interval", &wifi_ap_beacon_interval); + sysparam_get_int32("wificfg", "ap_bcn_interval", &wifi_ap_beacon_interval); if (wifi_ap_beacon_interval < 0 || wifi_ap_beacon_interval > 1000) { wifi_ap_beacon_interval = 100; } /* Default AP IP address and netmask. */ char *wifi_ap_ip_addr = NULL; - sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); + sysparam_get_string("wificfg", "ap_ip_addr", &wifi_ap_ip_addr); if (!wifi_ap_ip_addr) { - sysparam_set_string("wifi_ap_ip_addr", "172.16.0.1"); - sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); + sysparam_set_string("wificfg", "ap_ip_addr", "172.16.0.1"); + sysparam_get_string("wificfg", "ap_ip_addr", &wifi_ap_ip_addr); } char *wifi_ap_netmask = NULL; - sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); + sysparam_get_string("wificfg", "ap_netmask", &wifi_ap_netmask); if (!wifi_ap_netmask) { - sysparam_set_string("wifi_ap_netmask", "255.255.0.0"); - sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); + sysparam_set_string("wificfg", "ap_netmask", "255.255.0.0"); + sysparam_get_string("wificfg", "ap_netmask", &wifi_ap_netmask); } if (strlen(wifi_ap_ip_addr) >= 7 && strlen(wifi_ap_netmask) >= 7) { @@ -2245,20 +2246,20 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch) .max_connection = wifi_ap_max_conn, .beacon_interval = wifi_ap_beacon_interval, }; - strcpy((char *)ap_config.ssid, wifi_ap_ssid); + strncpy((char *)ap_config.ssid, wifi_ap_ssid, sizeof(ap_config.ssid)); ap_config.ssid_len = strlen(wifi_ap_ssid); - strcpy((char *)ap_config.password, wifi_ap_password); + strncpy((char *)ap_config.password, wifi_ap_password, sizeof(ap_config.password)); sdk_wifi_softap_set_config(&ap_config); int8_t wifi_ap_dhcp_leases = 4; - sysparam_get_int8("wifi_ap_dhcp_leases", &wifi_ap_dhcp_leases); + sysparam_get_int8("wificfg", "ap_dhcp_leases", &wifi_ap_dhcp_leases); if (wifi_ap_dhcp_leases) { ip4_addr_t first_client_ip; first_client_ip.addr = ap_ip.ip.addr + htonl(1); int8_t wifi_ap_dns = 1; - sysparam_get_int8("wifi_ap_dns", &wifi_ap_dns); + sysparam_get_int8("wificfg", "ap_dns", &wifi_ap_dns); if (wifi_ap_dns < 0 || wifi_ap_dns > 1) wifi_ap_dns = 1; diff --git a/extras/wificfg/wificfg.h b/extras/wificfg/wificfg.h index 3461c7a..c050f41 100644 --- a/extras/wificfg/wificfg.h +++ b/extras/wificfg/wificfg.h @@ -103,7 +103,7 @@ ssize_t wificfg_form_name_value(int s, bool *valp, size_t *rem, char *buf, size_ void wificfg_form_url_decode(char *string); /* Support for html-escaping of form values. */ -void wificfg_html_escape(char *string, char *buf, size_t len); +void wificfg_html_escape(const char *string, char *buf, size_t len); /* Support for writing a string in a response. */ ssize_t wificfg_write_string(int s, const char *str); diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c index 77ad177..e197189 100644 --- a/lwip/esp_interface.c +++ b/lwip/esp_interface.c @@ -365,7 +365,7 @@ ethernetif_init(struct netif *netif) /* Initialize interface hostname */ char *hostname = NULL; /* Disabled for now as there were reports of crashes here, sysparam issues */ - /* sysparam_get_string("hostname", &hostname); */ + /* sysparam_get_string("wificfg", "hostname", &hostname); */ if (hostname && strlen(hostname) == 0) { free(hostname); hostname = NULL;