Skip to content

Commit 2cc9057

Browse files
committed
matter: samples: Implement factory reset for persistent storage
* Handle factory reset for secure/non-secure configurations. * Add `FactoryReset` method to `AccessStorage` and `BridgeStorageManager`. * Add application specific factory reset handlers. Signed-off-by: Adrian Gielniewski <adrian.gielniewski@nordicsemi.no>
1 parent 9d080c1 commit 2cc9057

12 files changed

+169
-17
lines changed

applications/matter_bridge/src/main.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "app_task.h"
88

9+
#include <bridge/bridge_storage_manager.h>
910
#include <zephyr/logging/log.h>
1011

1112
LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL);
@@ -17,3 +18,8 @@ int main()
1718
LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format());
1819
return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE;
1920
}
21+
22+
bool AppFactoryResetHandler()
23+
{
24+
return Nrf::BridgeStorageManager::Instance().FactoryReset();
25+
}

samples/matter/common/src/bridge/bridge_storage_manager.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ template <> bool BridgeStorageManager::LoadBridgedDevice(BridgedDeviceV2 &device
188188

189189
bool BridgeStorageManager::Init()
190190
{
191-
const PSErrorCode status = Nrf::GetPersistentStorage().NonSecureInit();
191+
const PSErrorCode status = Nrf::GetPersistentStorage().NonSecureInit("br");
192192

193193
if (status != PSErrorCode::Success) {
194194
return false;
@@ -198,6 +198,15 @@ bool BridgeStorageManager::Init()
198198
return MigrateData();
199199
}
200200

201+
bool BridgeStorageManager::FactoryReset()
202+
{
203+
#ifndef CONFIG_CHIP_FACTORY_RESET_ERASE_SETTINGS
204+
return Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().NonSecureFactoryReset();
205+
#else
206+
return true;
207+
#endif
208+
}
209+
201210
#ifdef CONFIG_BRIDGE_MIGRATE_PRE_2_7_0
202211
bool BridgeStorageManager::MigrateDataOldScheme(uint8_t bridgedDeviceIndex)
203212
{

samples/matter/common/src/bridge/bridge_storage_manager.h

+8
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ class BridgeStorageManager {
9292
*/
9393
bool Init();
9494

95+
/**
96+
* @brief Factory reset the storage.
97+
*
98+
* @return true if success.
99+
* @return false otherwise.
100+
*/
101+
bool FactoryReset();
102+
95103
/**
96104
* @brief Store bridged devices count into settings
97105
*

samples/matter/common/src/persistent_storage/backends/persistent_storage_secure.cpp

+26-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ namespace Nrf
1212
PersistentStorageSecure::UidMap PersistentStorageSecure::sUidMap{};
1313
PersistentStorageSecure::Byte PersistentStorageSecure::sSerializedMapBuff[kMaxMapSerializationBufferSize]{};
1414

15-
PSErrorCode PersistentStorageSecure::_SecureInit()
15+
PSErrorCode PersistentStorageSecure::_SecureInit(const char *prefix)
1616
{
17+
// Ignored in this backend
18+
(void)prefix;
19+
1720
return LoadUIDMap();
1821
}
1922

@@ -85,6 +88,28 @@ PSErrorCode PersistentStorageSecure::_SecureRemove(PersistentStorageNode *node)
8588
return PSErrorCode::Failure;
8689
}
8790

91+
PSErrorCode PersistentStorageSecure::_SecureFactoryReset()
92+
{
93+
PSErrorCode error = PSErrorCode::Success;
94+
95+
// Remove all keys
96+
for (auto it = std::begin(sUidMap.mMap); it != std::end(sUidMap.mMap) - sUidMap.FreeSlots(); ++it) {
97+
psa_status_t status = psa_ps_remove(it->key);
98+
if (status != PSA_SUCCESS) {
99+
// Set error but try to remove all keys
100+
error = PSErrorCode::Failure;
101+
}
102+
}
103+
104+
// Remove UidMap
105+
psa_status_t status = psa_ps_remove(kKeyOffset);
106+
if (status != PSA_SUCCESS) {
107+
error = PSErrorCode::Failure;
108+
}
109+
110+
return error;
111+
}
112+
88113
psa_storage_uid_t PersistentStorageSecure::UIDFromString(char *str, bool *alreadyInTheMap)
89114
{
90115
for (auto &it : sUidMap.mMap) {

samples/matter/common/src/persistent_storage/backends/persistent_storage_secure.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@ namespace Nrf
1515
{
1616
class PersistentStorageSecure {
1717
protected:
18-
PSErrorCode _NonSecureInit();
18+
PSErrorCode _NonSecureInit(const char *prefix);
1919
PSErrorCode _NonSecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
2020
PSErrorCode _NonSecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2121
PSErrorCode _NonSecureHasEntry(PersistentStorageNode *node);
2222
PSErrorCode _NonSecureRemove(PersistentStorageNode *node);
23+
PSErrorCode _NonSecureFactoryReset();
2324

24-
PSErrorCode _SecureInit();
25+
PSErrorCode _SecureInit(const char *prefix);
2526
PSErrorCode _SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
2627
PSErrorCode _SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2728
PSErrorCode _SecureHasEntry(PersistentStorageNode *node);
2829
PSErrorCode _SecureRemove(PersistentStorageNode *node);
30+
PSErrorCode _SecureFactoryReset();
2931

3032
private:
3133
static constexpr size_t kMaxEntriesNumber = CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_MAX_ENTRY_NUMBER;
@@ -90,7 +92,7 @@ class PersistentStorageSecure {
9092
static Byte sSerializedMapBuff[kMaxMapSerializationBufferSize];
9193
};
9294

93-
inline PSErrorCode PersistentStorageSecure::_NonSecureInit()
95+
inline PSErrorCode PersistentStorageSecure::_NonSecureInit(const char *prefix)
9496
{
9597
return PSErrorCode::NotSupported;
9698
};
@@ -117,4 +119,9 @@ inline PSErrorCode PersistentStorageSecure::_NonSecureRemove(PersistentStorageNo
117119
return PSErrorCode::NotSupported;
118120
}
119121

122+
inline PSErrorCode PersistentStorageSecure::_NonSecureFactoryReset()
123+
{
124+
return PSErrorCode::NotSupported;
125+
}
126+
120127
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/backends/persistent_storage_settings.cpp

+43-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ struct ReadEntry {
2020
bool result;
2121
};
2222

23+
struct DeleteSubtreeEntry {
24+
const char *prefix;
25+
int result;
26+
};
27+
2328
/* Random magic bytes to represent an empty value.
2429
It is needed because Zephyr settings subsystem does not distinguish an empty value from no value. */
2530
constexpr uint8_t kEmptyValue[] = { 0x22, 0xa6, 0x54, 0xd1, 0x39 };
@@ -61,12 +66,36 @@ int LoadEntryCallback(const char *name, size_t entrySize, settings_read_cb readC
6166

6267
return 1;
6368
}
69+
70+
int DeleteSubtreeCallback(const char *name, size_t entrySize, settings_read_cb readCb, void *cbArg, void *param)
71+
{
72+
DeleteSubtreeEntry &entry = *static_cast<DeleteSubtreeEntry *>(param);
73+
char fullKey[SETTINGS_MAX_NAME_LEN + 1];
74+
75+
// name comes from Zephyr settings subsystem so it is guaranteed to fit in the buffer.
76+
(void)snprintf(fullKey, sizeof(fullKey), "%s/%s", entry.prefix, name);
77+
const int result = settings_delete(fullKey);
78+
79+
// Return the first error, but continue removing remaining keys anyway.
80+
if (entry.result == 0) {
81+
entry.result = result;
82+
}
83+
84+
return 0;
85+
}
86+
6487
} /* namespace */
6588

6689
namespace Nrf
6790
{
68-
PSErrorCode PersistentStorageSettings::_NonSecureInit()
91+
PSErrorCode PersistentStorageSettings::_NonSecureInit(const char *prefix)
6992
{
93+
if (prefix == nullptr) {
94+
return PSErrorCode::Failure;
95+
}
96+
97+
mPrefix = prefix;
98+
7099
return settings_load() ? PSErrorCode::Failure : PSErrorCode::Success;
71100
}
72101

@@ -160,4 +189,17 @@ bool PersistentStorageSettings::LoadEntry(const char *key, void *data, size_t da
160189

161190
return true;
162191
}
192+
193+
PSErrorCode PersistentStorageSettings::_NonSecureFactoryReset()
194+
{
195+
DeleteSubtreeEntry entry{ mPrefix, 0 };
196+
int result = settings_load_subtree_direct(mPrefix, DeleteSubtreeCallback, &entry);
197+
198+
if (result == 0 && entry.result == 0) {
199+
return PSErrorCode::Success;
200+
}
201+
202+
return PSErrorCode::Failure;
203+
}
204+
163205
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/backends/persistent_storage_settings.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@ namespace Nrf
1212
{
1313
class PersistentStorageSettings {
1414
protected:
15-
PSErrorCode _NonSecureInit();
15+
PSErrorCode _NonSecureInit(const char *prefix);
1616
PSErrorCode _NonSecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
1717
PSErrorCode _NonSecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
1818
PSErrorCode _NonSecureHasEntry(PersistentStorageNode *node);
1919
PSErrorCode _NonSecureRemove(PersistentStorageNode *node);
20+
PSErrorCode _NonSecureFactoryReset();
2021

21-
PSErrorCode _SecureInit();
22+
PSErrorCode _SecureInit(const char *prefix);
2223
PSErrorCode _SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
2324
PSErrorCode _SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
2425
PSErrorCode _SecureHasEntry(PersistentStorageNode *node);
2526
PSErrorCode _SecureRemove(PersistentStorageNode *node);
27+
PSErrorCode _SecureFactoryReset();
2628

2729
private:
2830
bool LoadEntry(const char *key, void *data = nullptr, size_t dataMaxSize = 0, size_t *outSize = nullptr);
31+
32+
const char *mPrefix = nullptr;
2933
};
3034

31-
inline PSErrorCode PersistentStorageSettings::_SecureInit()
35+
inline PSErrorCode PersistentStorageSettings::_SecureInit(const char *prefix)
3236
{
3337
return PSErrorCode::NotSupported;
3438
};
@@ -55,4 +59,9 @@ inline PSErrorCode PersistentStorageSettings::_SecureRemove(PersistentStorageNod
5559
return PSErrorCode::NotSupported;
5660
}
5761

62+
inline PSErrorCode PersistentStorageSettings::_SecureFactoryReset()
63+
{
64+
return PSErrorCode::NotSupported;
65+
}
66+
5867
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/persistent_storage.h

+26-6
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ class PersistentStorage {
2626
/**
2727
* @brief Perform the initialization required before using the storage.
2828
*
29+
* @param prefix storage key prefix
2930
* @return true if success.
3031
* @return false otherwise.
3132
*/
32-
PSErrorCode NonSecureInit();
33+
PSErrorCode NonSecureInit(const char *prefix);
3334

3435
/**
3536
* @brief Store data into the persistent storage.
@@ -72,12 +73,21 @@ class PersistentStorage {
7273
*/
7374
PSErrorCode NonSecureRemove(PersistentStorageNode *node);
7475

76+
/**
77+
* @brief Perform factory reset and remove all keys.
78+
*
79+
* @return true if subtree has been removed successfully.
80+
* @return false an error occurred.
81+
*/
82+
PSErrorCode NonSecureFactoryReset();
83+
7584
/* Secure storage API counterparts.*/
76-
PSErrorCode SecureInit();
85+
PSErrorCode SecureInit(const char *prefix);
7786
PSErrorCode SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize);
7887
PSErrorCode SecureLoad(PersistentStorageNode *node, void *data, size_t dataMaxSize, size_t &outSize);
7988
PSErrorCode SecureHasEntry(PersistentStorageNode *node);
8089
PSErrorCode SecureRemove(PersistentStorageNode *node);
90+
PSErrorCode SecureFactoryReset();
8191

8292
protected:
8393
PersistentStorage() = default;
@@ -107,9 +117,9 @@ inline PersistentStorageImpl *PersistentStorage::Impl()
107117
}
108118

109119
/* Non secure storage API. */
110-
inline PSErrorCode PersistentStorage::NonSecureInit()
120+
inline PSErrorCode PersistentStorage::NonSecureInit(const char *prefix)
111121
{
112-
return Impl()->_NonSecureInit();
122+
return Impl()->_NonSecureInit(prefix);
113123
};
114124

115125
inline PSErrorCode PersistentStorage::NonSecureStore(PersistentStorageNode *node, const void *data, size_t dataSize)
@@ -133,10 +143,15 @@ inline PSErrorCode PersistentStorage::NonSecureRemove(PersistentStorageNode *nod
133143
return Impl()->_NonSecureRemove(node);
134144
}
135145

146+
inline PSErrorCode PersistentStorage::NonSecureFactoryReset()
147+
{
148+
return Impl()->_NonSecureFactoryReset();
149+
}
150+
136151
/* Secure storage API. */
137-
inline PSErrorCode PersistentStorage::SecureInit()
152+
inline PSErrorCode PersistentStorage::SecureInit(const char *prefix)
138153
{
139-
return Impl()->_SecureInit();
154+
return Impl()->_SecureInit(prefix);
140155
};
141156

142157
inline PSErrorCode PersistentStorage::SecureStore(PersistentStorageNode *node, const void *data, size_t dataSize)
@@ -160,4 +175,9 @@ inline PSErrorCode PersistentStorage::SecureRemove(PersistentStorageNode *node)
160175
return Impl()->_SecureRemove(node);
161176
}
162177

178+
inline PSErrorCode PersistentStorage::SecureFactoryReset()
179+
{
180+
return Impl()->_SecureFactoryReset();
181+
}
182+
163183
} /* namespace Nrf */

samples/matter/common/src/persistent_storage/persistent_storage_impl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ class PersistentStorageImpl : public PersistentStorage
3131
friend class PersistentStorage;
3232

3333
#ifdef CONFIG_NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND
34-
3534
using PersistentStorageSettings::_NonSecureHasEntry;
3635
using PersistentStorageSettings::_NonSecureInit;
3736
using PersistentStorageSettings::_NonSecureLoad;
3837
using PersistentStorageSettings::_NonSecureRemove;
38+
using PersistentStorageSettings::_NonSecureFactoryReset;
3939
using PersistentStorageSettings::_NonSecureStore;
4040
#endif
4141

4242
#ifdef CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND
43+
using PersistentStorageSecure::_SecureFactoryReset;
4344
using PersistentStorageSecure::_SecureHasEntry;
4445
using PersistentStorageSecure::_SecureInit;
4546
using PersistentStorageSecure::_SecureLoad;

samples/matter/lock/src/access/access_storage.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,27 @@ bool GetStorageFreeSpace(size_t &freeBytes)
5353
#define PSStore SecureStore
5454
#define PSRemove SecureRemove
5555
#define PSLoad SecureLoad
56+
#define PSFactoryReset SecureFactoryReset
5657
#elif defined(CONFIG_NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND)
5758
#define PSInit NonSecureInit
5859
#define PSStore NonSecureStore
5960
#define PSLoad NonSecureLoad
6061
#define PSRemove NonSecureRemove
62+
#define PSFactoryReset NonSecureFactoryReset
6163
#endif
6264

6365
bool AccessStorage::Init()
6466
{
65-
return (Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().PSInit());
67+
return Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().PSInit(kAccessPrefix);
68+
}
69+
70+
bool AccessStorage::FactoryReset()
71+
{
72+
#ifndef CONFIG_CHIP_FACTORY_RESET_ERASE_SETTINGS
73+
return Nrf::PSErrorCode::Success == Nrf::GetPersistentStorage().PSFactoryReset();
74+
#else
75+
return true;
76+
#endif
6677
}
6778

6879
bool AccessStorage::PrepareKeyName(Type storageType, uint16_t index, uint16_t subindex)

samples/matter/lock/src/access/access_storage.h

+8
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ class AccessStorage {
6363
*/
6464
bool Init();
6565

66+
/**
67+
* @brief Factory reset the storage.
68+
*
69+
* @return true if success.
70+
* @return false otherwise.
71+
*/
72+
bool FactoryReset();
73+
6674
/**
6775
* @brief Store the entry into the persistent storage.
6876
*

0 commit comments

Comments
 (0)