diff --git a/include/aos/cm/communication/communication.hpp b/include/aos/cm/communication/communication.hpp new file mode 100644 index 000000000..5d0e6b188 --- /dev/null +++ b/include/aos/cm/communication/communication.hpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2025 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_CM_COMMUNICATION_HPP_ +#define AOS_CM_COMMUNICATION_HPP_ + +#include "aos/common/cloudprotocol/state.hpp" +#include "aos/common/types.hpp" + +namespace aos::cm::communication { + +/** @addtogroup cm Communication Manager + * @{ + */ + +/** + * Communication interface. + */ +class CommunicationItf { +public: + /** + * Sends instances new state. + * + * @param newState new state to send. + * @return Error. + */ + virtual Error SendInstanceNewState(const cloudprotocol::NewState& newState) = 0; + + /** + * Sends instances update state. + * + * @param updateState update state to send. + * @return Error. + */ + virtual Error SendInstanceStateRequest(const cloudprotocol::StateRequest& stateRequest) = 0; + + /** + * Destructor. + */ + virtual ~CommunicationItf() = default; +}; + +} // namespace aos::cm::communication + +#endif diff --git a/include/aos/cm/storagestate/storagestate.hpp b/include/aos/cm/storagestate/storagestate.hpp new file mode 100644 index 000000000..367b52f70 --- /dev/null +++ b/include/aos/cm/storagestate/storagestate.hpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2025 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_STORAGESTATE_HPP_ +#define AOS_STORAGESTATE_HPP_ + +#include "aos/common/cloudprotocol/state.hpp" +#include "aos/common/crypto/crypto.hpp" +#include "aos/common/tools/noncopyable.hpp" +#include "aos/common/tools/thread.hpp" +#include "aos/common/types.hpp" + +namespace aos::cm::storagestate { + +/** @addtogroup cm Communication Manager + * @{ + */ + +/** + * Setup storage state instance params. + */ +struct SetupParams { + InstanceIdent mInstanceIdent; + size_t mUID {}; + size_t mGID {}; + size_t mStateQuota {}; + size_t mStorageQuota {}; +}; + +/** + * Storage state instance info. + */ +struct StorageStateInstanceInfo { + InstanceIdent mInstanceIdent; + StaticString mInstanceID; + size_t mStorageQuota {}; + size_t mStateQuota {}; + StaticString mStateChecksum; + + /** + * Compares storage state instance info. + * + * @param instance instance to compare with. + * @return bool. + */ + bool operator==(const StorageStateInstanceInfo& instance) const + { + return mInstanceIdent == instance.mInstanceIdent && mInstanceID == instance.mInstanceID + && mStorageQuota == instance.mStorageQuota && mStateQuota == instance.mStateQuota + && mStateChecksum == instance.mStateChecksum; + } + + /** + * Compares storage state instance info. + * + * @param instance instance to compare with. + * @return bool. + */ + bool operator!=(const StorageStateInstanceInfo& instance) const { return !operator==(instance); } +}; + +/** + * StorageState storage interface. + */ +class StorageItf { +public: + /** + * Adds storage state instance info. + * + * @param storageStateInfo storage state instance info to add. + * @return Error. + */ + virtual Error AddStorageStateInfo(const StorageStateInstanceInfo& storageStateInfo) = 0; + + /** + * Removes storage state instance info. + * + * @param instanceIdent instance ident to remove. + * @return Error. + */ + virtual Error RemoveStorageStateInfo(const InstanceIdent& instanceIdent) = 0; + + /** + * Returns all storage state instance infos. + * + * @param storageStateInfos[out] array to return storage state instance infos. + * @return Error. + */ + virtual Error GetAllStorageStateInfo(Array& storageStateInfos) = 0; + + /** + * Returns storage state instance info by instance ident. + * + * @param instanceIdent instance ident to get storage state info for. + * @param storageStateInfo[out] storage state instance info result. + * @return Error. + */ + virtual Error GetStorageStateInfo(const InstanceIdent& instanceIdent, StorageStateInstanceInfo& storageStateInfo) + = 0; + + /** + * Updates storage state instance info. + * + * @param storageStateInfo storage state instance info to update. + * @return Error. + */ + virtual Error UpdateStorageStateInfo(const StorageStateInstanceInfo& storageStateInfo) = 0; + + /** + * Destructor. + */ + virtual ~StorageItf() = default; +}; + +/** + * Interface to manage storage and state partitions. + */ +class StorageStateItf : public NonCopyable { +public: + /** + * Setups storage state instance. + * + * @param setupParams setup parameters. + * @param storagePath[out] storage path. + * @param statePath[out] state path. + * @return Error. + */ + virtual Error Setup(const SetupParams& setupParams, String& storagePath, String& statePath) = 0; + + /** + * Clean-ups storage state instance. + * + * @param instanceIdent instance ident. + * @return Error. + */ + virtual Error Cleanup(const InstanceIdent& instanceIdent) = 0; + + /** + * Removes storage state instance. + * + * @param instanceIdent instance ident. + * @return Error. + */ + virtual Error Remove(const InstanceIdent& instanceIdent) = 0; + + /** + * Updates storage state with new state. + * + * @param state new state. + * @return Error. + */ + virtual Error UpdateState(const cloudprotocol::UpdateState& state) = 0; + + /** + * Accepts state from storage. + * + * @param state state to accept. + * @return Error. + */ + virtual Error AcceptState(const cloudprotocol::StateAcceptance& state) = 0; + + /** + * Returns instance's checksum. + * + * @param instanceIdent instance ident. + * @param checkSum[out] checksum. + * @return Error + */ + virtual Error GetInstanceCheckSum(const InstanceIdent& instanceIdent, String& checkSum) = 0; + + /** + * Destructor. + */ + virtual ~StorageStateItf() = default; +}; + +} // namespace aos::cm::storagestate + +#endif diff --git a/include/aos/common/cloudprotocol/cloudprotocol.hpp b/include/aos/common/cloudprotocol/cloudprotocol.hpp index 8078bd762..5833a61be 100644 --- a/include/aos/common/cloudprotocol/cloudprotocol.hpp +++ b/include/aos/common/cloudprotocol/cloudprotocol.hpp @@ -7,6 +7,7 @@ #ifndef AOS_CLOUDPROTOCOL_HPP_ #define AOS_CLOUDPROTOCOL_HPP_ +#include "aos/common/tools/enum.hpp" #include "aos/common/tools/optional.hpp" #include "aos/common/types.hpp" @@ -74,6 +75,34 @@ struct InstanceFilter { } }; +/** + * Message type. + */ +class MessageTypeType { +public: + enum class Enum { + eStateAcceptance, + eUpdateState, + eNewState, + eStateRequest, + }; + + static const Array GetStrings() + { + static const char* const sStrings[] = { + "stateAcceptance", + "updateState", + "newState", + "stateRequest", + }; + + return Array(sStrings, ArraySize(sStrings)); + }; +}; + +using MessageTypeEnum = MessageTypeType::Enum; +using MessageType = EnumStringer; + } // namespace aos::cloudprotocol #endif diff --git a/include/aos/common/cloudprotocol/state.hpp b/include/aos/common/cloudprotocol/state.hpp new file mode 100644 index 000000000..4569ba680 --- /dev/null +++ b/include/aos/common/cloudprotocol/state.hpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2025 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_CLOUDPROTOCOL_STATE_HPP_ +#define AOS_CLOUDPROTOCOL_STATE_HPP_ + +#include "aos/common/cloudprotocol/cloudprotocol.hpp" +#include "aos/common/crypto/crypto.hpp" +#include "aos/common/tools/optional.hpp" +#include "aos/common/types.hpp" + +namespace aos::cloudprotocol { + +/** + * State length. + */ +static constexpr auto cStateLen = AOS_CONFIG_CLOUDPROTOCOL_STATE_LEN; + +/** + * State reason length. + */ +static constexpr auto cStateReason = cErrorMessageLen; + +/** + * State result type. + */ +class StateResultType { +public: + enum class Enum { + eAccepted, + eRejected, + }; + + static const Array GetStrings() + { + static const char* const sStrings[] = { + "accepted", + "rejected", + }; + + return Array(sStrings, ArraySize(sStrings)); + }; +}; + +using StateResultEnum = StateResultType::Enum; +using StateResult = EnumStringer; + +struct BaseState { + /** + * Constructor. + * + * @param instanceIdent instance identifier. + * @param messageType state message type. + */ + BaseState(const InstanceIdent& instanceIdent, MessageType messageType) + : mInstanceIdent(instanceIdent) + , mMessageType(messageType) + { + } + + InstanceIdent mInstanceIdent; + MessageType mMessageType; +}; + +/** + * State acceptance. + */ +struct StateAcceptance : public BaseState { + /** + * Constructor. + * + * @param instanceIdent instance identifier. + */ + explicit StateAcceptance(const InstanceIdent& instanceIdent = InstanceIdent()) + : BaseState(instanceIdent, MessageTypeEnum::eStateAcceptance) + { + } + + StaticString mChecksum; + StateResult mResult; + StaticString mReason; +}; + +/** + * Update state. + */ +struct UpdateState : public BaseState { + /** + * Constructor. + * + * @param instanceIdent instance identifier. + */ + explicit UpdateState(const InstanceIdent& instanceIdent = InstanceIdent()) + : BaseState(instanceIdent, MessageTypeEnum::eUpdateState) + { + } + + StaticString mChecksum; + StaticString mState; +}; + +/** + * New state. + */ +struct NewState : public BaseState { + /** + * Constructor. + * + * @param instanceIdent instance identifier. + */ + explicit NewState(const InstanceIdent& instanceIdent = InstanceIdent()) + : BaseState(instanceIdent, MessageTypeEnum::eNewState) + { + } + + StaticString mChecksum; + StaticString mState; +}; + +/** + * State request. + */ +struct StateRequest : public BaseState { + /** + * Constructor. + * + * @param instanceIdent instance identifier. + */ + explicit StateRequest(const InstanceIdent& instanceIdent = InstanceIdent()) + : BaseState(instanceIdent, MessageTypeEnum::eStateRequest) + { + } + + bool mDefault {}; +}; + +} // namespace aos::cloudprotocol + +#endif diff --git a/include/aos/common/config.hpp b/include/aos/common/config.hpp index ff5adcea5..655c44ef0 100644 --- a/include/aos/common/config.hpp +++ b/include/aos/common/config.hpp @@ -690,13 +690,6 @@ #define AOS_CONFIG_CRYPTO_SHA2_DIGEST_SIZE 64 #endif -/** - * Maximum size of SHA1 digest. - */ -#ifndef AOS_CONFIG_CRYPTO_SHA1_DIGEST_SIZE -#define AOS_CONFIG_CRYPTO_SHA1_DIGEST_SIZE 20 -#endif - /** * Maximum size of input data for SHA1 hash calculation. */ @@ -1026,6 +1019,13 @@ #define AOS_CONFIG_CLOUDPROTOCOL_BEARER_TOKEN_LEN 256 #endif +/** + * State len. + */ +#ifndef AOS_CONFIG_CLOUDPROTOCOL_STATE_LEN +#define AOS_CONFIG_CLOUDPROTOCOL_STATE_LEN 64 * 1024 +#endif + /** * Maximum supported number of timers. */ diff --git a/include/aos/common/crypto/crypto.hpp b/include/aos/common/crypto/crypto.hpp index cfbc9f28f..98a9ed9c6 100644 --- a/include/aos/common/crypto/crypto.hpp +++ b/include/aos/common/crypto/crypto.hpp @@ -203,6 +203,7 @@ class HashType { eSHA256, eSHA384, eSHA512, + eSHA3_224, eSHA3_256, eNone, }; @@ -215,6 +216,7 @@ class HashType { "SHA256", "SHA384", "SHA512", + "SHA3-224", "SHA3-256", "NONE", }; diff --git a/include/aos/common/tools/fs.hpp b/include/aos/common/tools/fs.hpp index e25915623..e86a7ddea 100644 --- a/include/aos/common/tools/fs.hpp +++ b/include/aos/common/tools/fs.hpp @@ -68,6 +68,16 @@ class FSPlatformItf { * @return RetWithError. */ virtual RetWithError GetAvailableSize(const String& dir) const = 0; + + /** + * Sets user quota for the given path. + * + * @param path path to set quota for. + * @param quota quota size in bytes. + * @param uid user ID. + * @return Error. + */ + virtual Error SetUserQuota(const String& path, size_t quota, size_t uid) const = 0; }; /** diff --git a/include/aos/common/types.hpp b/include/aos/common/types.hpp index e392c9c09..ae9dddddb 100644 --- a/include/aos/common/types.hpp +++ b/include/aos/common/types.hpp @@ -381,6 +381,17 @@ struct InstanceIdent { StaticString mSubjectID; uint64_t mInstance = 0; + /** + * Compares instance ident. + * + * @param instance ident to compare. + * @return bool. + */ + bool operator<(const InstanceIdent& instance) const + { + return mServiceID <= instance.mServiceID && mSubjectID <= instance.mSubjectID && mInstance < instance.mInstance; + } + /** * Compares instance ident. * diff --git a/src/common/crypto/mbedtls/cryptoprovider.cpp b/src/common/crypto/mbedtls/cryptoprovider.cpp index fc7e6fecc..3f53147de 100644 --- a/src/common/crypto/mbedtls/cryptoprovider.cpp +++ b/src/common/crypto/mbedtls/cryptoprovider.cpp @@ -578,6 +578,8 @@ RetWithError> MbedTLSCryptoProvider::CreateHash(Hash algorith if (algorithm.GetValue() == HashEnum::eSHA256) { alg = PSA_ALG_SHA_256; + } else if (algorithm.GetValue() == HashEnum::eSHA3_224) { + alg = PSA_ALG_SHA3_224; } else if (algorithm.GetValue() == HashEnum::eSHA3_256) { alg = PSA_ALG_SHA3_256; } else { diff --git a/tests/include/mocks/communicationmock.hpp b/tests/include/mocks/communicationmock.hpp new file mode 100644 index 000000000..888f1c67a --- /dev/null +++ b/tests/include/mocks/communicationmock.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 EPAM Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef AOS_COMMUNICATION_MOCK_HPP_ +#define AOS_COMMUNICATION_MOCK_HPP_ + +#include + +#include "aos/cm/communication/communication.hpp" + +namespace aos::cm::communication { + +/** + * Communication interface mock. + */ +class CommunicationMock : public CommunicationItf { +public: + MOCK_METHOD(Error, SendInstanceNewState, (const cloudprotocol::NewState& newState), (override)); + MOCK_METHOD(Error, SendInstanceStateRequest, (const cloudprotocol::StateRequest& stateRequest), (override)); +}; + +} // namespace aos::cm::communication + +#endif diff --git a/tests/include/mocks/filesystemmock.hpp b/tests/include/mocks/filesystemmock.hpp index 9858f5d3d..5049c374b 100644 --- a/tests/include/mocks/filesystemmock.hpp +++ b/tests/include/mocks/filesystemmock.hpp @@ -18,6 +18,7 @@ class FSPlatformMock : public fs::FSPlatformItf { MOCK_METHOD(RetWithError, GetTotalSize, (const String& dir), (const, override)); MOCK_METHOD(RetWithError, GetDirSize, (const String& dir), (const, override)); MOCK_METHOD(RetWithError, GetAvailableSize, (const String& dir), (const, override)); + MOCK_METHOD(Error, SetUserQuota, (const String& path, size_t quota, size_t uid), (const, override)); }; } // namespace aos