esp32-sip-client-with-headset/main/config/config_manager.c

391 lines
12 KiB
C

/**
* Config Manager - NVS-basierte Konfigurationsverwaltung
*/
#include <string.h>
#include "config_manager.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "nvs.h"
static const char* TAG = "CONFIG";
// NVS Namespace
#define NVS_NAMESPACE "bsc_config"
// NVS Keys
#define KEY_WIFI_SSID "wifi_ssid"
#define KEY_WIFI_PASS "wifi_pass"
#define KEY_WIFI_IP_MODE "wifi_ip_mode"
#define KEY_WIFI_STATIC_IP "wifi_static_ip"
#define KEY_WIFI_GATEWAY "wifi_gw"
#define KEY_WIFI_NETMASK "wifi_nm"
#define KEY_WIFI_DNS "wifi_dns"
#define KEY_SIP_SERVER "sip_server"
#define KEY_SIP_PORT "sip_port"
#define KEY_SIP_USER "sip_user"
#define KEY_SIP_PASS "sip_pass"
#define KEY_SIP_DISPLAY "sip_display"
#define KEY_BT_NAME "bt_name"
#define KEY_BT_DISCOVERABLE "bt_disc"
#define KEY_BT_DEV_COUNT "bt_dev_cnt"
#define KEY_BT_DEV_PREFIX "bt_dev_" // bt_dev_0, bt_dev_1, ...
// Aktuelle Konfiguration
static device_config_t s_config;
static bool s_initialized = false;
// NVS Handle
static nvs_handle_t s_nvs_handle;
// Hilfsfunktionen
static esp_err_t load_string(const char* key, char* buf, size_t max_len)
{
size_t len = max_len;
esp_err_t err = nvs_get_str(s_nvs_handle, key, buf, &len);
if (err == ESP_ERR_NVS_NOT_FOUND) {
buf[0] = '\0';
return ESP_OK;
}
return err;
}
static esp_err_t save_string(const char* key, const char* value)
{
return nvs_set_str(s_nvs_handle, key, value);
}
static esp_err_t load_wifi_config(void)
{
esp_err_t err;
err = load_string(KEY_WIFI_SSID, s_config.wifi.ssid, CONFIG_MAX_SSID_LEN);
if (err != ESP_OK) return err;
err = load_string(KEY_WIFI_PASS, s_config.wifi.password, CONFIG_MAX_PASSWORD_LEN);
if (err != ESP_OK) return err;
uint8_t ip_mode = 0;
err = nvs_get_u8(s_nvs_handle, KEY_WIFI_IP_MODE, &ip_mode);
if (err == ESP_ERR_NVS_NOT_FOUND) {
s_config.wifi.ip_mode = IP_MODE_DHCP;
} else if (err == ESP_OK) {
s_config.wifi.ip_mode = (ip_mode_t)ip_mode;
} else {
return err;
}
load_string(KEY_WIFI_STATIC_IP, s_config.wifi.static_ip, CONFIG_MAX_IP_LEN);
load_string(KEY_WIFI_GATEWAY, s_config.wifi.gateway, CONFIG_MAX_IP_LEN);
load_string(KEY_WIFI_NETMASK, s_config.wifi.netmask, CONFIG_MAX_IP_LEN);
load_string(KEY_WIFI_DNS, s_config.wifi.dns, CONFIG_MAX_IP_LEN);
// Konfiguriert wenn SSID vorhanden
s_config.wifi.configured = (strlen(s_config.wifi.ssid) > 0);
return ESP_OK;
}
static esp_err_t load_sip_config(void)
{
esp_err_t err;
err = load_string(KEY_SIP_SERVER, s_config.sip.server, CONFIG_MAX_SIP_SERVER_LEN);
if (err != ESP_OK) return err;
uint16_t port = CONFIG_BSC_SIP_DEFAULT_PORT;
nvs_get_u16(s_nvs_handle, KEY_SIP_PORT, &port);
s_config.sip.port = port;
load_string(KEY_SIP_USER, s_config.sip.username, CONFIG_MAX_SIP_USER_LEN);
load_string(KEY_SIP_PASS, s_config.sip.password, CONFIG_MAX_PASSWORD_LEN);
load_string(KEY_SIP_DISPLAY, s_config.sip.display_name, CONFIG_MAX_SIP_USER_LEN);
// Konfiguriert wenn Server und User vorhanden
s_config.sip.configured = (strlen(s_config.sip.server) > 0 &&
strlen(s_config.sip.username) > 0);
return ESP_OK;
}
static esp_err_t load_bt_config(void)
{
// Bluetooth-Gerätename
esp_err_t err = load_string(KEY_BT_NAME, s_config.bluetooth.device_name, CONFIG_MAX_BT_NAME_LEN);
if (err != ESP_OK || strlen(s_config.bluetooth.device_name) == 0) {
strncpy(s_config.bluetooth.device_name, CONFIG_BSC_BT_DEVICE_NAME, CONFIG_MAX_BT_NAME_LEN);
}
// Discoverable Status
uint8_t disc = 1;
nvs_get_u8(s_nvs_handle, KEY_BT_DISCOVERABLE, &disc);
s_config.bluetooth.discoverable = (disc != 0);
// Gepaarte Geräte laden
uint8_t dev_count = 0;
nvs_get_u8(s_nvs_handle, KEY_BT_DEV_COUNT, &dev_count);
s_config.bluetooth.device_count = 0;
for (int i = 0; i < dev_count && i < CONFIG_BSC_MAX_BT_DEVICES; i++) {
char key[32];
char data[128];
snprintf(key, sizeof(key), "%s%d", KEY_BT_DEV_PREFIX, i);
size_t len = sizeof(data);
if (nvs_get_str(s_nvs_handle, key, data, &len) == ESP_OK) {
// Format: "address|name|auto_connect|priority"
bt_device_config_t* dev = &s_config.bluetooth.devices[s_config.bluetooth.device_count];
char* token = strtok(data, "|");
if (token) strncpy(dev->address, token, CONFIG_MAX_BT_ADDR_LEN);
token = strtok(NULL, "|");
if (token) strncpy(dev->name, token, CONFIG_MAX_BT_NAME_LEN);
token = strtok(NULL, "|");
if (token) dev->auto_connect = (atoi(token) != 0);
token = strtok(NULL, "|");
if (token) dev->priority = (uint8_t)atoi(token);
dev->paired = true;
s_config.bluetooth.device_count++;
}
}
return ESP_OK;
}
static esp_err_t save_bt_devices(void)
{
esp_err_t err;
// Anzahl speichern
err = nvs_set_u8(s_nvs_handle, KEY_BT_DEV_COUNT, s_config.bluetooth.device_count);
if (err != ESP_OK) return err;
// Jedes Gerät speichern
for (int i = 0; i < s_config.bluetooth.device_count; i++) {
char key[32];
char data[128];
bt_device_config_t* dev = &s_config.bluetooth.devices[i];
snprintf(key, sizeof(key), "%s%d", KEY_BT_DEV_PREFIX, i);
snprintf(data, sizeof(data), "%s|%s|%d|%d",
dev->address, dev->name, dev->auto_connect ? 1 : 0, dev->priority);
err = nvs_set_str(s_nvs_handle, key, data);
if (err != ESP_OK) return err;
}
return nvs_commit(s_nvs_handle);
}
// Public API
esp_err_t config_manager_init(void)
{
if (s_initialized) {
return ESP_OK;
}
ESP_LOGI(TAG, "Initialisiere Config Manager");
// NVS öffnen
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &s_nvs_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "NVS öffnen fehlgeschlagen: %s", esp_err_to_name(err));
return err;
}
// Konfiguration initialisieren
memset(&s_config, 0, sizeof(s_config));
// Laden
err = load_wifi_config();
if (err != ESP_OK) {
ESP_LOGW(TAG, "WiFi-Config laden fehlgeschlagen: %s", esp_err_to_name(err));
}
err = load_sip_config();
if (err != ESP_OK) {
ESP_LOGW(TAG, "SIP-Config laden fehlgeschlagen: %s", esp_err_to_name(err));
}
err = load_bt_config();
if (err != ESP_OK) {
ESP_LOGW(TAG, "BT-Config laden fehlgeschlagen: %s", esp_err_to_name(err));
}
ESP_LOGI(TAG, "Konfiguration geladen:");
ESP_LOGI(TAG, " WiFi: %s", s_config.wifi.configured ? s_config.wifi.ssid : "(nicht konfiguriert)");
ESP_LOGI(TAG, " SIP: %s", s_config.sip.configured ? s_config.sip.server : "(nicht konfiguriert)");
ESP_LOGI(TAG, " BT: %d gepaarte Geräte", s_config.bluetooth.device_count);
s_initialized = true;
return ESP_OK;
}
const device_config_t* config_get(void)
{
return &s_config;
}
esp_err_t config_save_wifi(const wifi_config_data_t* wifi_config)
{
if (!wifi_config) return ESP_ERR_INVALID_ARG;
ESP_LOGI(TAG, "Speichere WiFi-Konfiguration: SSID=%s", wifi_config->ssid);
esp_err_t err;
err = save_string(KEY_WIFI_SSID, wifi_config->ssid);
if (err != ESP_OK) return err;
err = save_string(KEY_WIFI_PASS, wifi_config->password);
if (err != ESP_OK) return err;
err = nvs_set_u8(s_nvs_handle, KEY_WIFI_IP_MODE, (uint8_t)wifi_config->ip_mode);
if (err != ESP_OK) return err;
if (wifi_config->ip_mode == IP_MODE_STATIC) {
save_string(KEY_WIFI_STATIC_IP, wifi_config->static_ip);
save_string(KEY_WIFI_GATEWAY, wifi_config->gateway);
save_string(KEY_WIFI_NETMASK, wifi_config->netmask);
save_string(KEY_WIFI_DNS, wifi_config->dns);
}
err = nvs_commit(s_nvs_handle);
if (err != ESP_OK) return err;
// Lokale Kopie aktualisieren
memcpy(&s_config.wifi, wifi_config, sizeof(wifi_config_data_t));
s_config.wifi.configured = (strlen(s_config.wifi.ssid) > 0);
return ESP_OK;
}
esp_err_t config_save_sip(const sip_config_data_t* sip_config)
{
if (!sip_config) return ESP_ERR_INVALID_ARG;
ESP_LOGI(TAG, "Speichere SIP-Konfiguration: %s@%s:%d",
sip_config->username, sip_config->server, sip_config->port);
esp_err_t err;
err = save_string(KEY_SIP_SERVER, sip_config->server);
if (err != ESP_OK) return err;
err = nvs_set_u16(s_nvs_handle, KEY_SIP_PORT, sip_config->port);
if (err != ESP_OK) return err;
err = save_string(KEY_SIP_USER, sip_config->username);
if (err != ESP_OK) return err;
err = save_string(KEY_SIP_PASS, sip_config->password);
if (err != ESP_OK) return err;
save_string(KEY_SIP_DISPLAY, sip_config->display_name);
err = nvs_commit(s_nvs_handle);
if (err != ESP_OK) return err;
// Lokale Kopie aktualisieren
memcpy(&s_config.sip, sip_config, sizeof(sip_config_data_t));
s_config.sip.configured = (strlen(s_config.sip.server) > 0 &&
strlen(s_config.sip.username) > 0);
return ESP_OK;
}
esp_err_t config_save_bt_device(const bt_device_config_t* device)
{
if (!device) return ESP_ERR_INVALID_ARG;
// Prüfen ob Gerät bereits existiert
for (int i = 0; i < s_config.bluetooth.device_count; i++) {
if (strcmp(s_config.bluetooth.devices[i].address, device->address) == 0) {
// Update
memcpy(&s_config.bluetooth.devices[i], device, sizeof(bt_device_config_t));
return save_bt_devices();
}
}
// Neues Gerät
if (s_config.bluetooth.device_count >= CONFIG_BSC_MAX_BT_DEVICES) {
ESP_LOGW(TAG, "Maximale Anzahl BT-Geräte erreicht");
return ESP_ERR_NO_MEM;
}
memcpy(&s_config.bluetooth.devices[s_config.bluetooth.device_count],
device, sizeof(bt_device_config_t));
s_config.bluetooth.device_count++;
ESP_LOGI(TAG, "BT-Gerät hinzugefügt: %s (%s)", device->name, device->address);
return save_bt_devices();
}
esp_err_t config_remove_bt_device(const char* address)
{
if (!address) return ESP_ERR_INVALID_ARG;
for (int i = 0; i < s_config.bluetooth.device_count; i++) {
if (strcmp(s_config.bluetooth.devices[i].address, address) == 0) {
// Gefunden - entfernen durch Verschieben
ESP_LOGI(TAG, "Entferne BT-Gerät: %s", address);
for (int j = i; j < s_config.bluetooth.device_count - 1; j++) {
memcpy(&s_config.bluetooth.devices[j],
&s_config.bluetooth.devices[j + 1],
sizeof(bt_device_config_t));
}
s_config.bluetooth.device_count--;
return save_bt_devices();
}
}
return ESP_ERR_NOT_FOUND;
}
esp_err_t config_clear_bt_devices(void)
{
ESP_LOGI(TAG, "Lösche alle BT-Geräte");
s_config.bluetooth.device_count = 0;
return save_bt_devices();
}
esp_err_t config_factory_reset(void)
{
ESP_LOGW(TAG, "Werksreset durchführen!");
esp_err_t err = nvs_erase_all(s_nvs_handle);
if (err != ESP_OK) return err;
err = nvs_commit(s_nvs_handle);
if (err != ESP_OK) return err;
// Konfiguration zurücksetzen
memset(&s_config, 0, sizeof(s_config));
strncpy(s_config.bluetooth.device_name, CONFIG_BSC_BT_DEVICE_NAME, CONFIG_MAX_BT_NAME_LEN);
s_config.bluetooth.discoverable = true;
s_config.sip.port = CONFIG_BSC_SIP_DEFAULT_PORT;
return ESP_OK;
}
bool config_wifi_is_configured(void)
{
return s_config.wifi.configured;
}
bool config_sip_is_configured(void)
{
return s_config.sip.configured;
}