Skip to content

Commit 6ace92f

Browse files
adigieArekBalysNordic
authored andcommitted
applications: matter_bridge: Migrate bridged device data to version 2
Migrate bridged device data from old scheme and new scheme version 1 to version 2. Signed-off-by: Adrian Gielniewski <[email protected]>
1 parent cbf4925 commit 6ace92f

File tree

2 files changed

+152
-55
lines changed

2 files changed

+152
-55
lines changed

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

Lines changed: 125 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "bridge_storage_manager.h"
88
#include "bridge_manager.h"
9+
#include "platform/ConfigurationManager.h"
910

1011
#include <zephyr/logging/log.h>
1112

@@ -196,76 +197,150 @@ bool BridgeStorageManager::Init()
196197
return MigrateData();
197198
}
198199

199-
bool BridgeStorageManager::MigrateData()
200+
bool BridgeStorageManager::MigrateDataOldScheme(uint8_t bridgedDeviceIndex)
200201
{
201-
uint8_t version;
202-
203-
/* Check if version key is present in settings to provide backward compatibility between post-2.6.0 releases and
204-
* the previous one. If the version key is present it means that the new keys structure is used (only version
205-
* equal to 1 is for now valid). Otherwise, the deprecated structure is used, so the migration has to be done.
206-
*/
207-
if (!LoadDataToObject(&mVersion, version)) {
208-
uint8_t count;
209-
uint8_t indexes[BridgeManager::kMaxBridgedDevices] = { 0 };
210-
size_t indexesCount = 0;
211-
212-
if (LoadBridgedDevicesCount(count) &&
213-
LoadBridgedDevicesIndexes(indexes, BridgeManager::kMaxBridgedDevices, indexesCount)) {
214-
/* Load all devices based on the read count number. */
215-
for (size_t i = 0; i < indexesCount; i++) {
216-
BridgedDevice device;
217-
if (!LoadBridgedDeviceEndpointId(device.mEndpointId, i)) {
218-
return false;
219-
}
202+
BridgedDevice device;
203+
if (!LoadBridgedDeviceEndpointId(device.mEndpointId, bridgedDeviceIndex)) {
204+
return false;
205+
}
220206

221-
/* Ignore an error, as node label is optional, so it may not be found. */
222-
if (!LoadBridgedDeviceNodeLabel(device.mNodeLabel, sizeof(device.mNodeLabel),
223-
device.mNodeLabelLength, i)) {
224-
device.mNodeLabelLength = 0;
225-
}
207+
/* Ignore an error, as node label is optional, so it may not be found. */
208+
if (!LoadBridgedDeviceNodeLabel(device.mNodeLabel, sizeof(device.mNodeLabel), device.mNodeLabelLength,
209+
bridgedDeviceIndex)) {
210+
device.mNodeLabelLength = 0;
211+
}
226212

227-
if (!LoadBridgedDeviceType(device.mDeviceType, i)) {
228-
return false;
229-
}
213+
if (!LoadBridgedDeviceType(device.mDeviceType, bridgedDeviceIndex)) {
214+
return false;
215+
}
230216

231217
#ifdef CONFIG_BRIDGED_DEVICE_BT
232-
bt_addr_le_t btAddr;
218+
bt_addr_le_t btAddr;
233219

234-
if (!LoadBtAddress(btAddr, i)) {
235-
return false;
236-
}
220+
if (!LoadBtAddress(btAddr, bridgedDeviceIndex)) {
221+
return false;
222+
}
237223

238-
/* Insert Bluetooth LE address as a part of implementation specific user data. */
239-
device.mUserDataSize = sizeof(btAddr);
240-
device.mUserData = reinterpret_cast<uint8_t *>(&btAddr);
224+
/* Insert Bluetooth LE address as a part of implementation specific user data. */
225+
device.mUserDataSize = sizeof(btAddr);
226+
device.mUserData = reinterpret_cast<uint8_t *>(&btAddr);
241227
#endif
242228

243-
/* Store all information using a new scheme. */
244-
if (!StoreBridgedDevice(device, i)) {
245-
return false;
246-
}
229+
/* Generate UniqueID */
230+
CHIP_ERROR result =
231+
chip::DeviceLayer::ConfigurationMgrImpl().GenerateUniqueId(device.mUniqueID, sizeof(device.mUniqueID));
232+
if (result != CHIP_NO_ERROR) {
233+
return false;
234+
}
235+
device.mUniqueIDLength = strlen(device.mUniqueID);
236+
237+
/* Store all information using a new scheme. */
238+
if (!StoreBridgedDevice(device, bridgedDeviceIndex)) {
239+
return false;
240+
}
247241

248-
/* Remove all information described using an old scheme. */
249-
RemoveBridgedDeviceEndpointId(i);
250-
RemoveBridgedDeviceNodeLabel(i);
251-
RemoveBridgedDeviceType(i);
242+
/* Remove all information described using an old scheme. */
243+
RemoveBridgedDeviceEndpointId(bridgedDeviceIndex);
244+
RemoveBridgedDeviceNodeLabel(bridgedDeviceIndex);
245+
RemoveBridgedDeviceType(bridgedDeviceIndex);
252246

253247
#ifdef CONFIG_BRIDGED_DEVICE_BT
254-
RemoveBtAddress(i);
248+
RemoveBtAddress(bridgedDeviceIndex);
255249
#endif
256-
}
257-
}
258250

259-
version = 1;
260-
Nrf::GetPersistentStorage().NonSecureStore(&mVersion, &version, sizeof(version));
251+
return true;
252+
}
253+
254+
bool BridgeStorageManager::MigrateDataVersion1(uint8_t bridgedDeviceIndex)
255+
{
256+
BridgedDeviceV1 v1;
257+
BridgedDevice device;
258+
259+
#ifdef CONFIG_BRIDGED_DEVICE_BT
260+
bt_addr_le_t btAddr;
261261

262-
} else if (version != 1) {
263-
/* Currently only no-version or version equal to 1 is supported. */
262+
/* Insert Bluetooth LE address as a part of implementation specific user data. */
263+
v1.mUserDataSize = sizeof(btAddr);
264+
v1.mUserData = reinterpret_cast<uint8_t *>(&btAddr);
265+
#endif
266+
267+
/* Load all information from old scheme */
268+
if (!LoadBridgedDevice(v1, bridgedDeviceIndex)) {
269+
return false;
270+
}
271+
272+
/* Copy all information to new scheme */
273+
device.mEndpointId = v1.mEndpointId;
274+
device.mDeviceType = v1.mDeviceType;
275+
device.mNodeLabelLength = v1.mNodeLabelLength;
276+
memcpy(device.mNodeLabel, v1.mNodeLabel, v1.mNodeLabelLength);
277+
device.mUserDataSize = v1.mUserDataSize;
278+
device.mUserData = v1.mUserData;
279+
280+
/* Generate UniqueID */
281+
CHIP_ERROR result =
282+
chip::DeviceLayer::ConfigurationMgrImpl().GenerateUniqueId(device.mUniqueID, sizeof(device.mUniqueID));
283+
if (result != CHIP_NO_ERROR) {
284+
return false;
285+
}
286+
device.mUniqueIDLength = strlen(device.mUniqueID);
287+
288+
/* Store all information using new scheme */
289+
if (!StoreBridgedDevice(device, bridgedDeviceIndex)) {
264290
return false;
265291
}
292+
266293
return true;
267294
}
268295

296+
bool BridgeStorageManager::MigrateData()
297+
{
298+
/* Check if migration is needed to provide backward compatibility between releases.
299+
* Perform migration in following cases:
300+
* 1) If the version key is missing - it means that the pre-2.7.0 release structure is used.
301+
* 2) If the version key is present but the version number does not match kCurrentVersion.
302+
*/
303+
uint8_t version;
304+
const bool versionPresent = LoadDataToObject(&mVersion, version);
305+
const bool migrationNeeded = !versionPresent || version != kCurrentVersion;
306+
307+
if (!migrationNeeded) {
308+
/* No migration needed */
309+
return true;
310+
}
311+
312+
if (versionPresent && (version < 1 || version > kCurrentVersion)) {
313+
/* Not supported version */
314+
return false;
315+
}
316+
317+
uint8_t count;
318+
uint8_t indexes[BridgeManager::kMaxBridgedDevices] = { 0 };
319+
size_t indexesCount = 0;
320+
321+
if (LoadBridgedDevicesCount(count) &&
322+
LoadBridgedDevicesIndexes(indexes, BridgeManager::kMaxBridgedDevices, indexesCount)) {
323+
/* Migrate all devices */
324+
for (size_t i = 0; i < indexesCount; i++) {
325+
if (!versionPresent) {
326+
if (!MigrateDataOldScheme(indexes[i])) {
327+
return false;
328+
}
329+
} else if (version == 1) {
330+
if (!MigrateDataVersion1(indexes[i])) {
331+
return false;
332+
}
333+
}
334+
}
335+
}
336+
337+
/* Store current version */
338+
version = kCurrentVersion;
339+
const PSErrorCode status = Nrf::GetPersistentStorage().NonSecureStore(&mVersion, &version, sizeof(version));
340+
341+
return status == PSErrorCode::Success;
342+
}
343+
269344
bool BridgeStorageManager::StoreBridgedDevicesCount(uint8_t count)
270345
{
271346
return Nrf::GetPersistentStorage().NonSecureStore(&mBridgedDevicesCount, &count, sizeof(count));

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

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class BridgeStorageManager {
5555
};
5656

5757
using BridgedDevice = BridgedDeviceV2;
58+
static constexpr uint8_t kCurrentVersion = 2;
5859

5960
static constexpr auto kMaxIndexLength = 3;
6061

@@ -163,17 +164,38 @@ class BridgeStorageManager {
163164
/**
164165
* @brief Provides backward compatibility between non-compatible data scheme versions.
165166
*
166-
* It checks the used data scheme version based on version key value.
167-
* If the version key is present it means that the new keys structure is used (only version
168-
* equal to 1 is for now valid and means post nRF Connect SDK 2.6.0).
169-
* Otherwise, the deprecated structure is used, so the migration has to be done. In such a case, method loads
170-
* the data using key names from an old scheme, removes the old data and stores again using the new key names.
167+
* It checks the used data scheme version based on version key value. If the version key is not present (it
168+
* means that the old scheme is used - pre nRF Connect SDK 2.7.0) or if the version is different than
169+
* kCurrentVersion, the migration has to be done.
171170
*
172171
* @return true if migration was successful
173172
* @return false an error occurred
174173
*/
175174
bool MigrateData();
176175

176+
/**
177+
* @brief Migrate bridged device data at given index.
178+
*
179+
* It migrates bridge device structure from pre nRF Connect SDK 2.7.0 scheme to current one. Method loads the
180+
* data using key names from an old scheme, removes the old data and stores again using the new key names.
181+
*
182+
* @param bridgedDeviceIndex index describing specific bridged device to be removed
183+
* @return true if migration was successful
184+
* @return false an error occurred
185+
*/
186+
bool MigrateDataOldScheme(uint8_t bridgedDeviceIndex);
187+
188+
/**
189+
* @brief Migrate bridged device data at given index.
190+
*
191+
* It migrates bridge device structure from version 1 to current one.
192+
*
193+
* @param bridgedDeviceIndex index describing specific bridged device to be removed
194+
* @return true if migration was successful
195+
* @return false an error occurred
196+
*/
197+
bool MigrateDataVersion1(uint8_t bridgedDeviceIndex);
198+
177199
/* The below methods are deprecated and used only for the migration purposes between the older scheme versions.
178200
*/
179201

0 commit comments

Comments
 (0)