@@ -35,13 +35,85 @@ using namespace chip::app::Clusters::MeterIdentification::Attributes;
35
35
36
36
using chip::Protocols::InteractionModel::Status;
37
37
38
+ namespace {
39
+ bool NullableCharSpanCompare (const DataModel::Nullable<CharSpan> & a, const DataModel::Nullable<CharSpan> & b)
40
+ {
41
+ if (a.IsNull () && b.IsNull ())
42
+ {
43
+ return true ;
44
+ }
45
+
46
+ if (!a.IsNull () && !b.IsNull ())
47
+ {
48
+ return a.Value ().data_equal (b.Value ());
49
+ }
50
+
51
+ return false ;
52
+ }
53
+
54
+ CHIP_ERROR NullableCharSpanCopy (DataModel::Nullable<CharSpan> & dst, const DataModel::Nullable<CharSpan> & src)
55
+ {
56
+ const size_t len = src.IsNull () ? 0 : src.Value ().size ();
57
+ if (64 < len)
58
+ {
59
+ return CHIP_ERROR_INVALID_STRING_LENGTH;
60
+ }
61
+
62
+ if (!dst.IsNull ())
63
+ {
64
+ chip::Platform::MemoryFree (const_cast <char *>(dst.Value ().data ()));
65
+ dst.SetNull ();
66
+ }
67
+
68
+ if (!src.IsNull ())
69
+ {
70
+ if (auto * str = static_cast <char *>(chip::Platform::MemoryAlloc (1 + len)))
71
+ {
72
+ memcpy (str, src.Value ().data (), len);
73
+ str[len] = 0 ;
74
+ dst = MakeNullable (CharSpan (str, len));
75
+ }
76
+ else
77
+ {
78
+ return CHIP_ERROR_NO_MEMORY;
79
+ }
80
+ }
81
+
82
+ return CHIP_NO_ERROR;
83
+ }
84
+ } // namespace
85
+
38
86
namespace chip {
39
87
namespace app {
40
88
namespace Clusters {
41
89
namespace MeterIdentification {
42
90
91
+ Instance::~Instance ()
92
+ {
93
+ Shutdown ();
94
+ if (!mPointOfDelivery .IsNull ())
95
+ {
96
+ chip::Platform::MemoryFree (const_cast <char *>(mPointOfDelivery .Value ().data ()));
97
+ }
98
+ if (!mMeterSerialNumber .IsNull ())
99
+ {
100
+ chip::Platform::MemoryFree (const_cast <char *>(mMeterSerialNumber .Value ().data ()));
101
+ }
102
+ if (!mProtocolVersion .IsNull ())
103
+ {
104
+ chip::Platform::MemoryFree (const_cast <char *>(mProtocolVersion .Value ().data ()));
105
+ }
106
+ }
107
+
43
108
CHIP_ERROR Instance::Init ()
44
109
{
110
+ // Check if the cluster has been selected in zap
111
+ VerifyOrDie (emberAfContainsServer (mEndpointId , Id));
112
+ SetMeterType (std::nullopt);
113
+ SetPointOfDelivery (std::nullopt);
114
+ SetMeterSerialNumber (std::nullopt);
115
+ SetProtocolVersion (std::nullopt);
116
+ SetPowerThreshold (std::nullopt);
45
117
VerifyOrReturnError (AttributeAccessInterfaceRegistry::Instance ().Register (this ), CHIP_ERROR_INCORRECT_STATE);
46
118
return CHIP_NO_ERROR;
47
119
}
@@ -56,6 +128,114 @@ bool Instance::HasFeature(const Feature & aFeature) const
56
128
return mFeature .Has (aFeature);
57
129
}
58
130
131
+ CHIP_ERROR Instance::SetMeterType (const DataModel::Nullable<MeterTypeEnum> & newValue)
132
+ {
133
+ if (newValue.IsNull ())
134
+ {
135
+ if (mMeterType .IsNull ())
136
+ {
137
+ return CHIP_NO_ERROR;
138
+ }
139
+
140
+ mMeterType .SetNull ();
141
+ }
142
+ else
143
+ {
144
+ if (!mMeterType .IsNull () && mMeterType .Value () == newValue.Value ())
145
+ {
146
+ return CHIP_NO_ERROR;
147
+ }
148
+
149
+ if (MeterTypeEnum::kUnknownEnumValue == EnsureKnownEnumValue (newValue.Value ()))
150
+ {
151
+ return CHIP_ERROR_INVALID_INTEGER_VALUE;
152
+ }
153
+
154
+ mMeterType .SetNonNull (newValue.Value ());
155
+ }
156
+
157
+ MatterReportingAttributeChangeCallback (mEndpointId , MeterIdentification::Id, MeterType::Id);
158
+ return CHIP_NO_ERROR;
159
+ }
160
+
161
+ CHIP_ERROR Instance::SetPointOfDelivery (const DataModel::Nullable<CharSpan> & newValue)
162
+ {
163
+ if (NullableCharSpanCompare (newValue, mPointOfDelivery ))
164
+ {
165
+ return CHIP_NO_ERROR;
166
+ }
167
+
168
+ const CHIP_ERROR ret = NullableCharSpanCopy (mPointOfDelivery , newValue);
169
+ if (CHIP_NO_ERROR == ret)
170
+ {
171
+ MatterReportingAttributeChangeCallback (mEndpointId , MeterIdentification::Id, PointOfDelivery::Id);
172
+ }
173
+ return ret;
174
+ }
175
+
176
+ CHIP_ERROR Instance::SetMeterSerialNumber (const DataModel::Nullable<CharSpan> & newValue)
177
+ {
178
+ if (NullableCharSpanCompare (newValue, mMeterSerialNumber ))
179
+ {
180
+ return CHIP_NO_ERROR;
181
+ }
182
+
183
+ const CHIP_ERROR ret = NullableCharSpanCopy (mMeterSerialNumber , newValue);
184
+ if (CHIP_NO_ERROR == ret)
185
+ {
186
+ MatterReportingAttributeChangeCallback (mEndpointId , MeterIdentification::Id, MeterSerialNumber::Id);
187
+ }
188
+ return ret;
189
+ }
190
+
191
+ CHIP_ERROR Instance::SetProtocolVersion (const DataModel::Nullable<CharSpan> & newValue)
192
+ {
193
+ if (NullableCharSpanCompare (newValue, mProtocolVersion ))
194
+ {
195
+ return CHIP_NO_ERROR;
196
+ }
197
+
198
+ const CHIP_ERROR ret = NullableCharSpanCopy (mProtocolVersion , newValue);
199
+ if (CHIP_NO_ERROR == ret)
200
+ {
201
+ MatterReportingAttributeChangeCallback (mEndpointId , MeterIdentification::Id, ProtocolVersion::Id);
202
+ }
203
+ return ret;
204
+ }
205
+
206
+ CHIP_ERROR Instance::SetPowerThreshold (const DataModel::Nullable<Structs::PowerThresholdStruct::Type> & newValue)
207
+ {
208
+ if (newValue.IsNull ())
209
+ {
210
+ if (mPowerThreshold .IsNull ())
211
+ {
212
+ return CHIP_NO_ERROR;
213
+ }
214
+
215
+ mPowerThreshold .SetNull ();
216
+ }
217
+ else
218
+ {
219
+ if (!mPowerThreshold .IsNull () && (newValue.Value ().powerThreshold == mPowerThreshold .Value ().powerThreshold &&
220
+ newValue.Value ().apparentPowerThreshold == mPowerThreshold .Value ().apparentPowerThreshold &&
221
+ newValue.Value ().powerThresholdSource == mPowerThreshold .Value ().powerThresholdSource ))
222
+ {
223
+ return CHIP_NO_ERROR;
224
+ }
225
+
226
+ if (!(newValue.ExistingValueInEncodableRange () && (newValue.Value ().powerThresholdSource .IsNull () ||
227
+ PowerThresholdSourceEnum::kUnknownEnumValue != EnsureKnownEnumValue (newValue.Value ().powerThresholdSource .Value ()))))
228
+ {
229
+ return CHIP_ERROR_DECODE_FAILED;
230
+ }
231
+
232
+ mPowerThreshold .SetNonNull (newValue.Value ());
233
+ }
234
+
235
+ MatterReportingAttributeChangeCallback (mEndpointId , MeterIdentification::Id, PowerThreshold::Id);
236
+ return CHIP_NO_ERROR;
237
+ }
238
+
59
239
// AttributeAccessInterface
60
240
CHIP_ERROR Instance::Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
61
241
{
@@ -67,24 +247,24 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu
67
247
ReturnErrorOnFailure (aEncoder.Encode (mFeature ));
68
248
break ;
69
249
case MeterType::Id:
70
- ReturnErrorOnFailure (aEncoder.Encode (mDelegate . GetMeterType ()));
250
+ ReturnErrorOnFailure (aEncoder.Encode (GetMeterType ()));
71
251
break ;
72
252
73
253
case PointOfDelivery::Id:
74
- ReturnErrorOnFailure (aEncoder.Encode (mDelegate . GetPointOfDelivery ()));
254
+ ReturnErrorOnFailure (aEncoder.Encode (GetPointOfDelivery ()));
75
255
break ;
76
256
77
257
case MeterSerialNumber::Id:
78
- ReturnErrorOnFailure (aEncoder.Encode (mDelegate . GetMeterSerialNumber ()));
258
+ ReturnErrorOnFailure (aEncoder.Encode (GetMeterSerialNumber ())); ;
79
259
break ;
80
260
81
261
case ProtocolVersion::Id:
82
- ReturnErrorOnFailure (aEncoder.Encode (mDelegate . GetProtocolVersion ()));
262
+ ReturnErrorOnFailure (aEncoder.Encode (GetProtocolVersion ()));
83
263
break ;
84
264
85
265
case PowerThreshold::Id:
86
266
if (HasFeature (Feature::kPowerThreshold ))
87
- ReturnErrorOnFailure (aEncoder.Encode (mDelegate . GetPowerThreshold ()));
267
+ ReturnErrorOnFailure (aEncoder.Encode (GetPowerThreshold ()));
88
268
else
89
269
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
90
270
break ;
0 commit comments