22
22
#include " pigweed/rpc_services/internal/StatusUtils.h"
23
23
24
24
#include < app-common/zap-generated/attribute-type.h>
25
+ #include < app/AttributeAccessInterfaceRegistry.h>
25
26
#include < app/InteractionModelEngine.h>
26
27
#include < app/MessageDef/AttributeReportIBs.h>
28
+ #include < app/reporting/reporting.h>
27
29
#include < app/util/attribute-storage.h>
28
30
#include < app/util/attribute-table.h>
29
31
#include < app/util/ember-compatibility-functions.h>
@@ -42,37 +44,99 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
42
44
::pw::Status Write (const chip_rpc_AttributeWrite & request, pw_protobuf_Empty & response)
43
45
{
44
46
const void * data;
47
+ size_t data_len = 0 ;
45
48
DeviceLayer::StackLock lock;
46
49
47
50
switch (request.data .which_data )
48
51
{
49
52
case chip_rpc_AttributeData_data_bool_tag:
50
53
data = &request.data .data .data_bool ;
54
+ data_len = sizeof (request.data .data .data_bool );
51
55
break ;
52
56
case chip_rpc_AttributeData_data_uint8_tag:
53
57
data = &request.data .data .data_uint8 ;
58
+ data_len = sizeof (request.data .data .data_uint8 );
54
59
break ;
55
60
case chip_rpc_AttributeData_data_uint16_tag:
56
61
data = &request.data .data .data_uint16 ;
62
+ data_len = sizeof (request.data .data .data_uint16 );
57
63
break ;
58
64
case chip_rpc_AttributeData_data_uint32_tag:
59
65
data = &request.data .data .data_uint32 ;
66
+ data_len = sizeof (request.data .data .data_uint32 );
60
67
break ;
61
68
case chip_rpc_AttributeData_data_int8_tag:
62
69
data = &request.data .data .data_int8 ;
70
+ data_len = sizeof (request.data .data .data_int8 );
63
71
break ;
64
72
case chip_rpc_AttributeData_data_int16_tag:
65
73
data = &request.data .data .data_int16 ;
74
+ data_len = sizeof (request.data .data .data_int16 );
66
75
break ;
67
76
case chip_rpc_AttributeData_data_int32_tag:
68
77
data = &request.data .data .data_int32 ;
78
+ data_len = sizeof (request.data .data .data_int32 );
69
79
break ;
70
80
case chip_rpc_AttributeData_data_bytes_tag:
71
81
data = &request.data .data .data_bytes ;
82
+ data_len = sizeof (request.data .data .data_bytes );
72
83
break ;
73
84
default :
74
85
return pw::Status::InvalidArgument ();
75
86
}
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
76
140
RETURN_STATUS_IF_NOT_OK (
77
141
emberAfWriteAttribute (request.metadata .endpoint , request.metadata .cluster , request.metadata .attribute_id ,
78
142
const_cast <uint8_t *>(static_cast <const uint8_t *>(data)), request.metadata .type ));
0 commit comments