3 * Copyright (c) 2020 Project CHIP Authors
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * This file implements a class for managing client application
22 * user-editable settings on Linux platform.
33 #include <platform/Linux/CHIPLinuxStorage.h>
34 #include <platform/internal/CHIPDeviceLayerInternal.h>
35 #include <support/Base64.h>
36 #include <support/CHIPMem.h>
37 #include <support/CodeUtils.h>
38 #include <support/ScopedBuffer.h>
39 #include <support/logging/CHIPLogging.h>
42 namespace DeviceLayer {
45 ChipLinuxStorage::ChipLinuxStorage()
50 ChipLinuxStorage::~ChipLinuxStorage() {}
52 CHIP_ERROR ChipLinuxStorage::Init(const char * configFile)
54 CHIP_ERROR retval = CHIP_NO_ERROR;
56 mConfigPath.assign(configFile);
57 retval = ChipLinuxStorageIni::Init();
59 if (retval == CHIP_NO_ERROR)
63 ifs.open(configFile, std::ifstream::in);
65 // Create default setting file if not exist.
74 if (retval == CHIP_NO_ERROR)
76 retval = ChipLinuxStorageIni::AddConfig(mConfigPath);
82 CHIP_ERROR ChipLinuxStorage::ReadValue(const char * key, bool & val)
84 CHIP_ERROR retval = CHIP_NO_ERROR;
89 retval = ChipLinuxStorageIni::GetUIntValue(key, result);
97 CHIP_ERROR ChipLinuxStorage::ReadValue(const char * key, uint32_t & val)
99 CHIP_ERROR retval = CHIP_NO_ERROR;
103 retval = ChipLinuxStorageIni::GetUIntValue(key, val);
110 CHIP_ERROR ChipLinuxStorage::ReadValue(const char * key, uint64_t & val)
112 CHIP_ERROR retval = CHIP_NO_ERROR;
116 retval = ChipLinuxStorageIni::GetUInt64Value(key, val);
123 CHIP_ERROR ChipLinuxStorage::ReadValueStr(const char * key, char * buf, size_t bufSize, size_t & outLen)
125 CHIP_ERROR retval = CHIP_NO_ERROR;
129 retval = ChipLinuxStorageIni::GetStringValue(key, buf, bufSize, outLen);
136 CHIP_ERROR ChipLinuxStorage::ReadValueBin(const char * key, uint8_t * buf, size_t bufSize, size_t & outLen)
138 CHIP_ERROR retval = CHIP_NO_ERROR;
142 retval = ChipLinuxStorageIni::GetBinaryBlobValue(key, buf, bufSize, outLen);
149 CHIP_ERROR ChipLinuxStorage::WriteValue(const char * key, bool val)
151 CHIP_ERROR retval = CHIP_NO_ERROR;
155 retval = WriteValue(key, static_cast<uint32_t>(1));
159 retval = WriteValue(key, static_cast<uint32_t>(0));
165 CHIP_ERROR ChipLinuxStorage::WriteValue(const char * key, uint32_t val)
169 snprintf(buf, sizeof(buf), "%d", val);
171 return WriteValueStr(key, buf);
174 CHIP_ERROR ChipLinuxStorage::WriteValue(const char * key, uint64_t val)
178 snprintf(buf, sizeof(buf), "%" PRIu64, val);
180 return WriteValueStr(key, buf);
183 CHIP_ERROR ChipLinuxStorage::WriteValueStr(const char * key, const char * val)
185 CHIP_ERROR retval = CHIP_NO_ERROR;
189 retval = ChipLinuxStorageIni::AddEntry(key, val);
198 CHIP_ERROR ChipLinuxStorage::WriteValueBin(const char * key, const uint8_t * data, size_t dataLen)
200 static const size_t kMaxBlobSize = 5 * 1024;
202 CHIP_ERROR retval = CHIP_NO_ERROR;
203 chip::Platform::ScopedMemoryBuffer<char> encodedData;
204 size_t encodedDataLen = 0;
205 size_t expectedEncodedLen = ((dataLen + 3) * 4) / 3;
207 // We only support encoding blobs up to 5kb
208 if (dataLen > kMaxBlobSize)
210 retval = CHIP_ERROR_INVALID_ARGUMENT;
213 // Compute our expectedEncodedLen
214 // Allocate just enough space for the encoded data, and the NULL terminator
215 if (retval == CHIP_NO_ERROR)
217 if (!encodedData.Alloc(expectedEncodedLen + 1))
219 retval = CHIP_ERROR_NO_MEMORY;
224 if (retval == CHIP_NO_ERROR)
226 // We tested above that dataLen is no more than kMaxBlobSize.
227 static_assert(kMaxBlobSize < UINT16_MAX, "dataLen won't fit");
228 encodedDataLen = Base64Encode(data, static_cast<uint16_t>(dataLen), encodedData.Get());
229 encodedData[encodedDataLen] = 0;
233 if (retval == CHIP_NO_ERROR)
235 WriteValueStr(key, encodedData.Get());
241 CHIP_ERROR ChipLinuxStorage::ClearValue(const char * key)
243 CHIP_ERROR retval = CHIP_NO_ERROR;
247 retval = ChipLinuxStorageIni::RemoveEntry(key);
249 if (retval == CHIP_NO_ERROR)
255 retval = CHIP_ERROR_KEY_NOT_FOUND;
263 CHIP_ERROR ChipLinuxStorage::ClearAll()
265 CHIP_ERROR retval = CHIP_NO_ERROR;
269 retval = ChipLinuxStorageIni::RemoveAll();
273 if (retval == CHIP_NO_ERROR)
280 retval = CHIP_ERROR_WRITE_FAILED;
286 bool ChipLinuxStorage::HasValue(const char * key)
292 retval = ChipLinuxStorageIni::HasValue(key);
299 CHIP_ERROR ChipLinuxStorage::Commit()
301 CHIP_ERROR retval = CHIP_NO_ERROR;
303 if (mDirty && !mConfigPath.empty())
307 retval = ChipLinuxStorageIni::CommitConfig(mConfigPath);
313 retval = CHIP_ERROR_WRITE_FAILED;
319 } // namespace Internal
320 } // namespace DeviceLayer