Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / platform / K32W / K32WConfig.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2020 Google LLC.
5  *    Copyright (c) 2018 Nest Labs, Inc.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *    @file
22  *          Utilities for accessing persisted device configuration on
23  *          platforms based on the NXP K32W SDK.
24  */
25 /* this file behaves like a config.h, comes first */
26 #include <platform/internal/CHIPDeviceLayerInternal.h>
27
28 #include <platform/K32W/K32WConfig.h>
29
30 #include <core/CHIPEncoding.h>
31 #include <platform/internal/testing/ConfigUnitTest.h>
32
33 #include "FreeRTOS.h"
34
35 namespace chip {
36 namespace DeviceLayer {
37 namespace Internal {
38
39 CHIP_ERROR K32WConfig::Init()
40 {
41     CHIP_ERROR err;
42     int pdmStatus;
43
44     /* Initialise the Persistent Data Manager */
45     pdmStatus = PDM_Init();
46     SuccessOrExit(err = MapPdmInitStatus(pdmStatus));
47
48 exit:
49     return err;
50 }
51
52 CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val)
53 {
54     CHIP_ERROR err;
55     bool tempVal;
56     uint16_t bytesRead;
57     PDM_teStatus pdmStatus;
58
59     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
60     pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(bool), &bytesRead);
61     SuccessOrExit(err = MapPdmStatus(pdmStatus));
62     val = tempVal;
63
64 exit:
65     return err;
66 }
67
68 CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val)
69 {
70     CHIP_ERROR err;
71     uint32_t tempVal;
72     uint16_t bytesRead;
73     uint16_t recordSize;
74     PDM_teStatus pdmStatus;
75
76     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
77     if (PDM_bDoesDataExist((uint16_t) key, &recordSize))
78     {
79         pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead);
80         SuccessOrExit(err = MapPdmStatus(pdmStatus));
81         val = tempVal;
82     }
83     else
84     {
85         err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
86         goto exit;
87     }
88
89 exit:
90     return err;
91 }
92
93 CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val)
94 {
95     CHIP_ERROR err;
96     uint64_t tempVal;
97     uint16_t bytesRead;
98     uint16_t recordSize;
99     PDM_teStatus pdmStatus;
100
101     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
102
103     if (PDM_bDoesDataExist((uint16_t) key, &recordSize))
104     {
105         pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint64_t), &bytesRead);
106         SuccessOrExit(err = MapPdmStatus(pdmStatus));
107         val = tempVal;
108     }
109     else
110     {
111         err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
112         goto exit;
113     }
114
115 exit:
116     return err;
117 }
118
119 CHIP_ERROR K32WConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
120 {
121     CHIP_ERROR err;
122     const uint8_t * strEnd;
123     char * pData = NULL;
124     uint16_t bytesRead;
125     uint16_t recordSize;
126     PDM_teStatus pdmStatus;
127
128     outLen = 0;
129
130     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
131
132     if (PDM_bDoesDataExist((uint16_t) key, &recordSize))
133     {
134         pData = (char *) pvPortMalloc(recordSize);
135         VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY);
136
137         pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead);
138         SuccessOrExit(err = MapPdmStatus(pdmStatus));
139
140         strEnd = (const uint8_t *) memchr(pData, 0, bytesRead);
141         VerifyOrExit(strEnd != NULL, err = CHIP_ERROR_INVALID_ARGUMENT);
142
143         outLen = strEnd - (const uint8_t *) pData;
144
145         // NOTE: the caller is allowed to pass NULL for buf to query the length of the stored value.
146
147         if (buf != NULL)
148         {
149             VerifyOrExit(bufSize > outLen, err = CHIP_ERROR_BUFFER_TOO_SMALL);
150
151             memcpy(buf, pData, outLen + 1);
152         }
153     }
154     else
155     {
156         err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
157         goto exit;
158     }
159
160 exit:
161     if (pData != NULL)
162     {
163         vPortFree((void *) pData);
164     }
165     return err;
166 }
167
168 CHIP_ERROR K32WConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
169 {
170     CHIP_ERROR err;
171     uint8_t * pData = NULL;
172     uint16_t bytesRead;
173     uint16_t recordSize;
174     PDM_teStatus pdmStatus;
175
176     outLen = 0;
177
178     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
179
180     if (PDM_bDoesDataExist((uint16_t) key, &recordSize))
181     {
182         pData = (uint8_t *) pvPortMalloc(recordSize);
183         VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY);
184
185         pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead);
186         SuccessOrExit(err = MapPdmStatus(pdmStatus));
187
188         if (buf != NULL)
189         {
190             VerifyOrExit((bufSize >= bytesRead), err = CHIP_ERROR_BUFFER_TOO_SMALL);
191             memcpy(buf, pData, bytesRead);
192         }
193         outLen = bytesRead;
194     }
195     else
196     {
197         err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
198         goto exit;
199     }
200
201 exit:
202     if (pData != NULL)
203     {
204         vPortFree((void *) pData);
205     }
206
207     return err;
208 }
209
210 CHIP_ERROR K32WConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val)
211 {
212     CHIP_ERROR err;
213     uint32_t tempVal;
214     uint16_t bytesRead;
215     uint16_t recordSize;
216     PDM_teStatus pdmStatus;
217
218     Key key = kMinConfigKey_ChipCounter + counterIdx;
219     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
220
221     if (PDM_bDoesDataExist((uint16_t) key, &recordSize))
222     {
223         pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead);
224         SuccessOrExit(err = MapPdmStatus(pdmStatus));
225         val = tempVal;
226     }
227     else
228     {
229         err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
230         goto exit;
231     }
232
233 exit:
234     return err;
235 }
236
237 CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val)
238 {
239     CHIP_ERROR err;
240     PDM_teStatus pdmStatus;
241
242     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
243     pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(bool));
244     SuccessOrExit(err = MapPdmStatus(pdmStatus));
245
246 exit:
247     return err;
248 }
249
250 CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val)
251 {
252     CHIP_ERROR err;
253     PDM_teStatus pdmStatus;
254
255     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
256     pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t));
257     SuccessOrExit(err = MapPdmStatus(pdmStatus));
258
259 exit:
260     return err;
261 }
262
263 CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val)
264 {
265     CHIP_ERROR err;
266     PDM_teStatus pdmStatus;
267
268     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
269     pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint64_t));
270     SuccessOrExit(err = MapPdmStatus(pdmStatus));
271
272 exit:
273     return err;
274 }
275
276 CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str)
277 {
278     return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0);
279 }
280
281 CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen)
282 {
283     CHIP_ERROR err;
284     PDM_teStatus pdmStatus;
285
286     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
287
288     if (str != NULL)
289     {
290         pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) str, strLen);
291         SuccessOrExit(err = MapPdmStatus(pdmStatus));
292     }
293     else
294     {
295         err = ClearConfigValue(key);
296         SuccessOrExit(err);
297     }
298
299 exit:
300     return err;
301 }
302
303 CHIP_ERROR K32WConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
304 {
305     CHIP_ERROR err;
306     PDM_teStatus pdmStatus;
307
308     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
309
310     if ((data != NULL) && (dataLen > 0))
311     {
312         pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) data, dataLen);
313         SuccessOrExit(err = MapPdmStatus(pdmStatus));
314     }
315     else
316     {
317         err = ClearConfigValue(key);
318         SuccessOrExit(err);
319     }
320
321 exit:
322     return err;
323 }
324
325 CHIP_ERROR K32WConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val)
326 {
327     CHIP_ERROR err;
328     PDM_teStatus pdmStatus;
329
330     Key key = kMinConfigKey_ChipCounter + counterIdx;
331     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
332     pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t));
333     SuccessOrExit(err = MapPdmStatus(pdmStatus));
334
335 exit:
336     return err;
337 }
338
339 CHIP_ERROR K32WConfig::ClearConfigValue(Key key)
340 {
341     CHIP_ERROR err = CHIP_NO_ERROR;
342
343     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
344     PDM_vDeleteDataRecord((uint16_t) key);
345
346     SuccessOrExit(err);
347
348 exit:
349     return err;
350 }
351
352 bool K32WConfig::ConfigValueExists(Key key)
353 {
354     CHIP_ERROR err;
355     uint16_t size = 0;
356
357     VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
358     VerifyOrExit(PDM_bDoesDataExist((uint16_t) key, &size), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND);
359
360 exit:
361     // Return true if the record was found.
362     return (err == CHIP_NO_ERROR);
363 }
364
365 CHIP_ERROR K32WConfig::FactoryResetConfig(void)
366 {
367     CHIP_ERROR err;
368
369     // Iterate over all the CHIP Config PDM ID records and delete each one
370     err = ForEachRecord(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig, false,
371                         [](const Key & pdmKey, const size_t & length) -> CHIP_ERROR {
372                             CHIP_ERROR err2;
373
374                             err2 = ClearConfigValue(pdmKey);
375                             SuccessOrExit(err2);
376
377                         exit:
378                             return err2;
379                         });
380
381     // Return success at end of iterations.
382     if (err == CHIP_END_OF_INPUT)
383     {
384         err = CHIP_NO_ERROR;
385     }
386
387     return err;
388 }
389
390 CHIP_ERROR K32WConfig::MapPdmStatus(PDM_teStatus pdmStatus)
391 {
392     CHIP_ERROR err;
393
394     switch (pdmStatus)
395     {
396     case PDM_E_STATUS_OK:
397         err = CHIP_NO_ERROR;
398         break;
399     default:
400         err = CHIP_CONFIG_ERROR_MIN + pdmStatus;
401         break;
402     }
403
404     return err;
405 }
406
407 CHIP_ERROR K32WConfig::MapPdmInitStatus(int pdmStatus)
408 {
409     return (pdmStatus == 0) ? CHIP_NO_ERROR : CHIP_CONFIG_ERROR_MIN + pdmStatus;
410 }
411
412 bool K32WConfig::ValidConfigKey(Key key)
413 {
414     // Returns true if the key is in the valid CHIP Config PDM key range.
415
416     if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_ChipCounter))
417     {
418         return true;
419     }
420
421     return false;
422 }
423
424 CHIP_ERROR K32WConfig::ForEachRecord(Key firstKey, Key lastKey, bool addNewRecord, ForEachRecordFunct funct)
425 {
426     CHIP_ERROR err = CHIP_NO_ERROR;
427
428     for (Key pdmKey = firstKey; pdmKey <= lastKey; pdmKey++)
429     {
430         uint16_t dataLen;
431
432         if (PDM_bDoesDataExist((uint16_t) pdmKey, &dataLen))
433         {
434             if (!addNewRecord)
435             {
436                 // Invoke the caller's function
437                 // (for retrieve,store,delete,enumerate GroupKey operations).
438                 err = funct(pdmKey, dataLen);
439             }
440         }
441         else
442         {
443             if (addNewRecord)
444             {
445                 // Invoke caller's function
446                 // (for add GroupKey operation).
447                 err = funct(pdmKey, dataLen);
448             }
449         }
450
451         SuccessOrExit(err);
452     }
453
454 exit:
455     return err;
456 }
457
458 } // namespace Internal
459 } // namespace DeviceLayer
460 } // namespace chip