@@ -46,6 +46,77 @@ using namespace chip::app::Clusters;
46
46
namespace {
47
47
48
48
constexpr uint8_t kMaxRetries = 10 ;
49
+ constexpr int kNodeLabelSize = 32 ;
50
+
51
+ // Current ZCL implementation of Struct uses a max-size array of 254 bytes
52
+ constexpr int kDescriptorAttributeArraySize = 254 ;
53
+
54
+ // ENDPOINT DEFINITIONS:
55
+ // =================================================================================
56
+ //
57
+ // Endpoint definitions will be reused across multiple endpoints for every instance of the
58
+ // endpoint type.
59
+ // There will be no intrinsic storage for the endpoint attributes declared here.
60
+ // Instead, all attributes will be treated as EXTERNAL, and therefore all reads
61
+ // or writes to the attributes must be handled within the emberAfExternalAttributeWriteCallback
62
+ // and emberAfExternalAttributeReadCallback functions declared herein. This fits
63
+ // the typical model of a bridge, since a bridge typically maintains its own
64
+ // state database representing the devices connected to it.
65
+
66
+ // (taken from matter-devices.xml)
67
+ #define DEVICE_TYPE_BRIDGED_NODE 0x0013
68
+
69
+ // Device Version for dynamic endpoints:
70
+ #define DEVICE_VERSION_DEFAULT 1
71
+
72
+ // ---------------------------------------------------------------------------
73
+ //
74
+ // SYNCED DEVICE ENDPOINT: contains the following clusters:
75
+ // - Descriptor
76
+ // - Bridged Device Basic Information
77
+ // - Administrator Commissioning
78
+
79
+ // Declare Descriptor cluster attributes
80
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN (descriptorAttrs)
81
+ DECLARE_DYNAMIC_ATTRIBUTE (Descriptor::Attributes::DeviceTypeList::Id, ARRAY, kDescriptorAttributeArraySize , 0 ), /* device list */
82
+ DECLARE_DYNAMIC_ATTRIBUTE (Descriptor::Attributes::ServerList::Id, ARRAY, kDescriptorAttributeArraySize , 0 ), /* server list */
83
+ DECLARE_DYNAMIC_ATTRIBUTE (Descriptor::Attributes::ClientList::Id, ARRAY, kDescriptorAttributeArraySize , 0 ), /* client list */
84
+ DECLARE_DYNAMIC_ATTRIBUTE (Descriptor::Attributes::PartsList::Id, ARRAY, kDescriptorAttributeArraySize , 0 ), /* parts list */
85
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_END ();
86
+
87
+ // Declare Bridged Device Basic Information cluster attributes
88
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN (bridgedDeviceBasicAttrs)
89
+ DECLARE_DYNAMIC_ATTRIBUTE (BridgedDeviceBasicInformation::Attributes::NodeLabel::Id, CHAR_STRING, kNodeLabelSize , 0 ), /* NodeLabel */
90
+ DECLARE_DYNAMIC_ATTRIBUTE (BridgedDeviceBasicInformation::Attributes::Reachable::Id, BOOLEAN, 1 , 0 ), /* Reachable */
91
+ DECLARE_DYNAMIC_ATTRIBUTE (BridgedDeviceBasicInformation::Attributes::FeatureMap::Id, BITMAP32, 4 , 0 ), /* feature map */
92
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_END ();
93
+
94
+ // Declare Administrator Commissioning cluster attributes
95
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN (AdministratorCommissioningAttrs)
96
+ DECLARE_DYNAMIC_ATTRIBUTE (AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1 , 0 ), /* NodeLabel */
97
+ DECLARE_DYNAMIC_ATTRIBUTE (AdministratorCommissioning::Attributes::AdminFabricIndex::Id, FABRIC_IDX, 1 , 0 ), /* Reachable */
98
+ DECLARE_DYNAMIC_ATTRIBUTE (AdministratorCommissioning::Attributes::AdminVendorId::Id, VENDOR_ID, 2 , 0 ), /* Reachable */
99
+ DECLARE_DYNAMIC_ATTRIBUTE_LIST_END ();
100
+
101
+ constexpr CommandId administratorCommissioningCommands[] = {
102
+ app::Clusters::AdministratorCommissioning::Commands::OpenCommissioningWindow::Id,
103
+ app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Id,
104
+ app::Clusters::AdministratorCommissioning::Commands::RevokeCommissioning::Id,
105
+ kInvalidCommandId ,
106
+ };
107
+
108
+ // Declare Cluster List for Bridged Node endpoint
109
+ DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN (bridgedNodeClusters)
110
+ DECLARE_DYNAMIC_CLUSTER (Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr , nullptr ),
111
+ DECLARE_DYNAMIC_CLUSTER (BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr , nullptr ),
112
+ DECLARE_DYNAMIC_CLUSTER (AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER),
113
+ administratorCommissioningCommands, nullptr ) DECLARE_DYNAMIC_CLUSTER_LIST_END;
114
+
115
+ // Declare Bridged Node endpoint
116
+ DECLARE_DYNAMIC_ENDPOINT (sBridgedNodeEndpoint , bridgedNodeClusters);
117
+ DataVersion sBridgedNodeDataVersions [ArraySize(bridgedNodeClusters)];
118
+
119
+ const EmberAfDeviceType sBridgedDeviceTypes [] = { { DEVICE_TYPE_BRIDGED_NODE, DEVICE_VERSION_DEFAULT } };
49
120
50
121
} // namespace
51
122
@@ -60,11 +131,13 @@ void DeviceManager::Init()
60
131
mCurrentEndpointId = mFirstDynamicEndpointId ;
61
132
}
62
133
63
- int DeviceManager::AddDeviceEndpoint (Device * dev, EmberAfEndpointType * ep,
64
- const chip::Span<const EmberAfDeviceType> & deviceTypeList,
65
- const chip::Span<chip::DataVersion> & dataVersionStorage, chip::EndpointId parentEndpointId)
134
+ int DeviceManager::AddDeviceEndpoint (Device * dev, chip::EndpointId parentEndpointId)
66
135
{
67
- uint8_t index = 0 ;
136
+ uint8_t index = 0 ;
137
+ EmberAfEndpointType * ep = &sBridgedNodeEndpoint ;
138
+ const chip::Span<const EmberAfDeviceType> & deviceTypeList = Span<const EmberAfDeviceType>(sBridgedDeviceTypes );
139
+ const chip::Span<chip::DataVersion> & dataVersionStorage = Span<DataVersion>(sBridgedNodeDataVersions );
140
+
68
141
while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
69
142
{
70
143
if (nullptr == mDevices [index ])
@@ -81,8 +154,9 @@ int DeviceManager::AddDeviceEndpoint(Device * dev, EmberAfEndpointType * ep,
81
154
emberAfSetDynamicEndpoint (index , mCurrentEndpointId , ep, dataVersionStorage, deviceTypeList, parentEndpointId);
82
155
if (err == CHIP_NO_ERROR)
83
156
{
84
- ChipLogProgress (NotSpecified, " Added device %s to dynamic endpoint %d (index=%d)" , dev->GetName (),
85
- mCurrentEndpointId , index );
157
+ ChipLogProgress (NotSpecified,
158
+ " Added device with nodeId=0x" ChipLogFormatX64 " to dynamic endpoint %d (index=%d)" ,
159
+ ChipLogValueX64 (dev->GetNodeId ()), mCurrentEndpointId , index );
86
160
return index ;
87
161
}
88
162
if (err != CHIP_ERROR_ENDPOINT_EXISTS)
@@ -125,11 +199,43 @@ int DeviceManager::RemoveDeviceEndpoint(Device * dev)
125
199
return -1 ;
126
200
}
127
201
128
- Device * DeviceManager::GetDevice (uint16_t index) const
202
+ Device * DeviceManager::GetDevice (chip::EndpointId endpointId) const
203
+ {
204
+ for (uint8_t index = 0 ; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index )
205
+ {
206
+ if (mDevices [index ] && mDevices [index ]->GetEndpointId () == endpointId)
207
+ {
208
+ return mDevices [index ];
209
+ }
210
+ }
211
+ return nullptr ;
212
+ }
213
+
214
+ Device * DeviceManager::GetDeviceByNodeId (chip::NodeId nodeId) const
129
215
{
130
- if ( index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
216
+ for ( uint8_t index = 0 ; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++ index )
131
217
{
132
- return mDevices [index ];
218
+ if (mDevices [index ] && mDevices [index ]->GetNodeId () == nodeId)
219
+ {
220
+ return mDevices [index ];
221
+ }
133
222
}
134
223
return nullptr ;
135
224
}
225
+
226
+ int DeviceManager::RemoveDeviceByNodeId (chip::NodeId nodeId)
227
+ {
228
+ for (uint8_t index = 0 ; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index )
229
+ {
230
+ if (mDevices [index ] && mDevices [index ]->GetNodeId () == nodeId)
231
+ {
232
+ DeviceLayer::StackLock lock;
233
+ EndpointId ep = emberAfClearDynamicEndpoint (index );
234
+ mDevices [index ] = nullptr ;
235
+ ChipLogProgress (NotSpecified, " Removed device with NodeId=0x" ChipLogFormatX64 " from dynamic endpoint %d (index=%d)" ,
236
+ ChipLogValueX64 (nodeId), ep, index );
237
+ return index ;
238
+ }
239
+ }
240
+ return -1 ;
241
+ }
0 commit comments