alles ums licht im Keller und Sommerschein
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

334 lines
9.7 KiB

// #include "storage.h"
#include "esp_log.h"
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
#include "jsmn.h"
#include "esp_lan.h"
static const char *TAG = "storage";
const char *base_path = "/storage";
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
typedef struct
{
char *client_config;
char *controller_config;
} load_config;
typedef struct
{
bool debug;
uint16_t log_level;
struct network_config *network;
} main_config;
// allocates memory! free space after use!
static char *read_file(char *host_filename)
{
ESP_LOGI(TAG, "Reading file");
FILE *f;
char *fileContent;
f = fopen(host_filename, "rb");
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for reading");
return NULL;
}
size_t result;
fseek(f, 0, SEEK_END);
int fileSize = ftell(f);
rewind(f);
ESP_LOGI(TAG, "fileSize: %i\n", fileSize);
fileContent = (char *)malloc(sizeof(char) * fileSize + 1);
if (fileContent == NULL)
{
ESP_LOGE(TAG, "Memory error");
return NULL;
}
result = fread(fileContent, 1, fileSize, f);
if (result != fileSize)
{
ESP_LOGE(TAG, "Reading error");
free(fileContent);
return NULL;
}
fileContent[fileSize] = '\0';
fclose(f);
return fileContent;
};
static int jsoneq(const char *json, jsmntok_t *tok, const char *s)
{
if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
strncmp(json + tok->start, s, tok->end - tok->start) == 0)
{
return 0;
}
return -1;
}
void parse_trst_config(main_config *cfg, char *fileContent)
{
int i;
int r;
jsmn_parser p;
jsmntok_t t[256]; /* We expect no more than 128 tokens */
jsmn_init(&p);
// should be end at \0 so set max file size to not having to count
r = jsmn_parse(&p, fileContent, 8192, t,
sizeof(t) / sizeof(t[0]));
if (r < 0)
{
printf("Failed to parse JSON: %d\n", r);
return;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT)
{
printf("Object expected\n");
return;
}
/* Loop over all keys of the root object */
for (i = 1; i < r; i++)
{
if (jsoneq(fileContent, &t[i], "user") == 0)
{
/* We may use strndup() to fetch string value */
printf("- User: %.*s\n", t[i + 1].end - t[i + 1].start,
fileContent + t[i + 1].start);
i++;
}
else if (jsoneq(fileContent, &t[i], "admin") == 0)
{
/* We may additionally check if the value is either "true" or "false" */
printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start,
fileContent + t[i + 1].start);
i++;
}
else if (jsoneq(fileContent, &t[i], "debug") == 0)
{
/* We may additionally check if the value is either "true" or "false" */
printf("-debug: %.*s\n", t[i + 1].end - t[i + 1].start,
fileContent + t[i + 1].start);
i++;
}
else if (jsoneq(fileContent, &t[i], "uid") == 0)
{
/* We may want to do strtol() here to get numeric value */
printf("- UID: %.*s\n", t[i + 1].end - t[i + 1].start,
fileContent + t[i + 1].start);
i++;
}
else if (jsoneq(fileContent, &t[i], "groups") == 0)
{
int j;
printf("- Groups:\n");
if (t[i + 1].type != JSMN_ARRAY)
{
continue; /* We expect groups to be an array of strings */
}
for (j = 0; j < t[i + 1].size; j++)
{
jsmntok_t *g = &t[i + j + 2];
printf(" * %.*s\n", g->end - g->start, fileContent + g->start);
}
i += t[i + 1].size + 1;
}
else
{
printf("Unexpected key%i: %.*s\n", i, t[i].end - t[i].start,
fileContent + t[i].start);
}
}
}
char* parse_string(jsmntok_t *token,char* fileContent){
uint16_t size = (token->end - token->start);
char* value = malloc(size+1);
strncpy(value, fileContent + token->start, size);
value[size] = '\0';
return value;
}
bool parse_bool(jsmntok_t *token,char* fileContent){
if(fileContent[token->start] == 't'){
return true;
} else {
return false;
}
}
uint16_t parse_int(jsmntok_t *token,char* fileContent){
// uint16_t size = (token.end - token.start);
return atoi(fileContent + token->start);
}
int parse_eth_config(lan_eth_config *cfg,jsmntok_t *token, char *fileContent){
ESP_LOGI(TAG, "t->start:(%d),t->end:(%d),t->size:(%d)", token->start, token->end, token->size);
return NULL;
}
int parse_network_config(network_config *cfg,jsmntok_t *token, char *fileContent){// add pos?
ESP_LOGI(TAG, "t->start:(%d),t->end:(%d),t->size:(%d)", token->start, token->end, token->size);
int stringPos = token->start;
int tokenPos = 1;
while(stringPos < token->end){
ESP_LOGI(TAG, "stringPos:(%d),tokenPos:(%d)", stringPos, tokenPos);
if (jsoneq(fileContent, &token[tokenPos], "debug") == 0){
stringPos = token[tokenPos].end;
tokenPos++;
} else
{
stringPos = token[tokenPos].end;
printf("Unexpected nc key%i: %.*s\n", tokenPos, token[tokenPos].end - token[tokenPos].start,
fileContent + token[tokenPos].start);
tokenPos++;
}
ESP_LOGI(TAG, "stringPos(%d)",stringPos);
};
return tokenPos+1;
}
void parse_main_config(main_config *cfg, char *fileContent)
{
int i;
int r;
jsmn_parser p;
jsmntok_t t[256]; /* We expect no more than 256 tokens */
jsmn_init(&p);
// should be end at \0 so set max file size to not having to count
r = jsmn_parse(&p, fileContent, 8192, t,
sizeof(t) / sizeof(t[0]));
if (r < 0)
{
printf("Failed to parse JSON: %d\n", r);
return;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT)
{
printf("Object expected\n");
return;
}
/* Loop over all keys of the root object */
for (i = 1; i < r; i++)
{
if (jsoneq(fileContent, &t[i], "debug") == 0)
{
cfg->debug = parse_bool(&t[i + 1],fileContent);
i++;
}
else if (jsoneq(fileContent, &t[i], "log_level") == 0)
{
cfg->log_level = parse_int(&t[i + 1],fileContent);
i++;
}
else if (jsoneq(fileContent, &t[i], "network") == 0)
{
if(t[i+1].type == JSMN_OBJECT){
cfg->network = malloc(sizeof(network_config));
int size = parse_network_config(cfg->network, &t[i+1],fileContent);
i = i+size;
} else {
// error
}
}
else
{
printf("Unexpected key%i: %.*s\n", i, t[i].end - t[i].start,
fileContent + t[i].start);
}
}
}
void parse_load_config(load_config *cfg, char *fileContent)
{
int i;
int r;
jsmn_parser p;
jsmntok_t t[32]; /* We expect no more than 128 tokens */
jsmn_init(&p);
// should be end at \0 so set max file size to not having to count
r = jsmn_parse(&p, fileContent, 8192, t,
sizeof(t) / sizeof(t[0]));
if (r < 0)
{
printf("Failed to parse JSON: %d\n", r);
return;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT)
{
printf("Object expected\n");
return;
}
/* Loop over all keys of the root object */
for (i = 1; i < r; i++)
{
if (jsoneq(fileContent, &t[i], "client_config") == 0)
{
printf("parse_string client_config\n");
cfg->client_config = parse_string(&t[i+1],fileContent);
i++;
}
else if (jsoneq(fileContent, &t[i], "controller_config") == 0)
{
cfg->controller_config = parse_string(&t[i+1],fileContent);
i++;
}
else
{
printf("Unexpected key%i: %.*s\n", i, t[i].end - t[i].start,
fileContent + t[i].start);
}
}
}
main_config *init_config()
{
ESP_LOGI(TAG, "init_config:");
// main_config *l_cfg = load_load_config("/storage/load.cfg.json");
ESP_LOGI(TAG, "Mounting FAT filesystem");
// To mount device we need name of device partition, define base_path
// and allow format partition in case if it is new one and was not formatted before
const esp_vfs_fat_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 4,
.allocation_unit_size = 512,
.disk_status_check_enable = false};
esp_err_t err;
err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, "storage", &mount_config, &s_wl_handle);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return NULL;
}
char *fileContent = read_file("/storage/load.cfg.json");
load_config *load_cfg = malloc(sizeof(load_config));
parse_load_config(load_cfg, fileContent);
free(fileContent);
ESP_LOGI(TAG, "controller_config:(%s),client_config:(%s)", load_cfg->controller_config, load_cfg->client_config);
fileContent = read_file(load_cfg->controller_config);
main_config *main_cfg = malloc(sizeof(main_config));
parse_main_config(main_cfg, fileContent);
free(fileContent);
ESP_LOGI(TAG, "main_cfg->debug:(%d)", main_cfg->debug);
ESP_ERROR_CHECK(esp_vfs_fat_spiflash_unmount_rw_wl(base_path, s_wl_handle));
return main_cfg;
}