1 /*
2 * Copyright (c) 2018, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file includes definitions for non-volatile storage of settings.
32 */
33
34 #include "settings.hpp"
35
36 #include "common/array.hpp"
37 #include "common/code_utils.hpp"
38 #include "common/debug.hpp"
39 #include "common/locator_getters.hpp"
40 #include "common/num_utils.hpp"
41 #include "instance/instance.hpp"
42 #include "meshcop/dataset.hpp"
43 #include "thread/mle.hpp"
44
45 namespace ot {
46
47 RegisterLogModule("Settings");
48
49 //---------------------------------------------------------------------------------------------------------------------
50 // SettingsBase
51
52 // LCOV_EXCL_START
53
54 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
55
Log(Action aAction) const56 void SettingsBase::NetworkInfo::Log(Action aAction) const
57 {
58 LogInfo("%s NetworkInfo {rloc:0x%04x, extaddr:%s, role:%s, mode:0x%02x, version:%u, keyseq:0x%lx, ...",
59 ActionToString(aAction), GetRloc16(), GetExtAddress().ToString().AsCString(),
60 Mle::RoleToString(static_cast<Mle::DeviceRole>(GetRole())), GetDeviceMode(), GetVersion(),
61 ToUlong(GetKeySequence()));
62
63 LogInfo("... pid:0x%lx, mlecntr:0x%lx, maccntr:0x%lx, mliid:%s}", ToUlong(GetPreviousPartitionId()),
64 ToUlong(GetMleFrameCounter()), ToUlong(GetMacFrameCounter()), GetMeshLocalIid().ToString().AsCString());
65 }
66
Log(Action aAction) const67 void SettingsBase::ParentInfo::Log(Action aAction) const
68 {
69 LogInfo("%s ParentInfo {extaddr:%s, version:%u}", ActionToString(aAction), GetExtAddress().ToString().AsCString(),
70 GetVersion());
71 }
72
73 #if OPENTHREAD_FTD
Log(Action aAction) const74 void SettingsBase::ChildInfo::Log(Action aAction) const
75 {
76 LogInfo("%s ChildInfo {rloc:0x%04x, extaddr:%s, timeout:%lu, mode:0x%02x, version:%u}", ActionToString(aAction),
77 GetRloc16(), GetExtAddress().ToString().AsCString(), ToUlong(GetTimeout()), GetMode(), GetVersion());
78 }
79 #endif
80
81 #if OPENTHREAD_CONFIG_DUA_ENABLE
Log(Action aAction) const82 void SettingsBase::DadInfo::Log(Action aAction) const
83 {
84 LogInfo("%s DadInfo {DadCounter:%2d}", ActionToString(aAction), GetDadCounter());
85 }
86 #endif
87
88 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
LogPrefix(Action aAction,Key aKey,const Ip6::Prefix & aPrefix)89 void SettingsBase::LogPrefix(Action aAction, Key aKey, const Ip6::Prefix &aPrefix)
90 {
91 LogInfo("%s %s %s", ActionToString(aAction), KeyToString(aKey), aPrefix.ToString().AsCString());
92 }
93 #endif
94
95 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
Log(Action aAction) const96 void SettingsBase::SrpClientInfo::Log(Action aAction) const
97 {
98 LogInfo("%s SrpClientInfo {Server:[%s]:%u}", ActionToString(aAction), GetServerAddress().ToString().AsCString(),
99 GetServerPort());
100 }
101 #endif
102
103 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
Log(Action aAction) const104 void SettingsBase::SrpServerInfo::Log(Action aAction) const
105 {
106 LogInfo("%s SrpServerInfo {port:%u}", ActionToString(aAction), GetPort());
107 }
108 #endif
109
110 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
Log(Action aAction) const111 void SettingsBase::BorderAgentId::Log(Action aAction) const
112 {
113 char buffer[sizeof(BorderAgentId) * 2 + 1];
114 StringWriter sw(buffer, sizeof(buffer));
115
116 sw.AppendHexBytes(GetId().mId, sizeof(BorderAgentId));
117 LogInfo("%s BorderAgentId {id:%s}", ActionToString(aAction), buffer);
118 }
119 #endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
120
121 #endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
122
123 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
ActionToString(Action aAction)124 const char *SettingsBase::ActionToString(Action aAction)
125 {
126 static const char *const kActionStrings[] = {
127 "Read", // (0) kActionRead
128 "Saved", // (1) kActionSave
129 "Re-saved", // (2) kActionResave
130 "Deleted", // (3) kActionDelete
131 #if OPENTHREAD_FTD
132 "Added", // (4) kActionAdd,
133 "Removed", // (5) kActionRemove,
134 "Deleted all" // (6) kActionDeleteAll
135 #endif
136 };
137
138 static_assert(0 == kActionRead, "kActionRead value is incorrect");
139 static_assert(1 == kActionSave, "kActionSave value is incorrect");
140 static_assert(2 == kActionResave, "kActionResave value is incorrect");
141 static_assert(3 == kActionDelete, "kActionDelete value is incorrect");
142 #if OPENTHREAD_FTD
143 static_assert(4 == kActionAdd, "kActionAdd value is incorrect");
144 static_assert(5 == kActionRemove, "kActionRemove value is incorrect");
145 static_assert(6 == kActionDeleteAll, "kActionDeleteAll value is incorrect");
146 #endif
147
148 return kActionStrings[aAction];
149 }
150 #endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
151
152 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
KeyToString(Key aKey)153 const char *SettingsBase::KeyToString(Key aKey)
154 {
155 static const char *const kKeyStrings[] = {
156 "", // (0) (Unused)
157 "ActiveDataset", // (1) kKeyActiveDataset
158 "PendingDataset", // (2) kKeyPendingDataset
159 "NetworkInfo", // (3) kKeyNetworkInfo
160 "ParentInfo", // (4) kKeyParentInfo
161 "ChildInfo", // (5) kKeyChildInfo
162 "", // (6) Removed (previously auto-start).
163 "SlaacIidSecretKey", // (7) kKeySlaacIidSecretKey
164 "DadInfo", // (8) kKeyDadInfo
165 "", // (9) Removed (previously OMR prefix).
166 "", // (10) Removed (previously on-link prefix).
167 "SrpEcdsaKey", // (11) kKeySrpEcdsaKey
168 "SrpClientInfo", // (12) kKeySrpClientInfo
169 "SrpServerInfo", // (13) kKeySrpServerInfo
170 "", // (14) Removed (previously NAT64 prefix)
171 "BrUlaPrefix", // (15) kKeyBrUlaPrefix
172 "BrOnLinkPrefixes", // (16) kKeyBrOnLinkPrefixes
173 "BorderAgentId" // (17) kKeyBorderAgentId
174 };
175
176 static_assert(1 == kKeyActiveDataset, "kKeyActiveDataset value is incorrect");
177 static_assert(2 == kKeyPendingDataset, "kKeyPendingDataset value is incorrect");
178 static_assert(3 == kKeyNetworkInfo, "kKeyNetworkInfo value is incorrect");
179 static_assert(4 == kKeyParentInfo, "kKeyParentInfo value is incorrect");
180 static_assert(5 == kKeyChildInfo, "kKeyChildInfo value is incorrect");
181 static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect");
182 static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect");
183 static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
184 static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
185 static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
186 static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");
187 static_assert(16 == kKeyBrOnLinkPrefixes, "kKeyBrOnLinkPrefixes is incorrect");
188 static_assert(17 == kKeyBorderAgentId, "kKeyBorderAgentId is incorrect");
189
190 static_assert(kLastKey == kKeyBorderAgentId, "kLastKey is not valid");
191
192 OT_ASSERT(aKey <= kLastKey);
193
194 return kKeyStrings[aKey];
195 }
196 #endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
197
198 // LCOV_EXCL_STOP
199
200 //---------------------------------------------------------------------------------------------------------------------
201 // Settings
202
203 // This array contains sensitive keys that should be stored in the secure area.
204 const uint16_t Settings::kSensitiveKeys[] = {
205 SettingsBase::kKeyActiveDataset,
206 SettingsBase::kKeyPendingDataset,
207 SettingsBase::kKeySrpEcdsaKey,
208 };
209
Init(void)210 void Settings::Init(void) { Get<SettingsDriver>().Init(kSensitiveKeys, GetArrayLength(kSensitiveKeys)); }
211
Deinit(void)212 void Settings::Deinit(void) { Get<SettingsDriver>().Deinit(); }
213
Wipe(void)214 void Settings::Wipe(void)
215 {
216 Get<SettingsDriver>().Wipe();
217 LogInfo("Wiped all info");
218 }
219
KeyForDatasetType(MeshCoP::Dataset::Type aType)220 Settings::Key Settings::KeyForDatasetType(MeshCoP::Dataset::Type aType)
221 {
222 return (aType == MeshCoP::Dataset::kActive) ? kKeyActiveDataset : kKeyPendingDataset;
223 }
224
SaveOperationalDataset(MeshCoP::Dataset::Type aType,const MeshCoP::Dataset & aDataset)225 void Settings::SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset)
226 {
227 Key key = KeyForDatasetType(aType);
228 Error error = Get<SettingsDriver>().Set(key, aDataset.GetBytes(), aDataset.GetLength());
229
230 Log(kActionSave, error, key);
231
232 SuccessOrAssert(error);
233 }
234
ReadOperationalDataset(MeshCoP::Dataset::Type aType,MeshCoP::Dataset & aDataset) const235 Error Settings::ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const
236 {
237 Error error = kErrorNone;
238 uint16_t length = MeshCoP::Dataset::kMaxLength;
239
240 SuccessOrExit(error = Get<SettingsDriver>().Get(KeyForDatasetType(aType), aDataset.GetBytes(), &length));
241 VerifyOrExit(length <= MeshCoP::Dataset::kMaxLength, error = kErrorNotFound);
242
243 aDataset.SetLength(static_cast<uint8_t>(length));
244
245 exit:
246 OT_ASSERT(error != kErrorNotImplemented);
247 return error;
248 }
249
DeleteOperationalDataset(MeshCoP::Dataset::Type aType)250 void Settings::DeleteOperationalDataset(MeshCoP::Dataset::Type aType)
251 {
252 Key key = KeyForDatasetType(aType);
253 Error error = Get<SettingsDriver>().Delete(key);
254
255 Log(kActionDelete, error, key);
256 OT_ASSERT(error != kErrorNotImplemented);
257 }
258
259 #if OPENTHREAD_FTD
AddChildInfo(const ChildInfo & aChildInfo)260 Error Settings::AddChildInfo(const ChildInfo &aChildInfo)
261 {
262 Error error = Get<SettingsDriver>().Add(kKeyChildInfo, &aChildInfo, sizeof(aChildInfo));
263
264 Log(kActionAdd, error, kKeyChildInfo, &aChildInfo);
265
266 return error;
267 }
268
DeleteAllChildInfo(void)269 Error Settings::DeleteAllChildInfo(void)
270 {
271 Error error = Get<SettingsDriver>().Delete(kKeyChildInfo);
272
273 Log(kActionDeleteAll, error, kKeyChildInfo);
274
275 return error;
276 }
277
ChildInfoIterator(Instance & aInstance)278 Settings::ChildInfoIterator::ChildInfoIterator(Instance &aInstance)
279 : SettingsBase(aInstance)
280 , mIndex(0)
281 , mIsDone(false)
282 {
283 Read();
284 }
285
Advance(void)286 void Settings::ChildInfoIterator::Advance(void)
287 {
288 if (!mIsDone)
289 {
290 mIndex++;
291 Read();
292 }
293 }
294
Delete(void)295 Error Settings::ChildInfoIterator::Delete(void)
296 {
297 Error error = kErrorNone;
298
299 VerifyOrExit(!mIsDone, error = kErrorInvalidState);
300 SuccessOrExit(error = Get<SettingsDriver>().Delete(kKeyChildInfo, mIndex));
301
302 exit:
303 Log(kActionRemove, error, kKeyChildInfo, &mChildInfo);
304 return error;
305 }
306
Read(void)307 void Settings::ChildInfoIterator::Read(void)
308 {
309 uint16_t length = sizeof(ChildInfo);
310 Error error;
311
312 mChildInfo.Init();
313 SuccessOrExit(
314 error = Get<SettingsDriver>().Get(kKeyChildInfo, mIndex, reinterpret_cast<uint8_t *>(&mChildInfo), &length));
315
316 exit:
317 Log(kActionRead, error, kKeyChildInfo, &mChildInfo);
318 mIsDone = (error != kErrorNone);
319 }
320 #endif // OPENTHREAD_FTD
321
322 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
AddOrUpdateBrOnLinkPrefix(const BrOnLinkPrefix & aBrOnLinkPrefix)323 Error Settings::AddOrUpdateBrOnLinkPrefix(const BrOnLinkPrefix &aBrOnLinkPrefix)
324 {
325 Error error = kErrorNone;
326 int index = 0;
327 BrOnLinkPrefix brPrefix;
328 bool didUpdate = false;
329
330 while (ReadBrOnLinkPrefix(index, brPrefix) == kErrorNone)
331 {
332 if (brPrefix.GetPrefix() == aBrOnLinkPrefix.GetPrefix())
333 {
334 if (brPrefix.GetLifetime() == aBrOnLinkPrefix.GetLifetime())
335 {
336 // Existing entry fully matches `aBrOnLinkPrefix`.
337 // No need to make any changes.
338 ExitNow();
339 }
340
341 SuccessOrExit(error = Get<SettingsDriver>().Delete(kKeyBrOnLinkPrefixes, index));
342 didUpdate = true;
343 break;
344 }
345
346 index++;
347 }
348
349 SuccessOrExit(error = Get<SettingsDriver>().Add(kKeyBrOnLinkPrefixes, &aBrOnLinkPrefix, sizeof(BrOnLinkPrefix)));
350 brPrefix.Log(didUpdate ? "Updated" : "Added");
351
352 exit:
353 return error;
354 }
355
RemoveBrOnLinkPrefix(const Ip6::Prefix & aPrefix)356 Error Settings::RemoveBrOnLinkPrefix(const Ip6::Prefix &aPrefix)
357 {
358 Error error = kErrorNotFound;
359 BrOnLinkPrefix brPrefix;
360
361 for (int index = 0; ReadBrOnLinkPrefix(index, brPrefix) == kErrorNone; index++)
362 {
363 if (brPrefix.GetPrefix() == aPrefix)
364 {
365 SuccessOrExit(error = Get<SettingsDriver>().Delete(kKeyBrOnLinkPrefixes, index));
366 brPrefix.Log("Removed");
367 break;
368 }
369 }
370
371 exit:
372 return error;
373 }
374
DeleteAllBrOnLinkPrefixes(void)375 Error Settings::DeleteAllBrOnLinkPrefixes(void) { return Get<SettingsDriver>().Delete(kKeyBrOnLinkPrefixes); }
376
ReadBrOnLinkPrefix(int aIndex,BrOnLinkPrefix & aBrOnLinkPrefix)377 Error Settings::ReadBrOnLinkPrefix(int aIndex, BrOnLinkPrefix &aBrOnLinkPrefix)
378 {
379 uint16_t length = sizeof(BrOnLinkPrefix);
380
381 aBrOnLinkPrefix.Init();
382
383 return Get<SettingsDriver>().Get(kKeyBrOnLinkPrefixes, aIndex, &aBrOnLinkPrefix, &length);
384 }
385
Log(const char * aActionText) const386 void Settings::BrOnLinkPrefix::Log(const char *aActionText) const
387 {
388 OT_UNUSED_VARIABLE(aActionText);
389
390 LogInfo("%s %s entry {prefix:%s,lifetime:%lu}", aActionText, KeyToString(kKeyBrOnLinkPrefixes),
391 GetPrefix().ToString().AsCString(), ToUlong(GetLifetime()));
392 }
393
394 #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
395
ReadEntry(Key aKey,void * aValue,uint16_t aMaxLength) const396 Error Settings::ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const
397 {
398 Error error;
399 uint16_t length = aMaxLength;
400
401 error = Get<SettingsDriver>().Get(aKey, aValue, &length);
402 Log(kActionRead, error, aKey, aValue);
403
404 return error;
405 }
406
SaveEntry(Key aKey,const void * aValue,void * aPrev,uint16_t aLength)407 Error Settings::SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength)
408 {
409 Error error = kErrorNone;
410 uint16_t readLength = aLength;
411 Action action = kActionSave;
412
413 if ((Get<SettingsDriver>().Get(aKey, aPrev, &readLength) == kErrorNone) && (readLength == aLength) &&
414 (memcmp(aValue, aPrev, aLength) == 0))
415 {
416 action = kActionResave;
417 }
418 else
419 {
420 error = Get<SettingsDriver>().Set(aKey, aValue, aLength);
421 }
422
423 Log(action, error, aKey, aValue);
424
425 return error;
426 }
427
DeleteEntry(Key aKey)428 Error Settings::DeleteEntry(Key aKey)
429 {
430 Error error = Get<SettingsDriver>().Delete(aKey);
431
432 Log(kActionDelete, error, aKey);
433
434 return error;
435 }
436
Log(Action aAction,Error aError,Key aKey,const void * aValue)437 void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
438 {
439 OT_UNUSED_VARIABLE(aAction);
440 OT_UNUSED_VARIABLE(aKey);
441 OT_UNUSED_VARIABLE(aError);
442 OT_UNUSED_VARIABLE(aValue);
443
444 if (aError != kErrorNone)
445 {
446 // Log error if log level is at "warn" or higher.
447
448 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
449 const char *actionText = "";
450
451 switch (aAction)
452 {
453 case kActionSave:
454 case kActionResave:
455 actionText = "saving";
456 break;
457
458 case kActionDelete:
459 VerifyOrExit(aError != kErrorNotFound);
460 actionText = "deleting";
461 break;
462
463 #if OPENTHREAD_FTD
464 case kActionAdd:
465 actionText = "adding";
466 break;
467
468 case kActionRemove:
469 VerifyOrExit(aError != kErrorNotFound);
470 actionText = "removing";
471 break;
472
473 case kActionDeleteAll:
474 VerifyOrExit(aError != kErrorNotFound);
475 actionText = "deleting all";
476 break;
477 #endif
478 case kActionRead:
479 ExitNow();
480 }
481
482 LogWarn("Error %s %s %s", ErrorToString(aError), actionText, KeyToString(aKey));
483
484 #endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
485
486 ExitNow();
487 }
488
489 // We reach here when `aError` is `kErrorNone`.
490 // Log success if log level is at "info" or higher.
491
492 #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
493 if (aValue != nullptr)
494 {
495 switch (aKey)
496 {
497 case kKeyNetworkInfo:
498 reinterpret_cast<const NetworkInfo *>(aValue)->Log(aAction);
499 break;
500
501 case kKeyParentInfo:
502 reinterpret_cast<const ParentInfo *>(aValue)->Log(aAction);
503 break;
504
505 #if OPENTHREAD_FTD
506 case kKeyChildInfo:
507 reinterpret_cast<const ChildInfo *>(aValue)->Log(aAction);
508 break;
509 #endif
510
511 #if OPENTHREAD_CONFIG_DUA_ENABLE
512 case kKeyDadInfo:
513 reinterpret_cast<const DadInfo *>(aValue)->Log(aAction);
514 break;
515 #endif
516
517 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
518 case kKeyBrUlaPrefix:
519 LogPrefix(aAction, aKey, *reinterpret_cast<const Ip6::Prefix *>(aValue));
520 break;
521 #endif
522
523 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
524 case kKeySrpClientInfo:
525 reinterpret_cast<const SrpClientInfo *>(aValue)->Log(aAction);
526 break;
527 #endif
528
529 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
530 case kKeySrpServerInfo:
531 reinterpret_cast<const SrpServerInfo *>(aValue)->Log(aAction);
532 break;
533 #endif
534
535 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE && OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
536 case kKeyBorderAgentId:
537 reinterpret_cast<const BorderAgentId *>(aValue)->Log(aAction);
538 break;
539 #endif
540
541 default:
542 // For any other keys, we do not want to include the value
543 // in the log, so even if it is given we set `aValue` to
544 // `nullptr`. This ensures that we just log the action and
545 // the key.
546 aValue = nullptr;
547 break;
548 }
549 }
550
551 if (aValue == nullptr)
552 {
553 LogInfo("%s %s", ActionToString(aAction), KeyToString(aKey));
554 }
555 #endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
556
557 exit:
558 return;
559 }
560
561 } // namespace ot
562
563 //---------------------------------------------------------------------------------------------------------------------
564 // Default/weak implementation of settings platform APIs
565
otPlatSettingsSetCriticalKeys(otInstance * aInstance,const uint16_t * aKeys,uint16_t aKeysLength)566 OT_TOOL_WEAK void otPlatSettingsSetCriticalKeys(otInstance *aInstance, const uint16_t *aKeys, uint16_t aKeysLength)
567 {
568 OT_UNUSED_VARIABLE(aInstance);
569 OT_UNUSED_VARIABLE(aKeys);
570 OT_UNUSED_VARIABLE(aKeysLength);
571 }
572