sysparam: split the key into a name-space and name.

This is largely to aid compatibility with other non-volatile stores
that have limited sized names but support a name space. This might
open a path to more compact storage of the key names although that is
not implemented here.
This commit is contained in:
Our Air Quality 2018-06-08 10:51:01 +10:00
parent f89ba44f6e
commit 1c3d5996a6
7 changed files with 379 additions and 208 deletions

View file

@ -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
*

View file

@ -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) <binary-data> (%d)", ctx->addr, iter->key, value_ctx.addr, iter->value_len);
debug(2, "iter_next: (0x%08x) '%s' : '%s' = (0x%08x) <binary-data> (%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);
}

View file

@ -29,7 +29,7 @@ void usage(void) {
"Available commands:\n"
" <key>? -- Query the value of <key>\n"
" <key>=<value> -- Set <key> to text <value>\n"
" <key>:<hexdata> -- Set <key> to binary value represented as hex\n"
" <key>%%<hexdata> -- Set <key> 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");

View file

@ -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"

View file

@ -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, "<dt>Hostname</dt><dd>", 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;

View file

@ -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);

View file

@ -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;