Added max_points in .ini, increased spiff csv file character limit, and file name limit. Added more prints for how many devices you can configure based on current memory size and max_points.
This commit is contained in:
@@ -101,6 +101,32 @@ static void copy_str(char *dst, size_t dst_size, const char *src)
|
||||
dst[dst_size - 1U] = '\0';
|
||||
}
|
||||
|
||||
static bool copy_dyn_str(char **dst, const char *src)
|
||||
{
|
||||
char *new_value;
|
||||
size_t len;
|
||||
|
||||
if (dst == NULL)
|
||||
return false;
|
||||
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
len = strlen(src);
|
||||
|
||||
new_value = malloc(len + 1U);
|
||||
if (new_value == NULL)
|
||||
return false;
|
||||
|
||||
memcpy(new_value, src, len + 1U);
|
||||
|
||||
if (*dst != NULL)
|
||||
free(*dst);
|
||||
|
||||
*dst = new_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int parse_device_section_index(const char *section)
|
||||
{
|
||||
unsigned long idx;
|
||||
@@ -149,7 +175,7 @@ static void set_device_defaults(virtual_device_settings_t *dev, uint8_t index)
|
||||
|
||||
snprintf(default_name, sizeof(default_name), "Device_%u", (unsigned)(index + 1U));
|
||||
copy_str(dev->name, sizeof(dev->name), default_name);
|
||||
dev->csv[0] = '\0';
|
||||
dev->csv = NULL;
|
||||
}
|
||||
|
||||
void config_store_set_defaults(device_config_t *cfg)
|
||||
@@ -171,20 +197,91 @@ void config_store_set_defaults(device_config_t *cfg)
|
||||
cfg->modbus.port = 502;
|
||||
cfg->modbus.max_clients = 4;
|
||||
cfg->modbus.device_count = 1;
|
||||
cfg->modbus.max_points = 150;
|
||||
|
||||
for (i = 0; i < MAX_VIRTUAL_DEVICES; i++)
|
||||
set_device_defaults(&cfg->devices[i], (uint8_t)i);
|
||||
}
|
||||
|
||||
void config_store_free(device_config_t *cfg)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (cfg == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_VIRTUAL_DEVICES; i++)
|
||||
{
|
||||
if (cfg->devices[i].csv != NULL)
|
||||
{
|
||||
free(cfg->devices[i].csv);
|
||||
cfg->devices[i].csv = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool read_dynamic_line(FILE *fp, char **out_line)
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t capacity = 128U;
|
||||
size_t length = 0U;
|
||||
int ch;
|
||||
|
||||
if (fp == NULL || out_line == NULL)
|
||||
return false;
|
||||
|
||||
*out_line = NULL;
|
||||
|
||||
line = malloc(capacity);
|
||||
if (line == NULL)
|
||||
return false;
|
||||
|
||||
while ((ch = fgetc(fp)) != EOF)
|
||||
{
|
||||
char *new_line;
|
||||
|
||||
if (length + 1U >= capacity)
|
||||
{
|
||||
size_t new_capacity = capacity * 2U;
|
||||
|
||||
new_line = realloc(line, new_capacity);
|
||||
if (new_line == NULL)
|
||||
{
|
||||
free(line);
|
||||
return false;
|
||||
}
|
||||
|
||||
line = new_line;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
|
||||
line[length++] = (char)ch;
|
||||
|
||||
if (ch == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
if (length == 0U && ch == EOF)
|
||||
{
|
||||
free(line);
|
||||
return false;
|
||||
}
|
||||
|
||||
line[length] = '\0';
|
||||
*out_line = line;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
char *line = NULL;
|
||||
char section[32];
|
||||
|
||||
if (filename == NULL || cfg == NULL)
|
||||
return false;
|
||||
|
||||
config_store_free(cfg);
|
||||
config_store_set_defaults(cfg);
|
||||
memset(section, 0, sizeof(section));
|
||||
|
||||
@@ -192,7 +289,7 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
if (fp == NULL)
|
||||
return false;
|
||||
|
||||
while (fgets(line, sizeof(line), fp) != NULL)
|
||||
while (read_dynamic_line(fp, &line))
|
||||
{
|
||||
char *eq;
|
||||
char *key;
|
||||
@@ -202,10 +299,19 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
trim_whitespace(line);
|
||||
|
||||
if (line[0] == '\0')
|
||||
{
|
||||
free(line);
|
||||
line = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (line[0] == ';' || line[0] == '#')
|
||||
{
|
||||
free(line);
|
||||
line = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '[')
|
||||
{
|
||||
@@ -217,12 +323,18 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
copy_str(section, sizeof(section), &line[1]);
|
||||
trim_whitespace(section);
|
||||
}
|
||||
free(line);
|
||||
line = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
eq = strchr(line, '=');
|
||||
if (eq == NULL)
|
||||
{
|
||||
free(line);
|
||||
line = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
*eq = '\0';
|
||||
key = line;
|
||||
@@ -274,6 +386,13 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
cfg->modbus.device_count = (uint8_t)v;
|
||||
}
|
||||
}
|
||||
else if (str_ieq(key, "max_points"))
|
||||
{
|
||||
if (parse_u32(value, &v) && v > 0U)
|
||||
{
|
||||
cfg->modbus.max_points = (size_t)v;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -301,16 +420,28 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
}
|
||||
else if (str_ieq(key, "csv"))
|
||||
{
|
||||
copy_str(dev->csv, sizeof(dev->csv), value);
|
||||
if (!copy_dyn_str(&dev->csv, value))
|
||||
{
|
||||
free(line);
|
||||
line = NULL;
|
||||
fclose(fp);
|
||||
config_store_free(cfg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
line = NULL;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (cfg->wifi.ssid[0] == '\0')
|
||||
{
|
||||
printf("CONFIG ERROR: wifi.ssid is empty\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cfg->modbus.port == 0U)
|
||||
return false;
|
||||
@@ -318,6 +449,9 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
if (cfg->modbus.max_clients == 0U)
|
||||
return false;
|
||||
|
||||
if (cfg->modbus.max_points == 0U)
|
||||
return false;
|
||||
|
||||
if (cfg->modbus.device_count == 0U || cfg->modbus.device_count > MAX_VIRTUAL_DEVICES)
|
||||
return false;
|
||||
|
||||
@@ -330,10 +464,17 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
continue;
|
||||
|
||||
if (dev->unit_id == 0U)
|
||||
{
|
||||
printf("CONFIG ERROR: enable device %u has invalid unit_id 0\n",
|
||||
(unsigned)(i + 1U));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->csv[0] == '\0')
|
||||
if (dev->csv == NULL || dev->csv[0] == '\0')
|
||||
{
|
||||
printf("CONFIG ERROR: enabled device %u has empty csv\n", (unsigned)(i + 1U));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dev->name[0] == '\0')
|
||||
{
|
||||
@@ -348,7 +489,12 @@ bool config_store_load(const char *filename, device_config_t *cfg)
|
||||
continue;
|
||||
|
||||
if (dev->unit_id == cfg->devices[j].unit_id)
|
||||
return false;
|
||||
{
|
||||
printf("CONFIG ERROR: duplicate unit_id %u between device %u and device %u\n",
|
||||
(unsigned)dev->unit_id,
|
||||
(unsigned)(i + 1U),
|
||||
(unsigned)(j + 1U));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user