Skip to content

Commit c561334

Browse files
committed
Fix media-input accessinterface
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)
1 parent 3bc5667 commit c561334

File tree

6 files changed

+124
-14
lines changed

6 files changed

+124
-14
lines changed

examples/chef/common/clusters/media-input/MediaInputManager.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ uint8_t MediaInputManager::HandleGetCurrentInput()
5454
return mCurrentInput;
5555
}
5656

57+
bool MediaInputManager::HandleSetCurrentInput(const uint8_t index)
58+
{
59+
return HandleSelectInput(index);
60+
}
61+
5762
bool MediaInputManager::HandleSelectInput(const uint8_t index)
5863
{
5964
for (auto const & inputData : mInputs)
@@ -99,4 +104,11 @@ bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharS
99104

100105
return false;
101106
}
107+
108+
static MediaInputManager mediaInputManager;
109+
void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
110+
{
111+
ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate");
112+
chip::app::Clusters::MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager);
113+
}
102114
#endif // MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER

examples/chef/common/clusters/media-input/MediaInputManager.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class MediaInputManager : public chip::app::Clusters::MediaInput::Delegate
3333

3434
CHIP_ERROR HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) override;
3535
uint8_t HandleGetCurrentInput() override;
36+
bool HandleSetCurrentInput(const uint8_t index) override;
3637
bool HandleSelectInput(const uint8_t index) override;
3738
bool HandleShowInputStatus() override;
3839
bool HandleHideInputStatus() override;

examples/chef/common/stubs.cpp

-10
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,6 @@ void emberAfLowPowerClusterInitCallback(EndpointId endpoint)
238238
}
239239
#endif
240240

241-
#ifdef MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER
242-
#include "media-input/MediaInputManager.h"
243-
static MediaInputManager mediaInputManager;
244-
void emberAfMediaInputClusterInitCallback(EndpointId endpoint)
245-
{
246-
ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate");
247-
MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager);
248-
}
249-
#endif
250-
251241
#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER
252242
#include "media-playback/MediaPlaybackManager.h"
253243
static MediaPlaybackManager mediaPlaybackManager;

examples/common/pigweed/rpc_services/Attributes.h

+64
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
#include "pigweed/rpc_services/internal/StatusUtils.h"
2323

