146 lines
4.2 KiB
C
146 lines
4.2 KiB
C
/* SPDX-License-Identifier: GPL-3.0-only */
|
|
/* Versioned persistent configuration for the station mDNS hostname. */
|
|
|
|
#include "mdns_config.h"
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#include "esp_mac.h"
|
|
#include "nvs.h"
|
|
#include "nvs_flash.h"
|
|
|
|
_Static_assert(sizeof(mdns_config_t) == MDNS_CONFIG_BLOB_SIZE,
|
|
"mDNS config schema size changed");
|
|
|
|
static bool suffix_character_is_valid(char character)
|
|
{
|
|
return (character >= 'a' && character <= 'z') ||
|
|
(character >= '0' && character <= '9') || character == '-';
|
|
}
|
|
|
|
void mdns_config_defaults(mdns_config_t *config)
|
|
{
|
|
static const char hex[] = "0123456789abcdef";
|
|
uint8_t mac[6] = {0};
|
|
|
|
if (config == NULL) {
|
|
return;
|
|
}
|
|
|
|
memset(config, 0, sizeof(*config));
|
|
config->schema_version = MDNS_CONFIG_SCHEMA_VERSION;
|
|
config->blob_size = MDNS_CONFIG_BLOB_SIZE;
|
|
if (esp_read_mac(mac, ESP_MAC_WIFI_STA) != ESP_OK) {
|
|
return;
|
|
}
|
|
for (size_t index = 0U; index < sizeof(mac); ++index) {
|
|
config->suffix[index * 2U] = hex[mac[index] >> 4U];
|
|
config->suffix[index * 2U + 1U] = hex[mac[index] & 0x0fU];
|
|
}
|
|
config->suffix_len = sizeof(mac) * 2U;
|
|
}
|
|
|
|
esp_err_t mdns_config_validate(const mdns_config_t *config)
|
|
{
|
|
if (config == NULL || config->schema_version != MDNS_CONFIG_SCHEMA_VERSION ||
|
|
config->blob_size != MDNS_CONFIG_BLOB_SIZE || config->suffix_len == 0U ||
|
|
config->suffix_len > MDNS_CONFIG_SUFFIX_MAX_LEN || config->reserved != 0U ||
|
|
config->suffix[config->suffix_len] != '\0') {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
if (config->suffix[0] == '-' || config->suffix[config->suffix_len - 1U] == '-') {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
for (size_t index = 0U; index < MDNS_CONFIG_SUFFIX_MAX_LEN; ++index) {
|
|
if (index < config->suffix_len) {
|
|
if (!suffix_character_is_valid(config->suffix[index])) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
} else if (config->suffix[index] != '\0') {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t mdns_config_load(mdns_config_t *config, bool *used_stored_config)
|
|
{
|
|
if (config == NULL || used_stored_config == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
mdns_config_defaults(config);
|
|
*used_stored_config = false;
|
|
if (mdns_config_validate(config) != ESP_OK) {
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
esp_err_t error = nvs_flash_init();
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
nvs_handle_t handle;
|
|
error = nvs_open(MDNS_CONFIG_NVS_NAMESPACE, NVS_READONLY, &handle);
|
|
if (error == ESP_ERR_NVS_NOT_FOUND) {
|
|
return ESP_OK;
|
|
}
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
size_t size = 0U;
|
|
error = nvs_get_blob(handle, MDNS_CONFIG_NVS_BLOB_KEY, NULL, &size);
|
|
if (error == ESP_ERR_NVS_NOT_FOUND || error == ESP_ERR_NVS_TYPE_MISMATCH ||
|
|
(error == ESP_OK && size != sizeof(*config))) {
|
|
nvs_close(handle);
|
|
return ESP_OK;
|
|
}
|
|
if (error != ESP_OK) {
|
|
nvs_close(handle);
|
|
return error;
|
|
}
|
|
mdns_config_t stored = {0};
|
|
error = nvs_get_blob(handle, MDNS_CONFIG_NVS_BLOB_KEY, &stored, &size);
|
|
nvs_close(handle);
|
|
if (error == ESP_ERR_NVS_INVALID_LENGTH) {
|
|
return ESP_OK;
|
|
}
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
if (size == sizeof(stored) && mdns_config_validate(&stored) == ESP_OK) {
|
|
*config = stored;
|
|
*used_stored_config = true;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t mdns_config_save(const mdns_config_t *config)
|
|
{
|
|
esp_err_t error = mdns_config_validate(config);
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
error = nvs_flash_init();
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
nvs_handle_t handle;
|
|
error = nvs_open(MDNS_CONFIG_NVS_NAMESPACE, NVS_READWRITE, &handle);
|
|
if (error != ESP_OK) {
|
|
return error;
|
|
}
|
|
error = nvs_set_blob(handle, MDNS_CONFIG_NVS_BLOB_KEY, config, sizeof(*config));
|
|
if (error == ESP_OK) {
|
|
error = nvs_commit(handle);
|
|
}
|
|
nvs_close(handle);
|
|
return error;
|
|
}
|
|
|
|
esp_err_t mdns_config_reset_storage(void)
|
|
{
|
|
mdns_config_t config;
|
|
mdns_config_defaults(&config);
|
|
return mdns_config_save(&config);
|
|
}
|