Skip to content

Commit

Permalink
Partial Attribute read impl
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadb-amazon committed Dec 19, 2023
1 parent cb3cbb5 commit e60b0f8
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "core/Types.h"

#include "lib/support/logging/CHIPLogging.h"
#include <app-common/zap-generated/cluster-objects.h>

namespace matter {
namespace casting {
Expand Down Expand Up @@ -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<C *>(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <app-common/zap-generated/cluster-objects.h>

namespace matter {
namespace casting {
namespace clusters {
namespace media_playback {

class CurrentState
: public core::Attribute<chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo, core::CurrentStateContext>
{
public:
CurrentState(memory::Weak<core::BaseCluster> cluster) :
core::Attribute<chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo, core::CurrentStateContext>(cluster)
{}
};

class MediaPlaybackCluster : public core::BaseCluster
{
private:
protected:
public:
MediaPlaybackCluster(memory::Weak<core::Endpoint> endpoint) : core::BaseCluster(endpoint) {}

// TODO: add commands
};

}; // namespace media_playback
}; // namespace clusters
}; // namespace casting
}; // namespace matter
147 changes: 124 additions & 23 deletions examples/tv-casting-app/tv-casting-common/core/Attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,155 @@
#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<void(void * context, CHIP_ERROR)>;

template <typename T>
using ReadResponseSuccessCallbackFn = std::function<void(void * context, chip::Optional<T> before, T after)>;
using ReadResponseFailureCallbackFn = std::function<void(void * context, CHIP_ERROR err)>;

template <typename T>
struct ReadAttributeContext
{
READ_ATTRIBUTE_NO_ERROR
ReadAttributeContext(void * attribute, memory::Strong<core::Endpoint> endpoint, void * clientContext,
ReadResponseSuccessCallbackFn<T> successCb, ReadResponseFailureCallbackFn failureCb,
bool aIsFabricFiltered) :
mEndpoint(endpoint),
mClientContext(clientContext), mSuccessCb(successCb), mFailureCb(failureCb), mAIsFabricFiltered(aIsFabricFiltered)
{
mAttribute = attribute;
}

void * mAttribute;
memory::Strong<core::Endpoint> mEndpoint;
void * mClientContext;
ReadResponseSuccessCallbackFn<T> mSuccessCb;
ReadResponseFailureCallbackFn mFailureCb;
bool mAIsFabricFiltered = true;
};

enum WriteAttributeError
struct CurrentStateContext : public ReadAttributeContext<chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo>
{
WRITE_ATTRIBUTE_NO_ERROR
CurrentStateContext(
void * attribute, memory::Strong<core::Endpoint> endpoint, void * context,
ReadResponseSuccessCallbackFn<chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo> successCb,
ReadResponseFailureCallbackFn failureCb, bool aIsFabricFiltered) :
ReadAttributeContext(attribute, endpoint, context, successCb, failureCb, aIsFabricFiltered)
{}
};

template <typename ValueType>
using ReadAttributeCallback = std::function<void(Optional<ValueType> before, ValueType after, ReadAttributeError)>;

using WriteAttributeCallback = std::function<void(WriteAttributeError)>;

class BaseCluster;

template <typename ValueType>
template <typename T, typename C>
class Attribute
{
private:
memory::Weak<BaseCluster> cluster;
ValueType value;
memory::Weak<BaseCluster> mCluster;
bool hasValue = false;
T value;

protected:
memory::Strong<BaseCluster> GetCluster() const { return mCluster.lock(); }

public:
Attribute(memory::Weak<BaseCluster> cluster) { this->cluster = cluster; }
Attribute(memory::Weak<BaseCluster> cluster) { this->mCluster = cluster; }

~Attribute() {}

Attribute() = delete;
Attribute(Attribute & other) = delete;
void operator=(const Attribute &) = delete;

protected:
memory::Strong<BaseCluster> GetCluster() const { return cluster.lock(); }

public:
ValueType GetValue();
void Read(ReadAttributeCallback<ValueType> onRead);
void Write(ValueType value, WriteAttributeCallback onWrite);
bool SubscribeAttribute(AttributeId attributeId, ReadAttributeCallback<ValueType> callback);
bool UnsubscribeAttribute(AttributeId attributeId, ReadAttributeCallback<ValueType> callback);
T GetValue() { return value; }
void Read(void * context, ReadResponseSuccessCallbackFn<T> successCb, ReadResponseFailureCallbackFn failureCb,
bool aIsFabricFiltered = true)
{
memory::Strong<core::Endpoint> 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<C *>(context);
ChipLogProgress(AppServer, "<Attribute>::Read() Found or established session");

// Read attribute
support::MediaClusterBase mediaClusterBase(exchangeMgr, sessionHandle,
_readAttributeContext->mEndpoint->GetId());
CHIP_ERROR err = mediaClusterBase.template ReadAttribute<T>(
_readAttributeContext,
// Read success handler
[](void * context, const T & response) {
C * _readAttributeContext = static_cast<C *>(context);
ChipLogProgress(AppServer, "<Attribute>::Read() success");
Attribute<T, C> * _attribute = static_cast<Attribute<T, C> *>(_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<C *>(context);
ChipLogError(AppServer,
"<Attribute>::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,
"<Attribute>::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<C *>(context);
ChipLogError(AppServer,
"<Attribute>::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, "<Attribute>::Read() failure in retrieving Endpoint");
failureCb(context, CHIP_ERROR_INCORRECT_STATE);
}
}

/*void Write(T value, WriteAttributeCallback onWrite);
bool SubscribeAttribute(ReadAttributeCallback<T> callback);
bool UnsubscribeAttribute(ReadAttributeCallback<T> callback);*/
};

}; // namespace core
Expand Down
3 changes: 3 additions & 0 deletions examples/tv-casting-app/tv-casting-common/core/Cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class BaseCluster
BaseCluster(BaseCluster & other) = delete;
void operator=(const BaseCluster &) = delete;

//template <typename T, typename C>
//void RegisterAttribute(const memory::Strong<Attribute<T, C>> endpoint);

protected:
memory::Weak<Endpoint> GetEndpoint() const { return mEndpoint.lock(); }
memory::Weak<Endpoint> mEndpoint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void EndpointListLoader::Complete()
break;

case chip::app::Clusters::MediaPlayback::Id:
endpoint->RegisterCluster<clusters::MediaPlaybackCluster>(clusterId);
endpoint->RegisterCluster<clusters::media_playback::MediaPlaybackCluster>(clusterId);
break;

case chip::app::Clusters::TargetNavigator::Id:
Expand Down

0 comments on commit e60b0f8

Please sign in to comment.