2424
#include <app-common/zap-generated/attribute-type.h>
25+
#include <app/AttributeAccessInterfaceRegistry.h>
2526
#include <app/InteractionModelEngine.h>
2627
#include <app/MessageDef/AttributeReportIBs.h>
28+
#include <app/reporting/reporting.h>
2729
#include <app/util/attribute-storage.h>
2830
#include <app/util/attribute-table.h>
2931
#include <app/util/ember-compatibility-functions.h>
@@ -42,37 +44,99 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
4244
::pw::Status Write(const chip_rpc_AttributeWrite & request, pw_protobuf_Empty & response)
4345
{
4446
const void * data;
47+
size_t data_len = 0;
4548
DeviceLayer::StackLock lock;
4649

4750
switch (request.data.which_data)
4851
{
4952
case chip_rpc_AttributeData_data_bool_tag:
5053
data = &request.data.data.data_bool;
54+
data_len = sizeof(request.data.data.data_bool);
5155
break;
5256
case chip_rpc_AttributeData_data_uint8_tag:
5357
data = &request.data.data.data_uint8;
58+
data_len = sizeof(request.data.data.data_uint8);
5459
break;
5560
case chip_rpc_AttributeData_data_uint16_tag:
5661
data = &request.data.data.data_uint16;
62+
data_len = sizeof(request.data.data.data_uint16);
5763
break;
5864
case chip_rpc_AttributeData_data_uint32_tag:
5965
data = &request.data.data.data_uint32;
66+
data_len = sizeof(request.data.data.data_uint32);
6067
break;
6168
case chip_rpc_AttributeData_data_int8_tag:
6269
data = &request.data.data.data_int8;
70+
data_len = sizeof(request.data.data.data_int8);
6371
break;
6472
case chip_rpc_AttributeData_data_int16_tag:
6573
data = &request.data.data.data_int16;
74+
data_len = sizeof(request.data.data.data_int16);
6675
break;
6776
case chip_rpc_AttributeData_data_int32_tag:
6877
data = &request.data.data.data_int32;
78+
data_len = sizeof(request.data.data.data_int32);
6979
break;
7080
case chip_rpc_AttributeData_data_bytes_tag:
7181
data = &request.data.data.data_bytes;
82+
data_len = sizeof(request.data.data.data_bytes);
7283
break;
7384
default:
7485
return pw::Status::InvalidArgument();
7586
}
87+
88+
#if 1 // Refering Duplicate WriteSingleClusterData to calling AttributeInterface when available
89+
if (data_len == 0) {
90+
ChipLogError(Zcl, "Invalid writing to PW RPC with data length: 0");
91+
return pw::Status::InvalidArgument();
92+
}
93+
if (auto * attrOverride = chip::app::GetAttributeAccessOverride(request.metadata.endpoint, request.metadata.cluster))
94+
{
95+
Access::SubjectDescriptor aSubjectDescriptor{ .authMode = chip::Access::AuthMode::kPase };
96+
app::ConcreteDataAttributePath aPath(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id);
97+
98+
uint8_t tlvBuffer[128] = { 0 };
99+
uint8_t value = *(static_cast<const uint8_t *>(data));
100+
101+
TLV::TLVReader aReader;
102+
103+
TLV::TLVType outerContainerType;
104+
TLV::TLVWriter writer;
105+
writer.Init(tlvBuffer);
106+
writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType);
107+
writer.Put(TLV::AnonymousTag(), value);
108+
writer.EndContainer(outerContainerType);
109+
writer.Finalize();
110+
111+
aReader.Init(tlvBuffer);
112+
app::AttributeValueDecoder valueDecoder(aReader, aSubjectDescriptor);
113+
114+
#if 1 // Test Decode
115+
app::DataModel::Nullable<uint8_t> nullableValue;
116+
117+
CHIP_ERROR err = valueDecoder.Decode(nullableValue);
118+
if (CHIP_NO_ERROR != err) {
119+
ChipLogError(Zcl, "Invalid writing to PW RPC due to data decoding failed");
120+
return pw::Status::InvalidArgument();
121+
}
122+
123+
if (nullableValue.IsNull()) {
124+
ChipLogError(Zcl, "Invalid writing to PW RPC with null data");
125+
return pw::Status::InvalidArgument();
126+
}
127+
128+
ChipLogError(Zcl, "Writing to PW RPC with data: %u", nullableValue.Value());
129+
#endif
130+
131+
PW_TRY(ChipErrorToPwStatus(attrOverride->Write(aPath, valueDecoder)));
132+
133+
if (valueDecoder.TriedDecode()) // TBD
134+
{
135+
MatterReportingAttributeChangeCallback(aPath);
136+
return pw::OkStatus();
137+
}
138+
}
139+
#endif
76140
RETURN_STATUS_IF_NOT_OK(
77141
emberAfWriteAttribute(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id,
78142
const_cast<uint8_t *>(static_cast<const uint8_t *>(data)), request.metadata.type));

src/app/clusters/media-input-server/media-input-delegate.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class Delegate
3535
// no easy way to handle the return memory of app::Clusters::MediaInput::Structs::InputInfoStruct::Type list, so encoder is used
3636
virtual CHIP_ERROR HandleGetInputList(app::AttributeValueEncoder & aEncoder) = 0;
3737
virtual uint8_t HandleGetCurrentInput() = 0;
38+
virtual bool HandleSetCurrentInput(const uint8_t index) = 0;
3839
virtual bool HandleSelectInput(const uint8_t index) = 0;
3940
virtual bool HandleShowInputStatus() = 0;
4041
virtual bool HandleHideInputStatus() = 0;

src/app/clusters/media-input-server/media-input-server.cpp

