Step 2.2: config registry and NVS store, GET/POST /api/config
- aes67_web/cfg.c: cfg_register(group, defaults, validate, apply), cfg_override_defaults() for project defaults, cfg_get(). Stored values are loaded on register and merged over defaults (known keys, matching types). NVS keeps only keys that differ from defaults, one JSON string per group, so new firmware defaults still reach untouched settings. - POST /api/config: type check against defaults, per-group validation, nothing stored unless every group passes; 400 "group.key: reason". Unknown keys/groups are ignored. Returns the new config. - Core groups registered by their components with the UI's ranges: ptp (aes67_ptp), aes67 (aes67_tx, incl. multicast range and mono_sum => 1 channel), net/inet (aes67_net), log (aes67_syslog). - Project: PROJECT.def overrides (hostname p4-aes67, name P4 AES67) and the "source" group in main/project_cfg.c. - Config is stored only; nothing is applied live yet. - Verified on board: defaults, valid save, 8 rejected values (nothing stored), persistence across reboot, restore to defaults. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+3
-2
@@ -1,4 +1,5 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
idf_component_register(SRCS "main.c" "project_cfg.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES esp_app_format esp_hw_support
|
||||
aes67_board aes67_net aes67_health aes67_tx aes67_web)
|
||||
aes67_board aes67_health aes67_net aes67_ptp
|
||||
aes67_syslog aes67_tx aes67_web)
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "aes67_board.h"
|
||||
#include "aes67_health.h"
|
||||
#include "aes67_net.h"
|
||||
#include "aes67_ptp.h"
|
||||
#include "aes67_syslog.h"
|
||||
#include "aes67_tx.h"
|
||||
#include "aes67_web.h"
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_log.h"
|
||||
#include "project_cfg.h"
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
@@ -20,10 +23,15 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "chip rev v%d.%d, %d cores",
|
||||
chip.revision / 100, chip.revision % 100, chip.cores);
|
||||
|
||||
project_cfg_defaults();
|
||||
|
||||
esp_eth_handle_t eth;
|
||||
ESP_ERROR_CHECK(aes67_board_eth_init(ð));
|
||||
ESP_ERROR_CHECK(aes67_net_init(eth));
|
||||
ESP_ERROR_CHECK(aes67_health_init());
|
||||
ESP_ERROR_CHECK(aes67_ptp_init());
|
||||
ESP_ERROR_CHECK(aes67_tx_init());
|
||||
ESP_ERROR_CHECK(aes67_syslog_init());
|
||||
project_cfg_register();
|
||||
ESP_ERROR_CHECK(aes67_web_start());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Project config: defaults over the core groups and the "source" group.
|
||||
#include "project_cfg.h"
|
||||
|
||||
#include "aes67_cfg.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
static const char SOURCE_DEFAULTS[] =
|
||||
"{\"mode\":\"spotify\",\"spotify_name\":\"P4 AES67\",\"spotify_bitrate\":320,\"hls_url\":\"\","
|
||||
"\"autoplay\":false,\"gain_db\":0,\"failover_delay_s\":5,\"failover_on_pause\":false}";
|
||||
|
||||
static bool source_validate(const cJSON *g, char *err, size_t n)
|
||||
{
|
||||
static const char *const modes[] = { "spotify", "hls", "auto", "off", NULL };
|
||||
static const double bitrates[] = { 96, 160, 320 };
|
||||
return cfg_check_enum(g, "mode", modes, err, n) &&
|
||||
cfg_check_str(g, "spotify_name", 1, 63, err, n) &&
|
||||
cfg_check_num_in(g, "spotify_bitrate", bitrates, 3, err, n) &&
|
||||
cfg_check_str(g, "hls_url", 0, 255, err, n) &&
|
||||
cfg_check_num(g, "gain_db", -60, 12, err, n) &&
|
||||
cfg_check_int(g, "failover_delay_s", 0, 3600, err, n);
|
||||
}
|
||||
|
||||
void project_cfg_defaults(void)
|
||||
{
|
||||
// Same as PROJECT.def in web/index.html.
|
||||
ESP_ERROR_CHECK(cfg_override_defaults("aes67", "{\"name\":\"P4 AES67\"}"));
|
||||
ESP_ERROR_CHECK(cfg_override_defaults("net", "{\"hostname\":\"p4-aes67\"}"));
|
||||
}
|
||||
|
||||
void project_cfg_register(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(cfg_register("source", SOURCE_DEFAULTS, source_validate, NULL));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
// Call before the core components register their groups.
|
||||
void project_cfg_defaults(void);
|
||||
// Registers the project's own config groups.
|
||||
void project_cfg_register(void);
|
||||
Reference in New Issue
Block a user