Skip to content

Commit

Permalink
Fix media-input accessinterface
Browse files Browse the repository at this point in the history
1. SelectInput command won't call reportData since
   MatterReportingAttributeChangeCallback isn't called

2. PW RPC Writing CurrentInput attribute of MediaInput cluster through won't reportData. The
   value is also mismatch with PW RPC Read. (But this is still under WIP
and not working)
  • Loading branch information
erwinpan1 committed Aug 19, 2024
1 parent 3bc5667 commit c561334
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 14 deletions.
12 changes: 12 additions & 0 deletions examples/chef/common/clusters/media-input/MediaInputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ uint8_t MediaInputManager::HandleGetCurrentInput()
return mCurrentInput;
}

bool MediaInputManager::HandleSetCurrentInput(const uint8_t index)
{
return HandleSelectInput(index);
}

bool MediaInputManager::HandleSelectInput(const uint8_t index)
{
for (auto const & inputData : mInputs)
Expand Down Expand Up @@ -99,4 +104,11 @@ bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharS

return false;
}

static MediaInputManager mediaInputManager;
void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
{
ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate");
chip::app::Clusters::MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager);
}
#endif // MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MediaInputManager : public chip::app::Clusters::MediaInput::Delegate

CHIP_ERROR HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) override;
uint8_t HandleGetCurrentInput() override;
bool HandleSetCurrentInput(const uint8_t index) override;
bool HandleSelectInput(const uint8_t index) override;
bool HandleShowInputStatus() override;
bool HandleHideInputStatus() override;
Expand Down
10 changes: 0 additions & 10 deletions examples/chef/common/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,6 @@ void emberAfLowPowerClusterInitCallback(EndpointId endpoint)
}
#endif

#ifdef MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER
#include "media-input/MediaInputManager.h"
static MediaInputManager mediaInputManager;
void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
{
ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate");
MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager);
}
#endif

#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER
#include "media-playback/MediaPlaybackManager.h"
static MediaPlaybackManager mediaPlaybackManager;
Expand Down
64 changes: 64 additions & 0 deletions examples/common/pigweed/rpc_services/Attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
#include "pigweed/rpc_services/internal/StatusUtils.h"

#include <app-common/zap-generated/attribute-type.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/InteractionModelEngine.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/reporting/reporting.h>
#include <app/util/attribute-storage.h>
#include <app/util/attribute-table.h>
#include <app/util/ember-compatibility-functions.h>
Expand All @@ -42,37 +44,99 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
::pw::Status Write(const chip_rpc_AttributeWrite & request, pw_protobuf_Empty & response)
{
const void * data;
size_t data_len = 0;
DeviceLayer::StackLock lock;

switch (request.data.which_data)
{
case chip_rpc_AttributeData_data_bool_tag:
data = &request.data.data.data_bool;
data_len = sizeof(request.data.data.data_bool);
break;
case chip_rpc_AttributeData_data_uint8_tag:
data = &request.data.data.data_uint8;
data_len = sizeof(request.data.data.data_uint8);
break;
case chip_rpc_AttributeData_data_uint16_tag:
data = &request.data.data.data_uint16;
data_len = sizeof(request.data.data.data_uint16);
break;
case chip_rpc_AttributeData_data_uint32_tag:
data = &request.data.data.data_uint32;
data_len = sizeof(request.data.data.data_uint32);
break;
case chip_rpc_AttributeData_data_int8_tag:
data = &request.data.data.data_int8;
data_len = sizeof(request.data.data.data_int8);
break;
case chip_rpc_AttributeData_data_int16_tag:
data = &request.data.data.data_int16;
data_len = sizeof(request.data.data.data_int16);
break;
case chip_rpc_AttributeData_data_int32_tag:
data = &request.data.data.data_int32;
data_len = sizeof(request.data.data.data_int32);
break;
case chip_rpc_AttributeData_data_bytes_tag:
data = &request.data.data.data_bytes;
data_len = sizeof(request.data.data.data_bytes);
break;
default:
return pw::Status::InvalidArgument();
}

#if 1 // Refering Duplicate WriteSingleClusterData to calling AttributeInterface when available
if (data_len == 0) {
ChipLogError(Zcl, "Invalid writing to PW RPC with data length: 0");
return pw::Status::InvalidArgument();
}
if (auto * attrOverride = chip::app::GetAttributeAccessOverride(request.metadata.endpoint, request.metadata.cluster))
{
Access::SubjectDescriptor aSubjectDescriptor{ .authMode = chip::Access::AuthMode::kPase };
app::ConcreteDataAttributePath aPath(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id);

uint8_t tlvBuffer[128] = { 0 };
uint8_t value = *(static_cast<const uint8_t *>(data));

TLV::TLVReader aReader;

TLV::TLVType outerContainerType;
TLV::TLVWriter writer;
writer.Init(tlvBuffer);
writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType);
writer.Put(TLV::AnonymousTag(), value);
writer.EndContainer(outerContainerType);
writer.Finalize();

aReader.Init(tlvBuffer);
app::AttributeValueDecoder valueDecoder(aReader, aSubjectDescriptor);

#if 1 // Test Decode
app::DataModel::Nullable<uint8_t> nullableValue;

CHIP_ERROR err = valueDecoder.Decode(nullableValue);
if (CHIP_NO_ERROR != err) {
ChipLogError(Zcl, "Invalid writing to PW RPC due to data decoding failed");
return pw::Status::InvalidArgument();
}

if (nullableValue.IsNull()) {
ChipLogError(Zcl, "Invalid writing to PW RPC with null data");
return pw::Status::InvalidArgument();
}

ChipLogError(Zcl, "Writing to PW RPC with data: %u", nullableValue.Value());
#endif

PW_TRY(ChipErrorToPwStatus(attrOverride->Write(aPath, valueDecoder)));

if (valueDecoder.TriedDecode()) // TBD
{
MatterReportingAttributeChangeCallback(aPath);
return pw::OkStatus();
}
}
#endif
RETURN_STATUS_IF_NOT_OK(
emberAfWriteAttribute(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id,
const_cast<uint8_t *>(static_cast<const uint8_t *>(data)), request.metadata.type));
Expand Down
1 change: 1 addition & 0 deletions src/app/clusters/media-input-server/media-input-delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Delegate
// no easy way to handle the return memory of app::Clusters::MediaInput::Structs::InputInfoStruct::Type list, so encoder is used
virtual CHIP_ERROR HandleGetInputList(app::AttributeValueEncoder & aEncoder) = 0;
virtual uint8_t HandleGetCurrentInput() = 0;
virtual bool HandleSetCurrentInput(const uint8_t index) = 0;
virtual bool HandleSelectInput(const uint8_t index) = 0;
virtual bool HandleShowInputStatus() = 0;
virtual bool HandleHideInputStatus() = 0;
Expand Down
50 changes: 46 additions & 4 deletions src/app/clusters/media-input-server/media-input-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/data-model/Encode.h>
#include <app/data-model/Decode.h>
#include <app/data-model/Nullable.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <platform/CHIPDeviceConfig.h>
Expand Down Expand Up @@ -82,6 +84,12 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
if (ep < kMediaInputDelegateTableSize)
{
gDelegateTable[ep] = delegate;
// Sync the attributes from delegate
Status status = Attributes::CurrentInput::Set(endpoint, delegate->HandleGetCurrentInput());

if (Status::Success != status) {
ChipLogError(Zcl, "Unable to save CurrentInput attribute ");
}
}
else
{
Expand Down Expand Up @@ -118,6 +126,7 @@ class MediaInputAttrAccess : public app::AttributeAccessInterface
MediaInputAttrAccess() : app::AttributeAccessInterface(Optional<EndpointId>::Missing(), chip::app::Clusters::MediaInput::Id) {}

CHIP_ERROR Read(const app::ConcreteReadAttributePath & aPath, app::AttributeValueEncoder & aEncoder) override;
CHIP_ERROR Write(const app::ConcreteDataAttributePath & aPath, app::AttributeValueDecoder & aDecoder) override;

private:
CHIP_ERROR ReadInputListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate);
Expand Down Expand Up @@ -156,6 +165,30 @@ CHIP_ERROR MediaInputAttrAccess::Read(const app::ConcreteReadAttributePath & aPa

return CHIP_NO_ERROR;
}

