#include "ssid_manager_c.h" #include #include #include #include #define TAG "SsidManager" #define NVS_NAMESPACE "wifi" #define MAX_WIFI_SSID_COUNT 10 #define MAX_SSID_LEN 32 #define MAX_PASS_LEN 64 // 内部结构体定义 typedef struct { char ssid[MAX_SSID_LEN + 1]; char password[MAX_PASS_LEN + 1]; } SsidEntry; struct SsidManager { SsidEntry entries[MAX_WIFI_SSID_COUNT]; int count; }; // 函数实现 SsidManager* ssid_manager_create() { SsidManager* manager = (SsidManager*)malloc(sizeof(SsidManager)); if (manager) { manager->count = 0; ssid_manager_load_from_nvs(manager); } return manager; } void ssid_manager_destroy(SsidManager* manager) { if (manager) { free(manager); } } void ssid_manager_clear(SsidManager* manager) { manager->count = 0; ssid_manager_save_to_nvs(manager); } void ssid_manager_load_from_nvs(SsidManager* manager) { manager->count = 0; nvs_handle_t nvs_handle; esp_err_t ret = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle); if (ret != ESP_OK) { ESP_LOGW(TAG, "NVS namespace %s doesn't exist", NVS_NAMESPACE); return; } for (int i = 0; i < MAX_WIFI_SSID_COUNT; i++) { char ssid_key[12]; char password_key[12]; // 安全生成键名 if (i == 0) { strncpy(ssid_key, "ssid", sizeof(ssid_key)); strncpy(password_key, "password", sizeof(password_key)); } else { // 使用更安全的格式化方式 int written = snprintf(ssid_key, sizeof(ssid_key), "ssid%d", i); if (written < 0 || written >= sizeof(ssid_key)) { ESP_LOGE(TAG, "ssid_key truncation for index %d", i); continue; } written = snprintf(password_key, sizeof(password_key), "password%d", i); if (written < 0 || written >= sizeof(password_key)) { ESP_LOGE(TAG, "password_key truncation for index %d", i); continue; } } char ssid[MAX_SSID_LEN + 1] = {0}; char password[MAX_PASS_LEN + 1] = {0}; size_t len = sizeof(ssid); // 获取SSID if (nvs_get_str(nvs_handle, ssid_key, ssid, &len) != ESP_OK) { continue; } // 获取密码 len = sizeof(password); if (nvs_get_str(nvs_handle, password_key, password, &len) != ESP_OK) { continue; } // 添加到管理器 if (manager->count < MAX_WIFI_SSID_COUNT) { strncpy(manager->entries[manager->count].ssid, ssid, MAX_SSID_LEN); manager->entries[manager->count].ssid[MAX_SSID_LEN] = '\0'; // 确保空终止 strncpy(manager->entries[manager->count].password, password, MAX_PASS_LEN); manager->entries[manager->count].password[MAX_PASS_LEN] = '\0'; // 确保空终止 manager->count++; } } nvs_close(nvs_handle); } void ssid_manager_save_to_nvs(SsidManager* manager) { nvs_handle_t nvs_handle; ESP_ERROR_CHECK(nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle)); // 安全清除所有旧键值 for (int i = 0; i < MAX_WIFI_SSID_COUNT; i++) { char ssid_key[12]; char password_key[12]; // 安全生成键名 if (i == 0) { strncpy(ssid_key, "ssid", sizeof(ssid_key)); strncpy(password_key, "password", sizeof(password_key)); } else { // 使用更安全的格式化方式 int written = snprintf(ssid_key, sizeof(ssid_key), "ssid%d", i); if (written < 0 || written >= sizeof(ssid_key)) { ESP_LOGE(TAG, "ssid_key truncation for index %d", i); continue; } written = snprintf(password_key, sizeof(password_key), "password%d", i); if (written < 0 || written >= sizeof(password_key)) { ESP_LOGE(TAG, "password_key truncation for index %d", i); continue; } } // 清除键值 nvs_erase_key(nvs_handle, ssid_key); nvs_erase_key(nvs_handle, password_key); } // 安全保存新数据 for (int i = 0; i < manager->count; i++) { char ssid_key[12]; char password_key[12]; // 安全生成键名 if (i == 0) { strncpy(ssid_key, "ssid", sizeof(ssid_key)); strncpy(password_key, "password", sizeof(password_key)); } else { // 使用更安全的格式化方式 int written = snprintf(ssid_key, sizeof(ssid_key), "ssid%d", i); if (written < 0 || written >= sizeof(ssid_key)) { ESP_LOGE(TAG, "ssid_key truncation for index %d", i); continue; } written = snprintf(password_key, sizeof(password_key), "password%d", i); if (written < 0 || written >= sizeof(password_key)) { ESP_LOGE(TAG, "password_key truncation for index %d", i); continue; } } // 设置键值 nvs_set_str(nvs_handle, ssid_key, manager->entries[i].ssid); nvs_set_str(nvs_handle, password_key, manager->entries[i].password); } nvs_commit(nvs_handle); nvs_close(nvs_handle); } void ssid_manager_add_ssid(SsidManager* manager, const char* ssid, const char* password) { // 检查是否已存在 for (int i = 0; i < manager->count; i++) { if (strcmp(manager->entries[i].ssid, ssid) == 0) { ESP_LOGW(TAG, "SSID %s already exists, overwrite it", ssid); strncpy(manager->entries[i].password, password, MAX_PASS_LEN); manager->entries[i].password[MAX_PASS_LEN] = '\0'; // 确保空终止 ssid_manager_save_to_nvs(manager); return; } } // 处理列表已满的情况 if (manager->count >= MAX_WIFI_SSID_COUNT) { ESP_LOGW(TAG, "SSID list is full, removing last entry"); manager->count--; } // 移动现有条目(为新条目腾出空间) for (int i = manager->count; i > 0; i--) { memcpy(&manager->entries[i], &manager->entries[i-1], sizeof(SsidEntry)); } // 添加新条目到开头 strncpy(manager->entries[0].ssid, ssid, MAX_SSID_LEN); manager->entries[0].ssid[MAX_SSID_LEN] = '\0'; // 确保空终止 strncpy(manager->entries[0].password, password, MAX_PASS_LEN); manager->entries[0].password[MAX_PASS_LEN] = '\0'; // 确保空终止 manager->count++; ssid_manager_save_to_nvs(manager); } void ssid_manager_remove_ssid(SsidManager* manager, int index) { if (index < 0 || index >= manager->count) { ESP_LOGW(TAG, "Invalid index %d", index); return; } // 移动后续条目覆盖要删除的条目 for (int i = index; i < manager->count - 1; i++) { memcpy(&manager->entries[i], &manager->entries[i+1], sizeof(SsidEntry)); } manager->count--; ssid_manager_save_to_nvs(manager); } void ssid_manager_set_default_ssid(SsidManager* manager, int index) { if (index < 0 || index >= manager->count) { ESP_LOGW(TAG, "Invalid index %d", index); return; } if (index == 0) { return; // 已经是默认 } // 保存目标条目 SsidEntry target; memcpy(&target, &manager->entries[index], sizeof(SsidEntry)); // 移动前面的条目 for (int i = index; i > 0; i--) { memcpy(&manager->entries[i], &manager->entries[i-1], sizeof(SsidEntry)); } // 将目标条目放在开头 memcpy(&manager->entries[0], &target, sizeof(SsidEntry)); ssid_manager_save_to_nvs(manager); } // 辅助函数 int ssid_manager_get_count(SsidManager* manager) { return manager->count; } const char* ssid_manager_get_ssid(SsidManager* manager, int index) { if (index < 0 || index >= manager->count) return NULL; return manager->entries[index].ssid; } const char* ssid_manager_get_password(SsidManager* manager, int index) { if (index < 0 || index >= manager->count) return NULL; return manager->entries[index].password; }