blob: a02fe5ed7f5d2d2acefdb7439d619e0eba4aef90 [file] [log] [blame]
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -07001/*
2 *
Rob Walkere812e672020-03-31 17:51:57 -07003 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2019 Nest Labs, Inc.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -07005 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/**
20 * @file
21 * Utilities for accessing persisted device configuration on
22 * platforms based on the Silicon Labs SDK.
23 */
Rob Walker35257392020-05-14 17:35:48 -070024/* this file behaves like a config.h, comes first */
Sagar Dhawan5cacfa32020-03-18 13:28:05 -070025#include <platform/internal/CHIPDeviceLayerInternal.h>
Rob Walker35257392020-05-14 17:35:48 -070026
chirag-silabs5ec87ed2022-11-28 18:47:59 +053027#include <platform/silabs/SilabsConfig.h>
Rob Walker35257392020-05-14 17:35:48 -070028
Zang MingJie53dd5832021-09-03 03:05:16 +080029#include <lib/core/CHIPEncoding.h>
Sagar Dhawan5cacfa32020-03-18 13:28:05 -070030#include <platform/internal/testing/ConfigUnitTest.h>
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070031
Rob Walker35257392020-05-14 17:35:48 -070032#include "FreeRTOS.h"
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070033#include "nvm3.h"
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040034#include "nvm3_default.h"
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070035#include "nvm3_hal_flash.h"
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070036
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040037// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd
38// for an application controlled re-entrance protection
chirag-silabs5ec87ed2022-11-28 18:47:59 +053039#define SILABS_SEM_TIMEOUT_ms 5
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040040static SemaphoreHandle_t nvm3_Sem;
41static StaticSemaphore_t nvm3_SemStruct;
42
43void nvm3_lockBegin(void)
44{
45 VerifyOrDie(nvm3_Sem != NULL);
chirag-silabs5ec87ed2022-11-28 18:47:59 +053046 xSemaphoreTake(nvm3_Sem, SILABS_SEM_TIMEOUT_ms);
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040047}
48
49void nvm3_lockEnd(void)
50{
51 VerifyOrDie(nvm3_Sem != NULL);
52 xSemaphoreGive(nvm3_Sem);
53}
54
Sagar Dhawan5cacfa32020-03-18 13:28:05 -070055namespace chip {
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070056namespace DeviceLayer {
57namespace Internal {
58
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040059// Matter NVM3 space is placed in the silabs default nvm3 section shared with other stack.
60// 'kMatterNvm3KeyDomain' identify the matter nvm3 domain.
61// The NVM3 default section is placed at end of Flash minus 1 page byt the linker file
62// See examples/platform/efr32/ldscripts/efr32mgXX.ld
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070063
chirag-silabs5ec87ed2022-11-28 18:47:59 +053064CHIP_ERROR SILABSConfig::Init()
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070065{
jepenven-silabs281ecea2021-03-30 16:04:29 -040066 nvm3_Sem = xSemaphoreCreateBinaryStatic(&nvm3_SemStruct);
jepenven-silabs28bbbef2020-09-03 17:51:46 -040067
68 if (nvm3_Sem == NULL)
69 {
70 return CHIP_ERROR_NO_MEMORY;
71 }
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070072
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040073 return MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit));
74}
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070075
chirag-silabs5ec87ed2022-11-28 18:47:59 +053076void SILABSConfig::DeInit()
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040077{
78 vSemaphoreDelete(nvm3_Sem);
79 nvm3_close(nvm3_defaultHandle);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070080}
81
chirag-silabs5ec87ed2022-11-28 18:47:59 +053082CHIP_ERROR SILABSConfig::ReadConfigValue(Key key, bool & val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070083{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -070084 CHIP_ERROR err;
Justin Wood0a9545e2020-04-20 18:15:21 -070085 uint32_t objectType;
86 size_t dataLen;
jmartinez-silabs35d64612022-10-06 16:35:45 -040087 bool tmpVal = 0;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070088
Sagar Dhawan5cacfa32020-03-18 13:28:05 -070089 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070090
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070091 // Get nvm3 object info.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040092 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070093 SuccessOrExit(err);
94
95 // Read nvm3 bytes into tmp.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -040096 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -070097 SuccessOrExit(err);
98 val = tmpVal;
99
100exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700101 return err;
102}
103
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530104CHIP_ERROR SILABSConfig::ReadConfigValue(Key key, uint32_t & val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700105{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700106 CHIP_ERROR err;
Justin Wood0a9545e2020-04-20 18:15:21 -0700107 uint32_t objectType;
108 size_t dataLen;
jmartinez-silabs35d64612022-10-06 16:35:45 -0400109 uint32_t tmpVal = 0;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700110
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700111 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700112
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700113 // Get nvm3 object info.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400114 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700115 SuccessOrExit(err);
116
117 // Read nvm3 bytes into tmp.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400118 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700119 SuccessOrExit(err);
120 val = tmpVal;
121
122exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700123 return err;
124}
125
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530126CHIP_ERROR SILABSConfig::ReadConfigValue(Key key, uint64_t & val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700127{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700128 CHIP_ERROR err;
Justin Wood0a9545e2020-04-20 18:15:21 -0700129 uint32_t objectType;
130 size_t dataLen;
jmartinez-silabs35d64612022-10-06 16:35:45 -0400131 uint64_t tmpVal = 0;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700132
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700133 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700134
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700135 // Get nvm3 object info.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400136 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700137 SuccessOrExit(err);
138
139 // Read nvm3 bytes into tmp.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400140 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700141 SuccessOrExit(err);
142 val = tmpVal;
143
144exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700145 return err;
146}
147
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530148CHIP_ERROR SILABSConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700149{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700150 CHIP_ERROR err;
Justin Wood0a9545e2020-04-20 18:15:21 -0700151 uint32_t objectType;
152 size_t dataLen;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700153
154 outLen = 0;
155
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700156 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700157
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700158 // Get nvm3 object info.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400159 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700160 SuccessOrExit(err);
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700161 VerifyOrExit(dataLen > 0, err = CHIP_ERROR_INVALID_STRING_LENGTH);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700162
163 if (buf != NULL)
164 {
165 // Read nvm3 bytes directly into the output buffer- check buffer is
166 // long enough to take the string (nvm3 string does not include the
167 // terminator char).
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700168 VerifyOrExit((bufSize > dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700169
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400170 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, buf, dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700171 SuccessOrExit(err);
172
173 outLen = ((dataLen == 1) && (buf[0] == 0)) ? 0 : dataLen;
174 buf[outLen] = 0; // Add the terminator char.
175 }
176 else
177 {
178 if (dataLen > 1)
179 {
180 outLen = dataLen;
181 }
182 else
183 {
184 // Read the first byte of the nvm3 string into a tmp var.
185 char firstByte;
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400186 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &firstByte, 1));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700187 SuccessOrExit(err);
188
189 outLen = (firstByte == 0) ? 0 : dataLen;
190 }
191 }
192
193exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700194 return err;
195}
196
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530197CHIP_ERROR SILABSConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700198{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700199 CHIP_ERROR err;
Justin Wood0a9545e2020-04-20 18:15:21 -0700200 uint32_t objectType;
201 size_t dataLen;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700202
203 outLen = 0;
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700204 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700205
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700206 // Get nvm3 object info.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400207 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700208 SuccessOrExit(err);
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700209 VerifyOrExit(dataLen > 0, err = CHIP_ERROR_INVALID_STRING_LENGTH);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700210
211 if (buf != NULL)
212 {
213 // Read nvm3 bytes directly into output buffer- check buffer is long
214 // enough to take the data.
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700215 VerifyOrExit((bufSize >= dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700216
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400217 err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, buf, dataLen));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700218 SuccessOrExit(err);
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400219
220 outLen = dataLen;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700221 }
222
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700223exit:
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400224 return err;
225}
226
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530227CHIP_ERROR SILABSConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset)
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400228{
229 CHIP_ERROR err;
230 uint32_t objectType;
231 size_t dataLen;
232
233 outLen = 0;
234 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
235
236 // Get nvm3 object info.
237 err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
238 SuccessOrExit(err);
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400239
240 if (buf != NULL)
241 {
242 // Read nvm3 bytes directly into output buffer- check buffer is long enough to take the data
243 // else read what we can but return CHIP_ERROR_BUFFER_TOO_SMALL.
244 size_t maxReadLength = dataLen - offset;
245 if (bufSize >= maxReadLength)
246 {
247 err = MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, maxReadLength));
248 SuccessOrExit(err);
249 outLen = maxReadLength;
250 }
251 else
252 {
253 err = MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, bufSize));
254 SuccessOrExit(err);
255 // read was successful, but we did not read all the data from the object.
256 err = CHIP_ERROR_BUFFER_TOO_SMALL;
257 outLen = bufSize;
258 }
259 }
260exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700261 return err;
262}
263
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530264CHIP_ERROR SILABSConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700265{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700266 CHIP_ERROR err;
jmartinez-silabs35d64612022-10-06 16:35:45 -0400267 uint32_t tmpVal = 0;
268 Key key = kMinConfigKey_MatterCounter + counterIdx;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400269
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700270 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700271
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700272 // Read bytes into tmp.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400273 err = MapNvm3Error(nvm3_readCounter(nvm3_defaultHandle, key, &tmpVal));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700274 SuccessOrExit(err);
275 val = tmpVal;
276
277exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700278 return err;
279}
280
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530281CHIP_ERROR SILABSConfig::WriteConfigValue(Key key, bool val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700282{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700283 CHIP_ERROR err;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400284
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700285 VerifyOrExit(ValidConfigKey(key), err = CHIP_ERROR_INVALID_ARGUMENT); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700286
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400287 err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700288 SuccessOrExit(err);
289
290exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700291 return err;
292}
293
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530294CHIP_ERROR SILABSConfig::WriteConfigValue(Key key, uint32_t val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700295{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700296 CHIP_ERROR err;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400297
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700298 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700299
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400300 err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700301 SuccessOrExit(err);
302
303exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700304 return err;
305}
306
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530307CHIP_ERROR SILABSConfig::WriteConfigValue(Key key, uint64_t val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700308{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700309 CHIP_ERROR err;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400310
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700311 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700312
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400313 err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700314 SuccessOrExit(err);
315
316exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700317 return err;
318}
319
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530320CHIP_ERROR SILABSConfig::WriteConfigValueStr(Key key, const char * str)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700321{
322 return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0);
323}
324
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530325CHIP_ERROR SILABSConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700326{
jmartinez-silabs12d8beb2022-07-05 08:47:49 -0400327 CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400328
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700329 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700330
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700331 if (str != NULL)
332 {
333 // Write the string to nvm3 without the terminator char (apart from
334 // empty strings where only the terminator char is stored in nvm3).
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400335 err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, str, (strLen > 0) ? strLen : 1));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700336 SuccessOrExit(err);
337 }
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700338
339exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700340 return err;
341}
342
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530343CHIP_ERROR SILABSConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700344{
jmartinez-silabs12d8beb2022-07-05 08:47:49 -0400345 CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400346
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700347 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700348
jmartinez-silabs12d8beb2022-07-05 08:47:49 -0400349 // Only write NULL pointer if the given size is 0, since in that case, nothing is read at the pointer
350 if ((data != NULL) || (dataLen == 0))
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700351 {
jmartinez-silabs12d8beb2022-07-05 08:47:49 -0400352 // Write the binary data to nvm3.
353 err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, data, dataLen));
354 SuccessOrExit(err);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700355 }
356
357exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700358 return err;
359}
360
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530361CHIP_ERROR SILABSConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700362{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700363 CHIP_ERROR err;
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400364 Key key = kMinConfigKey_MatterCounter + counterIdx;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400365
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700366 VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700367
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400368 err = MapNvm3Error(nvm3_writeCounter(nvm3_defaultHandle, key, val));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700369 SuccessOrExit(err);
370
371exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700372 return err;
373}
374
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530375CHIP_ERROR SILABSConfig::ClearConfigValue(Key key)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700376{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700377 CHIP_ERROR err;
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400378
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700379 // Delete the nvm3 object with the given key id.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400380 err = MapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, key));
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700381 SuccessOrExit(err);
382
383exit:
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700384 return err;
385}
386
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530387bool SILABSConfig::ConfigValueExists(Key key)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700388{
Justin Wood0a9545e2020-04-20 18:15:21 -0700389 uint32_t objectType;
390 size_t dataLen;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700391
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700392 // Find object with key id.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400393 CHIP_ERROR err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700394 return (err == CHIP_NO_ERROR);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700395}
396
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530397bool SILABSConfig::ConfigValueExists(Key key, size_t & dataLen)
Steven Cooreman3dc97f02022-08-04 20:34:20 +0200398{
399 uint32_t objectType;
400 size_t dLen;
401
402 // Find object with key id.
403 CHIP_ERROR err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dLen));
404
405 if (err == CHIP_NO_ERROR)
406 {
407 dataLen = dLen;
408 }
409
410 return (err == CHIP_NO_ERROR);
411}
412
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530413CHIP_ERROR SILABSConfig::FactoryResetConfig(void)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700414{
415 // Deletes all nvm3 'Config' type objects.
416 // Note- 'Factory' and 'Counter' type nvm3 objects are NOT deleted.
417
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700418 CHIP_ERROR err;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700419
Pankaj Garg43c9c682020-03-20 15:06:18 -0700420 // Iterate over all the CHIP Config nvm3 records and delete each one...
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400421 err = ForEachRecord(kMinConfigKey_MatterConfig, kMaxConfigKey_MatterConfig, false,
Justin Wood0a9545e2020-04-20 18:15:21 -0700422 [](const Key & nvm3Key, const size_t & length) -> CHIP_ERROR {
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700423 CHIP_ERROR err2;
jmartinez-silabscff9f212022-02-18 16:09:28 -0500424 // Delete the nvm3 object with the given key id.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400425 err2 = ClearConfigValue(nvm3Key);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700426 SuccessOrExit(err2);
427
428 exit:
429 return err2;
430 });
431
432 // Return success at end of iterations.
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700433 if (err == CHIP_END_OF_INPUT)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700434 {
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700435 err = CHIP_NO_ERROR;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700436 }
437
438 return err;
439}
440
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530441CHIP_ERROR SILABSConfig::MapNvm3Error(Ecode_t nvm3Res)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700442{
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700443 CHIP_ERROR err;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700444
445 switch (nvm3Res)
446 {
447 case ECODE_NVM3_OK:
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700448 err = CHIP_NO_ERROR;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700449 break;
450 case ECODE_NVM3_ERR_KEY_NOT_FOUND:
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700451 err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700452 break;
453 default:
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530454 err = CHIP_ERROR(ChipError::Range::kPlatform, (nvm3Res & 0xFF) + CHIP_DEVICE_CONFIG_SILABS_NVM3_ERROR_MIN);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700455 break;
456 }
457
458 return err;
459}
460
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530461CHIP_ERROR SILABSConfig::ForEachRecord(Key firstNvm3Key, Key lastNvm3Key, bool addNewRecord, ForEachRecordFunct funct)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700462{
463 // Iterates through the specified range of nvm3 object key ids.
464 // Invokes the callers CB function when appropriate.
465
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700466 CHIP_ERROR err = CHIP_NO_ERROR;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700467
468 for (Key nvm3Key = firstNvm3Key; nvm3Key <= lastNvm3Key; ++nvm3Key)
469 {
Justin Wood0a9545e2020-04-20 18:15:21 -0700470 Ecode_t nvm3Res;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700471 uint32_t objectType;
Justin Wood0a9545e2020-04-20 18:15:21 -0700472 size_t dataLen;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700473
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700474 // Find nvm3 object with current nvm3 iteration key.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400475 nvm3Res = nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objectType, &dataLen);
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700476 switch (nvm3Res)
477 {
478 case ECODE_NVM3_OK:
479 if (!addNewRecord)
480 {
481 // Invoke the caller's function
482 // (for retrieve,store,delete,enumerate GroupKey operations).
483 err = funct(nvm3Key, dataLen);
484 }
485 break;
486 case ECODE_NVM3_ERR_KEY_NOT_FOUND:
487 if (addNewRecord)
488 {
489 // Invoke caller's function
490 // (for add GroupKey operation).
491 err = funct(nvm3Key, dataLen);
492 }
493 break;
494 default:
495 err = MapNvm3Error(nvm3Res);
496 break;
497 }
498
499 SuccessOrExit(err);
500 }
501
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400502exit:;
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700503 return err;
504}
505
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530506bool SILABSConfig::ValidConfigKey(Key key)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700507{
jmartinez-silabs60a42dd2022-04-05 12:30:05 -0400508 // Returns true if the key is in the Matter nvm3 reserved key range.
509 // Additional check validates that the user consciously defined the expected key range
510 if ((key >= kMatterNvm3KeyLoLimit) && (key <= kMatterNvm3KeyHiLimit) && (key >= kMinConfigKey_MatterFactory) &&
511 (key <= kMaxConfigKey_MatterKvs))
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700512 {
513 return true;
514 }
515
516 return false;
517}
518
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530519void SILABSConfig::RunConfigUnitTest()
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700520{
521 // Run common unit test.
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530522 ::chip::DeviceLayer::Internal::RunConfigUnitTest<SILABSConfig>();
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700523}
524
chirag-silabs5ec87ed2022-11-28 18:47:59 +0530525void SILABSConfig::RepackNvm3Flash(void)
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700526{
527 // Repack nvm3 flash if nvm3 space < headroom threshold.
528 // Note- checking periodically during idle periods should prevent
529 // forced repack events on any write operation.
jmartinez-silabs3da3aa82022-03-31 23:54:17 -0400530 nvm3_repack(nvm3_defaultHandle);
jepenven-silabs28bbbef2020-09-03 17:51:46 -0400531}
532
Sagar Dhawanfa07bbf2020-03-18 12:49:08 -0700533} // namespace Internal
534} // namespace DeviceLayer
Sagar Dhawan5cacfa32020-03-18 13:28:05 -0700535} // namespace chip