Skip to content

Commit 7f78939

Browse files
andy31415andreilitvinbzbarsky-applerestyled-commitstcarmelveilleux
authored
Allow passing in a Path change listener to ember write functions (#35455)
* Cleaner usage: no need of a separate function that is used in one place only * Attempt an API update * Fix typos in the Accessors src * Fix typo and regen * More fixes on accessors * Update signature for emAfWriteAttributeExternal * Add a comment about all the checks being vague * Update src/app/util/af-types.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/af-types.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-storage.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/zap-templates/templates/app/attributes/Accessors-src.zapt Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/mock/CodegenEmberMocks.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/zap-templates/templates/app/attributes/Accessors-src.zapt Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/zap-templates/templates/app/attributes/Accessors-src.zapt Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * zap regen and restyle * Update src/app/zap-templates/templates/app/attributes/Accessors-src.zapt Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-table.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-storage.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-storage.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-table.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-table.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-storage.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/util/attribute-table.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Rename ChangedPathListener to AttributesChangedListener * Remove chip:: and chip::app * Update constructors of AttributePathParams and add nodiscard according to the linter to never call const methods without considering their return value * Restyled by clang-format * Remove auto-inserted include * Update again and zap regen: removed extra namespace prefixes in accessors.h/cpp * Add comment about uint8_t non-const usage... * Another rename given that the listener is now an attributes and not a path listener * Update src/app/util/attribute-table.h Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com> * Comment update to talk more about AttributesChangedListener * Restyle --------- Co-authored-by: Andrei Litvin <andreilitvin@google.com> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>
1 parent 86e1974 commit 7f78939

File tree

19 files changed

+9092
-8259
lines changed

19 files changed

+9092
-8259
lines changed

src/app/AttributePathParams.h

+17-10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class ReadClient;
3030
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT
3131
struct AttributePathParams
3232
{
33+
AttributePathParams() = default;
34+
35+
explicit AttributePathParams(EndpointId aEndpointId) :
36+
AttributePathParams(aEndpointId, kInvalidClusterId, kInvalidAttributeId, kInvalidListIndex)
37+
{}
38+
3339
//
3440
// TODO: (Issue #10596) Need to ensure that we do not encode the NodeId over the wire
3541
// if it is either not 'set', or is set to a value that matches accessing fabric
@@ -50,9 +56,10 @@ struct AttributePathParams
5056
mClusterId(aClusterId), mAttributeId(aAttributeId), mEndpointId(aEndpointId), mListIndex(aListIndex)
5157
{}
5258

53-
AttributePathParams() {}
54-
55-
bool IsWildcardPath() const { return HasWildcardEndpointId() || HasWildcardClusterId() || HasWildcardAttributeId(); }
59+
[[nodiscard]] bool IsWildcardPath() const
60+
{
61+
return HasWildcardEndpointId() || HasWildcardClusterId() || HasWildcardAttributeId();
62+
}
5663

5764
bool operator==(const AttributePathParams & aOther) const
5865
{
@@ -66,12 +73,12 @@ struct AttributePathParams
6673
* be wildcard. This does not verify that the attribute being targeted is actually of list type when the list index is not
6774
* wildcard.
6875
*/
69-
bool IsValidAttributePath() const { return HasWildcardListIndex() || !HasWildcardAttributeId(); }
76+
[[nodiscard]] bool IsValidAttributePath() const { return HasWildcardListIndex() || !HasWildcardAttributeId(); }
7077

71-
inline bool HasWildcardEndpointId() const { return mEndpointId == kInvalidEndpointId; }
72-
inline bool HasWildcardClusterId() const { return mClusterId == kInvalidClusterId; }
73-
inline bool HasWildcardAttributeId() const { return mAttributeId == kInvalidAttributeId; }
74-
inline bool HasWildcardListIndex() const { return mListIndex == kInvalidListIndex; }
78+
[[nodiscard]] inline bool HasWildcardEndpointId() const { return mEndpointId == kInvalidEndpointId; }
79+
[[nodiscard]] inline bool HasWildcardClusterId() const { return mClusterId == kInvalidClusterId; }
80+
[[nodiscard]] inline bool HasWildcardAttributeId() const { return mAttributeId == kInvalidAttributeId; }
81+
[[nodiscard]] inline bool HasWildcardListIndex() const { return mListIndex == kInvalidListIndex; }
7582
inline void SetWildcardEndpointId() { mEndpointId = kInvalidEndpointId; }
7683
inline void SetWildcardClusterId() { mClusterId = kInvalidClusterId; }
7784
inline void SetWildcardAttributeId()
@@ -80,7 +87,7 @@ struct AttributePathParams
8087
mListIndex = kInvalidListIndex;
8188
}
8289

83-
bool IsAttributePathSupersetOf(const AttributePathParams & other) const
90+
[[nodiscard]] bool IsAttributePathSupersetOf(const AttributePathParams & other) const
8491
{
8592
VerifyOrReturnError(HasWildcardEndpointId() || mEndpointId == other.mEndpointId, false);
8693
VerifyOrReturnError(HasWildcardClusterId() || mClusterId == other.mClusterId, false);
@@ -90,7 +97,7 @@ struct AttributePathParams
9097
return true;
9198
}
9299

93-
bool IsAttributePathSupersetOf(const ConcreteAttributePath & other) const
100+
[[nodiscard]] bool IsAttributePathSupersetOf(const ConcreteAttributePath & other) const
94101
{
95102
VerifyOrReturnError(HasWildcardEndpointId() || mEndpointId == other.mEndpointId, false);
96103
VerifyOrReturnError(HasWildcardClusterId() || mClusterId == other.mClusterId, false);

src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat
386386
}
387387
else
388388
{
389-
status = emAfWriteAttributeExternal(request.path.mEndpointId, request.path.mClusterId, request.path.mAttributeId,
390-
dataBuffer.data(), (*attributeMetadata)->attributeType);
389+
status =
390+
emAfWriteAttributeExternal(request.path, EmberAfWriteDataInput(dataBuffer.data(), (*attributeMetadata)->attributeType));
391391
}
392392

393393
if (status != Protocols::InteractionModel::Status::Success)

src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "EmberReadWriteOverride.h"
1818

1919
#include <app/util/attribute-storage.h>
20+
#include <app/util/attribute-table.h>
2021
#include <app/util/ember-io-storage.h>
2122
#include <lib/support/Span.h>
2223

@@ -100,8 +101,7 @@ Status emAfReadOrWriteAttribute(const EmberAfAttributeSearchRecord * attRecord,
100101
return Status::Success;
101102
}
102103

103-
Status emAfWriteAttributeExternal(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
104-
uint8_t * dataPtr, EmberAfAttributeType dataType)
104+
Status emAfWriteAttributeExternal(const chip::app::ConcreteAttributePath & path, const EmberAfWriteDataInput & input)
105105
{
106106
if (gEmberStatusCode != Status::Success)
107107
{
@@ -110,13 +110,13 @@ Status emAfWriteAttributeExternal(chip::EndpointId endpoint, chip::ClusterId clu
110110

111111
// ember here deduces the size of dataPtr. For testing however, we KNOW we read
112112
// out of the ember IO buffer, so we try to use that
113-
VerifyOrDie(dataPtr == chip::app::Compatibility::Internal::gEmberAttributeIOBufferSpan.data());
113+
VerifyOrDie(input.dataPtr == chip::app::Compatibility::Internal::gEmberAttributeIOBufferSpan.data());
114114

115115
// In theory this should do type validation and sizes. This is NOT done for testing.
116116
// copy over as much data as possible
117117
// NOTE: we do NOT use (*metadata)->size since it is unclear if our mocks set that correctly
118118
size_t len = std::min<size_t>(sizeof(gEmberIoBuffer), chip::app::Compatibility::Internal::gEmberAttributeIOBufferSpan.size());
119-
memcpy(gEmberIoBuffer, dataPtr, len);
119+
memcpy(gEmberIoBuffer, input.dataPtr, len);
120120
gEmberIoBufferFill = len;
121121

122122
return Status::Success;
@@ -125,5 +125,6 @@ Status emAfWriteAttributeExternal(chip::EndpointId endpoint, chip::ClusterId clu
125125
Status emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * dataPtr,
126126
EmberAfAttributeType dataType)
127127
{
128-
return emAfWriteAttributeExternal(endpoint, cluster, attributeID, dataPtr, dataType);
128+
return emAfWriteAttributeExternal(chip::app::ConcreteAttributePath(endpoint, cluster, attributeID),
129+
EmberAfWriteDataInput(dataPtr, dataType));
129130
}

src/app/reporting/Engine.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ CHIP_ERROR Engine::InsertPathIntoDirtySet(const AttributePathParams & aAttribute
855855
return CHIP_NO_ERROR;
856856
}
857857

858-
CHIP_ERROR Engine::SetDirty(AttributePathParams & aAttributePath)
858+
CHIP_ERROR Engine::SetDirty(const AttributePathParams & aAttributePath)
859859
{
860860
BumpDirtySetGeneration();
861861

src/app/reporting/Engine.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class Engine
9393
/**
9494
* Application marks mutated change path and would be sent out in later report.
9595
*/
96-
CHIP_ERROR SetDirty(AttributePathParams & aAttributePathParams);
96+
CHIP_ERROR SetDirty(const AttributePathParams & aAttributePathParams);
9797

9898
/**
9999
* @brief

src/app/reporting/reporting.cpp

+8-34
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,23 @@
2424
using namespace chip;
2525
using namespace chip::app;
2626

27-
namespace {
28-
29-
void IncreaseClusterDataVersion(const ConcreteClusterPath & aConcreteClusterPath)
30-
{
31-
DataVersion * version = emberAfDataVersionStorage(aConcreteClusterPath);
32-
if (version == nullptr)
33-
{
34-
ChipLogError(DataManagement, "Endpoint %x, Cluster " ChipLogFormatMEI " not found in IncreaseClusterDataVersion!",
35-
aConcreteClusterPath.mEndpointId, ChipLogValueMEI(aConcreteClusterPath.mClusterId));
36-
}
37-
else
38-
{
39-
(*(version))++;
40-
ChipLogDetail(DataManagement, "Endpoint %x, Cluster " ChipLogFormatMEI " update version to %" PRIx32,
41-
aConcreteClusterPath.mEndpointId, ChipLogValueMEI(aConcreteClusterPath.mClusterId), *(version));
42-
}
43-
}
44-
45-
} // namespace
46-
4727
void MatterReportingAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId)
4828
{
4929
// Attribute writes have asserted this already, but this assert should catch
5030
// applications notifying about changes from their end.
5131
assertChipStackLockedByCurrentThread();
5232

53-
AttributePathParams info;
54-
info.mClusterId = clusterId;
55-
info.mAttributeId = attributeId;
56-
info.mEndpointId = endpoint;
57-
58-
IncreaseClusterDataVersion(ConcreteClusterPath(endpoint, clusterId));
59-
InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(info);
33+
emberAfAttributeChanged(endpoint, clusterId, attributeId, emberAfGlobalInteractionModelAttributesChangedListener());
6034
}
6135

6236
void MatterReportingAttributeChangeCallback(const ConcreteAttributePath & aPath)
6337
{
64-
return MatterReportingAttributeChangeCallback(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId);
38+
// Attribute writes have asserted this already, but this assert should catch
39+
// applications notifying about changes from their end.
40+
assertChipStackLockedByCurrentThread();
41+
42+
emberAfAttributeChanged(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId,
43+
emberAfGlobalInteractionModelAttributesChangedListener());
6544
}
6645

6746
void MatterReportingAttributeChangeCallback(EndpointId endpoint)
@@ -70,10 +49,5 @@ void MatterReportingAttributeChangeCallback(EndpointId endpoint)
7049
// applications notifying about changes from their end.
7150
assertChipStackLockedByCurrentThread();
7251

73-
AttributePathParams info;
74-
info.mEndpointId = endpoint;
75-
76-
// We are adding or enabling a whole endpoint, in this case, we do not touch the cluster data version.
77-
78-
InteractionModelEngine::GetInstance()->GetReportingEngine().SetDirty(info);
52+
emberAfEndpointChanged(endpoint, emberAfGlobalInteractionModelAttributesChangedListener());
7953
}

src/app/util/af-types.h

+11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include <app/util/attribute-metadata.h> // EmberAfAttributeMetadata
3434

35+
#include <app/AttributePathParams.h>
3536
#include <app/ConcreteAttributePath.h>
3637
#include <app/data-model/Nullable.h>
3738
#include <lib/core/DataModelTypes.h>
@@ -314,5 +315,15 @@ enum class MarkAttributeDirty
314315
kYes,
315316
};
316317

318+
/// Notification object of a specific path being changed
319+
class AttributesChangedListener
320+
{
321+
public:
322+
virtual ~AttributesChangedListener() = default;
323+
324+
/// Called when the set of attributes identified by AttributePathParams (which may contain wildcards) is to be considered dirty.
325+
virtual void MarkDirty(const AttributePathParams & path) = 0;
326+
};
327+
317328
} // namespace app
318329
} // namespace chip

0 commit comments

Comments
 (0)