diff --git a/examples/chip-tool/config/PersistentStorage.cpp b/examples/chip-tool/config/PersistentStorage.cpp index 454c1df3262541..360f6863baa89b 100644 --- a/examples/chip-tool/config/PersistentStorage.cpp +++ b/examples/chip-tool/config/PersistentStorage.cpp @@ -17,7 +17,10 @@ */ #include "PersistentStorage.h" +#include + #include +#include using String = std::basic_string; using Section = std::map; @@ -33,6 +36,37 @@ constexpr const char kPortKey[] = "ListenPort"; constexpr const char kLoggingKey[] = "LoggingLevel"; constexpr LogCategory kDefaultLoggingLevel = kLogCategory_Detail; +namespace { + +std::string StringToBase64(const std::string & value) +{ + std::unique_ptr buffer(new char[BASE64_ENCODED_LEN(value.length())]); + + uint32_t len = + chip::Base64Encode32(reinterpret_cast(value.data()), static_cast(value.length()), buffer.get()); + if (len == UINT32_MAX) + { + return ""; + } + + return std::string(buffer.get(), len); +} + +std::string Base64ToString(const std::string & b64Value) +{ + std::unique_ptr buffer(new uint8_t[BASE64_MAX_DECODED_LEN(b64Value.length())]); + + uint32_t len = chip::Base64Decode32(b64Value.data(), static_cast(b64Value.length()), buffer.get()); + if (len == UINT32_MAX) + { + return ""; + } + + return std::string(reinterpret_cast(buffer.get()), len); +} + +} // namespace + CHIP_ERROR PersistentStorage::Init() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -53,46 +87,47 @@ CHIP_ERROR PersistentStorage::Init() return err; } -void PersistentStorage::SetStorageDelegate(PersistentStorageResultDelegate * delegate) {} - -CHIP_ERROR PersistentStorage::SyncGetKeyValue(const char * key, char * value, uint16_t & size) +CHIP_ERROR PersistentStorage::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { - CHIP_ERROR err = CHIP_NO_ERROR; std::string iniValue; - size_t iniValueLength = 0; auto section = mConfig.sections[kDefaultSectionName]; auto it = section.find(key); - VerifyOrExit(it != section.end(), err = CHIP_ERROR_KEY_NOT_FOUND); + ReturnErrorCodeIf(it == section.end(), CHIP_ERROR_KEY_NOT_FOUND); + + ReturnErrorCodeIf(!inipp::extract(section[key], iniValue), CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(inipp::extract(section[key], iniValue), err = CHIP_ERROR_INVALID_ARGUMENT); + iniValue = Base64ToString(iniValue); - iniValueLength = iniValue.size(); - VerifyOrExit(iniValueLength <= static_cast(size) - 1, err = CHIP_ERROR_BUFFER_TOO_SMALL); + uint16_t dataSize = static_cast(iniValue.size()); + if (dataSize > size) + { + size = dataSize; + return CHIP_ERROR_BUFFER_TOO_SMALL; + } - iniValueLength = iniValue.copy(value, iniValueLength); - value[iniValueLength] = '\0'; + size = dataSize; + memcpy(value, iniValue.data(), dataSize); -exit: - return err; + return CHIP_NO_ERROR; } -void PersistentStorage::AsyncSetKeyValue(const char * key, const char * value) +CHIP_ERROR PersistentStorage::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { auto section = mConfig.sections[kDefaultSectionName]; - section[key] = std::string(value); + section[key] = StringToBase64(std::string(static_cast(value), size)); mConfig.sections[kDefaultSectionName] = section; - CommitConfig(); + return CommitConfig(); } -void PersistentStorage::AsyncDeleteKeyValue(const char * key) +CHIP_ERROR PersistentStorage::SyncDeleteKeyValue(const char * key) { auto section = mConfig.sections[kDefaultSectionName]; section.erase(key); mConfig.sections[kDefaultSectionName] = section; - CommitConfig(); + return CommitConfig(); } CHIP_ERROR PersistentStorage::CommitConfig() diff --git a/examples/chip-tool/config/PersistentStorage.h b/examples/chip-tool/config/PersistentStorage.h index 066b43d7aecb3f..a8d991386183bf 100644 --- a/examples/chip-tool/config/PersistentStorage.h +++ b/examples/chip-tool/config/PersistentStorage.h @@ -28,10 +28,9 @@ class PersistentStorage : public chip::PersistentStorageDelegate CHIP_ERROR Init(); /////////// PersistentStorageDelegate Interface ///////// - void SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate) override; - CHIP_ERROR SyncGetKeyValue(const char * key, char * value, uint16_t & size) override; - void AsyncSetKeyValue(const char * key, const char * value) override; - void AsyncDeleteKeyValue(const char * key) override; + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; uint16_t GetListenPort(); chip::Logging::LogCategory GetLoggingLevel(); diff --git a/src/android/CHIPTool/.idea/compiler.xml b/src/android/CHIPTool/.idea/compiler.xml new file mode 100644 index 00000000000000..fb7f4a8a465d42 --- /dev/null +++ b/src/android/CHIPTool/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt index 664bf8384f4f82..8df4d984c2f7ac 100644 --- a/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt +++ b/src/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/CHIPToolActivity.kt @@ -38,7 +38,6 @@ import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceDetailsFragment import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceInfo import com.google.chip.chiptool.setuppayloadscanner.QrCodeInfo import chip.devicecontroller.KeyValueStoreManager -import chip.devicecontroller.PersistentStorage import chip.setuppayload.SetupPayload import chip.setuppayload.SetupPayloadParser @@ -54,7 +53,6 @@ class CHIPToolActivity : super.onCreate(savedInstanceState) setContentView(R.layout.top_activity) - PersistentStorage.initialize(this); KeyValueStoreManager.initialize(this); if (savedInstanceState == null) { diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index b5656d58a6928f..aa39a7d590b62e 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -76,18 +76,6 @@ constexpr bool useTestPairing() class ServerStorageDelegate : public PersistentStorageDelegate { - void SetStorageDelegate(PersistentStorageResultDelegate * delegate) override - { - ChipLogError(AppServer, "ServerStorageDelegate does not support async operations"); - chipDie(); - } - - void AsyncSetKeyValue(const char * key, const char * value) override - { - ChipLogError(AppServer, "ServerStorageDelegate does not support async operations"); - chipDie(); - } - CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override { ChipLogProgress(AppServer, "Retrieved value from server storage."); @@ -105,12 +93,6 @@ class ServerStorageDelegate : public PersistentStorageDelegate ChipLogProgress(AppServer, "Delete value in server storage"); return PersistedStorage::KeyValueStoreMgr().Delete(key); } - - void AsyncDeleteKeyValue(const char * key) override - { - ChipLogProgress(AppServer, "Delete value in server storage."); - PersistedStorage::KeyValueStoreMgr().Delete(key); - } }; ServerStorageDelegate gServerStorage; diff --git a/src/app/server/StorablePeerConnection.cpp b/src/app/server/StorablePeerConnection.cpp index 8b032c68a59d7f..f40340d5b82a98 100644 --- a/src/app/server/StorablePeerConnection.cpp +++ b/src/app/server/StorablePeerConnection.cpp @@ -50,8 +50,7 @@ CHIP_ERROR StorablePeerConnection::DeleteFromKVS(PersistentStorageDelegate & kvs char key[KeySize()]; ReturnErrorOnFailure(GenerateKey(keyId, key, sizeof(key))); - kvs.AsyncDeleteKeyValue(key); - return CHIP_NO_ERROR; + return kvs.SyncDeleteKeyValue(key); } constexpr size_t StorablePeerConnection::KeySize() diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 8de9918e9e8aff..b21f63c7d19aba 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -82,9 +82,6 @@ constexpr uint16_t kMdnsPort = 5353; constexpr const uint32_t kSessionEstablishmentTimeout = 30 * kMillisecondPerSecond; -// Maximum key ID is 65535 (given it's uint16_t type) -constexpr uint16_t kMaxKeyIDStringSize = 6; - // This macro generates a key using node ID an key prefix, and performs the given action // on that key. #define PERSISTENT_KEY_OP(node, keyPrefix, key, action) \ @@ -149,11 +146,6 @@ CHIP_ERROR DeviceController::Init(NodeId localDeviceId, ControllerInitParams par VerifyOrExit(mBleLayer != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); #endif - if (mStorageDelegate != nullptr) - { - mStorageDelegate->SetStorageDelegate(this); - } - mTransportMgr = chip::Platform::New(); mSessionMgr = chip::Platform::New(); mExchangeMgr = chip::Platform::New(); @@ -228,14 +220,9 @@ CHIP_ERROR DeviceController::Shutdown() chip::Platform::Delete(mInetLayer); #endif // CONFIG_DEVICE_LAYER - mSystemLayer = nullptr; - mInetLayer = nullptr; - - if (mStorageDelegate != nullptr) - { - mStorageDelegate->SetStorageDelegate(nullptr); - mStorageDelegate = nullptr; - } + mSystemLayer = nullptr; + mInetLayer = nullptr; + mStorageDelegate = nullptr; if (mExchangeMgr != nullptr) { @@ -342,7 +329,7 @@ CHIP_ERROR DeviceController::GetDevice(NodeId deviceId, Device ** out_device) uint16_t size = sizeof(deviceInfo.inner); PERSISTENT_KEY_OP(deviceId, kPairedDeviceKeyPrefix, key, - err = mStorageDelegate->SyncGetKeyValue(key, Uint8::to_char(deviceInfo.inner), size)); + err = mStorageDelegate->SyncGetKeyValue(key, deviceInfo.inner, size)); SuccessOrExit(err); VerifyOrExit(size <= sizeof(deviceInfo.inner), err = CHIP_ERROR_INVALID_DEVICE_DESCRIPTOR); @@ -386,8 +373,10 @@ void DeviceController::PersistDevice(Device * device) { SerializedDevice serialized; device->Serialize(serialized); + + // TODO: no need to base-64 the serialized values AGAIN PERSISTENT_KEY_OP(device->GetDeviceId(), kPairedDeviceKeyPrefix, key, - mStorageDelegate->AsyncSetKeyValue(key, Uint8::to_const_char(serialized.inner))); + mStorageDelegate->SyncSetKeyValue(key, serialized.inner, sizeof(serialized.inner))); } } @@ -596,8 +585,6 @@ CHIP_ERROR DeviceController::SetPairedDeviceList(const char * serialized) return err; } -void DeviceController::OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR err) {} - #if CHIP_DEVICE_CONFIG_ENABLE_MDNS void DeviceController::OnNodeIdResolved(const chip::Mdns::ResolvedNodeData & nodeData) { @@ -645,25 +632,12 @@ DeviceCommissioner::DeviceCommissioner() mPairedDevicesUpdated = false; } -CHIP_ERROR DeviceCommissioner::LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out) -{ - VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - - // TODO: Consider storing value in binary representation instead of converting to string - char keyIDStr[kMaxKeyIDStringSize]; - uint16_t size = sizeof(keyIDStr); - ReturnErrorOnFailure(delegate->SyncGetKeyValue(kNextAvailableKeyID, keyIDStr, size)); - - ReturnErrorCodeIf(!ArgParser::ParseInt(keyIDStr, out), CHIP_ERROR_INTERNAL); - - return CHIP_NO_ERROR; -} - CHIP_ERROR DeviceCommissioner::Init(NodeId localDeviceId, CommissionerInitParams params) { ReturnErrorOnFailure(DeviceController::Init(localDeviceId, params)); - if (LoadKeyId(mStorageDelegate, mNextKeyId) != CHIP_NO_ERROR) + uint16_t size = sizeof(mNextKeyId); + if (!mStorageDelegate->SyncGetKeyValue(kNextAvailableKeyID, &mNextKeyId, size) || (size != sizeof(mNextKeyId))) { mNextKeyId = 0; } @@ -862,7 +836,7 @@ CHIP_ERROR DeviceCommissioner::UnpairDevice(NodeId remoteDeviceId) if (mStorageDelegate != nullptr) { - PERSISTENT_KEY_OP(remoteDeviceId, kPairedDeviceKeyPrefix, key, mStorageDelegate->AsyncDeleteKeyValue(key)); + PERSISTENT_KEY_OP(remoteDeviceId, kPairedDeviceKeyPrefix, key, mStorageDelegate->SyncDeleteKeyValue(key)); } mPairedDevices.Remove(remoteDeviceId); @@ -963,8 +937,9 @@ void DeviceCommissioner::PersistDeviceList() const char * value = mPairedDevices.SerializeBase64(serialized, requiredSize); if (value != nullptr && requiredSize <= size) { + // TODO: no need to base64 again the value PERSISTENT_KEY_OP(static_cast(0), kPairedDeviceListKeyPrefix, key, - mStorageDelegate->AsyncSetKeyValue(key, value)); + mStorageDelegate->SyncSetKeyValue(key, value, static_cast(strlen(value)))); mPairedDevicesUpdated = false; } chip::Platform::MemoryFree(serialized); @@ -976,10 +951,7 @@ void DeviceCommissioner::PersistNextKeyId() { if (mStorageDelegate != nullptr) { - // TODO: Consider storing value in binary representation instead of converting to string - char keyIDStr[kMaxKeyIDStringSize]; - snprintf(keyIDStr, sizeof(keyIDStr), "%d", mNextKeyId); - mStorageDelegate->AsyncSetKeyValue(kNextAvailableKeyID, keyIDStr); + mStorageDelegate->SyncSetKeyValue(kNextAvailableKeyID, &mNextKeyId, sizeof(mNextKeyId)); } } diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index a6c5ae9fb07736..8667cb48553ca0 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -130,7 +130,6 @@ struct CommissionerInitParams : public ControllerInitParams */ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, public Messaging::ExchangeMgrDelegate, - public PersistentStorageResultDelegate, #if CHIP_DEVICE_CONFIG_ENABLE_MDNS public Mdns::ResolverDelegate, #endif @@ -260,9 +259,6 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, void OnNewConnection(SecureSessionHandle session, Messaging::ExchangeManager * mgr) override; void OnConnectionExpired(SecureSessionHandle session, Messaging::ExchangeManager * mgr) override; - //////////// PersistentStorageResultDelegate Implementation /////////////// - void OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR err) override; - #if CHIP_DEVICE_CONFIG_ENABLE_MDNS //////////// ResolverDelegate Implementation /////////////// void OnNodeIdResolved(const chip::Mdns::ResolvedNodeData & nodeData) override; diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 9685260e014e82..4c36795235c873 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -18,11 +18,12 @@ #include "AndroidDeviceControllerWrapper.h" #include "CHIPJNIError.h" +#include #include +#include #include -using chip::PersistentStorageResultDelegate; using chip::Controller::DeviceCommissioner; extern chip::Ble::BleLayer * GetJNIBleLayer(); @@ -67,62 +68,6 @@ void CallVoidInt(JNIEnv * env, jobject object, const char * methodName, jint arg env->CallVoidMethod(object, method, argument); } -CHIP_ERROR N2J_ByteArray(JNIEnv * env, const uint8_t * inArray, uint32_t inArrayLen, jbyteArray & outArray) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - outArray = env->NewByteArray((int) inArrayLen); - VerifyOrExit(outArray != NULL, err = CHIP_ERROR_NO_MEMORY); - - env->ExceptionClear(); - env->SetByteArrayRegion(outArray, 0, inArrayLen, (jbyte *) inArray); - VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); - -exit: - return err; -} - -CHIP_ERROR N2J_NewStringUTF(JNIEnv * env, const char * inStr, size_t inStrLen, jstring & outString) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - jbyteArray charArray = NULL; - jstring utf8Encoding = NULL; - jclass java_lang_String = NULL; - jmethodID ctor = NULL; - - err = N2J_ByteArray(env, reinterpret_cast(inStr), inStrLen, charArray); - SuccessOrExit(err); - - utf8Encoding = env->NewStringUTF("UTF-8"); - VerifyOrExit(utf8Encoding != NULL, err = CHIP_ERROR_NO_MEMORY); - - java_lang_String = env->FindClass("java/lang/String"); - VerifyOrExit(java_lang_String != NULL, err = CHIP_JNI_ERROR_TYPE_NOT_FOUND); - - ctor = env->GetMethodID(java_lang_String, "", "([BLjava/lang/String;)V"); - VerifyOrExit(ctor != NULL, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND); - - outString = (jstring) env->NewObject(java_lang_String, ctor, charArray, utf8Encoding); - VerifyOrExit(outString != NULL, err = CHIP_ERROR_NO_MEMORY); - -exit: - // error code propagated from here, so clear any possible - // exceptions that arose here - env->ExceptionClear(); - - if (utf8Encoding != NULL) - env->DeleteLocalRef(utf8Encoding); - if (charArray != NULL) - env->DeleteLocalRef(charArray); - - return err; -} - -CHIP_ERROR N2J_NewStringUTF(JNIEnv * env, const char * inStr, jstring & outString) -{ - return N2J_NewStringUTF(env, inStr, strlen(inStr), outString); -} - } // namespace AndroidDeviceControllerWrapper::~AndroidDeviceControllerWrapper() @@ -234,120 +179,27 @@ void AndroidDeviceControllerWrapper::OnMessage(chip::System::PacketBufferHandle void AndroidDeviceControllerWrapper::OnStatusChange(void) {} -void AndroidDeviceControllerWrapper::SetStorageDelegate(PersistentStorageResultDelegate * delegate) -{ - mStorageResultDelegate = delegate; -} - -CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, char * value, uint16_t & size) +CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { - jstring keyString = NULL; - jstring valueString = NULL; - const char * valueChars = nullptr; - CHIP_ERROR err = CHIP_NO_ERROR; - jclass storageCls = GetPersistentStorageClass(); - jmethodID method = GetJavaEnv()->GetStaticMethodID(storageCls, "getKeyValue", "(Ljava/lang/String;)Ljava/lang/String;"); + ChipLogProgress(chipTool, "KVS: Getting key %s", key); - GetJavaEnv()->ExceptionClear(); + size_t read_size = 0; - err = N2J_NewStringUTF(GetJavaEnv(), key, keyString); - SuccessOrExit(err); + CHIP_ERROR err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(key, value, size, &read_size); - valueString = (jstring) GetJavaEnv()->CallStaticObjectMethod(storageCls, method, keyString); - - if (valueString != NULL) - { - size_t stringLength = GetJavaEnv()->GetStringUTFLength(valueString); - if (stringLength > UINT16_MAX - 1) - { - err = CHIP_ERROR_BUFFER_TOO_SMALL; - } - else - { - if (value != nullptr) - { - valueChars = GetJavaEnv()->GetStringUTFChars(valueString, 0); - size = strlcpy(value, valueChars, size); - if (size < stringLength) - { - err = CHIP_ERROR_NO_MEMORY; - } - } - else - { - size = stringLength; - err = CHIP_ERROR_NO_MEMORY; - } - // Increment size to account for null termination - size += 1; - } - } - else - { - err = CHIP_ERROR_INVALID_ARGUMENT; - } + size = static_cast(read_size); -exit: - GetJavaEnv()->ExceptionClear(); - if (valueChars != nullptr) - { - GetJavaEnv()->ReleaseStringUTFChars(valueString, valueChars); - } - GetJavaEnv()->DeleteLocalRef(keyString); - GetJavaEnv()->DeleteLocalRef(valueString); return err; } -void AndroidDeviceControllerWrapper::AsyncSetKeyValue(const char * key, const char * value) +CHIP_ERROR AndroidDeviceControllerWrapper::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { - jclass storageCls = GetPersistentStorageClass(); - jmethodID method = GetJavaEnv()->GetStaticMethodID(storageCls, "setKeyValue", "(Ljava/lang/String;Ljava/lang/String;)V"); - - GetJavaEnv()->ExceptionClear(); - - jstring keyString = NULL; - jstring valueString = NULL; - CHIP_ERROR err = CHIP_NO_ERROR; - - err = N2J_NewStringUTF(GetJavaEnv(), key, keyString); - SuccessOrExit(err); - err = N2J_NewStringUTF(GetJavaEnv(), value, valueString); - SuccessOrExit(err); - - GetJavaEnv()->CallStaticVoidMethod(storageCls, method, keyString, valueString); - - if (mStorageResultDelegate) - { - mStorageResultDelegate->OnPersistentStorageStatus(key, PersistentStorageResultDelegate::Operation::kSET, CHIP_NO_ERROR); - } - -exit: - GetJavaEnv()->ExceptionClear(); - GetJavaEnv()->DeleteLocalRef(keyString); - GetJavaEnv()->DeleteLocalRef(valueString); + ChipLogProgress(chipTool, "KVS: Setting key %s", key); + return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(key, value, size); } -void AndroidDeviceControllerWrapper::AsyncDeleteKeyValue(const char * key) +CHIP_ERROR AndroidDeviceControllerWrapper::SyncDeleteKeyValue(const char * key) { - jclass storageCls = GetPersistentStorageClass(); - jmethodID method = GetJavaEnv()->GetStaticMethodID(storageCls, "deleteKeyValue", "(Ljava/lang/String;)V"); - - GetJavaEnv()->ExceptionClear(); - - jstring keyString = NULL; - CHIP_ERROR err = CHIP_NO_ERROR; - - err = N2J_NewStringUTF(GetJavaEnv(), key, keyString); - SuccessOrExit(err); - - GetJavaEnv()->CallStaticVoidMethod(storageCls, method, keyString); - - if (mStorageResultDelegate) - { - mStorageResultDelegate->OnPersistentStorageStatus(key, PersistentStorageResultDelegate::Operation::kDELETE, CHIP_NO_ERROR); - } - -exit: - GetJavaEnv()->ExceptionClear(); - GetJavaEnv()->DeleteLocalRef(keyString); + ChipLogProgress(chipTool, "KVS: Deleting key %s", key); + return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); } diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index a057c9ab7b34c0..b19f365bf8537e 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -50,10 +50,9 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel void OnStatusChange(void) override; // PersistentStorageDelegate implementation - void SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate) override; - CHIP_ERROR SyncGetKeyValue(const char * key, char * value, uint16_t & size) override; - void AsyncSetKeyValue(const char * key, const char * value) override; - void AsyncDeleteKeyValue(const char * key) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; jlong ToJNIHandle() { @@ -76,7 +75,6 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel using ChipDeviceControllerPtr = std::unique_ptr; ChipDeviceControllerPtr mController; - chip::PersistentStorageResultDelegate * mStorageResultDelegate = nullptr; JavaVM * mJavaVM = nullptr; jobject mJavaObjectRef = nullptr; diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 47e4fcebb2fd47..121f662795435d 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -54,12 +54,10 @@ android_library("java") { sources = [ "src/chip/devicecontroller/AndroidChipStack.java", - "src/chip/devicecontroller/AndroidPersistentStorageDelegate.java", "src/chip/devicecontroller/ChipCommandType.java", "src/chip/devicecontroller/ChipDeviceController.java", "src/chip/devicecontroller/ChipDeviceControllerException.java", "src/chip/devicecontroller/KeyValueStoreManager.java", - "src/chip/devicecontroller/PersistentStorage.java", ] javac_flags = [ "-Xlint:deprecation" ] diff --git a/src/controller/java/src/chip/devicecontroller/AndroidPersistentStorageDelegate.java b/src/controller/java/src/chip/devicecontroller/AndroidPersistentStorageDelegate.java deleted file mode 100644 index 75a546b542fa60..00000000000000 --- a/src/controller/java/src/chip/devicecontroller/AndroidPersistentStorageDelegate.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ -package chip.devicecontroller; - -/** Interface for custom storage implementations. */ -public interface AndroidPersistentStorageDelegate { - /** Get the value string associated with the input key. */ - public String getKeyValue(String key); - - /** Set the value for a key. */ - public void setKeyValue(String key, String value); - - /** Delete the value associated with the input key. */ - public void deleteKeyValue(String key); -} diff --git a/src/controller/java/src/chip/devicecontroller/PersistentStorage.java b/src/controller/java/src/chip/devicecontroller/PersistentStorage.java deleted file mode 100644 index 30ff5ed54cf6b8..00000000000000 --- a/src/controller/java/src/chip/devicecontroller/PersistentStorage.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * 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. - * - */ -package chip.devicecontroller; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Log; - -/** - * Persistent storage class, meant to be called by the CHIP SDK. Defaults to use SharedPreferences - * for storage, or uses a delegate if set. - */ -public class PersistentStorage { - private static final String TAG = PersistentStorage.class.getSimpleName(); - private static SharedPreferences preferences; - private static AndroidPersistentStorageDelegate storageDelegate; - - private static final String PREFERENCE_FILE_KEY = - "com.google.chip.devicecontroller.PREFERENCE_FILE_KEY"; - - public static String getKeyValue(String key) { - Log.d(TAG, "getKeyValue called with key: " + key); - - if (storageDelegate != null) { - return storageDelegate.getKeyValue(key); - } else { - String value = preferences.getString(key, null); - if (value == null) { - Log.d(TAG, "Key " + key + " not found in shared preferences"); - } - return value; - } - } - - public static void setKeyValue(String key, String value) { - Log.d(TAG, "setKeyValue called with key: " + key + " value: " + value); - - if (storageDelegate != null) { - storageDelegate.setKeyValue(key, value); - } else { - preferences.edit().putString(key, value).apply(); - } - } - - public static void deleteKeyValue(String key) { - Log.d(TAG, "deleteKeyValue called with key: " + key); - - if (storageDelegate != null) { - storageDelegate.deleteKeyValue(key); - } else { - preferences.edit().remove(key).apply(); - } - } - - public static void setStorageDelegate(AndroidPersistentStorageDelegate newStorageDelegate) { - storageDelegate = newStorageDelegate; - } - - /** Initialize storage with the given context. Not required if a delegate is set. */ - public static void initialize(Context context) { - preferences = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE); - } -} diff --git a/src/controller/python/ChipDeviceController-StorageDelegate.cpp b/src/controller/python/ChipDeviceController-StorageDelegate.cpp index 49fae338885680..35d83fcfe49407 100644 --- a/src/controller/python/ChipDeviceController-StorageDelegate.cpp +++ b/src/controller/python/ChipDeviceController-StorageDelegate.cpp @@ -29,12 +29,7 @@ namespace chip { namespace Controller { -void PythonPersistentStorageDelegate::SetStorageDelegate(PersistentStorageResultDelegate * delegate) -{ - mDelegate = delegate; -} - -CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, char * value, uint16_t & size) +CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { auto val = mStorage.find(key); if (val == mStorage.end()) @@ -47,7 +42,7 @@ CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, ch size = 0; } - uint16_t neededSize = val->second.size() + 1; + uint16_t neededSize = val->second.size(); if (size == 0) { size = neededSize; @@ -56,28 +51,28 @@ CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, ch if (size < neededSize) { - memcpy(value, val->second.c_str(), size - 1); - value[size - 1] = '\0'; - size = neededSize; + memcpy(value, val->second.data(), size); + size = neededSize; return CHIP_ERROR_NO_MEMORY; } - memcpy(value, val->second.c_str(), neededSize); + memcpy(value, val->second.data(), neededSize); size = neededSize; return CHIP_NO_ERROR; } -void PythonPersistentStorageDelegate::AsyncSetKeyValue(const char * key, const char * value) +CHIP_ERROR PythonPersistentStorageDelegate::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { - mStorage[key] = value; - ChipLogDetail(Controller, "AsyncSetKeyValue: %s=%s", key, value); - mDelegate->OnPersistentStorageStatus(key, PersistentStorageResultDelegate::Operation::kSET, CHIP_NO_ERROR); + mStorage[key] = std::string(static_cast(value), size); + ChipLogDetail(Controller, "SyncSetKeyValue on %s", key); + + return CHIP_NO_ERROR; } -void PythonPersistentStorageDelegate::AsyncDeleteKeyValue(const char * key) +CHIP_ERROR PythonPersistentStorageDelegate::SyncDeleteKeyValue(const char * key) { mStorage.erase(key); - mDelegate->OnPersistentStorageStatus(key, PersistentStorageResultDelegate::Operation::kDELETE, CHIP_NO_ERROR); + return CHIP_NO_ERROR; } } // namespace Controller diff --git a/src/controller/python/ChipDeviceController-StorageDelegate.h b/src/controller/python/ChipDeviceController-StorageDelegate.h index 40347af60ff777..02d30293df3563 100644 --- a/src/controller/python/ChipDeviceController-StorageDelegate.h +++ b/src/controller/python/ChipDeviceController-StorageDelegate.h @@ -36,13 +36,11 @@ class PythonPersistentStorageDelegate : public PersistentStorageDelegate { public: PythonPersistentStorageDelegate() {} - void SetStorageDelegate(PersistentStorageResultDelegate * delegate) override; - CHIP_ERROR SyncGetKeyValue(const char * key, char * value, uint16_t & size) override; - void AsyncSetKeyValue(const char * key, const char * value) override; - void AsyncDeleteKeyValue(const char * key) override; + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; private: - PersistentStorageResultDelegate * mDelegate; std::map mStorage; }; diff --git a/src/controller/python/chip/internal/CommissionerImpl.cpp b/src/controller/python/chip/internal/CommissionerImpl.cpp index 0114293e203cf7..56382e5ab5976f 100644 --- a/src/controller/python/chip/internal/CommissionerImpl.cpp +++ b/src/controller/python/chip/internal/CommissionerImpl.cpp @@ -30,19 +30,6 @@ namespace { class ServerStorageDelegate : public chip::PersistentStorageDelegate { public: - void SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate) override { mAsyncDelegate = delegate; } - - void AsyncSetKeyValue(const char * key, const char * value) override - { - - CHIP_ERROR err = SyncSetKeyValue(key, value, strlen(value)); - - if (err != CHIP_NO_ERROR) - { - mAsyncDelegate->OnPersistentStorageStatus(key, chip::PersistentStorageResultDelegate::Operation::kSET, err); - } - } - CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override { @@ -58,11 +45,6 @@ class ServerStorageDelegate : public chip::PersistentStorageDelegate { return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); } - - void AsyncDeleteKeyValue(const char * key) override { chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(key); } - -private: - chip::PersistentStorageResultDelegate * mAsyncDelegate = nullptr; }; // FIXME: implement this class diff --git a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m index 65372fdf7a8a70..d16f372c5340b8 100644 --- a/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m +++ b/src/darwin/CHIPTool/CHIPTool/Framework Helpers/DefaultsUtils.m @@ -118,12 +118,6 @@ void CHIPUnpairDeviceWithID(uint64_t deviceId) @implementation CHIPToolPersistentStorageDelegate // MARK: CHIPPersistentStorageDelegate -- (void)CHIPGetKeyValue:(NSString *)key handler:(SendKeyValue)completionHandler -{ - NSString * value = CHIPGetDomainValueForKey(kCHIPToolDefaultsDomain, key); - NSLog(@"CHIPPersistentStorageDelegate Get Value for Key: %@, value %@", key, value); - completionHandler(key, value); -} - (NSString *)CHIPGetKeyValue:(NSString *)key { @@ -132,16 +126,14 @@ - (NSString *)CHIPGetKeyValue:(NSString *)key return value; } -- (void)CHIPSetKeyValue:(NSString *)key value:(NSString *)value handler:(CHIPSendSetStatus)completionHandler +- (void)CHIPSetKeyValue:(NSString *)key value:(NSString *)value { CHIPSetDomainValueForKey(kCHIPToolDefaultsDomain, key, value); - completionHandler(key, [CHIPError errorForCHIPErrorCode:0]); } -- (void)CHIPDeleteKeyValue:(NSString *)key handler:(CHIPSendDeleteStatus)completionHandler +- (void)CHIPDeleteKeyValue:(NSString *)key { CHIPRemoveDomainValueForKey(kCHIPToolDefaultsDomain, key); - completionHandler(key, [CHIPError errorForCHIPErrorCode:0]); } @end diff --git a/src/darwin/Framework/CHIP/CHIPDeviceController.mm b/src/darwin/Framework/CHIP/CHIPDeviceController.mm index 5e3e1e334bf948..e31cc60c9597ff 100644 --- a/src/darwin/Framework/CHIP/CHIPDeviceController.mm +++ b/src/darwin/Framework/CHIP/CHIPDeviceController.mm @@ -30,7 +30,7 @@ #include #include -static const char * const CHIP_COMMISSIONER_DEVICE_ID_KEY = "com.zigbee.chip.commissioner.device.id"; +static const char * const CHIP_COMMISSIONER_DEVICE_ID_KEY = "com.zigbee.chip.commissioner.device_id"; static NSString * const kErrorMemoryInit = @"Init Memory failure"; static NSString * const kErrorCommissionerInit = @"Init failure while initializing a commissioner"; @@ -178,17 +178,16 @@ - (NSNumber *)getControllerNodeId - (NSNumber *)_getControllerNodeId { - uint16_t idStringLen = 32; - char deviceIdString[idStringLen]; + uint16_t deviceIdLength = sizeof(_localDeviceId); if (CHIP_NO_ERROR - != _persistentStorageDelegateBridge->SyncGetKeyValue(CHIP_COMMISSIONER_DEVICE_ID_KEY, deviceIdString, idStringLen)) { + != _persistentStorageDelegateBridge->SyncGetKeyValue(CHIP_COMMISSIONER_DEVICE_ID_KEY, &_localDeviceId, deviceIdLength)) { _localDeviceId = arc4random(); _localDeviceId = _localDeviceId << 32 | arc4random(); CHIP_LOG_ERROR("Assigned %llx node ID to the controller", _localDeviceId); - _persistentStorageDelegateBridge->AsyncSetKeyValue( - CHIP_COMMISSIONER_DEVICE_ID_KEY, [[NSString stringWithFormat:@"%llx", _localDeviceId] UTF8String]); + + _persistentStorageDelegateBridge->SyncSetKeyValue(CHIP_COMMISSIONER_DEVICE_ID_KEY, &_localDeviceId, sizeof(_localDeviceId)); } else { - NSScanner * scanner = [NSScanner scannerWithString:[NSString stringWithUTF8String:deviceIdString]]; + NSScanner * scanner = [NSScanner scannerWithString:[NSString stringWithFormat:@"%lld", _localDeviceId]]; [scanner scanHexLongLong:&_localDeviceId]; CHIP_LOG_ERROR("Found %llx node ID for the controller", _localDeviceId); } diff --git a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegate.h b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegate.h index 32bf391a49b885..4b1a232133f544 100644 --- a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegate.h +++ b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegate.h @@ -19,10 +19,6 @@ NS_ASSUME_NONNULL_BEGIN -typedef void (^SendKeyValue)(NSString * key, NSString * value); -typedef void (^CHIPSendSetStatus)(NSString * key, NSError * status); -typedef void (^CHIPSendDeleteStatus)(NSString * key, NSError * status); - /** * The protocol definition for the CHIPPersistenStorageDelegate * @@ -31,12 +27,6 @@ typedef void (^CHIPSendDeleteStatus)(NSString * key, NSError * status); @protocol CHIPPersistentStorageDelegate @required -/** - * Get the value for the given key - * - */ -- (void)CHIPGetKeyValue:(NSString *)key handler:(SendKeyValue)completionHandler; - /** * Get the value for the given key * @@ -47,13 +37,13 @@ typedef void (^CHIPSendDeleteStatus)(NSString * key, NSError * status); * Set the value of the key to the given value * */ -- (void)CHIPSetKeyValue:(NSString *)key value:(NSString *)value handler:(CHIPSendSetStatus)completionHandler; +- (void)CHIPSetKeyValue:(NSString *)key value:(NSString *)value; /** * Delete the key and corresponding value * */ -- (void)CHIPDeleteKeyValue:(NSString *)key handler:(CHIPSendDeleteStatus)completionHandler; +- (void)CHIPDeleteKeyValue:(NSString *)key; @end diff --git a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.h b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.h index 532227cdb906ac..fc5be8b0a94670 100644 --- a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.h +++ b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.h @@ -30,21 +30,16 @@ class CHIPPersistentStorageDelegateBridge : public chip::PersistentStorageDelega void setFrameworkDelegate(_Nullable id delegate, _Nullable dispatch_queue_t queue); - void SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate) override; + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; - CHIP_ERROR SyncGetKeyValue(const char * key, char * value, uint16_t & size) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; - void AsyncSetKeyValue(const char * key, const char * value) override; - - void AsyncDeleteKeyValue(const char * key) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; private: id mDelegate; dispatch_queue_t mQueue; - chip::PersistentStorageResultDelegate * mCallback; - CHIPSendSetStatus mSetStatusHandler; - CHIPSendDeleteStatus mDeleteStatusHandler; NSUserDefaults * mDefaultPersistentStorage; dispatch_queue_t mWorkQueue; }; diff --git a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.mm b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.mm index 8737f05a917455..6e9bfa699c963a 100644 --- a/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.mm +++ b/src/darwin/Framework/CHIP/CHIPPersistentStorageDelegateBridge.mm @@ -17,6 +17,40 @@ #import "CHIPPersistentStorageDelegateBridge.h" +#include +#include +#include +#include + +namespace { + +std::string StringToBase64(const std::string & value) +{ + std::unique_ptr buffer(new char[BASE64_ENCODED_LEN(value.length())]); + + uint32_t len = chip::Base64Encode32( + reinterpret_cast(value.data()), static_cast(value.length()), buffer.get()); + if (len == UINT32_MAX) { + return ""; + } + + return std::string(buffer.get(), len); +} + +std::string Base64ToString(const std::string & b64Value) +{ + std::unique_ptr buffer(new uint8_t[BASE64_MAX_DECODED_LEN(b64Value.length())]); + + uint32_t len = chip::Base64Decode32(b64Value.data(), static_cast(b64Value.length()), buffer.get()); + if (len == UINT32_MAX) { + return ""; + } + + return std::string(reinterpret_cast(buffer.get()), len); +} + +} // namespace + CHIPPersistentStorageDelegateBridge::CHIPPersistentStorageDelegateBridge(void) : mDelegate(nil) { @@ -40,43 +74,11 @@ }); } -void CHIPPersistentStorageDelegateBridge::SetStorageDelegate(chip::PersistentStorageResultDelegate * delegate) -{ - dispatch_async(mWorkQueue, ^{ - if (delegate) { - mCallback = delegate; - - mSetStatusHandler = ^(NSString * key, NSError * status) { - chip::PersistentStorageResultDelegate * callback = mCallback; - if (callback) { - dispatch_async(mWorkQueue, ^{ - callback->OnPersistentStorageStatus([key UTF8String], - chip::PersistentStorageResultDelegate::Operation::kSET, [CHIPError errorToCHIPErrorCode:status]); - }); - } - }; - - mDeleteStatusHandler = ^(NSString * key, NSError * status) { - chip::PersistentStorageResultDelegate * callback = mCallback; - if (callback) { - dispatch_async(mWorkQueue, ^{ - callback->OnPersistentStorageStatus([key UTF8String], - chip::PersistentStorageResultDelegate::Operation::kDELETE, [CHIPError errorToCHIPErrorCode:status]); - }); - } - }; - } else { - mCallback = nil; - mSetStatusHandler = nil; - mDeleteStatusHandler = nil; - } - }); -} - -CHIP_ERROR CHIPPersistentStorageDelegateBridge::SyncGetKeyValue(const char * key, char * value, uint16_t & size) +CHIP_ERROR CHIPPersistentStorageDelegateBridge::SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) { __block CHIP_ERROR error = CHIP_NO_ERROR; NSString * keyString = [NSString stringWithUTF8String:key]; + dispatch_sync(mWorkQueue, ^{ NSLog(@"PersistentStorageDelegate Sync Get Value for Key: %@", keyString); @@ -90,20 +92,20 @@ } if (valueString != nil) { - if (([valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1) > UINT16_MAX) { + std::string decoded = Base64ToString([valueString UTF8String]); + + if (decoded.length() > UINT16_MAX) { error = CHIP_ERROR_BUFFER_TOO_SMALL; } else { - if (value != nullptr) { - size = (uint16_t) strlcpy(value, [valueString UTF8String], size); - if (size < [valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) { + if (buffer != nullptr) { + memcpy(buffer, decoded.data(), std::min(decoded.length(), size)); + if (size < decoded.length()) { error = CHIP_ERROR_NO_MEMORY; } } else { - size = (uint16_t) [valueString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; error = CHIP_ERROR_NO_MEMORY; } - // Increment size to account for null termination - size += 1; + size = decoded.length(); } } else { error = CHIP_ERROR_KEY_NOT_FOUND; @@ -112,43 +114,52 @@ return error; } -void CHIPPersistentStorageDelegateBridge::AsyncSetKeyValue(const char * key, const char * value) +CHIP_ERROR CHIPPersistentStorageDelegateBridge::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { + std::string base64Value = StringToBase64(std::string(static_cast(value), size)); + NSString * keyString = [NSString stringWithUTF8String:key]; - NSString * valueString = [NSString stringWithUTF8String:value]; - dispatch_async(mWorkQueue, ^{ - NSLog(@"PersistentStorageDelegate Set Key %@, Value %@", keyString, valueString); + NSString * valueString = [NSString stringWithUTF8String:base64Value.c_str()]; + + dispatch_sync(mWorkQueue, ^{ + NSLog(@"PersistentStorageDelegate Set Key %@", keyString); id strongDelegate = mDelegate; if (strongDelegate && mQueue) { - dispatch_async(mQueue, ^{ - [strongDelegate CHIPSetKeyValue:keyString value:valueString handler:mSetStatusHandler]; + dispatch_sync(mQueue, ^{ + [strongDelegate CHIPSetKeyValue:keyString value:valueString]; }); } else { [mDefaultPersistentStorage setObject:valueString forKey:keyString]; - if (mSetStatusHandler) { - mSetStatusHandler(keyString, [CHIPError errorForCHIPErrorCode:0]); - } } }); + + // TODO: ideally the error from the dispatch should be returned + // however we expect to replace the storage delegate with KVS so for now + // we return no error (return used to be void due to async dispatch anyway) + + return CHIP_NO_ERROR; } -void CHIPPersistentStorageDelegateBridge::AsyncDeleteKeyValue(const char * key) +CHIP_ERROR CHIPPersistentStorageDelegateBridge::SyncDeleteKeyValue(const char * key) { NSString * keyString = [NSString stringWithUTF8String:key]; - dispatch_async(mWorkQueue, ^{ + dispatch_sync(mWorkQueue, ^{ NSLog(@"PersistentStorageDelegate Delete Key: %@", keyString); id strongDelegate = mDelegate; if (strongDelegate && mQueue) { - dispatch_async(mQueue, ^{ - [strongDelegate CHIPDeleteKeyValue:keyString handler:mDeleteStatusHandler]; + dispatch_sync(mQueue, ^{ + [strongDelegate CHIPDeleteKeyValue:keyString]; }); } else { [mDefaultPersistentStorage removeObjectForKey:keyString]; - if (mDeleteStatusHandler) { - mDeleteStatusHandler(keyString, [CHIPError errorForCHIPErrorCode:0]); - } } }); + + // TODO: ideally the error from the dispatch should be returned + // however we expect to replace the storage delegate with KVS so for now + // we return no error (return used to be void due to async dispatch anyway) + + return CHIP_NO_ERROR; } diff --git a/src/lib/core/CHIPPersistentStorageDelegate.h b/src/lib/core/CHIPPersistentStorageDelegate.h index afde29c9457f06..fca2f387f83138 100644 --- a/src/lib/core/CHIPPersistentStorageDelegate.h +++ b/src/lib/core/CHIPPersistentStorageDelegate.h @@ -23,80 +23,21 @@ namespace chip { -class DLL_EXPORT PersistentStorageResultDelegate -{ -public: - enum class Operation : uint8_t - { - kGET = 0, - kSET, - kDELETE, - }; - - virtual ~PersistentStorageResultDelegate() {} - - /** - * @brief - * Called on completion of an operation in PersistentStorageDelegate API - * - * @param[in] key Key for which the status is being returned - * @param[in] op Operation that was being performed on the key - * @param[in] result CHIP_NO_ERROR or corresponding error code - */ - virtual void OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR result) = 0; -}; - class DLL_EXPORT PersistentStorageDelegate { public: virtual ~PersistentStorageDelegate() {} - /** - * @brief - * Set the callback object with methods that are called on completion - * of the operation. - * - * @param[in] delegate The callback object - */ - virtual void SetStorageDelegate(PersistentStorageResultDelegate * delegate) = 0; - /** * @brief * This is a synchronous Get API, where the value is returned via the output - * buffer. This API should be used sparingly, since it may block for - * some duration. - * - * @param[in] key Key to lookup - * @param[out] value Value for the key. This will always be - * null-terminated if the function succeeds. - * @param[in, out] size Input value buffer size, output size of buffer - * needed to store the value. Note that due to - * null-termination this will be 1 bigger than the "length" - * of the value. - * - * The output size could be larger than input value. In - * such cases, the user should allocate the buffer large - * enough (>= output size), and call the API again. In this - * case SyncGetKeyValue will place as many bytes as it can in - * the buffer and return CHIP_ERROR_NO_MEMORY. - * - * If value is null, the input size is treated as 0. - * - * @return CHIP_ERROR_KEY_NOT_FOUND there is no value for the given key. - * @return CHIP_ERROR_NO_MEMORY if the input buffer is not big enough for - * the value. - * @return CHIP_ERROR_BUFFER_TOO_SMALL if the value's size is too large to - * be expressed as a uint16_t. - */ - virtual CHIP_ERROR SyncGetKeyValue(const char * key, char * value, uint16_t & size) { return CHIP_ERROR_NOT_IMPLEMENTED; } - - /** - * @brief - * This is a synchronous Get API, where the value is returned via the output - * buffer. This API should be used sparingly, since it may block for - * some duration. + * buffer. * * This API can be used to retrieve a byte buffer value from the storage. + * There is no implied data format and and data will be stored/fetched binary. + * Caller is responsible to take care of any special formatting needs (e.g. byte + * order, null terminators, consistency checks or versioning). + * * * @param[in] key Key to lookup * @param[out] buffer Value for the key @@ -105,16 +46,7 @@ class DLL_EXPORT PersistentStorageDelegate * such cases, the user should allocate the buffer large * enough (>= output length), and call the API again. */ - virtual CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) { return CHIP_ERROR_NOT_IMPLEMENTED; } - - /** - * @brief - * Set the value for the key to a null terminated string. - * - * @param[in] key Key to be set - * @param[in] value Value to be set - */ - virtual void AsyncSetKeyValue(const char * key, const char * value) = 0; + virtual CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) = 0; /** * @brief @@ -124,15 +56,7 @@ class DLL_EXPORT PersistentStorageDelegate * @param[in] value Value to be set * @param[in] size Size of the Value */ - virtual CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) { return CHIP_ERROR_NOT_IMPLEMENTED; } - - /** - * @brief - * Deletes the value for the key - * - * @param[in] key Key to be deleted - */ - virtual CHIP_ERROR SyncDeleteKeyValue(const char * key) { return CHIP_ERROR_NOT_IMPLEMENTED; } + virtual CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) = 0; /** * @brief @@ -140,7 +64,7 @@ class DLL_EXPORT PersistentStorageDelegate * * @param[in] key Key to be deleted */ - virtual void AsyncDeleteKeyValue(const char * key) = 0; + virtual CHIP_ERROR SyncDeleteKeyValue(const char * key) = 0; }; } // namespace chip