From a5eb1db932ff7bc68190b315e0f15cb5d85ca085 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs Date: Mon, 6 Mar 2023 16:42:32 -0500 Subject: [PATCH] Removed global SceneTable functions and pointer, reworked UnregisterHanlder --- src/app/chip_data_model.gni | 6 +- ...nsionFieldsSets.h => ExtensionFieldSets.h} | 0 ...etsImpl.cpp => ExtensionFieldSetsImpl.cpp} | 16 +-- ...ldsSetsImpl.h => ExtensionFieldSetsImpl.h} | 12 +- src/app/clusters/scenes/SceneTable.h | 63 ++++------ src/app/clusters/scenes/SceneTableImpl.cpp | 63 +++++----- src/app/clusters/scenes/SceneTableImpl.h | 3 +- src/app/server/BUILD.gn | 6 + src/app/server/Server.cpp | 4 + src/app/server/Server.h | 111 ++++++++++++++---- src/app/tests/BUILD.gn | 6 +- src/app/tests/TestSceneTable.cpp | 66 ++++++----- src/lib/support/TestSceneTable.h | 18 ++- 13 files changed, 229 insertions(+), 145 deletions(-) rename src/app/clusters/scenes/{ExtensionFieldsSets.h => ExtensionFieldSets.h} (100%) rename src/app/clusters/scenes/{ExtensionFieldsSetsImpl.cpp => ExtensionFieldSetsImpl.cpp} (87%) rename src/app/clusters/scenes/{ExtensionFieldsSetsImpl.h => ExtensionFieldSetsImpl.h} (93%) diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 221312a60c3906..197f81b0effdb7 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -157,9 +157,9 @@ template("chip_data_model") { "${_app_root}/clusters/identify-server/identify-server.h", "${_app_root}/clusters/level-control/level-control.h", "${_app_root}/clusters/on-off-server/on-off-server.h", - "${_app_root}/clusters/scenes/ExtensionFieldsSets.h", - "${_app_root}/clusters/scenes/ExtensionFieldsSetsImpl.cpp", - "${_app_root}/clusters/scenes/ExtensionFieldsSetsImpl.h", + "${_app_root}/clusters/scenes/ExtensionFieldSets.h", + "${_app_root}/clusters/scenes/ExtensionFieldSetsImpl.cpp", + "${_app_root}/clusters/scenes/ExtensionFieldSetsImpl.h", "${_app_root}/clusters/scenes/SceneTable.h", "${_app_root}/clusters/scenes/SceneTableImpl.cpp", "${_app_root}/clusters/scenes/SceneTableImpl.h", diff --git a/src/app/clusters/scenes/ExtensionFieldsSets.h b/src/app/clusters/scenes/ExtensionFieldSets.h similarity index 100% rename from src/app/clusters/scenes/ExtensionFieldsSets.h rename to src/app/clusters/scenes/ExtensionFieldSets.h diff --git a/src/app/clusters/scenes/ExtensionFieldsSetsImpl.cpp b/src/app/clusters/scenes/ExtensionFieldSetsImpl.cpp similarity index 87% rename from src/app/clusters/scenes/ExtensionFieldsSetsImpl.cpp rename to src/app/clusters/scenes/ExtensionFieldSetsImpl.cpp index 3e9a2232ad4660..c4e32832cb85bc 100644 --- a/src/app/clusters/scenes/ExtensionFieldsSetsImpl.cpp +++ b/src/app/clusters/scenes/ExtensionFieldSetsImpl.cpp @@ -15,14 +15,14 @@ * limitations under the License. */ -#include +#include namespace chip { namespace scenes { -ExtensionFieldsSetsImpl::ExtensionFieldsSetsImpl() : ExtensionFieldsSets() {} +ExtensionFieldSetsImpl::ExtensionFieldSetsImpl() : ExtensionFieldsSets() {} -CHIP_ERROR ExtensionFieldsSetsImpl::Serialize(TLV::TLVWriter & writer) const +CHIP_ERROR ExtensionFieldSetsImpl::Serialize(TLV::TLVWriter & writer) const { TLV::TLVType container; ReturnErrorOnFailure(writer.StartContainer(TLV::ContextTag(kTagEFSArrayContainer), TLV::kTLVType_Structure, container)); @@ -41,7 +41,7 @@ CHIP_ERROR ExtensionFieldsSetsImpl::Serialize(TLV::TLVWriter & writer) const return writer.EndContainer(container); } -CHIP_ERROR ExtensionFieldsSetsImpl::Deserialize(TLV::TLVReader & reader) +CHIP_ERROR ExtensionFieldSetsImpl::Deserialize(TLV::TLVReader & reader) { TLV::TLVType container; ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::ContextTag(kTagEFSArrayContainer))); @@ -61,7 +61,7 @@ CHIP_ERROR ExtensionFieldsSetsImpl::Deserialize(TLV::TLVReader & reader) return reader.ExitContainer(container); } -void ExtensionFieldsSetsImpl::Clear() +void ExtensionFieldSetsImpl::Clear() { if (!this->IsEmpty()) { @@ -77,7 +77,7 @@ void ExtensionFieldsSetsImpl::Clear() /// If the same ID is present in the EFS array, it will overwrite it. /// @param fieldSet field set to be inserted /// @return CHIP_NO_ERROR if insertion worked, CHIP_ERROR_NO_MEMORY if the array is already full -CHIP_ERROR ExtensionFieldsSetsImpl::InsertFieldSet(ExtensionFieldsSet & fieldSet) +CHIP_ERROR ExtensionFieldSetsImpl::InsertFieldSet(ExtensionFieldsSet & fieldSet) { CHIP_ERROR err = CHIP_ERROR_NO_MEMORY; uint8_t idPosition = kInvalidPosition; @@ -115,7 +115,7 @@ CHIP_ERROR ExtensionFieldsSetsImpl::InsertFieldSet(ExtensionFieldsSet & fieldSet return err; } -CHIP_ERROR ExtensionFieldsSetsImpl::GetFieldSetAtPosition(ExtensionFieldsSet & fieldSet, uint8_t position) +CHIP_ERROR ExtensionFieldSetsImpl::GetFieldSetAtPosition(ExtensionFieldsSet & fieldSet, uint8_t position) { VerifyOrReturnError(position < this->mFieldNum, CHIP_ERROR_BUFFER_TOO_SMALL); @@ -124,7 +124,7 @@ CHIP_ERROR ExtensionFieldsSetsImpl::GetFieldSetAtPosition(ExtensionFieldsSet & f return CHIP_NO_ERROR; } -CHIP_ERROR ExtensionFieldsSetsImpl::RemoveFieldAtPosition(uint8_t position) +CHIP_ERROR ExtensionFieldSetsImpl::RemoveFieldAtPosition(uint8_t position) { VerifyOrReturnError(position < kMaxClusterPerScenes, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnValue(!this->IsEmpty() && !this->mEFS[position].IsEmpty(), CHIP_NO_ERROR); diff --git a/src/app/clusters/scenes/ExtensionFieldsSetsImpl.h b/src/app/clusters/scenes/ExtensionFieldSetsImpl.h similarity index 93% rename from src/app/clusters/scenes/ExtensionFieldsSetsImpl.h rename to src/app/clusters/scenes/ExtensionFieldSetsImpl.h index a8b24623145dee..5e02e561b8344c 100644 --- a/src/app/clusters/scenes/ExtensionFieldsSetsImpl.h +++ b/src/app/clusters/scenes/ExtensionFieldSetsImpl.h @@ -17,7 +17,7 @@ #pragma once -#include +#include #include namespace chip { @@ -105,11 +105,11 @@ struct ExtensionFieldsSet } }; -class ExtensionFieldsSetsImpl : public ExtensionFieldsSets +class ExtensionFieldSetsImpl : public ExtensionFieldsSets { public: - ExtensionFieldsSetsImpl(); - ~ExtensionFieldsSetsImpl() override{}; + ExtensionFieldSetsImpl(); + ~ExtensionFieldSetsImpl() override{}; // overrides CHIP_ERROR Serialize(TLV::TLVWriter & writer) const override; @@ -123,7 +123,7 @@ class ExtensionFieldsSetsImpl : public ExtensionFieldsSets CHIP_ERROR GetFieldSetAtPosition(ExtensionFieldsSet & field, uint8_t position); CHIP_ERROR RemoveFieldAtPosition(uint8_t position); - bool operator==(const ExtensionFieldsSetsImpl & other) + bool operator==(const ExtensionFieldSetsImpl & other) { for (uint8_t i = 0; i < kMaxClusterPerScenes; i++) { @@ -135,7 +135,7 @@ class ExtensionFieldsSetsImpl : public ExtensionFieldsSets return true; } - ExtensionFieldsSetsImpl & operator=(const ExtensionFieldsSetsImpl & other) + ExtensionFieldSetsImpl & operator=(const ExtensionFieldSetsImpl & other) { for (uint8_t i = 0; i < kMaxClusterPerScenes; i++) { diff --git a/src/app/clusters/scenes/SceneTable.h b/src/app/clusters/scenes/SceneTable.h index cd126b9a99eb13..0b7989d9328a15 100644 --- a/src/app/clusters/scenes/SceneTable.h +++ b/src/app/clusters/scenes/SceneTable.h @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include #include #include @@ -56,10 +56,12 @@ class SceneHandler SceneHandler(){}; virtual ~SceneHandler() = default; - /// @brief Gets the list of supported clusters for an endpoint + /// @brief Copies the list of supported clusters for an endpoint in a Span and resizes the span to fit the actual number of + /// supported clusters /// @param endpoint target endpoint /// @param clusterBuffer Buffer to hold the supported cluster IDs, cannot hold more than - /// CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENES + /// CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENES, the function shall use the reduce_size() method in the event it is supporting + /// less than CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENES clusters virtual void GetSupportedClusters(EndpointId endpoint, Span & clusterBuffer) = 0; /// @brief Returns whether or not a cluster for scenes is supported on an endpoint @@ -78,8 +80,8 @@ class SceneHandler virtual CHIP_ERROR SerializeAdd(EndpointId endpoint, ClusterId & cluster, MutableByteSpan & serialisedBytes, app::Clusters::Scenes::Structs::ExtensionFieldSet::DecodableType & extensionFieldSet) = 0; - /// @brief From command StoreScene, retrieves ExtensionField from nvm, it is the functions responsability to resize the mutable - /// span if necessary, a number of byte equal to the span will be stored in memory + /// @brief From command StoreScene, retrieves ExtensionField from currently active values, it is the functions responsability to + /// resize the mutable span if necessary, a number of byte equal to the span will be stored in memory /// @param endpoint Target Endpoint /// @param cluster Target Cluster /// @param serialisedBytes Output buffer, data needs to be writen in there and size adjusted if smaller than @@ -176,7 +178,7 @@ class SceneTable char mName[kSceneNameMax] = { 0 }; size_t mNameLength = 0; SceneTransitionTime mSceneTransitionTime = 0; - ExtensionFieldsSetsImpl mExtensionFieldsSets; + ExtensionFieldSetsImpl mExtensionFieldSets; TransitionTime100ms mTransitionTime100ms = 0; CharSpan mNameSpan; @@ -185,19 +187,19 @@ class SceneTable { this->SetName(sceneName); } - SceneData(ExtensionFieldsSetsImpl fields, const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0, + SceneData(ExtensionFieldSetsImpl fields, const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0, TransitionTime100ms time100ms = 0) : mSceneTransitionTime(time), mTransitionTime100ms(time100ms) { this->SetName(sceneName); - mExtensionFieldsSets = fields; + mExtensionFieldSets = fields; } SceneData(const SceneData & other) : mSceneTransitionTime(other.mSceneTransitionTime), mTransitionTime100ms(other.mTransitionTime100ms) { this->SetName(other.mNameSpan); - mExtensionFieldsSets = other.mExtensionFieldsSets; + mExtensionFieldSets = other.mExtensionFieldSets; } ~SceneData(){}; @@ -217,7 +219,7 @@ class SceneTable writer.Put(TLV::ContextTag(kTagSceneDTransitionTime), static_cast(this->mSceneTransitionTime))); ReturnErrorOnFailure( writer.Put(TLV::ContextTag(kTagSceneDTransitionTime100), static_cast(this->mTransitionTime100ms))); - ReturnErrorOnFailure(this->mExtensionFieldsSets.Serialize(writer)); + ReturnErrorOnFailure(this->mExtensionFieldSets.Serialize(writer)); return writer.EndContainer(container); } @@ -243,7 +245,7 @@ class SceneTable ReturnErrorOnFailure(reader.Get(this->mSceneTransitionTime)); ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagSceneDTransitionTime100))); ReturnErrorOnFailure(reader.Get(this->mTransitionTime100ms)); - ReturnErrorOnFailure(this->mExtensionFieldsSets.Deserialize(reader)); + ReturnErrorOnFailure(this->mExtensionFieldSets.Deserialize(reader)); return reader.ExitContainer(container); } @@ -269,20 +271,20 @@ class SceneTable this->SetName(CharSpan()); mSceneTransitionTime = 0; mTransitionTime100ms = 0; - mExtensionFieldsSets.Clear(); + mExtensionFieldSets.Clear(); } bool operator==(const SceneData & other) { return (this->mNameSpan.data_equal(other.mNameSpan) && (this->mSceneTransitionTime == other.mSceneTransitionTime) && (this->mTransitionTime100ms == other.mTransitionTime100ms) && - (this->mExtensionFieldsSets == other.mExtensionFieldsSets)); + (this->mExtensionFieldSets == other.mExtensionFieldSets)); } void operator=(const SceneData & other) { this->SetName(other.mNameSpan); - this->mExtensionFieldsSets = other.mExtensionFieldsSets; + this->mExtensionFieldSets = other.mExtensionFieldSets; this->mSceneTransitionTime = other.mSceneTransitionTime; this->mTransitionTime100ms = other.mTransitionTime100ms; } @@ -332,8 +334,9 @@ class SceneTable virtual CHIP_ERROR RemoveSceneTableEntryAtPosition(FabricIndex fabric_index, SceneIndex scened_idx) = 0; // SceneHandlers - virtual CHIP_ERROR RegisterHandler(SceneHandler * handler) = 0; - virtual CHIP_ERROR UnregisterHandler(uint8_t position) = 0; + virtual CHIP_ERROR RegisterHandler(SceneHandler * handler) = 0; + virtual CHIP_ERROR UnregisterHandler(SceneHandler * handler) = 0; + virtual CHIP_ERROR UnregisterAllHandler() = 0; // Extension field sets operation virtual CHIP_ERROR SceneSaveEFS(SceneTableEntry & scene) = 0; @@ -348,33 +351,13 @@ class SceneTable virtual SceneEntryIterator * IterateSceneEntry(FabricIndex fabric_index) = 0; // Handlers - virtual bool HandlerListEmpty() { return (handlerNum == 0); } - virtual bool HandlerListFull() { return (handlerNum >= kMaxSceneHandlers); } - virtual uint8_t GetHandlerNum() { return this->handlerNum; } + virtual bool HandlerListEmpty() { return (mNumHandlers == 0); } + virtual bool HandlerListFull() { return (mNumHandlers >= kMaxSceneHandlers); } + virtual uint8_t GetHandlerNum() { return this->mNumHandlers; } SceneHandler * mHandlers[kMaxSceneHandlers] = { nullptr }; - uint8_t handlerNum = 0; + uint8_t mNumHandlers = 0; }; -/** - * Instance getter for the global SceneTable. - * - * Callers have to externally synchronize usage of this function. - * - * @return The global Scene Table - */ -SceneTable * GetSceneTable(); - -/** - * Instance setter for the global Scene Table. - * - * Callers have to externally synchronize usage of this function. - * - * The `provider` can be set to nullptr if the owner is done with it fully. - * - * @param[in] provider pointer to the Scene Table global instance to use - */ -void SetSceneTable(SceneTable * provider); - } // namespace scenes } // namespace chip diff --git a/src/app/clusters/scenes/SceneTableImpl.cpp b/src/app/clusters/scenes/SceneTableImpl.cpp index df68536f763265..db44b482aa27da 100644 --- a/src/app/clusters/scenes/SceneTableImpl.cpp +++ b/src/app/clusters/scenes/SceneTableImpl.cpp @@ -431,17 +431,32 @@ CHIP_ERROR DefaultSceneTableImpl::RegisterHandler(SceneHandler * handler) else if (fisrtEmptyPosition < kMaxSceneHandlers) { this->mHandlers[fisrtEmptyPosition] = handler; - this->handlerNum++; + this->mNumHandlers++; err = CHIP_NO_ERROR; } return err; } -CHIP_ERROR DefaultSceneTableImpl::UnregisterHandler(uint8_t position) +CHIP_ERROR DefaultSceneTableImpl::UnregisterHandler(SceneHandler * handler) { - VerifyOrReturnError(position < kMaxSceneHandlers, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnValue(!this->HandlerListEmpty() && !(this->mHandlers[position] == nullptr), CHIP_NO_ERROR); + uint8_t position = kInvalidPosition; + + // Verify list is populated and handler is not null + VerifyOrReturnValue(!this->HandlerListEmpty() && !(handler == nullptr), CHIP_NO_ERROR); + + // Finds the position of the Handler to unregister + for (uint8_t i = 0; i < this->mNumHandlers; i++) + { + if (this->mHandlers[i] == handler) + { + position = i; + break; + } + } + + // Verify Handler was found + VerifyOrReturnValue(position < kMaxSceneHandlers, CHIP_NO_ERROR); uint8_t nextPos = static_cast(position + 1); uint8_t moveNum = static_cast(kMaxSceneHandlers - nextPos); @@ -450,9 +465,19 @@ CHIP_ERROR DefaultSceneTableImpl::UnregisterHandler(uint8_t position) // Compress array after removal memmove(&this->mHandlers[position], &this->mHandlers[nextPos], sizeof(this->mHandlers[position]) * moveNum); - this->handlerNum--; + this->mNumHandlers--; // Clear last occupied position - this->mHandlers[handlerNum] = nullptr; + this->mHandlers[mNumHandlers] = nullptr; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DefaultSceneTableImpl::UnregisterAllHandler() +{ + for (uint8_t i = 0; i < this->mNumHandlers; i++) + { + ReturnErrorOnFailure(this->UnregisterHandler(this->mHandlers[0])); + } return CHIP_NO_ERROR; } @@ -461,7 +486,7 @@ CHIP_ERROR DefaultSceneTableImpl::SceneSaveEFS(SceneTableEntry & scene) { if (!this->HandlerListEmpty()) { - for (uint8_t i = 0; i < this->handlerNum; i++) + for (uint8_t i = 0; i < this->mNumHandlers; i++) { clusterId cArray[kMaxClusterPerScenes]; Span cSpan(cArray); @@ -476,7 +501,7 @@ CHIP_ERROR DefaultSceneTableImpl::SceneSaveEFS(SceneTableEntry & scene) EFS.mID = cArray[j]; ReturnErrorOnFailure(this->mHandlers[i]->SerializeSave(scene.mStorageId.mEndpointId, EFS.mID, EFSSpan)); EFS.mUsedBytes = (uint8_t) EFSSpan.size(); - ReturnErrorOnFailure(scene.mStorageData.mExtensionFieldsSets.InsertFieldSet(EFS)); + ReturnErrorOnFailure(scene.mStorageData.mExtensionFieldSets.InsertFieldSet(EFS)); } } } @@ -499,9 +524,9 @@ CHIP_ERROR DefaultSceneTableImpl::SceneApplyEFS(FabricIndex fabric_index, const if (!this->HandlerListEmpty()) { - for (uint8_t i = 0; i < scene.mStorageData.mExtensionFieldsSets.GetFieldNum(); i++) + for (uint8_t i = 0; i < scene.mStorageData.mExtensionFieldSets.GetFieldNum(); i++) { - scene.mStorageData.mExtensionFieldsSets.GetFieldSetAtPosition(EFS, i); + scene.mStorageData.mExtensionFieldSets.GetFieldSetAtPosition(EFS, i); cluster = EFS.mID; time = scene.mStorageData.mSceneTransitionTime * 1000 + (scene.mStorageData.mTransitionTime100ms ? scene.mStorageData.mTransitionTime100ms * 10 : 0); @@ -509,7 +534,7 @@ CHIP_ERROR DefaultSceneTableImpl::SceneApplyEFS(FabricIndex fabric_index, const if (!EFS.IsEmpty()) { - for (uint8_t j = 0; j < this->handlerNum; j++) + for (uint8_t j = 0; j < this->mNumHandlers; j++) { ReturnErrorOnFailure(this->mHandlers[j]->ApplyScene(scene.mStorageId.mEndpointId, cluster, EFSSpan, time)); } @@ -590,21 +615,5 @@ void DefaultSceneTableImpl::SceneEntryIteratorImpl::Release() mProvider.mSceneEntryIterators.ReleaseObject(this); } -namespace { - -SceneTable * gSceneTable = nullptr; - -} // namespace - -SceneTable * GetSceneTable() -{ - return gSceneTable; -} - -void SetSceneTable(SceneTable * provider) -{ - gSceneTable = provider; -} - } // namespace scenes } // namespace chip diff --git a/src/app/clusters/scenes/SceneTableImpl.h b/src/app/clusters/scenes/SceneTableImpl.h index 42576779900d29..b703c51e6547c0 100644 --- a/src/app/clusters/scenes/SceneTableImpl.h +++ b/src/app/clusters/scenes/SceneTableImpl.h @@ -184,7 +184,8 @@ class DefaultSceneTableImpl : public SceneTable // SceneHandlers CHIP_ERROR RegisterHandler(SceneHandler * handler) override; - CHIP_ERROR UnregisterHandler(uint8_t position) override; + CHIP_ERROR UnregisterHandler(SceneHandler * handler) override; + CHIP_ERROR UnregisterAllHandler() override; // Extension field sets operation CHIP_ERROR SceneSaveEFS(SceneTableEntry & scene) override; diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index d77162909ee5e6..c76b20ab650b9d 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -27,6 +27,12 @@ static_library("server") { output_name = "libCHIPAppServer" sources = [ + "../clusters/scenes/ExtensionFieldSets.h", + "../clusters/scenes/ExtensionFieldSetsImpl.cpp", + "../clusters/scenes/ExtensionFieldSetsImpl.h", + "../clusters/scenes/SceneTable.h", + "../clusters/scenes/SceneTableImpl.cpp", + "../clusters/scenes/SceneTableImpl.h", "AclStorage.cpp", "AclStorage.h", "CommissioningModeProvider.h", diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index b80c3ca8f45b11..229ec7ac963be5 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -162,6 +162,8 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) mGroupsProvider = initParams.groupDataProvider; SetGroupDataProvider(mGroupsProvider); + mSceneTable = initParams.sceneTable; + mTestEventTriggerDelegate = initParams.testEventTriggerDelegate; deviceInfoprovider = DeviceLayer::GetDeviceInfoProvider(); @@ -535,6 +537,8 @@ KvsPersistentStorageDelegate CommonCaseDeviceServerInitParams::sKvsPersistenStor PersistentStorageOperationalKeystore CommonCaseDeviceServerInitParams::sPersistentStorageOperationalKeystore; Credentials::PersistentStorageOpCertStore CommonCaseDeviceServerInitParams::sPersistentStorageOpCertStore; Credentials::GroupDataProviderImpl CommonCaseDeviceServerInitParams::sGroupDataProvider; +// TODO: complete scene cluster implementation before uncommenting +// scenes::DefaultSceneTableImpl CommonCaseDeviceServerInitParams::sSceneTable; IgnoreCertificateValidityPolicy CommonCaseDeviceServerInitParams::sDefaultCertValidityPolicy; #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION SimpleSessionResumptionStorage CommonCaseDeviceServerInitParams::sSessionResumptionStorage; diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 45bcf0a7290515..3b28d216874262 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -89,7 +91,7 @@ struct ServerInitParams ServerInitParams() = default; // Not copyable - ServerInitParams(const ServerInitParams &) = delete; + ServerInitParams(const ServerInitParams &) = delete; ServerInitParams & operator=(const ServerInitParams &) = delete; // Application delegate to handle some commissioning lifecycle events @@ -116,6 +118,8 @@ struct ServerInitParams // Group data provider: MUST be injected. Used to maintain critical keys such as the Identity // Protection Key (IPK) for CASE. Must be initialized before being provided. Credentials::GroupDataProvider * groupDataProvider = nullptr; + // Scene Table: optionnal, required if Scene Cluster implemented + scenes::SceneTable * sceneTable = nullptr; // Session keystore: MUST be injected. Used to derive and manage lifecycle of symmetric keys. Crypto::SessionKeystore * sessionKeystore = nullptr; // Access control delegate: MUST be injected. Used to look up access control rules. Must be @@ -205,7 +209,7 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams CommonCaseDeviceServerInitParams() = default; // Not copyable - CommonCaseDeviceServerInitParams(const CommonCaseDeviceServerInitParams &) = delete; + CommonCaseDeviceServerInitParams(const CommonCaseDeviceServerInitParams &) = delete; CommonCaseDeviceServerInitParams & operator=(const CommonCaseDeviceServerInitParams &) = delete; /** @@ -256,6 +260,11 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams ReturnErrorOnFailure(sGroupDataProvider.Init()); this->groupDataProvider = &sGroupDataProvider; + // TODO: complete scene cluster implementation before uncommenting + // Scene Table + // this->sceneTable = &sSceneTable; + // this->sceneTable->Init(this->persistentStorageDelegate); + #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION ReturnErrorOnFailure(sSessionResumptionStorage.Init(this->persistentStorageDelegate)); this->sessionResumptionStorage = &sSessionResumptionStorage; @@ -289,6 +298,8 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams static PersistentStorageOperationalKeystore sPersistentStorageOperationalKeystore; static Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore; static Credentials::GroupDataProviderImpl sGroupDataProvider; + // TODO: complete scene cluster implementation before uncommenting + // static scenes::DefaultSceneTableImpl sSceneTable; static IgnoreCertificateValidityPolicy sDefaultCertValidityPolicy; #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION static SimpleSessionResumptionStorage sSessionResumptionStorage; @@ -333,41 +344,97 @@ class Server */ void RejoinExistingMulticastGroups(); - FabricTable & GetFabricTable() { return mFabrics; } + FabricTable & GetFabricTable() + { + return mFabrics; + } + + CASESessionManager * GetCASESessionManager() + { + return &mCASESessionManager; + } - CASESessionManager * GetCASESessionManager() { return &mCASESessionManager; } + Messaging::ExchangeManager & GetExchangeManager() + { + return mExchangeMgr; + } - Messaging::ExchangeManager & GetExchangeManager() { return mExchangeMgr; } + SessionManager & GetSecureSessionManager() + { + return mSessions; + } - SessionManager & GetSecureSessionManager() { return mSessions; } + SessionResumptionStorage * GetSessionResumptionStorage() + { + return mSessionResumptionStorage; + } - SessionResumptionStorage * GetSessionResumptionStorage() { return mSessionResumptionStorage; } + app::SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() + { + return mSubscriptionResumptionStorage; + } - app::SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() { return mSubscriptionResumptionStorage; } + TransportMgrBase & GetTransportManager() + { + return mTransports; + } - TransportMgrBase & GetTransportManager() { return mTransports; } + Credentials::GroupDataProvider * GetGroupDataProvider() + { + return mGroupsProvider; + } - Credentials::GroupDataProvider * GetGroupDataProvider() { return mGroupsProvider; } + scenes::SceneTable * GetSceneTable() + { + return mSceneTable; + } - Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; } + Crypto::SessionKeystore * GetSessionKeystore() const + { + return mSessionKeystore; + } #if CONFIG_NETWORK_LAYER_BLE - Ble::BleLayer * GetBleLayerObject() { return mBleLayer; } + Ble::BleLayer * GetBleLayerObject() + { + return mBleLayer; + } #endif - CommissioningWindowManager & GetCommissioningWindowManager() { return mCommissioningWindowManager; } + CommissioningWindowManager & GetCommissioningWindowManager() + { + return mCommissioningWindowManager; + } - PersistentStorageDelegate & GetPersistentStorage() { return *mDeviceStorage; } + PersistentStorageDelegate & GetPersistentStorage() + { + return *mDeviceStorage; + } - app::FailSafeContext & GetFailSafeContext() { return mFailSafeContext; } + app::FailSafeContext & GetFailSafeContext() + { + return mFailSafeContext; + } - TestEventTriggerDelegate * GetTestEventTriggerDelegate() { return mTestEventTriggerDelegate; } + TestEventTriggerDelegate * GetTestEventTriggerDelegate() + { + return mTestEventTriggerDelegate; + } - Crypto::OperationalKeystore * GetOperationalKeystore() { return mOperationalKeystore; } + Crypto::OperationalKeystore * GetOperationalKeystore() + { + return mOperationalKeystore; + } - Credentials::OperationalCertificateStore * GetOpCertStore() { return mOpCertStore; } + Credentials::OperationalCertificateStore * GetOpCertStore() + { + return mOpCertStore; + } - app::DefaultAttributePersistenceProvider & GetDefaultAttributePersister() { return mAttributePersister; } + app::DefaultAttributePersistenceProvider & GetDefaultAttributePersister() + { + return mAttributePersister; + } /** * This function causes the ShutDown event to be generated async on the @@ -384,7 +451,10 @@ class Server return System::SystemClock().GetMonotonicMicroseconds64() - mInitTimestamp; } - static Server & GetInstance() { return sServer; } + static Server & GetInstance() + { + return sServer; + } private: Server() = default; @@ -565,6 +635,7 @@ class Server app::SubscriptionResumptionStorage * mSubscriptionResumptionStorage; Credentials::CertificateValidityPolicy * mCertificateValidityPolicy; Credentials::GroupDataProvider * mGroupsProvider; + scenes::SceneTable * mSceneTable; Crypto::SessionKeystore * mSessionKeystore; app::DefaultAttributePersistenceProvider mAttributePersister; GroupDataProviderListener mListener; diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 606b6d74937d54..a0b580bc93c65c 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -81,9 +81,9 @@ source_set("ota-requestor-test-srcs") { source_set("scenes-table-test-srcs") { sources = [ - "${chip_root}/src/app/clusters/scenes/ExtensionFieldsSets.h", - "${chip_root}/src/app/clusters/scenes/ExtensionFieldsSetsImpl.cpp", - "${chip_root}/src/app/clusters/scenes/ExtensionFieldsSetsImpl.h", + "${chip_root}/src/app/clusters/scenes/ExtensionFieldSets.h", + "${chip_root}/src/app/clusters/scenes/ExtensionFieldSetsImpl.cpp", + "${chip_root}/src/app/clusters/scenes/ExtensionFieldSetsImpl.h", "${chip_root}/src/app/clusters/scenes/SceneTable.h", "${chip_root}/src/app/clusters/scenes/SceneTableImpl.cpp", "${chip_root}/src/app/clusters/scenes/SceneTableImpl.h", diff --git a/src/app/tests/TestSceneTable.cpp b/src/app/tests/TestSceneTable.cpp index 4f0813f9d9cb82..248d2e9c7772c6 100644 --- a/src/app/tests/TestSceneTable.cpp +++ b/src/app/tests/TestSceneTable.cpp @@ -127,15 +127,21 @@ class TestSceneHandler : public scenes::DefaultSceneHandlerImpl ClusterId * buffer = clusterBuffer.data(); if (endpoint == TEST_ENDPOINT1) { - buffer[0] = ON_OFF_CID; - buffer[1] = LV_CTR_CID; - clusterBuffer.reduce_size(2); + if (clusterBuffer.size() >= 2) + { + buffer[0] = ON_OFF_CID; + buffer[1] = LV_CTR_CID; + clusterBuffer.reduce_size(2); + } } else if (endpoint == TEST_ENDPOINT2) { - buffer[0] = ON_OFF_CID; - buffer[1] = CC_CTR_CID; - clusterBuffer.reduce_size(2); + if (clusterBuffer.size() >= 2) + { + buffer[0] = ON_OFF_CID; + buffer[1] = CC_CTR_CID; + clusterBuffer.reduce_size(2); + } } } @@ -282,52 +288,55 @@ void ResetSceneTable(SceneTable * sceneTable) void TestHandlerRegistration(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; TestSceneHandler tmpHandler[scenes::kMaxSceneHandlers]; for (uint8_t i = 0; i < scenes::kMaxSceneHandlers; i++) { - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == i); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == i); NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->RegisterHandler(&tmpHandler[i])); + printf("Handler : %d | Address : %p \n", i, &tmpHandler[i]); } - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == scenes::kMaxSceneHandlers); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == scenes::kMaxSceneHandlers); // Removal at begining - NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(0)); - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == static_cast(scenes::kMaxSceneHandlers - 1)); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(&tmpHandler[0])); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == static_cast(scenes::kMaxSceneHandlers - 1)); // Confirm array was compressed and last position is now null NL_TEST_ASSERT(aSuite, nullptr == sceneTable->mHandlers[scenes::kMaxSceneHandlers - 1]); // Removal at the middle - NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(3)); - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == static_cast(scenes::kMaxSceneHandlers - 2)); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(&tmpHandler[3])); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == static_cast(scenes::kMaxSceneHandlers - 2)); // Confirm array was compressed and last position is now null NL_TEST_ASSERT(aSuite, nullptr == sceneTable->mHandlers[scenes::kMaxSceneHandlers - 2]); - // Removal at the middle - NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(scenes::kMaxSceneHandlers - 3)); - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == static_cast(scenes::kMaxSceneHandlers - 3)); + // Removal at the end + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(&tmpHandler[scenes::kMaxSceneHandlers - 1])); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == static_cast(scenes::kMaxSceneHandlers - 3)); NL_TEST_ASSERT(aSuite, nullptr == sceneTable->mHandlers[scenes::kMaxSceneHandlers - 3]); // Emptying Handler array + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterAllHandler()); for (uint8_t i = 0; i < scenes::kMaxSceneHandlers; i++) { - NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(0)); + NL_TEST_ASSERT(aSuite, CHIP_NO_ERROR == sceneTable->UnregisterHandler(&tmpHandler[i])); } // Verify the handler num has been updated properly - NL_TEST_ASSERT(aSuite, sceneTable->handlerNum == 0); + NL_TEST_ASSERT(aSuite, sceneTable->mNumHandlers == 0); // Verify all array is empty for (uint8_t i = 0; i < scenes::kMaxSceneHandlers; i++) { + printf("Handler : %d | Address : %p \n", i, sceneTable->mHandlers[i]); NL_TEST_ASSERT(aSuite, nullptr == sceneTable->mHandlers[i]); } } void TestHandlerFunctions(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; ClusterId tempCluster = 0; app::Clusters::Scenes::Structs::ExtensionFieldSet::Type extensionFieldSetOut; @@ -522,7 +531,7 @@ void TestHandlerFunctions(nlTestSuite * aSuite, void * aContext) void TestStoreScenes(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; NL_TEST_ASSERT(aSuite, sceneTable); // Reset test @@ -587,7 +596,7 @@ void TestStoreScenes(nlTestSuite * aSuite, void * aContext) void TestOverwriteScenes(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; NL_TEST_ASSERT(aSuite, sceneTable); SceneTableEntry scene; @@ -611,7 +620,7 @@ void TestOverwriteScenes(nlTestSuite * aSuite, void * aContext) void TestIterateScenes(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; NL_TEST_ASSERT(aSuite, sceneTable); SceneTableEntry scene; @@ -647,7 +656,7 @@ void TestIterateScenes(nlTestSuite * aSuite, void * aContext) void TestRemoveScenes(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; NL_TEST_ASSERT(aSuite, sceneTable); SceneTableEntry scene; @@ -738,7 +747,7 @@ void TestRemoveScenes(nlTestSuite * aSuite, void * aContext) void TestFabricScenes(nlTestSuite * aSuite, void * aContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); + SceneTable * sceneTable = &sSceneTable; NL_TEST_ASSERT(aSuite, sceneTable); // Reset test @@ -804,8 +813,6 @@ int TestSetup(void * inContext) VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE); VerifyOrReturnError(CHIP_NO_ERROR == sSceneTable.Init(&testStorage), FAILURE); - SetSceneTable(&sSceneTable); - return SUCCESS; } @@ -814,12 +821,9 @@ int TestSetup(void * inContext) */ int TestTeardown(void * inContext) { - SceneTable * sceneTable = chip::scenes::GetSceneTable(); - if (nullptr != sceneTable) - { - sceneTable->Finish(); - } + sSceneTable.Finish(); chip::Platform::MemoryShutdown(); + return SUCCESS; } int TestSceneTable() diff --git a/src/lib/support/TestSceneTable.h b/src/lib/support/TestSceneTable.h index 26bfb84bd55e62..5a8446351334bf 100644 --- a/src/lib/support/TestSceneTable.h +++ b/src/lib/support/TestSceneTable.h @@ -82,15 +82,21 @@ class TestSceneHandler : public scenes::DefaultSceneHandlerImpl ClusterId * buffer = clusterBuffer.data(); if (endpoint == TEST_ENDPOINT1) { - buffer[0] = ON_OFF_CID; - buffer[1] = LV_CTR_CID; - clusterBuffer.reduce_size(2); + if (clusterBuffer.size() >= 2) + { + buffer[0] = ON_OFF_CID; + buffer[1] = LV_CTR_CID; + clusterBuffer.reduce_size(2); + } } else if (endpoint == TEST_ENDPOINT2) { - buffer[0] = ON_OFF_CID; - buffer[1] = CC_CTR_CID; - clusterBuffer.reduce_size(2); + if (clusterBuffer.size() >= 2) + { + buffer[0] = ON_OFF_CID; + buffer[1] = CC_CTR_CID; + clusterBuffer.reduce_size(2); + } } }