Compare commits

...
Sign in to create a new pull request.

14 commits

6 changed files with 127 additions and 54 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
build

View file

@ -1,5 +1,9 @@
set(REQUIRES "")
set(SRCS src/configulator.c src/cfglr_signal_callback.c)
set(SRCS
src/configulator.c
src/cfglr_signal_callback.c
src/element_list.c
)
if(${ESP_PLATFORM})
list(APPEND REQUIRES nvs_flash esp_event)

View file

@ -10,7 +10,7 @@ ESP_EVENT_DECLARE_BASE(CFGLR_EVENT_BASE);
void cfglr_signaler_idf_init(cfglr_signaler_t *signaler, cfglr_handle_t *handle);
void cfglr_signaler_idf_dispatch(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig);
#define CFGLR_SIGNALER_IDF_EVENT() {\
#define CFGLR_SIGNALER_IDF_EVENT() (cfglr_signaler_t){\
.dispatch = &cfglr_signaler_idf_dispatch,\
}

View file

@ -8,9 +8,11 @@
#define CFGLR_SIGNALERS_MAX (04)
typedef enum {
CFGLR_SIGNAL_LOADED = 0,
CFGLR_SIGNAL_INIT = 0,
CFGLR_SIGNAL_LOADED,
CFGLR_SIGNAL_CHANGE,
CFGLR_SIGNAL_DELETE,
CFGLR_SIGNAL_FAILED,
} cfglr_signal_e;
typedef enum {
@ -28,9 +30,10 @@ typedef enum {
#define CFGLR_DATATYPE_COUNT (uint8_t)(CFGLR_DATATYPE_BIN - CFGLR_DATATYPE_U8)
typedef struct cfglr_signaler cfglr_signaler_t;
typedef struct cfglr_handle_struct cfglr_handle_t;
typedef struct cfglr_config cfglr_config_t;
typedef struct cfglr_element cfglr_element_t;
typedef struct cfglr_handle cfglr_handle_t;
typedef struct cfglr_signaler cfglr_signaler_t;
typedef void (*cfglr_signaler_init_t)(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_handle_t *handle);
typedef void (*cfglr_signaler_dispatch_t)(cfglr_signaler_t *signaler, cfglr_element_t *element, cfglr_signal_e sig);
@ -69,6 +72,19 @@ struct cfglr_element {
}\
}
#define CFGLR_ELEMENT_PTR(KEY, POINTER, TYPE, SIZE, DEFAULT, DEF_SIZE, SIGNALERS...) (cfglr_element_t){\
.key = KEY,\
.data = POINTER,\
.datatype = TYPE,\
.datatype_size = SIZE,\
.default_data = (void*)DEFAULT,\
.default_size = DEF_SIZE,\
.signalers = {\
SIGNALERS,\
{ NULL }\
}\
}
#define CFGLR_ELEMENT_U8(KEY, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U8, sizeof(uint8_t), DEFAULT, 1, SIGNALERS)
#define CFGLR_ELEMENT_I8(KEY, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I8, sizeof(int8_t), DEFAULT, 1, SIGNALERS)
#define CFGLR_ELEMENT_U16(KEY, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U16, sizeof(uint16_t), DEFAULT, 2, SIGNALERS)
@ -78,7 +94,7 @@ struct cfglr_element {
#define CFGLR_ELEMENT_U64(KEY, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_U64, sizeof(uint64_t), DEFAULT, 8, SIGNALERS)
#define CFGLR_ELEMENT_I64(KEY, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_I64, sizeof(int64_t), DEFAULT, 8, SIGNALERS)
#define CFGLR_ELEMENT_BIN(KEY, SIZE, DEFAULT, DEF_SIZE, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_BIN, SIZE, DEFAULT, DEF_SIZE, SIGNALERS)
#define CFGLR_ELEMENT_STR(KEY, SIZE, DEFAULT, SIGNALERS...) CFGLR_ELEMENT(KEY, CFGLR_DATATYPE_STR, SIZE, DEFAULT, strlen(DEFAULT), SIGNALERS)
#define CFGLR_ELEMENT_STR(KEY, POINTER, SIZE, DEFAULT, SIGNALERS...) CFGLR_ELEMENT_PTR(KEY, POINTER, CFGLR_DATATYPE_STR, SIZE, DEFAULT, strlen(DEFAULT), SIGNALERS)
typedef struct cfglr_backend cfglr_backend_t;
@ -105,16 +121,26 @@ struct cfglr_backend {
.set = SET,\
}
struct cfglr_handle_struct {
struct cfglr_config {
const char *namespace;
// TODO cleanup, what is store_default for?
uint8_t store_default;
uint8_t backend_count;
uint8_t element_count;
cfglr_backend_t backend;
cfglr_element_t elements[CFGLR_ELEMENTS_MAX];
};
struct cfglr_handle {
const char *namespace;
uint8_t backend_count;
uint8_t element_count;
cfglr_backend_t backend;
cfglr_element_t elements[CFGLR_ELEMENTS_MAX];
void *extra;
};
extern cfglr_handle_t *configulator;
uint8_t cfglr_init(cfglr_handle_t *handle);
uint8_t cfglr_fetch_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handler);
cfglr_element_t * cfglr_get_element(cfglr_handle_t *handle, const char *name);

View file

@ -17,6 +17,8 @@ void cfglr_backend_nvs_close(cfglr_backend_t *backend, cfglr_handle_t *handle) {
uint16_t cfglr_backend_nvs_get(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) {
esp_err_t err = ESP_OK;
CFGLR_LOGI(TAG, "cfglr_backend_nvs_get->datatype: %d", element->datatype);
switch(element->datatype) {
case CFGLR_DATATYPE_U8:
err = nvs_get_u8((nvs_handle_t)backend->handle, element->key, (uint8_t*)element->data);
@ -52,7 +54,7 @@ uint16_t cfglr_backend_nvs_get(cfglr_backend_t *backend, cfglr_element_t *elemen
case CFGLR_DATATYPE_STR:
case CFGLR_DATATYPE_BIN:
uint8_t read_size = 0;
size_t read_size = element->datatype_size;
err = nvs_get_blob((nvs_handle_t)backend->handle, element->key, element->data, &read_size);

View file

@ -1,13 +1,85 @@
#include "string.h"
#include "configulator.h"
#include "cfglr_log.h"
#include "element_list.h"
#define TAG "CFGLR"
cfglr_handle_t *configulator;
element_list_node_t *cfglr_element_list_add(cfglr_handle_t *handle, cfglr_element_t *element) {
element_list_node_t *node = malloc(sizeof(element_list_node_t));
bzero(node, sizeof(element_list_node_t));
node->element = element;
// initiaze the first node
// it is only first/last
if(handle->extra == NULL) {
handle->extra = node;
node->first = node;
node->last = node;
return node;
}
return element_list_add(handle->extra, node);
}
uint8_t cfglr_add_element(cfglr_handle_t *handle, cfglr_element_t *element) {
cfglr_signaler_t *signaler;
CFGLR_LOGI(TAG, "Initializing element: %s", element->key);
CFGLR_LOGI(TAG, "size: %d", element->datatype_size);
element->handle = handle;
if(element->data == NULL) {
element->data = (void*)malloc(element->datatype_size);
bzero(element->data, 0);
CFGLR_LOGD(TAG, "malloc: %d @ %p", element->datatype_size, element->data);
}
CFGLR_LOGD(TAG, "Initializing %d Signalers", element->signaler_count);
while((signaler = &element->signalers[element->signaler_count])) {
if(signaler->init == NULL && signaler->dispatch == NULL) break;
if(signaler->init != NULL) {
signaler->init(signaler, element, handle);
}
element->signaler_count++;
}
cfglr_signal_e signal;
if(handle->backend.get(&handle->backend, element, handle) == 0) {
signal = CFGLR_SIGNAL_LOADED;
} else {
CFGLR_LOGI(TAG, "failed to load %s, setting default", element->key);
memcpy((void*)&element->data, (void*)&element->default_data, element->default_size);
signal = CFGLR_SIGNAL_INIT;
if(handle->backend.set(&handle->backend, element, handle) != 0) {
signal = CFGLR_SIGNAL_FAILED;
}
}
for(uint8_t i = 0; i < element->signaler_count; i++) {
element->signalers[i].dispatch(&element->signalers[i], element, signal);
}
cfglr_element_list_add(handle, element);
return ++handle->element_count;
}
uint8_t cfglr_init(cfglr_handle_t *handle) {
cfglr_backend_t *backend = &handle->backend;
cfglr_element_t *element;
cfglr_signaler_t *signaler;
handle->element_count = 0;
@ -23,46 +95,7 @@ uint8_t cfglr_init(cfglr_handle_t *handle) {
while((element = &handle->elements[handle->element_count])) {
if(element->key == NULL) break;
CFGLR_LOGI(TAG, "Initializing element: %s", element->key);
CFGLR_LOGI(TAG, "size: %d", element->datatype_size);
element->handle = handle;
element->data = (void*)malloc(element->datatype_size);
bzero(element->data, 0);
CFGLR_LOGW(TAG, "malloc: %d @ %p", element->datatype_size, element->data);
//CFGLR_LOGI(TAG, "element->data: %p", element->data);
while((signaler = &element->signalers[element->signaler_count])) {
if(signaler->init == NULL && signaler->dispatch == NULL) break;
if(signaler->init != NULL) {
signaler->init(signaler, element, handle);
}
element->signaler_count++;
}
bool dispatch = false;
if(handle->backend.get(&handle->backend, element, handle) == 0) {
dispatch = true;
} else {
CFGLR_LOGI(TAG, "failed to load %s, setting default", element->key);
memcpy((void*)&element->data, (void*)&element->default_data, element->default_size);
if(handle->backend.set(&handle->backend, element, handle) == 0) {
dispatch = true;
}
}
if(dispatch) {
for(uint8_t i = 0; i < element->signaler_count; i++) {
element->signalers[i].dispatch(&element->signalers[i], element, CFGLR_SIGNAL_LOADED);
}
}
++handle->element_count;
cfglr_add_element(handle, element);
}
return 0;
@ -79,7 +112,7 @@ uint16_t cfglr_commit(cfglr_element_t *element) {
uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, cfglr_handle_t *handle) {
uint16_t ret = backend->set(backend, element, handle);
CFGLR_LOGI(TAG, "%s = %d (ret %d) %p", element->key, (uint8_t)&element->data, ret, element->data);
CFGLR_LOGI(TAG, "commit: %s->%s", handle->namespace, element->key);
if(ret == 0) {
for(uint8_t i = 0; i < element->signaler_count; i++) {
@ -92,10 +125,17 @@ uint16_t cfglr_commit_data(cfglr_backend_t *backend, cfglr_element_t *element, c
cfglr_element_t * cfglr_get_element(cfglr_handle_t *handle, const char *name) {
cfglr_element_t *element;
element_list_node_t *node = handle->extra;
node = node->first;
while(node) {
element = node->element;
CFGLR_LOGI(TAG, "element: %s @ %p", element->key, element);
uint8_t i = 0;
while((element = &handle->elements[i++]) != NULL) {
if(strcmp(element->key, name) == 0) return element;
node = node->next;
}
return NULL;