19
19
* @brief Implementation for the Power Source Server Cluster
20
20
***************************************************************************/
21
21
22
+ #include " power-source-server.h"
23
+
22
24
#include < app-common/zap-generated/cluster-objects.h>
23
25
#include < app-common/zap-generated/ids/Attributes.h>
24
- #include < app-common/zap-generated/ids/Clusters.h>
25
- #include < app/AttributeAccessInterface.h>
26
26
#include < app/util/attribute-storage.h>
27
27
#include < lib/support/CodeUtils.h>
28
28
#include < lib/support/logging/CHIPLogging.h>
29
+ #include < zap-generated/gen_config.h>
29
30
30
31
using namespace chip ;
31
- using namespace chip :: app;
32
- using namespace chip :: app::Clusters;
33
- using namespace chip :: app::Clusters::PowerSource::Attributes;
32
+ using namespace app ;
33
+ using namespace app ::Clusters;
34
+ using namespace app ::Clusters::PowerSource::Attributes;
34
35
35
36
namespace {
36
37
37
- class PowerSourceAttrAccess : public AttributeAccessInterface
38
+ struct PowerSourceClusterInfo
38
39
{
39
- public:
40
- // Register on all endpoints.
41
- PowerSourceAttrAccess () : AttributeAccessInterface(Optional<EndpointId>::Missing(), PowerSource::Id) {}
42
-
43
- CHIP_ERROR Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override ;
40
+ PowerSourceClusterInfo () : mClusterEndpoint (kInvalidEndpointId ) {}
41
+ explicit PowerSourceClusterInfo (EndpointId powerClusterEndpointId) : mClusterEndpoint(powerClusterEndpointId) {}
42
+ void Clear ()
43
+ {
44
+ mBuf .Free ();
45
+ mEndpointList = Span<EndpointId>();
46
+ }
47
+ CHIP_ERROR SetEndpointList (Span<EndpointId> endpointList)
48
+ {
49
+ Clear ();
50
+ if (endpointList.size () == 0 )
51
+ {
52
+ mEndpointList = Span<EndpointId>();
53
+ return CHIP_NO_ERROR;
54
+ }
55
+ mBuf .Calloc (endpointList.size ());
56
+ if (mBuf .Get () == nullptr )
57
+ {
58
+ return CHIP_ERROR_NO_MEMORY;
59
+ }
60
+ memcpy (mBuf .Get (), endpointList.data (), endpointList.size () * sizeof (EndpointId));
61
+ mEndpointList = Span<EndpointId>(mBuf .Get (), endpointList.size ());
62
+ return CHIP_NO_ERROR;
63
+ }
64
+ EndpointId mClusterEndpoint = kInvalidEndpointId ;
65
+ Platform::ScopedMemoryBuffer<EndpointId> mBuf ;
66
+ Span<EndpointId> mEndpointList ;
44
67
};
45
68
69
+ PowerSourceServer gPowerSourceServer ;
70
+
46
71
PowerSourceAttrAccess gAttrAccess ;
47
72
73
+ #ifdef ZCL_USING_POWER_SOURCE_CLUSTER_SERVER
74
+ #define POWER_SERVER_NUM_SUPPORTED_ENDPOINTS \
75
+ (EMBER_AF_POWER_SOURCE_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT)
76
+ #else
77
+ #define POWER_SERVER_NUM_SUPPORTED_ENDPOINTS CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT
78
+ #endif
79
+ static constexpr size_t kNumSupportedEndpoints = POWER_SERVER_NUM_SUPPORTED_ENDPOINTS;
80
+
81
+ #if POWER_SERVER_NUM_SUPPORTED_ENDPOINTS > 0
82
+ PowerSourceClusterInfo sPowerSourceClusterInfo [kNumSupportedEndpoints ] = {};
83
+ #else
84
+ PowerSourceClusterInfo * sPowerSourceClusterInfo = nullptr ;
85
+ #endif
86
+
87
+ } // anonymous namespace
88
+
89
+ void MatterPowerSourcePluginServerInitCallback ()
90
+ {
91
+ registerAttributeAccessOverride (&gAttrAccess );
92
+ }
93
+
94
+ namespace chip {
95
+ namespace app {
96
+ namespace Clusters {
97
+
48
98
CHIP_ERROR PowerSourceAttrAccess::Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
49
99
{
50
100
CHIP_ERROR err = CHIP_NO_ERROR;
@@ -55,20 +105,117 @@ CHIP_ERROR PowerSourceAttrAccess::Read(const ConcreteReadAttributePath & aPath,
55
105
// TODO: Needs implementation.
56
106
err = aEncoder.EncodeEmptyList ();
57
107
break ;
58
- case EndpointList::Id:
59
- // TODO: Needs implementation and a way to allow dynamic endpoints to register endpoints
60
- err = aEncoder.EncodeEmptyList ();
108
+ case EndpointList::Id: {
109
+ PowerSourceServer & server = PowerSourceServer::Instance ();
110
+ const Span<EndpointId> * span = server.GetEndpointList (aPath.mEndpointId );
111
+ if (span == nullptr )
112
+ {
113
+ err = aEncoder.EncodeEmptyList ();
114
+ }
115
+ else
116
+ {
117
+ err = aEncoder.EncodeList ([span](const auto & encoder) -> CHIP_ERROR {
118
+ for (auto id : *span)
119
+ {
120
+ ReturnErrorOnFailure (encoder.Encode (id));
121
+ }
122
+ return CHIP_NO_ERROR;
123
+ });
124
+ }
61
125
break ;
126
+ }
62
127
default :
63
128
break ;
64
129
}
65
130
66
131
return err;
67
132
}
68
133
69
- } // anonymous namespace
134
+ PowerSourceAttrAccess & TestOnlyGetPowerSourceAttrAccess ()
135
+ {
136
+ return gAttrAccess ;
137
+ }
70
138
71
- void MatterPowerSourcePluginServerInitCallback ()
139
+ PowerSourceServer & PowerSourceServer::Instance ()
72
140
{
73
- registerAttributeAccessOverride (&gAttrAccess );
141
+ return gPowerSourceServer ;
142
+ }
143
+
144
+ // Caller does not need to retain the span past the call point as these are copied into an internal storage
145
+ CHIP_ERROR PowerSourceServer::SetEndpointList (EndpointId powerSourceClusterEndpoint, Span<EndpointId> endpointList)
146
+ {
147
+ // TODO: should check here that the power source cluster exists on the endpoint, but for now let's take the caller's word
148
+ // for it
149
+
150
+ size_t idx = PowerSourceClusterEndpointIndex (powerSourceClusterEndpoint);
151
+ if (idx >= kNumSupportedEndpoints )
152
+ {
153
+ idx = NextEmptyIndex ();
154
+ }
155
+ if (idx >= kNumSupportedEndpoints )
156
+ {
157
+ return CHIP_ERROR_NO_MEMORY;
158
+ }
159
+
160
+ sPowerSourceClusterInfo [idx].Clear ();
161
+ if (endpointList.size () == 0 )
162
+ {
163
+ sPowerSourceClusterInfo [idx] = PowerSourceClusterInfo ();
164
+ }
165
+ else
166
+ {
167
+ sPowerSourceClusterInfo [idx] = PowerSourceClusterInfo (powerSourceClusterEndpoint);
168
+ sPowerSourceClusterInfo [idx].SetEndpointList (endpointList);
169
+ }
170
+ return CHIP_NO_ERROR;
171
+ }
172
+ const Span<EndpointId> * PowerSourceServer::GetEndpointList (EndpointId powerSourceClusterEndpoint) const
173
+ {
174
+ size_t idx = PowerSourceClusterEndpointIndex (powerSourceClusterEndpoint);
175
+ if (idx != std::numeric_limits<size_t >::max ())
176
+ {
177
+ return &sPowerSourceClusterInfo [idx].mEndpointList ;
178
+ }
179
+ return nullptr ;
180
+ }
181
+
182
+ void PowerSourceServer::Shutdown ()
183
+ {
184
+ for (size_t i = 0 ; i < kNumSupportedEndpoints ; ++i)
185
+ {
186
+ sPowerSourceClusterInfo [i].Clear ();
187
+ }
188
+ }
189
+
190
+ size_t PowerSourceServer::GetNumSupportedEndpointLists () const
191
+ {
192
+ return kNumSupportedEndpoints ;
74
193
}
194
+
195
+ size_t PowerSourceServer::PowerSourceClusterEndpointIndex (EndpointId endpointId) const
196
+ {
197
+ for (size_t i = 0 ; i < kNumSupportedEndpoints ; ++i)
198
+ {
199
+ if (sPowerSourceClusterInfo [i].mClusterEndpoint == endpointId)
200
+ {
201
+ return i;
202
+ }
203
+ }
204
+ return std::numeric_limits<size_t >::max ();
205
+ }
206
+
207
+ size_t PowerSourceServer::NextEmptyIndex () const
208
+ {
209
+ for (size_t i = 0 ; i < kNumSupportedEndpoints ; ++i)
210
+ {
211
+ if (sPowerSourceClusterInfo [i].mClusterEndpoint == kInvalidEndpointId )
212
+ {
213
+ return i;
214
+ }
215
+ }
216
+ return std::numeric_limits<size_t >::max ();
217
+ }
218
+
219
+ } // namespace Clusters
220
+ } // namespace app
221
+ } // namespace chip
0 commit comments