Skip to content

Commit 2cf028b

Browse files
DejinChenwqx6
andauthored
[ESP32] Support Thread and Wi-Fi network revert configuration (project-chip#33745)
* ESP32: Support Thread and Wi-Fi network revert configuration * Update src/platform/ESP32/NetworkCommissioningDriver.cpp Co-authored-by: Wang Qixiang <43193572+wqx6@users.noreply.github.com> * Update KeyValueStoreManagerImpl.cpp --------- Co-authored-by: Wang Qixiang <43193572+wqx6@users.noreply.github.com>
1 parent 3660c0d commit 2cf028b

File tree

3 files changed

+75
-33
lines changed

3 files changed

+75
-33
lines changed

src/platform/ESP32/KeyValueStoreManagerImpl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
6868
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
6969
size_t offset_bytes)
7070
{
71-
VerifyOrReturnError(value, CHIP_ERROR_INVALID_ARGUMENT);
71+
// value may be NULL when checking whether the key exists
7272

7373
// Offset and partial reads are not supported in nvs, for now just return NOT_IMPLEMENTED. Support can be added in the
7474
// future if this is needed.

src/platform/ESP32/NetworkCommissioningDriver.cpp

+73-31
Original file line numberDiff line numberDiff line change
@@ -95,39 +95,31 @@ CHIP_ERROR GetConfiguredNetwork(Network & network)
9595

9696
CHIP_ERROR ESPWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback)
9797
{
98-
CHIP_ERROR err;
99-
size_t ssidLen = 0;
100-
size_t credentialsLen = 0;
101-
102-
err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials,
103-
sizeof(mSavedNetwork.credentials), &credentialsLen);
104-
if (err == CHIP_ERROR_NOT_FOUND)
98+
wifi_config_t stationConfig;
99+
if (esp_wifi_get_config(WIFI_IF_STA, &stationConfig) == ESP_OK && stationConfig.sta.ssid[0] != 0)
105100
{
106-
return CHIP_NO_ERROR;
107-
}
101+
uint8_t ssidLen = static_cast<uint8_t>(
102+
strnlen(reinterpret_cast<const char *>(stationConfig.sta.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength));
103+
memcpy(mStagingNetwork.ssid, stationConfig.sta.ssid, ssidLen);
104+
mStagingNetwork.ssidLen = ssidLen;
108105

109-
err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, mSavedNetwork.ssid, sizeof(mSavedNetwork.ssid), &ssidLen);
110-
if (err == CHIP_ERROR_NOT_FOUND)
111-
{
112-
return CHIP_NO_ERROR;
113-
}
114-
if (!CanCastTo<uint8_t>(credentialsLen))
115-
{
116-
return CHIP_ERROR_INCORRECT_STATE;
117-
}
118-
mSavedNetwork.credentialsLen = static_cast<uint8_t>(credentialsLen);
106+
uint8_t credentialsLen = static_cast<uint8_t>(
107+
strnlen(reinterpret_cast<const char *>(stationConfig.sta.password), DeviceLayer::Internal::kMaxWiFiKeyLength));
119108

120-
if (!CanCastTo<uint8_t>(ssidLen))
121-
{
122-
return CHIP_ERROR_INCORRECT_STATE;
109+
memcpy(mStagingNetwork.credentials, stationConfig.sta.password, credentialsLen);
110+
mStagingNetwork.credentialsLen = credentialsLen;
123111
}
124-
mSavedNetwork.ssidLen = static_cast<uint8_t>(ssidLen);
125112

126-
mStagingNetwork = mSavedNetwork;
127113
mpScanCallback = nullptr;
128114
mpConnectCallback = nullptr;
129115
mpStatusChangeCallback = networkStatusChangeCallback;
130-
return err;
116+
117+
// If the network configuration backup exists, it means that the device has been rebooted with
118+
// the fail-safe armed. Since ESP-WiFi persists all wifi credentials changes, the backup must
119+
// be restored on the boot. If there's no backup, the below function is a no-op.
120+
RevertConfiguration();
121+
122+
return CHIP_NO_ERROR;
131123
}
132124

133125
void ESPWiFiDriver::Shutdown()
@@ -137,17 +129,51 @@ void ESPWiFiDriver::Shutdown()
137129

138130
CHIP_ERROR ESPWiFiDriver::CommitConfiguration()
139131
{
140-
ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen));
141-
ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials,
142-
mStagingNetwork.credentialsLen));
143-
mSavedNetwork = mStagingNetwork;
132+
PersistedStorage::KeyValueStoreMgr().Delete(kWiFiSSIDKeyName);
133+
PersistedStorage::KeyValueStoreMgr().Delete(kWiFiCredentialsKeyName);
134+
144135
return CHIP_NO_ERROR;
145136
}
146137

