@@ -54,6 +54,8 @@ CHIP_ERROR GenericThreadDriver::Init(Internal::BaseDriver::NetworkStatusChangeCa
54
54
// must be restored on the boot. If there's no backup, the below function is a no-op.
55
55
RevertConfiguration ();
56
56
57
+ CheckInterfaceEnabled ();
58
+
57
59
return CHIP_NO_ERROR;
58
60
}
59
61
@@ -95,6 +97,16 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration()
95
97
// since the fail-safe was armed, so return with no error.
96
98
ReturnErrorCodeIf (error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);
97
99
100
+ if (!GetEnabled ())
101
+ {
102
+ // When reverting configuration, set InterfaceEnabled to default value (true).
103
+ // From the spec:
104
+ // If InterfaceEnabled is written to false on the same interface as that which is used to write the value, the Administrator
105
+ // could await the recovery of network configuration to prior safe values, before being able to communicate with the
106
+ // node again.
107
+ ReturnErrorOnFailure (PersistedStorage::KeyValueStoreMgr ().Delete (kInterfaceEnabled ));
108
+ }
109
+
98
110
ChipLogProgress (NetworkProvisioning, " Reverting Thread operational dataset" );
99
111
100
112
if (error == CHIP_NO_ERROR)
@@ -166,6 +178,12 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c
166
178
{
167
179
NetworkCommissioning::Status status = MatchesNetworkId (mStagingNetwork , networkId);
168
180
181
+ if (!GetEnabled ())
182
+ {
183
+ // Set InterfaceEnabled to default value (true).
184
+ ReturnOnFailure (PersistedStorage::KeyValueStoreMgr ().Delete (kInterfaceEnabled ));
185
+ }
186
+
169
187
if (status == Status::kSuccess && BackupConfiguration () != CHIP_NO_ERROR)
170
188
{
171
189
status = Status::kUnknownError ;
@@ -183,6 +201,30 @@ void GenericThreadDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * c
183
201
}
184
202
}
185
203
204
+ CHIP_ERROR GenericThreadDriver::SetEnabled (bool enabled)
205
+ {
206
+ if (enabled == GetEnabled ())
207
+ {
208
+ return CHIP_NO_ERROR;
209
+ }
210
+
211
+ ReturnErrorOnFailure (PersistedStorage::KeyValueStoreMgr ().Put (kInterfaceEnabled , &enabled, sizeof (enabled)));
212
+
213
+ if ((!enabled && ThreadStackMgrImpl ().IsThreadEnabled ()) || (enabled && ThreadStackMgrImpl ().IsThreadProvisioned ()))
214
+ {
215
+ ReturnErrorOnFailure (ThreadStackMgrImpl ().SetThreadEnabled (enabled));
216
+ }
217
+ return CHIP_NO_ERROR;
218
+ }
219
+
220
+ bool GenericThreadDriver::GetEnabled ()
221
+ {
222
+ bool value;
223
+ // InterfaceEnabled default value is true.
224
+ VerifyOrReturnValue (PersistedStorage::KeyValueStoreMgr ().Get (kInterfaceEnabled , &value, sizeof (value)) == CHIP_NO_ERROR, true );
225
+ return value;
226
+ }
227
+
186
228
void GenericThreadDriver::ScanNetworks (ThreadDriver::ScanCallback * callback)
187
229
{
188
230
if (DeviceLayer::ThreadStackMgrImpl ().StartThreadScan (callback) != CHIP_NO_ERROR)
@@ -223,6 +265,18 @@ CHIP_ERROR GenericThreadDriver::BackupConfiguration()
223
265
return KeyValueStoreMgr ().Put (DefaultStorageKeyAllocator::FailSafeNetworkConfig ().KeyName (), dataset.data (), dataset.size ());
224
266
}
225
267
268
+ void GenericThreadDriver::CheckInterfaceEnabled ()
269
+ {
270
+ #if !CHIP_DEVICE_CONFIG_ENABLE_THREAD_AUTOSTART
271
+ // If the Thread interface is enabled and stack has been provisioned, but is not currently enabled, enable it now.
272
+ if (GetEnabled () && ThreadStackMgrImpl ().IsThreadProvisioned () && !ThreadStackMgrImpl ().IsThreadEnabled ())
273
+ {
274
+ ReturnOnFailure (ThreadStackMgrImpl ().SetThreadEnabled (true ));
275
+ ChipLogProgress (DeviceLayer, " OpenThread ifconfig up and thread start" );
276
+ }
277
+ #endif
278
+ }
279
+
226
280
size_t GenericThreadDriver::ThreadNetworkIterator::Count ()
227
281
{
228
282
return driver->mStagingNetwork .IsCommissioned () ? 1 : 0 ;
0 commit comments