/* * * Copyright (c) 2020 Project CHIP Authors * Copyright (c) 2019 Nest Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file * Utilities for accessing persisted device configuration. */ /* this file behaves like a config.h, comes first */ #include #include namespace chip { namespace DeviceLayer { namespace Internal { CHIP_ERROR CYW30739Config::Init() { return CHIP_NO_ERROR; } template CHIP_ERROR CYW30739Config::ReadConfigValue(Key key, T & val) { size_t read_count; ReturnErrorOnFailure(ReadConfigValueBin(key, &val, sizeof(val), read_count)); VerifyOrReturnError(sizeof(val) == read_count, CHIP_ERROR_PERSISTED_STORAGE_FAILED); return CHIP_NO_ERROR; } CHIP_ERROR CYW30739Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { const CHIP_ERROR err = ReadConfigValueBin(key, buf, bufSize, outLen); if (outLen >= bufSize) return CHIP_ERROR_BUFFER_TOO_SMALL; buf[outLen] = '\0'; return err; } CHIP_ERROR CYW30739Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { return ReadConfigValueBin(key, static_cast(buf), bufSize, outLen); } CHIP_ERROR CYW30739Config::ReadConfigValueBin(Key key, void * buf, size_t bufSize, size_t & outLen) { wiced_result_t result; uint16_t read_count; if (kMinConfigKey_ChipFactory <= key && key <= kMaxConfigKey_ChipFactory) { read_count = wiced_hal_read_nvram_static(key, bufSize, buf, &result); } else { read_count = wiced_hal_read_nvram(key, bufSize, (uint8_t *) buf, &result); } if (result == WICED_SUCCESS) { outLen = read_count; return CHIP_NO_ERROR; } return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; } template CHIP_ERROR CYW30739Config::ReadConfigValue(Key key, bool & val); template CHIP_ERROR CYW30739Config::ReadConfigValue(Key key, uint16_t & val); template CHIP_ERROR CYW30739Config::ReadConfigValue(Key key, uint32_t & val); template CHIP_ERROR CYW30739Config::ReadConfigValue(Key key, uint64_t & val); template CHIP_ERROR CYW30739Config::WriteConfigValue(Key key, T val) { return WriteConfigValueBin(key, &val, sizeof(val)); } template CHIP_ERROR CYW30739Config::WriteConfigValue(Key key, bool val); template CHIP_ERROR CYW30739Config::WriteConfigValue(Key key, uint32_t val); template CHIP_ERROR CYW30739Config::WriteConfigValue(Key key, uint64_t val); CHIP_ERROR CYW30739Config::WriteConfigValueStr(Key key, const char * str) { return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0); } CHIP_ERROR CYW30739Config::WriteConfigValueStr(Key key, const char * str, size_t strLen) { return WriteConfigValueBin(key, str, strLen); } CHIP_ERROR CYW30739Config::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { return WriteConfigValueBin(key, static_cast(data), dataLen); } CHIP_ERROR CYW30739Config::WriteConfigValueBin(Key key, const void * data, size_t dataLen) { /* Skip writing because the write API reports error result for zero length data. */ if (dataLen == 0) return CHIP_NO_ERROR; if (IsDataFromFlash(data)) { /* * Copy data to RAM before calling the platform API * which doesn't support writing data from the flash. */ using namespace chip::Platform; std::unique_ptr buffer(MemoryAlloc(dataLen), &MemoryFree); if (!buffer) { return CHIP_ERROR_NO_MEMORY; } memcpy(buffer.get(), data, dataLen); return WriteConfigValueBin(key, buffer.get(), dataLen); } wiced_result_t result; const uint16_t write_count = wiced_hal_write_nvram(key, dataLen, (uint8_t *) data, &result); if (result == WICED_SUCCESS && write_count == dataLen) return CHIP_NO_ERROR; ChipLogError(DeviceLayer, "%s wiced_hal_write_nvram %u", __func__, result); return CHIP_ERROR_PERSISTED_STORAGE_FAILED; } CHIP_ERROR CYW30739Config::ClearConfigValue(Key key) { wiced_result_t result; wiced_hal_delete_nvram(key, &result); if (result == WICED_SUCCESS) { return CHIP_NO_ERROR; } return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; } bool CYW30739Config::ConfigValueExists(Key key) { uint8_t val; return ChipError::IsSuccess(ReadConfigValue(key, val)); } CHIP_ERROR CYW30739Config::FactoryResetConfig(void) { for (Key key = kMinConfigKey_ChipConfig; key <= kMaxConfigKey_ChipConfig; key++) ClearConfigValue(key); return CHIP_NO_ERROR; } void CYW30739Config::RunConfigUnitTest(void) {} bool CYW30739Config::IsDataFromFlash(const void * data) { return reinterpret_cast(FLASH_BASE_ADDRESS) <= data && data < reinterpret_cast(FLASH_BASE_ADDRESS + FLASH_SIZE); } } // namespace Internal } // namespace DeviceLayer } // namespace chip