Skip to content

Commit 2f39c3d

Browse files
ArekBalysNordicrlubos
authored andcommitted
matter: samples: Switch to code-driven Identify cluster on MB
zapgen-driven Identify cluster implementation does not work anymore for dynamic-generated endpoints. Instead we must use code-driven implementation for this cluster. For now switch to the new implementation to build the applicationm but the MatterBridgedDevice constructor must be refactored later. Signed-off-by: Arkadiusz Balys <[email protected]>
1 parent 2db23db commit 2f39c3d

File tree

7 files changed

+100
-64
lines changed

7 files changed

+100
-64
lines changed

applications/matter_bridge/src/bridged_device_types/generic_switch.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
#include <zephyr/logging/log.h>
1010

11-
#include <app-common/zap-generated/ids/Commands.h>
1211
#include <app-common/zap-generated/attributes/Accessors.h>
12+
#include <app-common/zap-generated/ids/Commands.h>
1313
#include <app/clusters/switch-server/switch-server.h>
1414

1515
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
@@ -18,7 +18,6 @@ namespace
1818
{
1919
DESCRIPTOR_CLUSTER_ATTRIBUTES(descriptorAttrs);
2020
BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_ATTRIBUTES(bridgedDeviceBasicAttrs);
21-
IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs);
2221
}; /* namespace */
2322