CHIP_ERROR WriteCurrentInput(EndpointId endpoint, uint8_t newInput)
{
Delegate * delegate = GetDelegate(endpoint);
VerifyOrReturnError(!isDelegateNull(delegate, endpoint), CHIP_ERROR_INTERNAL);

return delegate->HandleSetCurrentInput(newInput) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

CHIP_ERROR MediaInputAttrAccess::Write(const app::ConcreteDataAttributePath & aPath, app::AttributeValueDecoder & aDecoder)

This comment has been minimized.

Copy link
@tcarmelveilleux

tcarmelveilleux Aug 19, 2024

Current input is not writable. DO NOT add a AAI for read-only attributes

This comment has been minimized.

Copy link
@erwinpan1

erwinpan1 Aug 20, 2024

Author Owner

OK. I'll remove this.

{
app::DataModel::Nullable<uint8_t> nullableValue;
ReturnErrorOnFailure(aDecoder.Decode(nullableValue));
VerifyOrReturnError(!nullableValue.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);

switch (aPath.mAttributeId)
{
case app::Clusters::MediaInput::Attributes::CurrentInput::Id:
return WriteCurrentInput(aPath.mEndpointId, nullableValue.Value());
}

ChipLogError(Zcl, "Unsupport MediaInput cluster attribute write %u", aPath.mAttributeId);
return CHIP_ERROR_INTERNAL;
}

CHIP_ERROR MediaInputAttrAccess::ReadInputListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
Expand All @@ -178,17 +211,26 @@ bool emberAfMediaInputClusterSelectInputCallback(app::CommandHandler * command,
{
CHIP_ERROR err = CHIP_NO_ERROR;
EndpointId endpoint = commandPath.mEndpointId;
Status status = Status::Success;
Status status = Status::Failure;

auto & input = commandData.index;
uint8_t currentInput = 0;

Delegate * delegate = GetDelegate(endpoint);
VerifyOrExit(isDelegateNull(delegate, endpoint) != true, err = CHIP_ERROR_INCORRECT_STATE);

if (!delegate->HandleSelectInput(input))
{
status = Status::Failure;
currentInput = delegate->HandleGetCurrentInput();

if (currentInput == input) {
ChipLogProgress(Zcl, "Endpoint %x CurrentInput already set to new value: %u", endpoint, input);
} else {
VerifyOrExit(delegate->HandleSelectInput(input), err = CHIP_ERROR_INVALID_ARGUMENT);
// Sync attribute to storage
VerifyOrExit(Status::Success == (status = chip::app::Clusters::MediaInput::Attributes::CurrentInput::Set(endpoint, input)), err = CHIP_ERROR_INTERNAL);
ChipLogProgress(Zcl, "Endpoint %x CurrentInput set to new value: %u successfully", endpoint, input);
}
status = Status::Success;

exit:
if (err != CHIP_NO_ERROR)
{
Expand Down

0 comments on commit c561334

Please sign in to comment.