feat(wifi): retain multiple network credentials
This commit is contained in:
@@ -15,8 +15,9 @@ typedef struct {
|
||||
/**
|
||||
* @brief Initialize Wi-Fi portal defaults and seed credentials.
|
||||
*
|
||||
* This writes the provided SSID/password into NVS if no credentials exist yet.
|
||||
* The underlying Wi-Fi manager is initialized lazily when starting STA or AP.
|
||||
* This saves the provided SSID/password as the highest-priority entry while
|
||||
* retaining existing credentials. The underlying Wi-Fi manager is initialized
|
||||
* lazily when starting STA or AP.
|
||||
*/
|
||||
esp_err_t wifi_portal_init_defaults(const char *seed_ssid, const char *seed_password);
|
||||
|
||||
@@ -50,8 +51,9 @@ esp_err_t wifi_portal_connect_sta(int timeout_ms);
|
||||
/**
|
||||
* @brief Trial-connect with credentials without persisting them first.
|
||||
*
|
||||
* On success, the trial credentials atomically replace the saved credential
|
||||
* list. On failure, the previous in-memory and NVS credentials remain intact.
|
||||
* On success, the trial credentials are saved as the highest-priority entry
|
||||
* while older credentials are retained. On failure, the previous in-memory
|
||||
* and NVS credentials remain intact.
|
||||
*/
|
||||
esp_err_t wifi_portal_connect_sta_with_credentials(const char *ssid,
|
||||
const char *password,
|
||||
|
||||
@@ -125,6 +125,35 @@ static esp_err_t wifi_portal_lock(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void promote_saved_wifi(const std::string &ssid)
|
||||
{
|
||||
if (ssid.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wifi_portal_lock() != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Could not promote connected Wi-Fi \"%s\": portal lock timed out",
|
||||
ssid.c_str());
|
||||
return;
|
||||
}
|
||||
PortalUnlockGuard guard;
|
||||
|
||||
install_wifi_storage_hooks();
|
||||
auto &credentials = SsidManager::GetInstance();
|
||||
const auto &ssid_list = credentials.GetSsidList();
|
||||
for (size_t i = 0; i < ssid_list.size(); ++i) {
|
||||
if (ssid_list[i].ssid != ssid) {
|
||||
continue;
|
||||
}
|
||||
if (i > 0U) {
|
||||
credentials.SetDefaultSsid((int)i);
|
||||
ESP_LOGI(TAG, "Promoted connected Wi-Fi \"%s\" to highest priority",
|
||||
ssid.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static wifi_portal_behavior_hooks_t snapshot_behavior_hooks(void)
|
||||
{
|
||||
wifi_portal_behavior_hooks_t hooks = {};
|
||||
@@ -153,6 +182,7 @@ static void wifi_manager_event_callback(WifiEvent event, const std::string &data
|
||||
break;
|
||||
case WifiEvent::Connected:
|
||||
ESP_LOGI(TAG, "Connected to \"%s\"", data.c_str());
|
||||
promote_saved_wifi(data);
|
||||
(void)apply_sta_stability_policy();
|
||||
break;
|
||||
case WifiEvent::Disconnected:
|
||||
@@ -209,24 +239,10 @@ static void seed_default_credentials(const char *ssid, const char *password)
|
||||
return;
|
||||
}
|
||||
|
||||
bool configured_ssid_saved = false;
|
||||
for (const auto &item : manager.GetSsidList()) {
|
||||
if (item.ssid == ssid) {
|
||||
configured_ssid_saved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (saved_count > 0U && !configured_ssid_saved) {
|
||||
ESP_LOGI(TAG,
|
||||
"Configured seed SSID changed to \"%s\"; replacing %u stale credential candidate(s)",
|
||||
ssid,
|
||||
(unsigned)saved_count);
|
||||
manager.Clear();
|
||||
}
|
||||
|
||||
manager.AddSsid(ssid, password != NULL ? password : "");
|
||||
promote_saved_wifi(ssid);
|
||||
ESP_LOGI(TAG,
|
||||
"Ensured configured Wi-Fi credentials for SSID \"%s\" with %u previous candidate(s)",
|
||||
"Ensured configured Wi-Fi credentials for SSID \"%s\" while preserving %u previous candidate(s)",
|
||||
ssid,
|
||||
(unsigned)saved_count);
|
||||
}
|
||||
@@ -456,10 +472,10 @@ esp_err_t wifi_portal_connect_sta_with_credentials(const char *ssid,
|
||||
ESP_RETURN_ON_ERROR(wifi_portal_lock(), TAG, "Failed to lock Wi-Fi portal");
|
||||
PortalUnlockGuard guard;
|
||||
auto &credentials = SsidManager::GetInstance();
|
||||
credentials.Clear();
|
||||
credentials.AddSsid(ssid, password != NULL ? password : "");
|
||||
promote_saved_wifi(ssid);
|
||||
ESP_LOGI(TAG,
|
||||
"Credential trial succeeded and replaced saved Wi-Fi for SSID \"%s\"",
|
||||
"Credential trial succeeded and saved Wi-Fi \"%s\" as highest priority",
|
||||
ssid);
|
||||
}
|
||||
|
||||
@@ -558,7 +574,8 @@ esp_err_t wifi_portal_save_credentials(const char *ssid, const char *password)
|
||||
"Password too long");
|
||||
|
||||
SsidManager::GetInstance().AddSsid(ssid, password != NULL ? password : "");
|
||||
ESP_LOGI(TAG, "Saved Wi-Fi credentials for SSID \"%s\"", ssid);
|
||||
promote_saved_wifi(ssid);
|
||||
ESP_LOGI(TAG, "Saved Wi-Fi credentials for SSID \"%s\" as highest priority", ssid);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user