+46-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <app/CommandHandler.h>
3131
#include <app/ConcreteCommandPath.h>
3232
#include <app/data-model/Encode.h>
33+
#include <app/data-model/Decode.h>
34+
#include <app/data-model/Nullable.h>
3335
#include <app/util/attribute-storage.h>
3436
#include <app/util/config.h>
3537
#include <platform/CHIPDeviceConfig.h>
@@ -82,6 +84,12 @@ void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
8284
if (ep < kMediaInputDelegateTableSize)
8385
{
8486
gDelegateTable[ep] = delegate;
87+
// Sync the attributes from delegate
88+
Status status = Attributes::CurrentInput::Set(endpoint, delegate->HandleGetCurrentInput());
89+
90+
if (Status::Success != status) {
91+
ChipLogError(Zcl, "Unable to save CurrentInput attribute ");
92+
}
8593
}
8694
else
8795
{
@@ -118,6 +126,7 @@ class MediaInputAttrAccess : public app::AttributeAccessInterface
118126
MediaInputAttrAccess() : app::AttributeAccessInterface(Optional<EndpointId>::Missing(), chip::app::Clusters::MediaInput::Id) {}
119127

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

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

157166
return CHIP_NO_ERROR;
158167
}
168+
169+
CHIP_ERROR WriteCurrentInput(EndpointId endpoint, uint8_t newInput)
170+
{
171+
Delegate * delegate = GetDelegate(endpoint);
172+
VerifyOrReturnError(!isDelegateNull(delegate, endpoint), CHIP_ERROR_INTERNAL);
173+
174+
return delegate->HandleSetCurrentInput(newInput) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
175+
}
176+
177+
CHIP_ERROR MediaInputAttrAccess::Write(const app::ConcreteDataAttributePath & aPath, app::AttributeValueDecoder & aDecoder)
178+
{
179+
app::DataModel::Nullable<uint8_t> nullableValue;
180+
ReturnErrorOnFailure(aDecoder.Decode(nullableValue));
181+
VerifyOrReturnError(!nullableValue.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);
182+
183+
switch (aPath.mAttributeId)
184+
{
185+
case app::Clusters::MediaInput::Attributes::CurrentInput::Id:
186+
return WriteCurrentInput(aPath.mEndpointId, nullableValue.Value());
187+
}
188+
189+
ChipLogError(Zcl, "Unsupport MediaInput cluster attribute write %u", aPath.mAttributeId);
190+
return CHIP_ERROR_INTERNAL;
191+
}
159192

160193
CHIP_ERROR MediaInputAttrAccess::ReadInputListAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
161194
{
@@ -178,17 +211,26 @@ bool emberAfMediaInputClusterSelectInputCallback(app::CommandHandler * command,
178211
{
179212
CHIP_ERROR err = CHIP_NO_ERROR;
180213
EndpointId endpoint = commandPath.mEndpointId;
181-
Status status = Status::Success;
214+
Status status = Status::Failure;
182215

183216
auto & input = commandData.index;
217+
uint8_t currentInput = 0;
184218

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

188-
if (!delegate->HandleSelectInput(input))
189-
{
190-
status = Status::Failure;
222+
currentInput = delegate->HandleGetCurrentInput();
223+
224+
if (currentInput == input) {
225+
ChipLogProgress(Zcl, "Endpoint %x CurrentInput already set to new value: %u", endpoint, input);
226+
} else {
227+
VerifyOrExit(delegate->HandleSelectInput(input), err = CHIP_ERROR_INVALID_ARGUMENT);
228+
// Sync attribute to storage
229+
VerifyOrExit(Status::Success == (status = chip::app::Clusters::MediaInput::Attributes::CurrentInput::Set(endpoint, input)), err = CHIP_ERROR_INTERNAL);
230+
ChipLogProgress(Zcl, "Endpoint %x CurrentInput set to new value: %u successfully", endpoint, input);
191231
}
232+
status = Status::Success;
233+
192234
exit:
193235
if (err != CHIP_NO_ERROR)
194236
{

0 commit comments

Comments
 (0)