2423
using namespace ::chip;
@@ -36,8 +35,7 @@ DECLARE_DYNAMIC_CLUSTER(Clusters::Switch::Id, switchAttr, ZAP_CLUSTER_MASK(SERVE
3635
DECLARE_DYNAMIC_CLUSTER(Clusters::Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
3736
DECLARE_DYNAMIC_CLUSTER(Clusters::BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs,
3837
ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
39-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(SERVER),
40-
sIdentifyIncomingCommands, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;
38+
DECLARE_DYNAMIC_CLUSTER_LIST_END;
4139

4240
DECLARE_DYNAMIC_ENDPOINT(bridgedGenericSwitchEndpoint, genericSwitchClusters);
4341

applications/matter_bridge/src/bridged_device_types/humidity_sensor.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace
1010
{
1111
DESCRIPTOR_CLUSTER_ATTRIBUTES(descriptorAttrs);
1212
BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_ATTRIBUTES(bridgedDeviceBasicAttrs);
13-
IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs);
1413
}; /* namespace */
1514

1615
using namespace ::chip;
@@ -32,8 +31,7 @@ DECLARE_DYNAMIC_CLUSTER(Clusters::RelativeHumidityMeasurement::Id, humiSensorAtt
3231
DECLARE_DYNAMIC_CLUSTER(Clusters::Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
3332
DECLARE_DYNAMIC_CLUSTER(Clusters::BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs,
3433
ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
35-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(SERVER),
36-
sIdentifyIncomingCommands, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;
34+
DECLARE_DYNAMIC_CLUSTER_LIST_END;
3735

3836
DECLARE_DYNAMIC_ENDPOINT(bridgedHumidityEndpoint, bridgedHumidityClusters);
3937

applications/matter_bridge/src/bridged_device_types/onoff_light.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@ namespace
1616
{
1717
DESCRIPTOR_CLUSTER_ATTRIBUTES(descriptorAttrs);
1818
BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_ATTRIBUTES(bridgedDeviceBasicAttrs);
19-
IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs);
2019
}; /* namespace */
2120

2221
using namespace ::chip;
2322
using namespace ::chip::app;
2423
using namespace Nrf;
2524

26-
constexpr CommandId identifyIncomingCommands[] = {
27-
app::Clusters::Identify::Commands::Identify::Id,
28-
app::Clusters::Identify::Commands::TriggerEffect::Id,
29-
kInvalidCommandId,
30-
};
31-
3225
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(onOffAttrs)
3326
DECLARE_DYNAMIC_ATTRIBUTE(Clusters::OnOff::Attributes::OnOff::Id, BOOLEAN, 1, 0),
3427
DECLARE_DYNAMIC_ATTRIBUTE(Clusters::OnOff::Attributes::FeatureMap::Id, BITMAP32, 4, 0),
@@ -80,8 +73,7 @@ DECLARE_DYNAMIC_CLUSTER(Clusters::OnOff::Id, onOffAttrs, ZAP_CLUSTER_MASK(SERVER
8073
groupsGeneratedCommands),
8174
DECLARE_DYNAMIC_CLUSTER(Clusters::BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs,
8275
ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
83-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(SERVER),
84-
identifyIncomingCommands, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;
76+
DECLARE_DYNAMIC_CLUSTER_LIST_END;
8577

8678
DECLARE_DYNAMIC_ENDPOINT(bridgedLightEndpoint, bridgedLightClusters);
8779

applications/matter_bridge/src/bridged_device_types/onoff_light_switch.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ namespace
1616
{
1717
DESCRIPTOR_CLUSTER_ATTRIBUTES(descriptorAttrs);
1818
BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_ATTRIBUTES(bridgedDeviceBasicAttrs);
19-
IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs);
2019
}; /* namespace */
2120

2221
using namespace ::chip;
@@ -46,10 +45,6 @@ DECLARE_DYNAMIC_CLUSTER(Clusters::OnOff::Id, onOffClientAttrs, ZAP_CLUSTER_MASK(
4645
DECLARE_DYNAMIC_CLUSTER(Clusters::Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
4746
DECLARE_DYNAMIC_CLUSTER(Clusters::BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs,
4847
ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
49-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(SERVER),
50-
sIdentifyIncomingCommands, nullptr),
51-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(CLIENT),
52-
sIdentifyIncomingCommands, nullptr),
5348
DECLARE_DYNAMIC_CLUSTER(Clusters::Binding::Id, bindingAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr,
5449
nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;
5550

applications/matter_bridge/src/bridged_device_types/temperature_sensor.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace
1010
{
1111
DESCRIPTOR_CLUSTER_ATTRIBUTES(descriptorAttrs);
1212
BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_ATTRIBUTES(bridgedDeviceBasicAttrs);
13-
IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs);
1413
}; /* namespace */
1514

1615
using namespace ::chip;
@@ -28,8 +27,7 @@ DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedTemperatureClusters)
2827
DECLARE_DYNAMIC_CLUSTER(Clusters::TemperatureMeasurement::Id, tempSensorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
2928
DECLARE_DYNAMIC_CLUSTER(Clusters::Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
3029
DECLARE_DYNAMIC_CLUSTER(Clusters::BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
31-
DECLARE_DYNAMIC_CLUSTER(Clusters::Identify::Id, identifyAttrs, ZAP_CLUSTER_MASK(SERVER), sIdentifyIncomingCommands,
32-
nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;
30+
DECLARE_DYNAMIC_CLUSTER_LIST_END;
3331

3432
DECLARE_DYNAMIC_ENDPOINT(bridgedTemperatureEndpoint, bridgedTemperatureClusters);
3533

applications/matter_bridge/src/core/matter_bridged_device.cpp

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
#include "matter_bridged_device.h"
88
#include <app-common/zap-generated/callback.h>
9+
#include <app/AttributeValueDecoder.h>
10+
#include <app/clusters/identify-server/IdentifyCluster.h>
11+
#include <app/data-model/Encode.h>
12+
#include <lib/core/TLVReader.h>
13+
#include <lib/core/TLVWriter.h>
914
#include <lib/support/ZclString.h>
1015

1116
using namespace ::chip;
@@ -85,12 +90,42 @@ CHIP_ERROR MatterBridgedDevice::HandleWriteIdentify(chip::AttributeId attributeI
8590
{
8691
switch (attributeId) {
8792
case Clusters::Identify::Attributes::IdentifyTime::Id:
88-
if (data && dataSize == sizeof(mIdentifyTime)) {
89-
memcpy(&mIdentifyTime, data, sizeof(mIdentifyTime));
90-
/* Externally stored attribute was updated, now we need to notify identify-server to
91-
leverage the Identify cluster implementation */
92-
app::ConcreteAttributePath attributePath{ mEndpointId, Clusters::Identify::Id, attributeId };
93-
MatterIdentifyClusterServerAttributeChangedCallback(attributePath);
93+
if (data && dataSize == sizeof(uint16_t)) {
94+
uint16_t identifyTime = *reinterpret_cast<uint16_t *>(data);
95+
96+
uint8_t tlvBuffer[64];
97+
TLV::TLVWriter writer;
98+
writer.Init(tlvBuffer, sizeof(tlvBuffer));
99+
100+
TLV::TLVType outerContainerType;
101+
ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure,
102+
outerContainerType));
103+
ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(1), identifyTime));
104+
ReturnErrorOnFailure(writer.EndContainer(outerContainerType));
105+
ReturnErrorOnFailure(writer.Finalize());
106+
107+
TLV::TLVReader reader;
108+
reader.Init(tlvBuffer, writer.GetLengthWritten());
109+
ReturnErrorOnFailure(reader.Next());
110+
ReturnErrorOnFailure(reader.EnterContainer(outerContainerType));
111+
ReturnErrorOnFailure(reader.Next());
112+
113+
Access::SubjectDescriptor subjectDescriptor;
114+
subjectDescriptor.fabricIndex = kUndefinedFabricIndex;
115+
subjectDescriptor.authMode = Access::AuthMode::kNone;
116+
117+
AttributeValueDecoder decoder(reader, subjectDescriptor);
118+
119+
DataModel::WriteAttributeRequest request;
120+
request.path.mEndpointId = mEndpointId;
121+
request.path.mClusterId = Clusters::Identify::Id;
122+
request.path.mAttributeId = attributeId;
123+
request.subjectDescriptor = &subjectDescriptor;
124+
125+
DataModel::ActionReturnStatus status = mIdentifyCluster.Cluster().WriteAttribute(request, decoder);
126+
if (!status.IsSuccess()) {
127+
return status.GetUnderlyingError();
128+
}
94129
return CHIP_NO_ERROR;
95130
}
96131
default:
@@ -111,11 +146,12 @@ CHIP_ERROR MatterBridgedDevice::HandleReadIdentify(chip::AttributeId attributeId
111146
return CopyAttribute(&featureMap, sizeof(featureMap), buffer, maxReadLength);
112147
}
113148
case Clusters::Identify::Attributes::IdentifyType::Id: {
114-
MatterBridgedDevice::IdentifyType type = mIdentifyServer.mIdentifyType;
149+
MatterBridgedDevice::IdentifyType type = mIdentifyCluster.Cluster().GetIdentifyType();
115150
return CopyAttribute(&type, sizeof(type), buffer, maxReadLength);
116151
}
117152
case Clusters::Identify::Attributes::IdentifyTime::Id: {
118-
return CopyAttribute(&mIdentifyTime, sizeof(mIdentifyTime), buffer, maxReadLength);
153+
uint16_t identifyTime = mIdentifyCluster.Cluster().GetIdentifyTime();
154+
return CopyAttribute(&identifyTime, sizeof(identifyTime), buffer, maxReadLength);
119155
}
120156
default:
121157
return CHIP_ERROR_INVALID_ARGUMENT;

applications/matter_bridge/src/core/matter_bridged_device.h

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66

77
#pragma once
88

9+
#include "app/server-cluster/ServerClusterInterfaceRegistry.h"
10+
#include "data-model-providers/codegen/CodegenDataModelProvider.h"
911
#include <app-common/zap-generated/ids/Attributes.h>
1012
#include <app-common/zap-generated/ids/Clusters.h>
11-
#include <app/clusters/identify-server/identify-server.h>
13+
#include <app/AttributeAccessInterfaceRegistry.h>
14+
#include <app/CommandHandlerInterfaceRegistry.h>
15+
#include <app/DefaultTimerDelegate.h>
16+
#include <app/clusters/identify-server/IdentifyCluster.h>
1217
#include <app/util/attribute-storage.h>
1318
#include <platform/ConfigurationManager.h>
1419

@@ -52,36 +57,33 @@ namespace Nrf
5257
0), /* feature map */ \
5358
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
5459

55-
/* Declare Bridged Device Identify cluster attributes */
60+
/* Codedriven delegate for the Identify cluster */
61+
class IdentifyBridgedDeviceDelegateImpl : public chip::app::Clusters::IdentifyDelegate {
62+
public:
63+
void OnIdentifyStart(chip::app::Clusters::IdentifyCluster &cluster) override
64+
{
65+
ChipLogError(DeviceLayer, "Starting bridged device identify on endpoint %d",
66+
cluster.GetPaths()[0].mEndpointId);
67+
}
5668

57-
constexpr chip::CommandId sIdentifyIncomingCommands[] = {
58-
chip::app::Clusters::Identify::Commands::Identify::Id,
59-
chip::kInvalidCommandId,
60-
};
69+
void OnIdentifyStop(chip::app::Clusters::IdentifyCluster &cluster) override
70+
{
71+
ChipLogError(DeviceLayer, "Stopping bridged device identify on endpoint %d",
72+
cluster.GetPaths()[0].mEndpointId);
73+
mIsTriggerEffectEnabled = false;
74+
}
6175

62-
#define IDENTIFY_CLUSTER_ATTRIBUTES(identifyAttrs) \
63-
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(identifyAttrs) \
64-
DECLARE_DYNAMIC_ATTRIBUTE(chip::app::Clusters::Identify::Attributes::IdentifyTime::Id, INT16U, 2, \
65-
ZAP_ATTRIBUTE_MASK(WRITABLE)), /* identify time*/ \
66-
DECLARE_DYNAMIC_ATTRIBUTE(chip::app::Clusters::Identify::Attributes::IdentifyType::Id, ENUM8, 1, \
67-
0), /* identify type */ \
68-
DECLARE_DYNAMIC_ATTRIBUTE(chip::app::Clusters::Identify::Attributes::FeatureMap::Id, BITMAP32, 4, \
69-
0), /* feature map */ \
70-
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
76+
void OnTriggerEffect(chip::app::Clusters::IdentifyCluster &cluster) override
77+
{
78+
ChipLogError(DeviceLayer, "Triggering effect on endpoint %d", cluster.GetPaths()[0].mEndpointId);
79+
mIsTriggerEffectEnabled = true;
80+
}
7181

72-
inline void IdentifyStartDefaultCb(Identify *identify)
73-
{
74-
VerifyOrReturn(identify);
75-
ChipLogProgress(DeviceLayer, "Starting bridged device identify on endpoint %d",
76-
identify->mCluster.Cluster().GetPaths()[0].mEndpointId);
77-
}
82+
bool IsTriggerEffectEnabled() const override { return mIsTriggerEffectEnabled; }
7883

79-
inline void IdentifyStopDefaultCb(Identify *identify)
80-
{
81-
VerifyOrReturn(identify);
82-
ChipLogProgress(DeviceLayer, "Stopping bridged device identify on endpoint %d",
83-
identify->mCluster.Cluster().GetPaths()[0].mEndpointId);
84-
}
84+
private:
85+
bool mIsTriggerEffectEnabled = false;
86+
};
8587

8688
class MatterBridgedDevice {
8789
public:
@@ -100,8 +102,14 @@ class MatterBridgedDevice {
100102
static constexpr uint8_t kDescriptorAttributeArraySize = 254;
101103

102104
explicit MatterBridgedDevice(const char *uniqueID, const char *nodeLabel)
103-
: mIdentifyServer(mEndpointId, IdentifyStartDefaultCb, IdentifyStopDefaultCb,
104-
IdentifyType::kVisibleIndicator)
105+
/* TODO: Currently the mEndpointId cannot be used here because it is initialized later.
106+
* We need to refactor this construtor to initialize the mEndpointId here.
107+
* Ref: KRKNWK-21020
108+
*/
109+
: mIdentifyCluster(
110+
chip::app::Clusters::IdentifyCluster::Config(mEndpointId, mTimerDelegate)
111+
.WithIdentifyType(chip::app::Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator)
112+
.WithDelegate(&mIdentifyDelegate))
105113
{
106114
if (uniqueID) {
107115
memcpy(mUniqueID, uniqueID, strnlen(uniqueID, Nrf::MatterBridgedDevice::kUniqueIDSize));
@@ -112,7 +120,17 @@ class MatterBridgedDevice {
112120
}
113121
virtual ~MatterBridgedDevice() { chip::Platform::MemoryFree(mDataVersion); }
114122

115-
void Init(chip::EndpointId endpoint) {}
123+
void Init(chip::EndpointId endpoint)
124+
{
125+
mEndpointId = endpoint;
126+
127+
CHIP_ERROR err = chip::app::CodegenDataModelProvider::Instance().Registry().Register(
128+
mIdentifyCluster.Registration());
129+
if (err != CHIP_NO_ERROR) {
130+
ChipLogError(DeviceLayer, "Failed to register Identify cluster: %s", ErrorStr(err));
131+
}
132+
}
133+
116134
chip::EndpointId GetEndpointId() const { return mEndpointId; }
117135

118136
virtual uint16_t GetDeviceType() const = 0;
@@ -156,8 +174,9 @@ class MatterBridgedDevice {
156174
bool mIsReachable = true;
157175
char mUniqueID[kUniqueIDSize] = "";
158176
char mNodeLabel[kNodeLabelSize] = "";
159-
Identify mIdentifyServer;
160-
uint16_t mIdentifyTime{};
177+
chip::app::RegisteredServerCluster<chip::app::Clusters::IdentifyCluster> mIdentifyCluster;
178+
chip::app::DefaultTimerDelegate mTimerDelegate;
179+
IdentifyBridgedDeviceDelegateImpl mIdentifyDelegate;
161180
};
162181

163182
} /* namespace Nrf */

0 commit comments

Comments
 (0)