diff --git a/examples/tv-casting-app/tv-casting-common/clusters/ClusterTemplates.h b/examples/tv-casting-app/tv-casting-common/clusters/ClusterTemplates.h index 806e454b8163b6..19a49f991e31f7 100644 --- a/examples/tv-casting-app/tv-casting-common/clusters/ClusterTemplates.h +++ b/examples/tv-casting-app/tv-casting-common/clusters/ClusterTemplates.h @@ -22,6 +22,7 @@ #include "core/Types.h" #include "lib/support/logging/CHIPLogging.h" +#include namespace matter { namespace casting { @@ -80,6 +81,7 @@ class Command CHIP_ERROR err = cluster.template InvokeCommand( _commandContext->mRequest, _commandContext, // Command success handler + // using ResponseType = Clusters::ContentLauncher::Commands::LauncherResponse::DecodableType; [](void * context, const chip::app::Clusters::ContentLauncher::Commands::LauncherResponse::DecodableType & response) { C * _commandContext = static_cast(context); diff --git a/examples/tv-casting-app/tv-casting-common/clusters/MediaPlaybackCluster.h b/examples/tv-casting-app/tv-casting-common/clusters/MediaPlaybackCluster.h index 8fe196597f001e..772ba956ce4657 100644 --- a/examples/tv-casting-app/tv-casting-common/clusters/MediaPlaybackCluster.h +++ b/examples/tv-casting-app/tv-casting-common/clusters/MediaPlaybackCluster.h @@ -18,25 +18,37 @@ #pragma once +#include "core/Attribute.h" +#include "core/Cluster.h" #include "core/Endpoint.h" #include "core/Types.h" #include "lib/support/logging/CHIPLogging.h" +#include namespace matter { namespace casting { namespace clusters { +namespace media_playback { + +class CurrentState + : public core::Attribute +{ +public: + CurrentState(memory::Weak cluster) : + core::Attribute(cluster) + {} +}; class MediaPlaybackCluster : public core::BaseCluster { -private: -protected: public: MediaPlaybackCluster(memory::Weak endpoint) : core::BaseCluster(endpoint) {} // TODO: add commands }; +}; // namespace media_playback }; // namespace clusters }; // namespace casting }; // namespace matter diff --git a/examples/tv-casting-app/tv-casting-common/core/Attribute.h b/examples/tv-casting-app/tv-casting-common/core/Attribute.h index 5c8716967bab86..a3fa4c47c17640 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Attribute.h +++ b/examples/tv-casting-app/tv-casting-common/core/Attribute.h @@ -21,38 +21,64 @@ #include "Cluster.h" #include "Types.h" -#include "lib/support/logging/CHIPLogging.h" +#include "clusters/ClusterTemplates.h" +#include "lib/support/logging/CHIPLogging.h" namespace matter { namespace casting { namespace core { -enum ReadAttributeError +using WriteAttributeCallback = std::function; + +template +using ReadResponseSuccessCallbackFn = std::function before, T after)>; +using ReadResponseFailureCallbackFn = std::function; + +template +struct ReadAttributeContext { - READ_ATTRIBUTE_NO_ERROR + ReadAttributeContext(void * attribute, memory::Strong endpoint, void * clientContext, + ReadResponseSuccessCallbackFn successCb, ReadResponseFailureCallbackFn failureCb, + bool aIsFabricFiltered) : + mEndpoint(endpoint), + mClientContext(clientContext), mSuccessCb(successCb), mFailureCb(failureCb), mAIsFabricFiltered(aIsFabricFiltered) + { + mAttribute = attribute; + } + + void * mAttribute; + memory::Strong mEndpoint; + void * mClientContext; + ReadResponseSuccessCallbackFn mSuccessCb; + ReadResponseFailureCallbackFn mFailureCb; + bool mAIsFabricFiltered = true; }; -enum WriteAttributeError +struct CurrentStateContext : public ReadAttributeContext { - WRITE_ATTRIBUTE_NO_ERROR + CurrentStateContext( + void * attribute, memory::Strong endpoint, void * context, + ReadResponseSuccessCallbackFn successCb, + ReadResponseFailureCallbackFn failureCb, bool aIsFabricFiltered) : + ReadAttributeContext(attribute, endpoint, context, successCb, failureCb, aIsFabricFiltered) + {} }; -template -using ReadAttributeCallback = std::function before, ValueType after, ReadAttributeError)>; - -using WriteAttributeCallback = std::function; - class BaseCluster; -template +template class Attribute { private: - memory::Weak cluster; - ValueType value; + memory::Weak mCluster; + bool hasValue = false; + T value; + +protected: + memory::Strong GetCluster() const { return mCluster.lock(); } public: - Attribute(memory::Weak cluster) { this->cluster = cluster; } + Attribute(memory::Weak cluster) { this->mCluster = cluster; } ~Attribute() {} @@ -60,15 +86,90 @@ class Attribute Attribute(Attribute & other) = delete; void operator=(const Attribute &) = delete; -protected: - memory::Strong GetCluster() const { return cluster.lock(); } - -public: - ValueType GetValue(); - void Read(ReadAttributeCallback onRead); - void Write(ValueType value, WriteAttributeCallback onWrite); - bool SubscribeAttribute(AttributeId attributeId, ReadAttributeCallback callback); - bool UnsubscribeAttribute(AttributeId attributeId, ReadAttributeCallback callback); + T GetValue() { return value; } + void Read(void * context, ReadResponseSuccessCallbackFn successCb, ReadResponseFailureCallbackFn failureCb, + bool aIsFabricFiltered = true) + { + memory::Strong endpoint = GetCluster()->GetEndpoint().lock(); + if (endpoint) + { + C * readAttributeContext = new C(this, endpoint, context, successCb, failureCb, aIsFabricFiltered); + + endpoint->GetCastingPlayer()->FindOrEstablishSession( + readAttributeContext, + // FindOrEstablishSession success handler + [](void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) { + C * _readAttributeContext = static_cast(context); + ChipLogProgress(AppServer, "::Read() Found or established session"); + + // Read attribute + support::MediaClusterBase mediaClusterBase(exchangeMgr, sessionHandle, + _readAttributeContext->mEndpoint->GetId()); + CHIP_ERROR err = mediaClusterBase.template ReadAttribute( + _readAttributeContext, + // Read success handler + [](void * context, const T & response) { + C * _readAttributeContext = static_cast(context); + ChipLogProgress(AppServer, "::Read() success"); + Attribute * _attribute = static_cast *>(_readAttributeContext->mAttribute); + _attribute->Value = response; + if (_attribute->hasValue) + { + _readAttributeContext->mSuccessCb(_readAttributeContext->mClientContext, + chip::MakeOptional(_attribute->Value), response); + } + else + { + _attribute->hasValue = true; + _readAttributeContext->mSuccessCb(_readAttributeContext->mClientContext, chip::NullOptional, + response); + } + delete _readAttributeContext; + }, + // Read failure handler + [](void * context, CHIP_ERROR error) { + C * _readAttributeContext = static_cast(context); + ChipLogError(AppServer, + "::Read() failure response on EndpointId: %d with error: " + "%" CHIP_ERROR_FORMAT, + _readAttributeContext->mEndpoint->GetId(), error.Format()); + _readAttributeContext->mFailureCb(_readAttributeContext->mClientContext, error); + delete _readAttributeContext; + }, + _readAttributeContext->mAIsFabricFiltered); + + // error in reading the attribute + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, + "::Read() failure in reading attribute on EndpointId: %d with error: " + "%" CHIP_ERROR_FORMAT, + _readAttributeContext->mEndpoint->GetId(), err.Format()); + _readAttributeContext->mFailureCb(_readAttributeContext->mClientContext, err); + delete _readAttributeContext; + } + }, + // FindOrEstablishSession failure handler + [](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) { + C * _readAttributeContext = static_cast(context); + ChipLogError(AppServer, + "::Read() failure in retrieving session info for peerId.nodeId: " + "0x" ChipLogFormatX64 ", peer.fabricIndex: %d with error: %" CHIP_ERROR_FORMAT, + ChipLogValueX64(peerId.GetNodeId()), peerId.GetFabricIndex(), error.Format()); + _readAttributeContext->mFailureCb(_readAttributeContext->mClientContext, error); + delete _readAttributeContext; + }); + } + else + { + ChipLogError(AppServer, "::Read() failure in retrieving Endpoint"); + failureCb(context, CHIP_ERROR_INCORRECT_STATE); + } + } + + /*void Write(T value, WriteAttributeCallback onWrite); + bool SubscribeAttribute(ReadAttributeCallback callback); + bool UnsubscribeAttribute(ReadAttributeCallback callback);*/ }; }; // namespace core diff --git a/examples/tv-casting-app/tv-casting-common/core/Cluster.h b/examples/tv-casting-app/tv-casting-common/core/Cluster.h index 2f317cff2103a3..871a2b1cc08f01 100644 --- a/examples/tv-casting-app/tv-casting-common/core/Cluster.h +++ b/examples/tv-casting-app/tv-casting-common/core/Cluster.h @@ -41,6 +41,9 @@ class BaseCluster BaseCluster(BaseCluster & other) = delete; void operator=(const BaseCluster &) = delete; + //template + //void RegisterAttribute(const memory::Strong> endpoint); + protected: memory::Weak GetEndpoint() const { return mEndpoint.lock(); } memory::Weak mEndpoint; diff --git a/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp b/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp index 040a27fc50150a..cab16586e3db88 100644 --- a/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp +++ b/examples/tv-casting-app/tv-casting-common/support/EndpointListLoader.cpp @@ -130,7 +130,7 @@ void EndpointListLoader::Complete() break; case chip::app::Clusters::MediaPlayback::Id: - endpoint->RegisterCluster(clusterId); + endpoint->RegisterCluster(clusterId); break; case chip::app::Clusters::TargetNavigator::Id: