391 lines
12 KiB
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;
|
|
}
|