@@ -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)
@@ -169,39 +150,46 @@ void GenericThreadBorderRouterDelegate::OnPlatformEventHandler(const DeviceLayer
169
150
}
170
151
}
171
152
172
- CHIP_ERROR GenericThreadBorderRouterDelegate::RevertActiveDataset ()
153
+ CHIP_ERROR GenericThreadBorderRouterDelegate::BackupActiveDataset ()
173
154
{
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)
155
+ // If active dataset is already backed up, return with no error
156
+ CHIP_ERROR err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadDatasetTlvsKey , nullptr , 0 );
157
+ if (err == CHIP_NO_ERROR || err == CHIP_ERROR_BUFFER_TOO_SMALL)
180
158
{
181
159
return CHIP_NO_ERROR;
182
160
}
183
- ReturnErrorOnFailure (err);
161
+ GetDataset (mStagingDataset , DatasetType::kActive );
162
+ ByteSpan dataset = mStagingDataset .AsByteSpan ();
163
+ return DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Put (kFailsafeThreadDatasetTlvsKey , dataset.data (), dataset.size ());
164
+ }
184
165
185
- ScopedThreadLock threadLock;
186
- if (threadIsEnabled)
166
+ CHIP_ERROR GenericThreadBorderRouterDelegate::CommitActiveDataset ()
167
+ {
168
+ // Delete Failsafe Key when committing.
169
+ DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadDatasetTlvsKey );
170
+ }
171
+
172
+ CHIP_ERROR GenericThreadBorderRouterDelegate::RevertActiveDataset ()
173
+ {
174
+ mCallback = nullptr ;
175
+ uint8_t datasetBytes[Thread::kSizeOperationalDataset ];
176
+ size_t datasetLength;
177
+ CHIP_ERROR err = DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Get (kFailsafeThreadDatasetTlvsKey , datasetBytes,
178
+ sizof (datasetBytes), &datasetLength);
179
+ // If no backup could be found, it means the active datset has not been modified since the fail-safe was armed,
180
+ // so return with no error.
181
+ ReturnErrorCodeIf (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);
182
+ if (err == CHIP_NO_ERROR)
187
183
{
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);
184
+ err = mStagingDataset .Init (ByteSpan (datasetBytes, datasetLength));
200
185
}
201
- ReturnErrorOnFailure (SetThreadEnabled (threadIsEnabled));
202
- // Delete Failsafe Keys after reverting.
186
+ if (err == CHIP_NO_ERROR)
187
+ {
188
+ err = DeviceLayer::ThreadStackMgrImpl ().AttachToThreadNetwork (mStagingDataset , nullptr );
189
+ }
190
+
191
+ // Always delete the backup, regardless if it can be successfully restored.
203
192
DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadDatasetTlvsKey );
204
- DeviceLayer::PersistedStorage::KeyValueStoreMgr ().Delete (kFailsafeThreadEnabledKey );
205
193
return CHIP_NO_ERROR;
206
194
}
207
195
@@ -218,33 +206,6 @@ CHIP_ERROR GenericThreadBorderRouterDelegate::SetPendingDataset(const Thread::Op
218
206
return CHIP_NO_ERROR;
219
207
}
220
208
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
209
} // namespace ThreadBorderRouterManagement
249
210
} // namespace Clusters
250
211
} // namespace app
0 commit comments