diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp index d94aafea5ac791..0c9b8e96b1a120 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -507,7 +507,7 @@ void AppTask::OTAHandler(AppEvent * aEvent) #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void AppTask::StartOTAQuery(intptr_t arg) { - static_cast(GetRequestorInstance())->TriggerImmediateQuery(); + static_cast(GetRequestorInstance())->TriggerImmediateQuery(); } #endif @@ -543,19 +543,19 @@ void AppTask::BleHandler(AppEvent * aEvent) } #if CONFIG_CHIP_NFC_COMMISSIONING -void AppTask::ThreadProvisioningHandler(const ChipDeviceEvent * event, intptr_t) -{ - if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) - { - if (event->ServiceProvisioningChange.IsServiceProvisioned) - { - sIsThreadProvisioned = TRUE; - } - else - { - sIsThreadProvisioned = FALSE; - } - } + void AppTask::ThreadProvisioningHandler(const ChipDeviceEvent * event, intptr_t) + { + if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) + { + if (event->ServiceProvisioningChange.IsServiceProvisioned) + { + sIsThreadProvisioned = TRUE; + } + else + { + sIsThreadProvisioned = FALSE; + } + } if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange && event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { @@ -689,18 +689,6 @@ void AppTask::OTAResumeEventHandler(AppEvent * aEvent) } } -extern "C" void vApplicationIdleHook( void ) -{ -#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - OTA_TransactionResume(); - - if (shouldReset) - { - ResetMCU(); - } -#endif -} - void AppTask::PostEvent(const AppEvent * aEvent) { if (sAppEventQueue != NULL) @@ -744,12 +732,12 @@ void AppTask::UpdateClusterStateInternal(intptr_t arg) void AppTask::UpdateDeviceState(void) { - bool onoffAttrValue = 0; + bool onoffAttrValue = 0; - /* get onoff attribute value */ - (void)emberAfReadAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, - (uint8_t *) &onoffAttrValue, 1, NULL); + /* get onoff attribute value */ + (void)emberAfReadAttribute(1, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, + (uint8_t *) &onoffAttrValue, 1, NULL); - /* set the device state */ - sLightLED.Set(onoffAttrValue); + /* set the device state */ + sLightLED.Set(onoffAttrValue); } diff --git a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c index 0884a8f261f226..49086acc400c46 100644 --- a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c +++ b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c @@ -30,6 +30,7 @@ #include "PWR_Interface.h" #include "TimersManager.h" #include "board.h" +#include "PDM.h" /* Bluetooth Low Energy */ #include "ble_config.h" @@ -52,6 +53,10 @@ #define APP_DBG_LOG(...) #endif +#define PDM_MAX_WRITES_INFINITE 0xFF + +extern bool shouldReset; + static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex) { assert(p_mutex != NULL); @@ -218,6 +223,8 @@ void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) OSA_InterruptEnable(); } +#endif /* (cPWR_UsePowerDownMode) && (configUSE_TICKLESS_IDLE != 0) */ + static void BOARD_ActionOnIdle(void) { #if ((defined gTcxo32k_ModeEn_c) && (gTcxo32k_ModeEn_c != 0)) @@ -230,7 +237,17 @@ static void BOARD_ActionOnIdle(void) void vApplicationIdleHook(void) { - BOARD_ActionOnIdle(); -} + PDM_vIdleTask(PDM_MAX_WRITES_INFINITE); -#endif /* (cPWR_UsePowerDownMode) && (configUSE_TICKLESS_IDLE != 0) */ +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + OTA_TransactionResume(); + + if (shouldReset) + { + ResetMCU(); + } +#endif + + + BOARD_ActionOnIdle(); +} \ No newline at end of file diff --git a/src/platform/nxp/k32w/k32w0/BUILD.gn b/src/platform/nxp/k32w/k32w0/BUILD.gn index eb3e52b0becaf0..074d737c4c27a8 100644 --- a/src/platform/nxp/k32w/k32w0/BUILD.gn +++ b/src/platform/nxp/k32w/k32w0/BUILD.gn @@ -40,6 +40,8 @@ static_library("k32w0") { "DiagnosticDataProviderImpl.h", "K32W0Config.cpp", "K32W0Config.h", + "ram_storage.c", + "ram_storage.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", "Logging.cpp", diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp index bf4910285160c4..2fe4220313c7ba 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp +++ b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp @@ -36,15 +36,87 @@ namespace chip { namespace DeviceLayer { namespace Internal { +#define BUFFER_LOG_SIZE 256 +#define CHIP_CONFIG_RAM_BUFFER_SIZE 3072 + +#ifndef NVM_ID_CHIP_CONFIG_DATA +#define NVM_ID_CHIP_CONFIG_DATA 0x5000 +#endif + +typedef struct +{ + uint16_t chipConfigRamBufferLen; + uint8_t chipConfigRamBuffer[1]; +} ChipConfigRamStruct_t; + +static ChipConfigRamStruct_t *chipConfigRamStruct; +static ramBufferDescriptor ramDescr = { 0 }; + +static rsError AddToRamStorage(ramBufferDescriptor * pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + rsError err; + uint32_t allocSize = ramDescr.ramBufferMaxLen; + + if ( allocSize <= *(pBuffer->ramBufferLen) + aValueLength ) + { + while (allocSize < *(pBuffer->ramBufferLen) + aValueLength) + { + /* Need to realocate the memory buffer, increase size by 512B until nvm data fits */ + allocSize += 512; + } + + allocSize += sizeof (uint16_t); + chipConfigRamStruct = (ChipConfigRamStruct_t *) realloc((void *)chipConfigRamStruct, allocSize); + VerifyOrExit((NULL != chipConfigRamStruct), err = RS_ERROR_NO_BUFS); + + ramDescr.ramBufferLen = &chipConfigRamStruct->chipConfigRamBufferLen; + ramDescr.ramBufferMaxLen = allocSize - sizeof(uint16_t); + ramDescr.pRamBuffer = &chipConfigRamStruct->chipConfigRamBuffer[0]; + } + + err = ramStorageSet(pBuffer, aKey, aValue, aValueLength); + +exit: + return err; +} CHIP_ERROR K32WConfig::Init() { CHIP_ERROR err; - int pdmStatus; + int pdmStatus;; + uint16_t bytesRead, recordSize; + bool bLoadDataFromNvm = false; + uint32_t allocSize = CHIP_CONFIG_RAM_BUFFER_SIZE; /* Initialise the Persistent Data Manager */ pdmStatus = PDM_Init(); SuccessOrExit(err = MapPdmInitStatus(pdmStatus)); + /* Check if dataset is present and get its size */ + if (PDM_bDoesDataExist((uint16_t) NVM_ID_CHIP_CONFIG_DATA, &recordSize)) + { + bLoadDataFromNvm = true; + while (recordSize > allocSize) + { + //increase size by 1k until nvm data fits + allocSize += 1024; + } + } + + chipConfigRamStruct = (ChipConfigRamStruct_t *) malloc(allocSize); + VerifyOrExit((NULL != chipConfigRamStruct), err = CHIP_ERROR_NO_MEMORY); + + chipConfigRamStruct->chipConfigRamBufferLen = 0; + ramDescr.ramBufferLen = &chipConfigRamStruct->chipConfigRamBufferLen; + ramDescr.ramBufferMaxLen = allocSize - sizeof(uint16_t); + ramDescr.pRamBuffer = &chipConfigRamStruct->chipConfigRamBuffer[0]; + + if(bLoadDataFromNvm) + { + /* Try to load the dataset in RAM */ + PDM_eReadDataFromRecord((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, recordSize, &bytesRead); + + } + exit: return err; } @@ -53,12 +125,12 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val) { CHIP_ERROR err; bool tempVal; - uint16_t bytesRead; - PDM_teStatus pdmStatus; + rsError status; + uint16_t sizeToRead = sizeof(tempVal); VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(bool), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); + status = ramStorageGet(&ramDescr, key, 0, (uint8_t*) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); val = tempVal; exit: @@ -69,22 +141,13 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) { CHIP_ERROR err; uint32_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - + rsError status; + uint16_t sizeToRead = sizeof(tempVal); + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + status = ramStorageGet(&ramDescr, key, 0, (uint8_t*) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + val = tempVal; exit: return err; @@ -93,24 +156,14 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) { CHIP_ERROR err; - uint64_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - + uint32_t tempVal; + rsError status; + uint16_t sizeToRead = sizeof(tempVal); + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint64_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + status = ramStorageGet(&ramDescr, key, 0, (uint8_t*) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + val = tempVal; exit: return err; @@ -119,130 +172,44 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) CHIP_ERROR K32WConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { CHIP_ERROR err; - const uint8_t * strEnd; - char * pData = NULL; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - - outLen = 0; + rsError status; + uint16_t sizeToRead = bufSize; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pData = (char *) pvPortMalloc(recordSize); - VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY); - - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - - strEnd = (const uint8_t *) memchr(pData, 0, bytesRead); - VerifyOrExit(strEnd != NULL, err = CHIP_ERROR_INVALID_ARGUMENT); - - outLen = strEnd - (const uint8_t *) pData; - - // NOTE: the caller is allowed to pass NULL for buf to query the length of the stored value. - - if (buf != NULL) - { - VerifyOrExit(bufSize > outLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(buf, pData, outLen + 1); - } - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + + //We can call ramStorageGet with null pointer to only retrieve the size + status = ramStorageGet(&ramDescr, key, 0, (uint8_t*) buf, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + outLen = sizeToRead; exit: - if (pData != NULL) - { - vPortFree((void *) pData); - } return err; } CHIP_ERROR K32WConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - CHIP_ERROR err; - uint8_t * pData = NULL; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - - outLen = 0; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pData = (uint8_t *) pvPortMalloc(recordSize); - VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY); - - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - - if (buf != NULL) - { - VerifyOrExit((bufSize >= bytesRead), err = CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(buf, pData, bytesRead); - } - outLen = bytesRead; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } - -exit: - if (pData != NULL) - { - vPortFree((void *) pData); - } - - return err; + return ReadConfigValueStr(key, (char*) buf, bufSize, outLen); } CHIP_ERROR K32WConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) { - CHIP_ERROR err; - uint32_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - Key key = kMinConfigKey_ChipCounter + counterIdx; - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } - -exit: - return err; + return ReadConfigValue(key, val); } CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(bool)); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); + status = AddToRamStorage(&ramDescr, key, (uint8_t *) &val, sizeof(bool)); + SuccessOrExit(err = MapRamStorageStatus(status)); + pdmStatus = PDM_eSaveRecordDataInIdleTask((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: return err; } @@ -250,10 +217,15 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t)); + status = AddToRamStorage(&ramDescr, key, (uint8_t *)&val, sizeof(uint32_t)); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = PDM_eSaveRecordDataInIdleTask((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: @@ -263,10 +235,15 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint64_t)); + status = AddToRamStorage(&ramDescr, key, (uint8_t *)&val, sizeof(uint64_t)); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = PDM_eSaveRecordDataInIdleTask((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: @@ -282,12 +259,17 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str { CHIP_ERROR err; PDM_teStatus pdmStatus; - + rsError status; + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. if (str != NULL) { - pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) str, strLen); + status = AddToRamStorage(&ramDescr, key, (uint8_t *) str, strLen); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = PDM_eSaveRecordDataInIdleTask((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); SuccessOrExit(err = MapPdmStatus(pdmStatus)); } else @@ -295,55 +277,34 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str err = ClearConfigValue(key); SuccessOrExit(err); } - exit: return err; } CHIP_ERROR K32WConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { - CHIP_ERROR err; - PDM_teStatus pdmStatus; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if ((data != NULL) && (dataLen > 0)) - { - pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) data, dataLen); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - } - else - { - err = ClearConfigValue(key); - SuccessOrExit(err); - } - -exit: - return err; + return WriteConfigValueStr(key, (char *) data, dataLen); } CHIP_ERROR K32WConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) { - CHIP_ERROR err; - PDM_teStatus pdmStatus; - Key key = kMinConfigKey_ChipCounter + counterIdx; - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t)); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - -exit: - return err; + return WriteConfigValue(key, val); } CHIP_ERROR K32WConfig::ClearConfigValue(Key key) { CHIP_ERROR err = CHIP_NO_ERROR; - + rsError status; + PDM_teStatus pdmStatus; + VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - PDM_vDeleteDataRecord((uint16_t) key); + status = ramStorageDelete(&ramDescr, key, 0); + SuccessOrExit(err = MapRamStorageStatus(status)); - SuccessOrExit(err); + pdmStatus = PDM_eSaveRecordDataInIdleTask((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: return err; @@ -351,20 +312,22 @@ CHIP_ERROR K32WConfig::ClearConfigValue(Key key) bool K32WConfig::ConfigValueExists(Key key) { - CHIP_ERROR err; - uint16_t size = 0; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - VerifyOrExit(PDM_bDoesDataExist((uint16_t) key, &size), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + rsError status; + uint16_t sizeToRead; + bool found = false; -exit: - // Return true if the record was found. - return (err == CHIP_NO_ERROR); + if (ValidConfigKey(key)) + { + status = ramStorageGet(&ramDescr, key, 0, NULL, &sizeToRead); + found = (status == RS_ERROR_NONE && sizeToRead != 0); + } + return found; } CHIP_ERROR K32WConfig::FactoryResetConfig(void) { CHIP_ERROR err; + PDM_teStatus pdmStatus; err = FactoryResetConfigInternal(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig); @@ -373,28 +336,21 @@ CHIP_ERROR K32WConfig::FactoryResetConfig(void) err = FactoryResetConfigInternal(kMinConfigKey_KVS, kMaxConfigKey_KVS); } + pdmStatus = PDM_eSaveRecordData((uint16_t) NVM_ID_CHIP_CONFIG_DATA, chipConfigRamStruct, + chipConfigRamStruct->chipConfigRamBufferLen + sizeof(uint16_t)); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); + +exit: return err; } CHIP_ERROR K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) { - CHIP_ERROR err; - - // Iterate over all the CHIP Config PDM ID records and delete each one - err = ForEachRecord(firstKey, lastKey, false, [](const Key & pdmKey, const size_t & length) -> CHIP_ERROR { - CHIP_ERROR err2; - - err2 = ClearConfigValue(pdmKey); - SuccessOrExit(err2); - - exit: - return err2; - }); + CHIP_ERROR err = CHIP_NO_ERROR; - // Return success at end of iterations. - if (err == CHIP_END_OF_INPUT) + for (Key key = firstKey; key <= lastKey; key++) { - err = CHIP_NO_ERROR; + ramStorageDelete(&ramDescr, key, 0); } return err; @@ -417,6 +373,29 @@ CHIP_ERROR K32WConfig::MapPdmStatus(PDM_teStatus pdmStatus) return err; } +CHIP_ERROR K32WConfig::MapRamStorageStatus(rsError rsStatus) +{ + CHIP_ERROR err; + + switch (rsStatus) + { + case RS_ERROR_NONE: + err = CHIP_NO_ERROR; + break; + case RS_ERROR_NOT_FOUND: + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; + default: + err = CHIP_ERROR_BUFFER_TOO_SMALL; + break; + } + + return err; +} + + + + CHIP_ERROR K32WConfig::MapPdmInitStatus(int pdmStatus) { return (pdmStatus == 0) ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kPlatform, pdmStatus); @@ -425,7 +404,6 @@ CHIP_ERROR K32WConfig::MapPdmInitStatus(int pdmStatus) bool K32WConfig::ValidConfigKey(Key key) { // Returns true if the key is in the valid CHIP Config PDM key range. - if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_KVS)) { return true; @@ -434,40 +412,6 @@ bool K32WConfig::ValidConfigKey(Key key) return false; } -CHIP_ERROR K32WConfig::ForEachRecord(Key firstKey, Key lastKey, bool addNewRecord, ForEachRecordFunct funct) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - for (Key pdmKey = firstKey; pdmKey <= lastKey; pdmKey++) - { - uint16_t dataLen; - - if (PDM_bDoesDataExist((uint16_t) pdmKey, &dataLen)) - { - if (!addNewRecord) - { - // Invoke the caller's function - // (for retrieve,store,delete,enumerate GroupKey operations). - err = funct(pdmKey, dataLen); - } - } - else - { - if (addNewRecord) - { - // Invoke caller's function - // (for add GroupKey operation). - err = funct(pdmKey, dataLen); - } - } - - SuccessOrExit(err); - } - -exit: - return err; -} - void K32WConfig::RunConfigUnitTest() {} } // namespace Internal diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.h b/src/platform/nxp/k32w/k32w0/K32W0Config.h index 789906049f7eb7..957a0aa980cc07 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.h +++ b/src/platform/nxp/k32w/k32w0/K32W0Config.h @@ -30,6 +30,7 @@ #include "MemManager.h" #include "PDM.h" +#include "ram_storage.h" namespace chip { namespace DeviceLayer { @@ -132,13 +133,12 @@ class K32WConfig static void RunConfigUnitTest(void); protected: - using ForEachRecordFunct = std::function; - static CHIP_ERROR ForEachRecord(Key firstKey, Key lastKey, bool addNewRecord, ForEachRecordFunct funct); static constexpr uint8_t GetPDMId(uint32_t key); static constexpr uint8_t GetRecordKey(uint32_t key); private: static CHIP_ERROR MapPdmStatus(PDM_teStatus pdmStatus); + static CHIP_ERROR MapRamStorageStatus(rsError rsStatus); static CHIP_ERROR MapPdmInitStatus(int pdmStatus); static CHIP_ERROR FactoryResetConfigInternal(Key firstKey, Key lastKey); }; diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp index 3db7074db3e35c..e103c0369c0511 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp @@ -43,100 +43,61 @@ constexpr size_t kMaxKeyValueBytes = 255; KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; -/* hashmap having: - * - the matter key string as key; - * - internal PDM identifier as value; - */ -std::unordered_map g_kvs_map; - -/* set containing used PDM identifiers */ -std::set g_key_ids_set; - -/* used to check if we need to restore values from flash (e.g.: reset) */ -static bool g_restored_from_flash = false; - -CHIP_ERROR RestoreFromFlash() +uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { - CHIP_ERROR err = CHIP_NO_ERROR; - uint8_t key_id = 0; - char key_string_id[kMaxKeyValueBytes] = { 0 }; - size_t key_string_id_size = 0; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - uint16_t pdm_internal_id = 0; - - if (g_restored_from_flash) - { - /* already restored from flash, nothing to do */ - return err; - } - - for (key_id = 0; key_id < kMaxNumberOfKeys; key_id++) + CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + uint8_t keyId = 0; + uint8_t pdmIdKvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; + bool bFreeIdxFound = false; + char keyString[kMaxKeyValueBytes] = { 0 }; + size_t keyStringSize = 0; + uint16_t pdmInternalId; + + for (keyId = 0; keyId < kMaxNumberOfKeys; keyId++) { - /* key was saved as string in flash (key_string_id) using (key_id + kMaxNumberOfKeys) as PDM key - * value corresponding to key_string_id was saved in flash using key_id as PDM key - */ - - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); - err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueStr(pdm_internal_id, key_string_id, kMaxKeyValueBytes, - key_string_id_size); - - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - err = CHIP_NO_ERROR; - continue; - } - else if (err != CHIP_NO_ERROR) - { - ChipLogProgress(DeviceLayer, "KVS, Error while restoring Matter key [%s] from flash with PDM id: %i", key_string_id, - pdm_internal_id); - return err; - } + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, kMaxNumberOfKeys + keyId); + err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueStr(pdmInternalId , keyString, + kMaxKeyValueBytes, keyStringSize); - if (key_string_id_size) + if (err == CHIP_NO_ERROR) { - g_key_ids_set.insert(key_id); - key_string_id_size = 0; - if (!g_kvs_map.insert(std::make_pair(std::string(key_string_id), key_id)).second) - { - /* key collision is not expected when restoring from flash */ - ChipLogProgress(DeviceLayer, "KVS, Unexpected collision while restoring Matter key [%s] from flash with PDM id: %i", - key_string_id, pdm_internal_id); - } - else + if (strcmp(key,keyString) == 0) { - ChipLogProgress(DeviceLayer, "KVS, restored Matter key [%s] from flash with PDM id: %i", key_string_id, - pdm_internal_id); + //found the entry we are looking for + break; } } + else if ((NULL != freeId) && (false == bFreeIdxFound)) + { + bFreeIdxFound = true; + *freeId = keyId; + } } - - g_restored_from_flash = true; - - return err; + return keyId; } + CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset_bytes) { - CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - std::unordered_map::const_iterator it; - size_t read_bytes = 0; - uint8_t key_id = 0; - uint16_t pdm_internal_id = 0; + CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + uint8_t pdmIdKvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; + size_t read_bytes = 0; + uint8_t keyId = 0; + uint16_t pdmInternalId = 0; - VerifyOrExit((key != NULL) && (value != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit((key != NULL) && (value != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); - if ((it = g_kvs_map.find(key)) != g_kvs_map.end()) - { - key_id = it->second; - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); + keyId = GetStringKeyId(key, NULL); - err = - chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(pdm_internal_id, (uint8_t *) value, value_size, read_bytes); + if (keyId < kMaxNumberOfKeys) + { + //This is the ID of the actual data + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, keyId); + err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(pdmInternalId, (uint8_t *) value, value_size, read_bytes); *read_bytes_size = read_bytes; - ChipLogProgress(DeviceLayer, "KVS, get Matter key [%s] with PDM id: %i", key, pdm_internal_id); + ChipLogProgress(DeviceLayer, "KVS, get Matter key [%s] with PDM id: %i", key, pdmInternalId); } exit: @@ -145,69 +106,58 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - uint8_t key_id; - bool_t put_key = false; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - std::unordered_map::const_iterator it; - uint16_t pdm_internal_id = 0; - - VerifyOrExit((key != NULL) && (value != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); - - if ((it = g_kvs_map.find(key)) == g_kvs_map.end()) /* new key */ + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + bool_t putKey = false; + uint8_t pdmIdKvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; + uint16_t pdmInternalId = 0; + uint16_t freeKeyId; + uint8_t keyId; + + VerifyOrExit((key != NULL) && (value != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); + + keyId = GetStringKeyId(key, &freeKeyId); + + //Key allready exists + if (keyId < kMaxNumberOfKeys) { - for (key_id = 0; key_id < kMaxNumberOfKeys; key_id++) - { - std::set::iterator iter = std::find(g_key_ids_set.begin(), g_key_ids_set.end(), key_id); - - if (iter == g_key_ids_set.end()) - { - if (g_key_ids_set.size() >= kMaxNumberOfKeys) - { - return CHIP_ERROR_NO_MEMORY; - } - - g_key_ids_set.insert(key_id); - - put_key = true; - break; - } - } + //Update just the value in this case + putKey = false; } - else /* overwrite key */ + else { - put_key = true; - key_id = it->second; + //Need to write both the value and the string key + putKey = true; + keyId = freeKeyId; } - if (put_key) - { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); - ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with PDM id: %i", key, pdm_internal_id); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, keyId); + ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with PDM id: %i", key, pdmInternalId); - g_kvs_map.insert(std::make_pair(std::string(key), key_id)); - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueBin(pdm_internal_id, (uint8_t *) value, value_size); + err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueBin(pdmInternalId, (uint8_t *) value, value_size); - /* save the 'key' in flash such that it can be retrieved later on */ - if (err == CHIP_NO_ERROR) + /* save the 'key' in flash such that it can be retrieved later on */ + if (err == CHIP_NO_ERROR) + { + if (true == putKey) { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); - ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with PDM id: %i", key, pdm_internal_id); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, keyId + kMaxNumberOfKeys); + ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with PDM id: %i", key, pdmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueStr(pdm_internal_id, key, strlen(key) + 1); + err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueStr(pdmInternalId, key, strlen(key) + 1); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } - else - { - ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); - } } + else + { + ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the value of the Matter key [%s] with PDM id: %i", key, + pdmInternalId); + } + exit: return err; @@ -215,48 +165,45 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { - CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - std::unordered_map::const_iterator it; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - uint8_t key_id = 0; - uint16_t pdm_internal_id = 0; + CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + uint8_t pdmIdKvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; + uint8_t keyId = 0; + uint16_t pdmInternalId = 0; - VerifyOrExit((key != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit((key != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); - if ((it = g_kvs_map.find(key)) != g_kvs_map.end()) - { - key_id = it->second; - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); + keyId = GetStringKeyId(key, NULL); - g_key_ids_set.erase(key_id); - g_kvs_map.erase(it); + if (keyId < kMaxNumberOfKeys) + { + //entry exists so we can remove it + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, keyId); - ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with PDM id: %i", key, pdm_internal_id); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdm_internal_id); + ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with PDM id: %i", key, pdmInternalId); + err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdmInternalId); /* also delete the 'key string' from flash */ if (err == CHIP_NO_ERROR) { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvs, keyId + kMaxNumberOfKeys); ChipLogProgress(DeviceLayer, "KVS, delete from flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdm_internal_id); + err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdmInternalId); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "KVS, Error while deleting from flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } else { ChipLogProgress(DeviceLayer, "KVS, Error while deleting from flash the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } - exit: return err; } diff --git a/src/platform/nxp/k32w/k32w0/ram_storage.c b/src/platform/nxp/k32w/k32w0/ram_storage.c new file mode 100644 index 00000000000000..d60d586e40e332 --- /dev/null +++ b/src/platform/nxp/k32w/k32w0/ram_storage.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +#include "FunctionLib.h" +#include "ram_storage.h" + +#ifndef RAM_STORAGE_LOG +#define RAM_STORAGE_LOG 0 +#endif + +#if RAM_STORAGE_LOG +#include "fsl_debug_console.h" +#define RAM_STORAGE_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define RAM_STORAGE_PRINTF(...) +#endif + +struct settingsBlock +{ + uint16_t key; + uint16_t length; +} __attribute__((packed)); + +static rsError ramStorageAdd(ramBufferDescriptor * pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + rsError error; + struct settingsBlock * currentBlock; + const uint16_t newBlockLength = sizeof(struct settingsBlock) + aValueLength; + + if (*(pBuffer->ramBufferLen) + newBlockLength <= pBuffer->ramBufferMaxLen) + { + currentBlock = (struct settingsBlock *) &pBuffer->pRamBuffer[*(pBuffer->ramBufferLen)]; + currentBlock->key = aKey; + currentBlock->length = aValueLength; + + memcpy(&pBuffer->pRamBuffer[*(pBuffer->ramBufferLen) + sizeof(struct settingsBlock)], aValue, aValueLength); + *(pBuffer->ramBufferLen) += newBlockLength; + + error = RS_ERROR_NONE; + } + else + { + error = RS_ERROR_NO_BUFS; + } + + RAM_STORAGE_PRINTF("key = %d lengthWriten = %d err = %d", aKey, aValueLength, error); + + return error; +} + +rsError ramStorageGet(const ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex, uint8_t * aValue, uint16_t * aValueLength) +{ + uint16_t i = 0; + uint16_t valueLength = 0; + uint16_t readLength; + int currentIndex = 0; + const struct settingsBlock * currentBlock; + rsError error = RS_ERROR_NOT_FOUND; + + while (i < *(pBuffer->ramBufferLen)) + { + currentBlock = (struct settingsBlock *) &pBuffer->pRamBuffer[i]; + + if (aKey == currentBlock->key) + { + if (currentIndex == aIndex) + { + readLength = currentBlock->length; + + // Perform read only if an input buffer was passed in + if (aValue != NULL && aValueLength != NULL) + { + // Adjust read length if input buffer size is smaller + if (readLength > *aValueLength) + { + readLength = *aValueLength; + } + + memcpy(aValue, &pBuffer->pRamBuffer[i + sizeof(struct settingsBlock)], readLength); + } + + valueLength = currentBlock->length; + error = RS_ERROR_NONE; + break; + } + + currentIndex++; + } + + i += sizeof(struct settingsBlock) + currentBlock->length; + } + + if (aValueLength != NULL) + { + *aValueLength = valueLength; + } + + RAM_STORAGE_PRINTF("key = %d err = %d", aKey, error); + + return error; +} + +rsError ramStorageSet(ramBufferDescriptor * pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + uint16_t i = 0; + uint16_t currentBlockLength; + uint16_t nextBlockStart; + const struct settingsBlock * currentBlock; + + // Delete all entries of aKey + while (i < *(pBuffer->ramBufferLen)) + { + currentBlock = (struct settingsBlock *) &pBuffer->pRamBuffer[i]; + currentBlockLength = sizeof(struct settingsBlock) + currentBlock->length; + + if (aKey == currentBlock->key) + { + nextBlockStart = i + currentBlockLength; + + if (nextBlockStart < *(pBuffer->ramBufferLen)) + { + memmove(&pBuffer->pRamBuffer[i], &pBuffer->pRamBuffer[nextBlockStart], *(pBuffer->ramBufferLen) - nextBlockStart); + } + + assert(*(pBuffer->ramBufferLen) >= currentBlockLength); + *(pBuffer->ramBufferLen) -= currentBlockLength; + } + else + { + i += currentBlockLength; + } + } + + return ramStorageAdd(pBuffer, aKey, aValue, aValueLength); +} + +rsError ramStorageDelete(ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex) +{ + uint16_t i = 0; + int currentIndex = 0; + uint16_t nextBlockStart; + uint16_t currentBlockLength; + const struct settingsBlock * currentBlock; + rsError error = RS_ERROR_NOT_FOUND; + + while (i < *(pBuffer->ramBufferLen)) + { + currentBlock = (struct settingsBlock *) &pBuffer->pRamBuffer[i]; + currentBlockLength = sizeof(struct settingsBlock) + currentBlock->length; + + if (aKey == currentBlock->key) + { + if (currentIndex == aIndex) + { + nextBlockStart = i + currentBlockLength; + + if (nextBlockStart < *(pBuffer->ramBufferLen)) + { + memmove(&pBuffer->pRamBuffer[i], &pBuffer->pRamBuffer[nextBlockStart], + *(pBuffer->ramBufferLen) - nextBlockStart); + } + + assert(*(pBuffer->ramBufferLen) >= currentBlockLength); + *(pBuffer->ramBufferLen) -= currentBlockLength; + + error = RS_ERROR_NONE; + break; + } + else + { + currentIndex++; + } + } + + i += currentBlockLength; + } + RAM_STORAGE_PRINTF("key = %d err = %d", aKey, error); + return error; +} \ No newline at end of file diff --git a/src/platform/nxp/k32w/k32w0/ram_storage.h b/src/platform/nxp/k32w/k32w0/ram_storage.h new file mode 100644 index 00000000000000..50d1b8ef6d965d --- /dev/null +++ b/src/platform/nxp/k32w/k32w0/ram_storage.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RAM_STORAGE_H +#define RAM_STORAGE_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + RS_ERROR_NONE, + RS_ERROR_NOT_FOUND, + RS_ERROR_NO_BUFS +} rsError; + +typedef struct +{ + uint16_t *ramBufferLen; + uint16_t ramBufferMaxLen; + uint8_t *pRamBuffer; +} ramBufferDescriptor; + +rsError ramStorageGet(const ramBufferDescriptor *pBuffer, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength); + +rsError ramStorageSet(ramBufferDescriptor *pBuffer, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength); + +rsError ramStorageDelete(ramBufferDescriptor *pBuffer, uint16_t aKey, int aIndex); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // RAM_STORAGE_H \ No newline at end of file