147138
CHIP_ERROR ESPWiFiDriver::RevertConfiguration()
148139
{
149-
mStagingNetwork = mSavedNetwork;
150-
return CHIP_NO_ERROR;
140+
WiFiNetwork network;
141+
Network configuredNetwork;
142+
size_t ssidLen = 0;
143+
size_t credentialsLen = 0;
144+
145+
CHIP_ERROR error = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, network.ssid, sizeof(network.ssid), &ssidLen);
146+
ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);
147+
VerifyOrExit(CanCastTo<uint8_t>(ssidLen), error = CHIP_ERROR_INTERNAL);
148+
VerifyOrExit(PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, network.credentials, sizeof(network.credentials),
149+
&credentialsLen) == CHIP_NO_ERROR,
150+
error = CHIP_ERROR_INTERNAL);
151+
VerifyOrExit(CanCastTo<uint8_t>(credentialsLen), error = CHIP_ERROR_INTERNAL);
152+
153+
network.ssidLen = static_cast<uint8_t>(ssidLen);
154+
network.credentialsLen = static_cast<uint8_t>(credentialsLen);
155+
mStagingNetwork = network;
156+
157+
if (GetConfiguredNetwork(configuredNetwork) == CHIP_NO_ERROR)
158+
{
159+
VerifyOrExit(!NetworkMatch(mStagingNetwork, ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)),
160+
error = CHIP_NO_ERROR);
161+
}
162+
163+
if (error == CHIP_NO_ERROR)
164+
{
165+
// ConnectWiFiNetwork can work with empty mStagingNetwork (ssidLen = 0).
166+
error = ConnectWiFiNetwork(reinterpret_cast<const char *>(mStagingNetwork.ssid), mStagingNetwork.ssidLen,
167+
reinterpret_cast<const char *>(mStagingNetwork.credentials), mStagingNetwork.credentialsLen);
168+
}
169+
170+
exit:
171+
172+
// Remove the backup.
173+
PersistedStorage::KeyValueStoreMgr().Delete(kWiFiSSIDKeyName);
174+
PersistedStorage::KeyValueStoreMgr().Delete(kWiFiCredentialsKeyName);
175+
176+
return error;
151177
}
152178

153179
bool ESPWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId)
@@ -163,6 +189,7 @@ Status ESPWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, Mu
163189
VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || NetworkMatch(mStagingNetwork, ssid), Status::kBoundsExceeded);
164190
VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), Status::kOutOfRange);
165191
VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange);
192+
VerifyOrReturnError(BackupConfiguration() == CHIP_NO_ERROR, Status::kUnknownError);
166193

167194
memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size());
168195
mStagingNetwork.credentialsLen = static_cast<decltype(mStagingNetwork.credentialsLen)>(credentials.size());
@@ -178,6 +205,7 @@ Status ESPWiFiDriver::RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDeb
178205
outDebugText.reduce_size(0);
179206
outNetworkIndex = 0;
180207
VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound);
208+
VerifyOrReturnError(BackupConfiguration() == CHIP_NO_ERROR, Status::kUnknownError);
181209

182210
// Use empty ssid for representing invalid network
183211
mStagingNetwork.ssidLen = 0;
@@ -273,6 +301,7 @@ void ESPWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callbac
273301
const uint32_t secToMiliSec = 1000;
274302

275303
VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), networkingStatus = Status::kNetworkIDNotFound);
304+
VerifyOrExit(BackupConfiguration() == CHIP_NO_ERROR, networkingStatus = Status::kUnknownError);
276305
VerifyOrExit(mpConnectCallback == nullptr, networkingStatus = Status::kUnknownError);
277306
ChipLogProgress(NetworkProvisioning, "ESP NetworkCommissioningDelegate: SSID: %.*s", static_cast<int>(networkId.size()),
278307
networkId.data());
@@ -484,6 +513,19 @@ bool ESPWiFiDriver::WiFiNetworkIterator::Next(Network & item)
484513
return true;
485514
}
486515

516+
CHIP_ERROR ESPWiFiDriver::BackupConfiguration()
517+
{
518+
CHIP_ERROR err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, nullptr, 0);
519+
if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL)
520+
{
521+
return CHIP_NO_ERROR;
522+
}
523+
ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiCredentialsKeyName, mStagingNetwork.credentials,
524+
mStagingNetwork.credentialsLen));
525+
ReturnErrorOnFailure(PersistedStorage::KeyValueStoreMgr().Put(kWiFiSSIDKeyName, mStagingNetwork.ssid, mStagingNetwork.ssidLen));
526+
return CHIP_NO_ERROR;
527+
}
528+
487529
} // namespace NetworkCommissioning
488530
} // namespace DeviceLayer
489531
} // namespace chip

src/platform/ESP32/NetworkCommissioningDriver.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ class ESPWiFiDriver final : public WiFiDriver
133133
private:
134134
bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId);
135135
CHIP_ERROR StartScanWiFiNetworks(ByteSpan ssid);
136+
CHIP_ERROR BackupConfiguration();
136137

137-
WiFiNetwork mSavedNetwork;
138138
WiFiNetwork mStagingNetwork;
139139
ScanCallback * mpScanCallback;
140140
ConnectCallback * mpConnectCallback;

0 commit comments

Comments
 (0)