14
14
* See the License for the specific language governing permissions and
15
15
* limitations under the License.
16
16
*/
17
- #include " lib/core/CHIPError.h"
18
17
#include < app/codegen-data-model/CodegenDataModel.h>
19
18
20
19
#include < optional>
29
28
#include < app/AttributeValueEncoder.h>
30
29
#include < app/GlobalAttributes.h>
31
30
#include < app/RequiredPrivilege.h>
31
+ #include < app/codegen-data-model/EmberMetadata.h>
32
32
#include < app/data-model/FabricScoped.h>
33
33
#include < app/util/af-types.h>
34
34
#include < app/util/attribute-metadata.h>
@@ -49,56 +49,6 @@ namespace app {
49
49
namespace {
50
50
using namespace chip ::app::Compatibility::Internal;
51
51
52
- // Fetch the source for the given attribute path: either a cluster (for global ones) or attribute
53
- // path.
54
- //
55
- // if returning a CHIP_ERROR, it will NEVER be CHIP_NO_ERROR.
56
- std::variant<const EmberAfCluster *, // global attribute, data from a cluster
57
- const EmberAfAttributeMetadata *, // a specific attribute stored by ember
58
- CHIP_ERROR // error, this will NEVER be CHIP_NO_ERROR
59
- >
60
- FindAttributeMetadata (const ConcreteAttributePath & aPath)
61
- {
62
- for (auto & attr : GlobalAttributesNotInMetadata)
63
- {
64
-
65
- if (attr == aPath.mAttributeId )
66
- {
67
- const EmberAfCluster * cluster = emberAfFindServerCluster (aPath.mEndpointId , aPath.mClusterId );
68
- if (cluster == nullptr )
69
- {
70
- return (emberAfFindEndpointType (aPath.mEndpointId ) == nullptr ) ? CHIP_IM_GLOBAL_STATUS (UnsupportedEndpoint)
71
- : CHIP_IM_GLOBAL_STATUS (UnsupportedCluster);
72
- }
73
-
74
- return cluster;
75
- }
76
- }
77
- const EmberAfAttributeMetadata * metadata =
78
- emberAfLocateAttributeMetadata (aPath.mEndpointId , aPath.mClusterId , aPath.mAttributeId );
79
-
80
- if (metadata == nullptr )
81
- {
82
- const EmberAfEndpointType * type = emberAfFindEndpointType (aPath.mEndpointId );
83
- if (type == nullptr )
84
- {
85
- return CHIP_IM_GLOBAL_STATUS (UnsupportedEndpoint);
86
- }
87
-
88
- const EmberAfCluster * cluster = emberAfFindClusterInType (type, aPath.mClusterId , CLUSTER_MASK_SERVER);
89
- if (cluster == nullptr )
90
- {
91
- return CHIP_IM_GLOBAL_STATUS (UnsupportedCluster);
92
- }
93
-
94
- // Since we know the attribute is unsupported and the endpoint/cluster are
95
- // OK, this is the only option left.
96
- return CHIP_IM_GLOBAL_STATUS (UnsupportedAttribute);
97
- }
98
-
99
- return metadata;
100
- }
101
-
102
52
// / Attempts to read via an attribute access interface (AAI)
103
53
// /
104
54
// / If it returns a CHIP_ERROR, then this is a FINAL result (i.e. either failure or success).
@@ -138,13 +88,27 @@ struct ShortPascalString
138
88
{
139
89
using LengthType = uint8_t ;
140
90
static constexpr LengthType kNullLength = 0xFF ;
91
+
92
+ static LengthType GetLength (const uint8_t * buffer)
93
+ {
94
+ // NOTE: we do NOT use emberAfLongStringLength because that will result in 0 length
95
+ // for null strings
96
+ return *buffer;
97
+ }
141
98
};
142
99
143
100
// / Metadata of what a ember/pascal LONG string means (prepended by a u16 length)
144
101
struct LongPascalString
145
102
{
146
103
using LengthType = uint16_t ;
147
104
static constexpr LengthType kNullLength = 0xFFFF ;
105
+
106
+ static LengthType GetLength (const uint8_t * buffer)
107
+ {
108
+ // NOTE: we do NOT use emberAfLongStringLength because that will result in 0 length
109
+ // for null strings
110
+ return Encoding::LittleEndian::Read16 (buffer);
111
+ }
148
112
};
149
113
150
114
// ember assumptions ... should just work
@@ -157,12 +121,8 @@ static_assert(sizeof(LongPascalString::LengthType) == 2);
157
121
template <class OUT , class ENCODING >
158
122
std::optional<OUT> ExtractEmberString (ByteSpan data)
159
123
{
160
- typename ENCODING::LengthType len;
161
-
162
- // Ember storage format for pascal-prefix data is specifically "native byte order",
163
- // hence the use of memcpy.
164
- VerifyOrDie (sizeof (len) <= data.size ());
165
- memcpy (&len, data.data (), sizeof (len));
124
+ VerifyOrDie (sizeof (typename ENCODING::LengthType) <= data.size ());
125
+ auto len = ENCODING::GetLength (data.data ());
166
126
167
127
if (len == ENCODING::kNullLength )
168
128
{
@@ -282,7 +242,7 @@ CHIP_ERROR EncodeEmberValue(ByteSpan data, const EmberAfAttributeMetadata * meta
282
242
return EncodeStringLike<ByteSpan, LongPascalString>(data, isNullable, encoder);
283
243
default :
284
244
ChipLogError (DataManagement, " Attribute type 0x%x not handled" , static_cast <int >(metadata->attributeType ));
285
- return CHIP_IM_GLOBAL_STATUS (UnsupportedRead );
245
+ return CHIP_IM_GLOBAL_STATUS (Failure );
286
246
}
287
247
}
288
248
@@ -311,21 +271,26 @@ CHIP_ERROR CodegenDataModel::ReadAttribute(const InteractionModel::ReadAttribute
311
271
RequiredPrivilege::ForReadAttribute (request.path ));
312
272
if (err != CHIP_NO_ERROR)
313
273
{
274
+ ReturnErrorCodeIf (err != CHIP_ERROR_ACCESS_DENIED, err);
275
+
314
276
// Implementation of 8.4.3.2 of the spec for path expansion
315
- if (request.path .mExpanded && (err == CHIP_ERROR_ACCESS_DENIED) )
277
+ if (request.path .mExpanded )
316
278
{
317
279
return CHIP_NO_ERROR;
318
280
}
319
- return err;
281
+ // access denied has a specific code for IM
282
+ return CHIP_IM_GLOBAL_STATUS (UnsupportedAccess);
320
283
}
321
284
}
322
285
323
- auto metadata = FindAttributeMetadata (request.path );
286
+ auto metadata = Ember:: FindAttributeMetadata (request.path );
324
287
325
288
// Explicit failure in finding a suitable metadata
326
289
if (const CHIP_ERROR * err = std::get_if<CHIP_ERROR>(&metadata))
327
290
{
328
- VerifyOrDie (*err != CHIP_NO_ERROR);
291
+ VerifyOrDie ((*err == CHIP_IM_GLOBAL_STATUS (UnsupportedEndpoint)) || //
292
+ (*err == CHIP_IM_GLOBAL_STATUS (UnsupportedCluster)) || //
293
+ (*err == CHIP_IM_GLOBAL_STATUS (UnsupportedAttribute)));
329
294
return *err;
330
295
}
331
296
0 commit comments