Add Typed Display Settings Administration
Implements admin-only Display settings with generation-checked Apply, Save, Load, Defaults, and Reset operations across the web UI, CLI, SSH dispatcher, and local UI owner. Adds bounded HTTP handling, session-isolated operation results, browser lifecycle support, and comprehensive host tests and documentation.
This commit is contained in:
+61
-13
@@ -203,6 +203,8 @@ static TickType_t s_diagnostic_hold_started;
|
||||
static uint32_t s_external_activity_sequence;
|
||||
static local_ui_config_t s_config;
|
||||
static bool s_config_available;
|
||||
static bool s_config_busy;
|
||||
static uint32_t s_config_generation;
|
||||
|
||||
static const gpio_num_t s_button_gpios[LOCAL_STATUS_BUTTON_COUNT] = {
|
||||
LOCAL_UI_BUTTON_PREVIOUS_GPIO,
|
||||
@@ -1368,21 +1370,62 @@ esp_err_t local_status_ui_get_config(local_ui_config_t *config)
|
||||
return available ? ESP_OK : ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t local_status_ui_get_settings(local_ui_config_t *config, uint32_t *generation)
|
||||
{
|
||||
if (config == NULL || generation == NULL) return ESP_ERR_INVALID_ARG;
|
||||
portENTER_CRITICAL(&s_timing_mux);
|
||||
esp_err_t error = !s_config_available ? ESP_ERR_INVALID_STATE :
|
||||
s_config_busy ? ESP_ERR_TIMEOUT : ESP_OK;
|
||||
if (error == ESP_OK) {
|
||||
*config = s_config;
|
||||
*generation = s_config_generation;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
return error;
|
||||
}
|
||||
|
||||
esp_err_t local_status_ui_update_settings(local_ui_settings_action_t action,
|
||||
uint32_t expected_generation, const local_ui_config_t *config, bool *loaded_defaults)
|
||||
{
|
||||
if (loaded_defaults != NULL) *loaded_defaults = false;
|
||||
if (action < LOCAL_UI_SETTINGS_APPLY || action > LOCAL_UI_SETTINGS_RESET ||
|
||||
(action == LOCAL_UI_SETTINGS_APPLY && local_ui_config_validate(config) != ESP_OK))
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
local_ui_config_t candidate;
|
||||
portENTER_CRITICAL(&s_timing_mux);
|
||||
esp_err_t error = !s_config_available ||
|
||||
(expected_generation && expected_generation != s_config_generation) ||
|
||||
s_config_generation == UINT32_MAX ? ESP_ERR_INVALID_STATE :
|
||||
s_config_busy ? ESP_ERR_TIMEOUT : ESP_OK;
|
||||
if (error == ESP_OK) {
|
||||
candidate = action == LOCAL_UI_SETTINGS_APPLY ? *config : s_config;
|
||||
s_config_busy = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
if (error != ESP_OK) return error;
|
||||
|
||||
bool stored = true;
|
||||
if (action == LOCAL_UI_SETTINGS_LOAD) error = local_ui_config_load(&candidate, &stored);
|
||||
if (action == LOCAL_UI_SETTINGS_DEFAULTS || action == LOCAL_UI_SETTINGS_RESET)
|
||||
local_ui_config_defaults(&candidate);
|
||||
if (action == LOCAL_UI_SETTINGS_SAVE || action == LOCAL_UI_SETTINGS_RESET)
|
||||
error = local_ui_config_save(&candidate);
|
||||
|
||||
portENTER_CRITICAL(&s_timing_mux);
|
||||
if (error == ESP_OK && action != LOCAL_UI_SETTINGS_SAVE) {
|
||||
s_config = candidate;
|
||||
++s_config_generation;
|
||||
++s_external_activity_sequence;
|
||||
}
|
||||
s_config_busy = false;
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
if (error == ESP_OK && loaded_defaults != NULL) *loaded_defaults = !stored;
|
||||
return error;
|
||||
}
|
||||
|
||||
esp_err_t local_status_ui_apply_config(const local_ui_config_t *config)
|
||||
{
|
||||
esp_err_t error = local_ui_config_validate(config);
|
||||
if (error != ESP_OK) {
|
||||
return error;
|
||||
}
|
||||
portENTER_CRITICAL(&s_timing_mux);
|
||||
if (!s_config_available) {
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_config = *config;
|
||||
++s_external_activity_sequence;
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
return ESP_OK;
|
||||
return local_status_ui_update_settings(LOCAL_UI_SETTINGS_APPLY, 0, config, NULL);
|
||||
}
|
||||
|
||||
esp_err_t local_status_ui_start(const local_ui_config_t *config)
|
||||
@@ -1397,6 +1440,11 @@ esp_err_t local_status_ui_start(const local_ui_config_t *config)
|
||||
|
||||
portENTER_CRITICAL(&s_timing_mux);
|
||||
s_config = *config;
|
||||
if (s_config_generation == UINT32_MAX) {
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
++s_config_generation;
|
||||
s_config_available = true;
|
||||
portEXIT_CRITICAL(&s_timing_mux);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user