@@ -121,35 +121,16 @@ CHIP_ERROR GenericThreadBorderRouterDelegate::GetDataset(Thread::OperationalData
121
121
CHIP_ERROR GenericThreadBorderRouterDelegate::SetActiveDataset (const Thread::OperationalDataset & activeDataset,
122
122
ActivateDatasetCallback * callback)
123
123
{
124
- otInstance * otInst = DeviceLayer::ThreadStackMgrImpl ().OTInstance ();
125
- VerifyOrReturnError (otInst, CHIP_ERROR_INCORRECT_STATE);
126
-
127
- VerifyOrReturnError (callback, CHIP_ERROR_INVALID_ARGUMENT);
128
- otOperationalDatasetTlvs datasetTlvs;
129
- memcpy (datasetTlvs.mTlvs , activeDataset.AsByteSpan ().data (), activeDataset.AsByteSpan ().size ());
130
- datasetTlvs.mLength = activeDataset.AsByteSpan ().size ();
131
-
132
- ScopedThreadLock threadLock;
133
- // Save the previous thread state and dataset for reverting
134
- bool threadIsEnabled = GetThreadEnabled ();
135
- ReturnErrorOnFailure (DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Put (kFailsafeThreadEnabledKey , threadIsEnabled));
136
- if (threadIsEnabled)
124
+ CHIP_ERROR err = BackupActiveDataset ();
125
+ if (err == CHIP_NO_ERROR)
137
126
{
138
- otOperationalDatasetTlvs stagingDataset;
139
- ReturnErrorCodeIf (otDatasetGetActiveTlvs (otInst, &stagingDataset) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
140
- if (activeDataset.AsByteSpan ().data_equal (ByteSpan (stagingDataset.mTlvs , stagingDataset.mLength )))
141
- {
142
- callback->OnActivateDatasetComplete (CHIP_NO_ERROR);
143
- return CHIP_NO_ERROR;
144
- }
145
- ReturnErrorOnFailure (DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Put (kFailsafeThreadDatasetTlvsKey ,
146
- stagingDataset.mTlvs , stagingDataset.mLength ));
127
+ err = DeviceLayer::ThreadStackMgrImpl ().AttachToThreadNetwork (activeDataset, nullptr );
147
128
}
148
- SetThreadEnabled ( false );
149
- ReturnErrorCodeIf ( otDatasetSetActiveTlvs (otInst, &datasetTlvs) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
150
- SetThreadEnabled ( true ) ;
151
- mCallback = callback;
152
- return CHIP_NO_ERROR ;
129
+ if (err == CHIP_NO_ERROR)
130
+ {
131
+ mCallback = callback ;
132
+ }
133
+ return err ;
153
134
}
154
135
155
136
void GenericThreadBorderRouterDelegate::OnPlatformEventHandler (const DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
@@ -163,45 +144,53 @@ void GenericThreadBorderRouterDelegate::OnPlatformEventHandler(const DeviceLayer
163
144
delegate->mCallback ->OnActivateDatasetComplete (CHIP_NO_ERROR);
164
145
// Delete Failsafe Keys after activating dataset is completed
165
146
DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadDatasetTlvsKey );
166
- DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadEnabledKey );
167
147
delegate->mCallback = nullptr ;
168
148
}
169
149
}
170
150
}
171
151
172
- CHIP_ERROR GenericThreadBorderRouterDelegate::RevertActiveDataset ()
152
+ CHIP_ERROR GenericThreadBorderRouterDelegate::BackupActiveDataset ()
173
153
{
174
- otInstance * otInst = DeviceLayer::ThreadStackMgrImpl ().OTInstance ();
175
- VerifyOrReturnError (otInst, CHIP_ERROR_INCORRECT_STATE);
176
-
177
- bool threadIsEnabled = false ;
178
- CHIP_ERROR err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadEnabledKey , &threadIsEnabled);
179
- if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
154
+ // If active dataset is already backed up, return with no error
155
+ CHIP_ERROR err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadDatasetTlvsKey , nullptr , 0 );
156
+ if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL)
180
157
{
181
158
return CHIP_NO_ERROR;
182
159
}
183
- ReturnErrorOnFailure (err);
160
+ GetDataset (mStagingDataset , DatasetType::kActive );
161
+ ByteSpan dataset = mStagingDataset .AsByteSpan ();
162
+ return DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Put (kFailsafeThreadDatasetTlvsKey , dataset.data (), dataset.size ());
163
+ }
184
164
185
- ScopedThreadLock threadLock;
186
- if (threadIsEnabled)
165
+ CHIP_ERROR GenericThreadBorderRouterDelegate::CommitActiveDataset ()
166
+ {
167
+ // Delete Failsafe Key when committing.
168
+ DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadDatasetTlvsKey );
169
+ return CHIP_NO_ERROR;
170
+ }
171
+
172
+ CHIP_ERROR GenericThreadBorderRouterDelegate::RevertActiveDataset ()
173
+ {
174
+ // The FailSafe Timer is triggered and the previous command request should be handled, so reset the callback.
175
+ mCallback = nullptr ;
176
+ uint8_t datasetBytes[Thread::kSizeOperationalDataset ];
177
+ size_t datasetLength;
178
+ CHIP_ERROR err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadDatasetTlvsKey , datasetBytes,
179
+ sizeof (datasetBytes), &datasetLength);
180
+ // If no backup could be found, it means the active datset has not been modified since the fail-safe was armed,
181
+ // so return with no error.
182
+ ReturnErrorCodeIf (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);
183
+ if (err == CHIP_NO_ERROR)
187
184
{
188
- otOperationalDatasetTlvs stagingDataset;
189
- size_t datasetTlvslen = 0 ;
190
- err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadDatasetTlvsKey , stagingDataset.mTlvs ,
191
- sizeof (stagingDataset.mTlvs ), &datasetTlvslen);
192
- if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
193
- {
194
- return CHIP_NO_ERROR;
195
- }
196
- ReturnErrorOnFailure (err);
197
- stagingDataset.mLength = datasetTlvslen;
198
- ReturnErrorOnFailure (SetThreadEnabled (false ));
199
- ReturnErrorCodeIf (otDatasetSetActiveTlvs (otInst, &stagingDataset) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
185
+ err = mStagingDataset .Init (ByteSpan (datasetBytes, datasetLength));
186
+ }
187
+ if (err == CHIP_NO_ERROR)
188
+ {
189
+ err = DeviceLayer::ThreadStackMgrImpl ().AttachToThreadNetwork (mStagingDataset , nullptr );
200
190
}
201
- ReturnErrorOnFailure ( SetThreadEnabled (threadIsEnabled));
202
- // Delete Failsafe Keys after reverting .
191
+
192
+ // Always delete the backup, regardless if it can be successfully restored .
203
193
DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadDatasetTlvsKey );
204
- DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadEnabledKey );
205
194
return CHIP_NO_ERROR;
206
195
}
207
196
@@ -218,33 +207,6 @@ CHIP_ERROR GenericThreadBorderRouterDelegate::SetPendingDataset(const Thread::Op
218
207
return CHIP_NO_ERROR;
219
208
}
220
209
221
- CHIP_ERROR GenericThreadBorderRouterDelegate::SetThreadEnabled (bool enabled)
222
- {
223
- otInstance * otInst = DeviceLayer::ThreadStackMgrImpl ().OTInstance ();
224
- VerifyOrReturnError (otInst, CHIP_ERROR_INCORRECT_STATE);
225
- bool isEnabled = (otThreadGetDeviceRole (otInst) != OT_DEVICE_ROLE_DISABLED);
226
- bool isIp6Enabled = otIp6IsEnabled (otInst);
227
- if (enabled && !isIp6Enabled)
228
- {
229
- ReturnErrorCodeIf (otIp6SetEnabled (otInst, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
230
- }
231
- if (enabled != isEnabled)
232
- {
233
- ReturnErrorCodeIf (otThreadSetEnabled (otInst, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
234
- }
235
- if (!enabled && isIp6Enabled)
236
- {
237
- ReturnErrorCodeIf (otIp6SetEnabled (otInst, enabled) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL);
238
- }
239
- return CHIP_NO_ERROR;
240
- }
241
-
242
- bool GenericThreadBorderRouterDelegate::GetThreadEnabled ()
243
- {
244
- otInstance * otInst = DeviceLayer::ThreadStackMgrImpl ().OTInstance ();
245
- return otInst && otIp6IsEnabled (otInst) && (otThreadGetDeviceRole (otInst) != OT_DEVICE_ROLE_DISABLED);
246
- }
247
-
248
210
} // namespace ThreadBorderRouterManagement
249
211
} // namespace Clusters
250
212
} // namespace app
0 commit comments