Add configurable Wi-Fi station mDNS hostname support. Mini-Feature #1
This commit is contained in:
@@ -38,6 +38,9 @@ idf_component_register(
|
||||
"wifi_config.c"
|
||||
"wifi_manager.c"
|
||||
"wifi_console.c"
|
||||
"mdns_config.c"
|
||||
"mdns_service.c"
|
||||
"mdns_console.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES
|
||||
bootloader_support
|
||||
@@ -58,6 +61,7 @@ idf_component_register(
|
||||
led_strip
|
||||
lwip
|
||||
mbedtls
|
||||
mdns
|
||||
nvs_flash
|
||||
wolfssl__wolfssh
|
||||
wolfssl__wolfssl
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
static const char *const s_root_candidates[] = {
|
||||
"help", "exit", "debug", "display", "serial", "broker", "usb", "user",
|
||||
"wifi", "web", "ssh", "ping", "nslookup", "traceroute", "reboot", "memory",
|
||||
"wifi", "mdns", "web", "ssh", "ping", "nslookup", "traceroute", "reboot", "memory",
|
||||
};
|
||||
|
||||
/* Keep full-line candidate strings grouped by their registered root command. */
|
||||
@@ -169,6 +169,14 @@ static const char *const s_completion_candidates[] = {
|
||||
"wifi nslookup",
|
||||
"wifi traceroute",
|
||||
|
||||
/* Station mDNS hostname configuration. */
|
||||
"mdns status",
|
||||
"mdns suffix",
|
||||
"mdns save",
|
||||
"mdns load",
|
||||
"mdns defaults",
|
||||
"mdns reset",
|
||||
|
||||
/* Authenticated HTTPS lifecycle and physical-admin recovery operations. */
|
||||
"web help",
|
||||
"web status",
|
||||
|
||||
@@ -4,6 +4,7 @@ dependencies:
|
||||
idf: ">=5.3.0"
|
||||
espressif/led_strip: "^3.0.3"
|
||||
espressif/esp_tinyusb: "^2.2.1"
|
||||
espressif/mdns: "^1.8.2"
|
||||
# Exact official registry versions form the reviewed Phase 6 integration baseline.
|
||||
wolfssl/wolfssl: "5.8.2~1"
|
||||
wolfssl/wolfssh: "1.4.20"
|
||||
|
||||
+23
@@ -14,6 +14,9 @@
|
||||
#include "local_ui_config.h"
|
||||
#include "local_ui_console.h"
|
||||
#include "local_ui_hw_test.h"
|
||||
#include "mdns_config.h"
|
||||
#include "mdns_console.h"
|
||||
#include "mdns_service.h"
|
||||
#include "rs232_hw_test.h"
|
||||
#include "rs232_port_owner.h"
|
||||
#include "secure_random.h"
|
||||
@@ -215,6 +218,23 @@ void app_main(void)
|
||||
"Stored Wi-Fi configuration is incompatible; using RAM defaults without overwriting it");
|
||||
}
|
||||
|
||||
mdns_config_t mdns_config;
|
||||
bool used_stored_mdns_config = false;
|
||||
esp_err_t mdns_config_error = mdns_config_load(&mdns_config, &used_stored_mdns_config);
|
||||
if (mdns_config_error != ESP_OK) {
|
||||
mdns_config_defaults(&mdns_config);
|
||||
ESP_LOGW(TAG, "NVS mDNS configuration unavailable (%s); using RAM defaults",
|
||||
esp_err_to_name(mdns_config_error));
|
||||
}
|
||||
esp_err_t mdns_service_error = mdns_service_init(&mdns_config);
|
||||
if (mdns_service_error != ESP_OK) {
|
||||
ESP_LOGW(TAG, "mDNS configuration service unavailable: %s; Wi-Fi will continue",
|
||||
esp_err_to_name(mdns_service_error));
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Using %s mDNS suffix sak-%s.local",
|
||||
used_stored_mdns_config ? "stored" : "default", mdns_config.suffix);
|
||||
}
|
||||
|
||||
esp_err_t wifi_error = wifi_config_error;
|
||||
if (wifi_config_error == ESP_OK) {
|
||||
wifi_error = wifi_manager_init(&wifi_config);
|
||||
@@ -301,6 +321,9 @@ void app_main(void)
|
||||
ESP_ERROR_CHECK(usb_console_register_commands());
|
||||
ESP_ERROR_CHECK(user_console_register_commands());
|
||||
ESP_ERROR_CHECK(wifi_console_register_commands());
|
||||
if (mdns_service_error == ESP_OK) {
|
||||
ESP_ERROR_CHECK(mdns_console_register_commands());
|
||||
}
|
||||
ESP_ERROR_CHECK(web_console_register_commands());
|
||||
ESP_ERROR_CHECK(ssh_console_register_commands());
|
||||
ESP_ERROR_CHECK(network_console_register_root_commands());
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/* 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);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* Versioned persistent configuration for the station mDNS hostname. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#define MDNS_CONFIG_SCHEMA_VERSION 1U
|
||||
#define MDNS_CONFIG_BLOB_SIZE 64U
|
||||
#define MDNS_CONFIG_SUFFIX_MAX_LEN 55U
|
||||
#define MDNS_CONFIG_NVS_NAMESPACE "mdns_cfg"
|
||||
#define MDNS_CONFIG_NVS_BLOB_KEY "config"
|
||||
|
||||
typedef struct {
|
||||
uint32_t schema_version;
|
||||
uint16_t blob_size;
|
||||
uint8_t suffix_len;
|
||||
uint8_t reserved;
|
||||
char suffix[MDNS_CONFIG_SUFFIX_MAX_LEN + 1U];
|
||||
} mdns_config_t;
|
||||
|
||||
void mdns_config_defaults(mdns_config_t *config);
|
||||
esp_err_t mdns_config_validate(const mdns_config_t *config);
|
||||
esp_err_t mdns_config_load(mdns_config_t *config, bool *used_stored_config);
|
||||
esp_err_t mdns_config_save(const mdns_config_t *config);
|
||||
esp_err_t mdns_config_reset_storage(void);
|
||||
@@ -0,0 +1,149 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* Administration console for the station mDNS hostname. */
|
||||
|
||||
#include "mdns_console.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_console.h"
|
||||
#include "mdns_config.h"
|
||||
#include "mdns_service.h"
|
||||
#include "wifi_manager.h"
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
printf("Usage: mdns status|suffix <lowercase-suffix>|save|load|defaults|reset\n");
|
||||
}
|
||||
|
||||
static int request_reannounce(void)
|
||||
{
|
||||
esp_err_t error = wifi_manager_mdns_reannounce();
|
||||
if (error != ESP_OK) {
|
||||
printf("mDNS configuration updated; it will be used when Wi-Fi STA receives an IP (%s).\n",
|
||||
esp_err_to_name(error));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_status(void)
|
||||
{
|
||||
mdns_service_snapshot_t snapshot;
|
||||
esp_err_t error = mdns_service_get_snapshot(&snapshot);
|
||||
if (error != ESP_OK) {
|
||||
printf("mDNS unavailable: %s\n", esp_err_to_name(error));
|
||||
return 1;
|
||||
}
|
||||
printf("mDNS: initialized=%s announced=%s hostname=%s.local suffix=%s last-error=%s\n",
|
||||
snapshot.initialized ? "yes" : "no", snapshot.announced ? "yes" : "no",
|
||||
snapshot.hostname, snapshot.suffix, esp_err_to_name(snapshot.last_error));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_suffix(const char *suffix)
|
||||
{
|
||||
size_t length = strlen(suffix);
|
||||
mdns_config_t config;
|
||||
esp_err_t error = mdns_service_get_config(&config);
|
||||
if (error == ESP_OK) {
|
||||
memset(config.suffix, 0, sizeof(config.suffix));
|
||||
if (length <= MDNS_CONFIG_SUFFIX_MAX_LEN) {
|
||||
memcpy(config.suffix, suffix, length);
|
||||
config.suffix_len = (uint8_t)length;
|
||||
error = mdns_service_set_config(&config);
|
||||
} else {
|
||||
error = ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
printf("Suffix must be 1..%u lowercase letters, digits, or hyphens, and cannot begin or end with a hyphen.\n",
|
||||
MDNS_CONFIG_SUFFIX_MAX_LEN);
|
||||
return 1;
|
||||
}
|
||||
printf("mDNS suffix updated in RAM; hostname is sak-%s.local; use 'mdns save' to persist it.\n",
|
||||
suffix);
|
||||
return request_reannounce();
|
||||
}
|
||||
|
||||
static int save_config(void)
|
||||
{
|
||||
mdns_config_t config;
|
||||
esp_err_t error = mdns_service_get_config(&config);
|
||||
if (error == ESP_OK) {
|
||||
error = mdns_config_save(&config);
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
printf("Could not save mDNS configuration: %s\n", esp_err_to_name(error));
|
||||
return 1;
|
||||
}
|
||||
printf("mDNS configuration saved to NVS.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_config(void)
|
||||
{
|
||||
mdns_config_t config;
|
||||
bool stored = false;
|
||||
esp_err_t error = mdns_config_load(&config, &stored);
|
||||
if (error == ESP_OK) {
|
||||
error = mdns_service_set_config(&config);
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
printf("Could not load mDNS configuration: %s\n", esp_err_to_name(error));
|
||||
return 1;
|
||||
}
|
||||
printf("Loaded %s mDNS configuration into RAM.\n", stored ? "stored" : "default");
|
||||
return request_reannounce();
|
||||
}
|
||||
|
||||
static int apply_defaults(bool persist)
|
||||
{
|
||||
mdns_config_t config;
|
||||
mdns_config_defaults(&config);
|
||||
esp_err_t error = mdns_service_set_config(&config);
|
||||
if (error == ESP_OK && persist) {
|
||||
error = mdns_config_save(&config);
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
printf("Could not apply mDNS defaults: %s\n", esp_err_to_name(error));
|
||||
return 1;
|
||||
}
|
||||
printf("MAC-derived mDNS defaults applied%s.\n", persist ? " and saved" : " in RAM");
|
||||
return request_reannounce();
|
||||
}
|
||||
|
||||
static int command_mdns(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1 || (argc == 2 && strcmp(argv[1], "status") == 0)) {
|
||||
return show_status();
|
||||
}
|
||||
if (argc == 3 && strcmp(argv[1], "suffix") == 0) {
|
||||
return set_suffix(argv[2]);
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "save") == 0) {
|
||||
return save_config();
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "load") == 0) {
|
||||
return load_config();
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "defaults") == 0) {
|
||||
return apply_defaults(false);
|
||||
}
|
||||
if (argc == 2 && strcmp(argv[1], "reset") == 0) {
|
||||
return apply_defaults(true);
|
||||
}
|
||||
print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t mdns_console_register_commands(void)
|
||||
{
|
||||
const esp_console_cmd_t command = {
|
||||
.command = "mdns",
|
||||
.help = "Configure the STA mDNS hostname; use 'mdns' for status",
|
||||
.hint = NULL,
|
||||
.func = &command_mdns,
|
||||
.argtable = NULL,
|
||||
};
|
||||
return esp_console_cmd_register(&command);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
esp_err_t mdns_console_register_commands(void);
|
||||
@@ -0,0 +1,133 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* mDNS runtime service; its lifecycle is owned by wifi_manager. */
|
||||
|
||||
#include "mdns_service.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "mdns.h"
|
||||
|
||||
static SemaphoreHandle_t s_mutex;
|
||||
static mdns_config_t s_config;
|
||||
static bool s_announced;
|
||||
static esp_err_t s_last_error;
|
||||
|
||||
static void lock_service(void)
|
||||
{
|
||||
(void)xSemaphoreTake(s_mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
static void unlock_service(void)
|
||||
{
|
||||
(void)xSemaphoreGive(s_mutex);
|
||||
}
|
||||
|
||||
static void make_hostname(const mdns_config_t *config, char *hostname, size_t size)
|
||||
{
|
||||
(void)snprintf(hostname, size, "sak-%s", config->suffix);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_init(const mdns_config_t *config)
|
||||
{
|
||||
if (mdns_config_validate(config) != ESP_OK) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (s_mutex != NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
s_mutex = xSemaphoreCreateMutex();
|
||||
if (s_mutex == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
s_config = *config;
|
||||
s_last_error = ESP_OK;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_get_config(mdns_config_t *config)
|
||||
{
|
||||
if (config == NULL || s_mutex == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
lock_service();
|
||||
*config = s_config;
|
||||
unlock_service();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_set_config(const mdns_config_t *config)
|
||||
{
|
||||
if (s_mutex == NULL || mdns_config_validate(config) != ESP_OK) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
lock_service();
|
||||
s_config = *config;
|
||||
unlock_service();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_get_snapshot(mdns_service_snapshot_t *snapshot)
|
||||
{
|
||||
if (snapshot == NULL || s_mutex == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
lock_service();
|
||||
memset(snapshot, 0, sizeof(*snapshot));
|
||||
snapshot->initialized = true;
|
||||
snapshot->announced = s_announced;
|
||||
memcpy(snapshot->suffix, s_config.suffix, s_config.suffix_len);
|
||||
make_hostname(&s_config, snapshot->hostname, sizeof(snapshot->hostname));
|
||||
snapshot->last_error = s_last_error;
|
||||
unlock_service();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_start(void)
|
||||
{
|
||||
if (s_mutex == NULL) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
lock_service();
|
||||
if (s_announced) {
|
||||
unlock_service();
|
||||
return ESP_OK;
|
||||
}
|
||||
mdns_config_t config = s_config;
|
||||
unlock_service();
|
||||
|
||||
esp_err_t error = mdns_init();
|
||||
if (error == ESP_OK) {
|
||||
char hostname[MDNS_CONFIG_SUFFIX_MAX_LEN + 5U] = {0};
|
||||
make_hostname(&config, hostname, sizeof(hostname));
|
||||
error = mdns_hostname_set(hostname);
|
||||
if (error == ESP_OK) {
|
||||
error = mdns_instance_name_set("ESP32 Serial Swiss Army Knife");
|
||||
}
|
||||
if (error != ESP_OK) {
|
||||
mdns_free();
|
||||
}
|
||||
}
|
||||
|
||||
lock_service();
|
||||
s_announced = error == ESP_OK;
|
||||
s_last_error = error;
|
||||
unlock_service();
|
||||
return error;
|
||||
}
|
||||
|
||||
void mdns_service_stop(void)
|
||||
{
|
||||
if (s_mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
lock_service();
|
||||
bool announced = s_announced;
|
||||
s_announced = false;
|
||||
unlock_service();
|
||||
if (announced) {
|
||||
mdns_free();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* mDNS runtime service; its lifecycle is owned by wifi_manager. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "mdns_config.h"
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
bool announced;
|
||||
char suffix[MDNS_CONFIG_SUFFIX_MAX_LEN + 1U];
|
||||
char hostname[MDNS_CONFIG_SUFFIX_MAX_LEN + 5U];
|
||||
esp_err_t last_error;
|
||||
} mdns_service_snapshot_t;
|
||||
|
||||
esp_err_t mdns_service_init(const mdns_config_t *config);
|
||||
esp_err_t mdns_service_get_config(mdns_config_t *config);
|
||||
esp_err_t mdns_service_set_config(const mdns_config_t *config);
|
||||
esp_err_t mdns_service_get_snapshot(mdns_service_snapshot_t *snapshot);
|
||||
|
||||
/* Only wifi_manager may call these lifecycle operations. */
|
||||
esp_err_t mdns_service_start(void);
|
||||
void mdns_service_stop(void);
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "mdns_service.h"
|
||||
|
||||
#define WIFI_MANAGER_QUEUE_LENGTH 16U
|
||||
#define WIFI_MANAGER_TASK_STACK_SIZE 6144U
|
||||
@@ -35,6 +36,7 @@ typedef enum {
|
||||
MESSAGE_COMMAND_APPLY,
|
||||
MESSAGE_COMMAND_RECONNECT,
|
||||
MESSAGE_COMMAND_NEXT_PROFILE,
|
||||
MESSAGE_COMMAND_MDNS_REANNOUNCE,
|
||||
MESSAGE_STA_CONNECTED,
|
||||
MESSAGE_STA_DISCONNECTED,
|
||||
MESSAGE_STA_GOT_IP,
|
||||
@@ -109,6 +111,15 @@ static void manager_task(void *context);
|
||||
static void start_profile_cycle(manager_runtime_t *runtime);
|
||||
static void start_next_profile(manager_runtime_t *runtime);
|
||||
|
||||
static void start_mdns_announcement(void)
|
||||
{
|
||||
esp_err_t error = mdns_service_start();
|
||||
if (error != ESP_OK) {
|
||||
/* Name discovery is optional; never make network or serial recovery depend on it. */
|
||||
ESP_LOGW(TAG, "mDNS announcement unavailable: %s", esp_err_to_name(error));
|
||||
}
|
||||
}
|
||||
|
||||
static void lock_shared(void)
|
||||
{
|
||||
(void)xSemaphoreTake(s_mutex, portMAX_DELAY);
|
||||
@@ -410,6 +421,7 @@ static void mark_intentional_disconnect(manager_runtime_t *runtime)
|
||||
|
||||
static void stop_radio(manager_runtime_t *runtime)
|
||||
{
|
||||
mdns_service_stop();
|
||||
if (!runtime->radio_started) {
|
||||
return;
|
||||
}
|
||||
@@ -744,6 +756,7 @@ static void handle_got_ip(manager_runtime_t *runtime,
|
||||
unlock_shared();
|
||||
|
||||
wifi_config_secure_wipe(&config, sizeof(config));
|
||||
start_mdns_announcement();
|
||||
}
|
||||
|
||||
static void handle_sta_disconnected(manager_runtime_t *runtime,
|
||||
@@ -764,6 +777,7 @@ static void handle_sta_disconnected(manager_runtime_t *runtime,
|
||||
bool had_attempt = runtime->attempt_deadline != 0;
|
||||
bool was_online = runtime->online;
|
||||
|
||||
mdns_service_stop();
|
||||
runtime->associated = false;
|
||||
runtime->online = false;
|
||||
runtime->attempt_deadline = 0;
|
||||
@@ -868,6 +882,13 @@ static void handle_message(manager_runtime_t *runtime,
|
||||
}
|
||||
break;
|
||||
|
||||
case MESSAGE_COMMAND_MDNS_REANNOUNCE:
|
||||
if (runtime->online) {
|
||||
mdns_service_stop();
|
||||
start_mdns_announcement();
|
||||
}
|
||||
break;
|
||||
|
||||
case MESSAGE_STA_CONNECTED:
|
||||
if (!manager_is_started() ||
|
||||
!connected_event_matches_active_profile(message)) {
|
||||
@@ -900,6 +921,7 @@ static void handle_message(manager_runtime_t *runtime,
|
||||
/* Ignore a delayed loss event after a newer DHCP lease. */
|
||||
break;
|
||||
}
|
||||
mdns_service_stop();
|
||||
runtime->online = false;
|
||||
runtime->stable_deadline = 0;
|
||||
runtime->attempt_deadline = esp_timer_get_time() + WIFI_MANAGER_ATTEMPT_US;
|
||||
@@ -1465,6 +1487,11 @@ esp_err_t wifi_manager_next_profile(void)
|
||||
return enqueue_lifecycle_command(MESSAGE_COMMAND_NEXT_PROFILE, -1);
|
||||
}
|
||||
|
||||
esp_err_t wifi_manager_mdns_reannounce(void)
|
||||
{
|
||||
return enqueue_lifecycle_command(MESSAGE_COMMAND_MDNS_REANNOUNCE, -1);
|
||||
}
|
||||
|
||||
esp_err_t wifi_manager_get_snapshot(wifi_manager_snapshot_t *snapshot)
|
||||
{
|
||||
if (snapshot == NULL) {
|
||||
|
||||
@@ -95,6 +95,8 @@ esp_err_t wifi_manager_stop(void);
|
||||
esp_err_t wifi_manager_reconnect(void);
|
||||
/* Advance to the next enabled station profile in priority order, wrapping safely. */
|
||||
esp_err_t wifi_manager_next_profile(void);
|
||||
/* Reannounce the configured hostname when the manager currently has a STA IP. */
|
||||
esp_err_t wifi_manager_mdns_reannounce(void);
|
||||
|
||||
/* Snapshot data never contains station or AP passwords. */
|
||||
esp_err_t wifi_manager_get_snapshot(wifi_manager_snapshot_t *snapshot);
|
||||
|
||||
Reference in New Issue
Block a user