Skip to content

Commit 4cb8226

Browse files
committed
Refactoring
1 parent 1b6af28 commit 4cb8226

File tree

2 files changed

+191
-29
lines changed

2 files changed

+191
-29
lines changed

src/app/clusters/meter-identification-server/meter-identification-server.cpp

+167-5
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,67 @@ using namespace chip::app::Clusters::MeterIdentification::Attributes;
3535

3636
using chip::Protocols::InteractionModel::Status;
3737

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+
auto * str = static_cast<char *>(chip::Platform::MemoryAlloc(1 + len));
71+
if (nullptr == str)
72+
{
73+
return CHIP_ERROR_NO_MEMORY;
74+
}
75+
76+
memcpy(str, src.Value().data(), len);
77+
str[len] = 0;
78+
dst = MakeNullable(CharSpan(str, len));
79+
}
80+
81+
return CHIP_NO_ERROR;
82+
}
83+
} // namespace
84+
3885
namespace chip {
3986
namespace app {
4087
namespace Clusters {
4188
namespace MeterIdentification {
4289

4390
CHIP_ERROR Instance::Init()
4491
{
92+
// Check if the cluster has been selected in zap
93+
VerifyOrDie(emberAfContainsServer(mEndpointId, Id));
94+
SetMeterType(std::nullopt);
95+
SetPointOfDelivery(std::nullopt);
96+
SetMeterSerialNumber(std::nullopt);
97+
SetProtocolVersion(std::nullopt);
98+
SetPowerThreshold(std::nullopt);
4599
VerifyOrReturnError(AttributeAccessInterfaceRegistry::Instance().Register(this), CHIP_ERROR_INCORRECT_STATE);
46100
return CHIP_NO_ERROR;
47101
}
@@ -56,6 +110,114 @@ bool Instance::HasFeature(const Feature & aFeature) const
56110
return mFeature.Has(aFeature);
57111
}
58112

113+
CHIP_ERROR Instance::SetMeterType(const DataModel::Nullable<MeterTypeEnum> & newValue)
114+
{
115+
if (newValue.IsNull())
116+
{
117+
if (mMeterType.IsNull())
118+
{
119+
return CHIP_NO_ERROR;
120+
}
121+
122+
mMeterType.SetNull();
123+
}
124+
else
125+
{
126+
if (!mMeterType.IsNull() && mMeterType.Value() == newValue.Value())
127+
{
128+
return CHIP_NO_ERROR;
129+
}
130+
131+
if(MeterTypeEnum::kUnknownEnumValue == EnsureKnownEnumValue(newValue.Value()))
132+
{
133+
return CHIP_ERROR_INVALID_INTEGER_VALUE;
134+
}
135+
136+
mMeterType.SetNonNull(newValue.Value());
137+
}
138+
139+
MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, MeterType::Id);
140+
return CHIP_NO_ERROR;
141+
}
142+
143+
CHIP_ERROR Instance::SetPointOfDelivery(const DataModel::Nullable<CharSpan> & newValue)
144+
{
145+
if (NullableCharSpanCompare(newValue, mPointOfDelivery))
146+
{
147+
return CHIP_NO_ERROR;
148+
}
149+
150+
const CHIP_ERROR ret = NullableCharSpanCopy(mPointOfDelivery, newValue);
151+
if (CHIP_NO_ERROR == ret)
152+
{
153+
MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, PointOfDelivery::Id);
154+
}
155+
return ret;
156+
}
157+
158+
CHIP_ERROR Instance::SetMeterSerialNumber(const DataModel::Nullable<CharSpan> & newValue)
159+
{
160+
if (NullableCharSpanCompare(newValue, mMeterSerialNumber))
161+
{
162+
return CHIP_NO_ERROR;
163+
}
164+
165+
const CHIP_ERROR ret = NullableCharSpanCopy(mMeterSerialNumber, newValue);
166+
if (CHIP_NO_ERROR == ret)
167+
{
168+
MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, MeterSerialNumber::Id);
169+
}
170+
return ret;
171+
}
172+
173+
CHIP_ERROR Instance::SetProtocolVersion(const DataModel::Nullable<CharSpan> & newValue)
174+
{
175+
if (NullableCharSpanCompare(newValue, mProtocolVersion))
176+
{
177+
return CHIP_NO_ERROR;
178+
}
179+
180+
const CHIP_ERROR ret = NullableCharSpanCopy(mProtocolVersion, newValue);
181+
if (CHIP_NO_ERROR == ret)
182+
{
183+
MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, ProtocolVersion::Id);
184+
}
185+
return ret;
186+
}
187+
188+
CHIP_ERROR Instance::SetPowerThreshold(const DataModel::Nullable<Structs::PowerThresholdStruct::Type> & newValue)
189+
{
190+
if (newValue.IsNull())
191+
{
192+
if (mPowerThreshold.IsNull())
193+
{
194+
return CHIP_NO_ERROR;
195+
}
196+
197+
mPowerThreshold.SetNull();
198+
}
199+
else
200+
{
201+
if (!mPowerThreshold.IsNull() && (newValue.Value().powerThreshold == mPowerThreshold.Value().powerThreshold &&
202+
newValue.Value().apparentPowerThreshold == mPowerThreshold.Value().apparentPowerThreshold &&
203+
newValue.Value().powerThresholdSource == mPowerThreshold.Value().powerThresholdSource))
204+
{
205+
return CHIP_NO_ERROR;
206+
}
207+
208+
if (!(newValue.ExistingValueInEncodableRange() && (newValue.Value().powerThresholdSource.IsNull() ||
209+
PowerThresholdSourceEnum::kUnknownEnumValue != EnsureKnownEnumValue(newValue.Value().powerThresholdSource.Value()))))
210+
{
211+
return CHIP_ERROR_DECODE_FAILED;
212+
}
213+
214+
mPowerThreshold.SetNonNull(newValue.Value());
215+
}
216+
217+
MatterReportingAttributeChangeCallback(mEndpointId, MeterIdentification::Id, PowerThreshold::Id);
218+
return CHIP_NO_ERROR;
219+
}
220+
59221
// AttributeAccessInterface
60222
CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
61223
{
@@ -67,24 +229,24 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu
67229
ReturnErrorOnFailure(aEncoder.Encode(mFeature));
68230
break;
69231
case MeterType::Id:
70-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetMeterType()));
232+
ReturnErrorOnFailure(aEncoder.Encode(GetMeterType()));
71233
break;
72234

73235
case PointOfDelivery::Id:
74-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPointOfDelivery()));
236+
ReturnErrorOnFailure(aEncoder.Encode(GetPointOfDelivery()));
75237
break;
76238

77239
case MeterSerialNumber::Id:
78-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetMeterSerialNumber()));
240+
ReturnErrorOnFailure(aEncoder.Encode(GetMeterSerialNumber()));;
79241
break;
80242

81243
case ProtocolVersion::Id:
82-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetProtocolVersion()));
244+
ReturnErrorOnFailure(aEncoder.Encode(GetProtocolVersion()));
83245
break;
84246

85247
case PowerThreshold::Id:
86248
if (HasFeature(Feature::kPowerThreshold))
87-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPowerThreshold()));
249+
ReturnErrorOnFailure(aEncoder.Encode(GetPowerThreshold()));
88250
else
89251
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
90252
break;

src/app/clusters/meter-identification-server/meter-identification-server.h

+24-24
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,40 @@ namespace app {
3232
namespace Clusters {
3333
namespace MeterIdentification {
3434

35-
struct Delegate
36-
{
37-
EndpointId mEndpointId = 0;
38-
39-
public:
40-
virtual ~Delegate() = default;
41-
42-
void SetEndpointId(const EndpointId & aEndpoint) { mEndpointId = aEndpoint; }
43-
44-
virtual DataModel::Nullable<MeterTypeEnum> GetMeterType() = 0;
45-
virtual DataModel::Nullable<CharSpan> GetPointOfDelivery() = 0;
46-
virtual DataModel::Nullable<CharSpan> GetMeterSerialNumber() = 0;
47-
virtual DataModel::Nullable<CharSpan> GetProtocolVersion() = 0;
48-
virtual DataModel::Nullable<Structs::PowerThresholdStruct::Type> GetPowerThreshold() = 0;
49-
};
50-
5135
class Instance : public AttributeAccessInterface
5236
{
5337
public:
54-
Instance(const EndpointId & aEndpointId, Delegate & aDelegate, const BitMask<Feature> & aFeature) :
55-
AttributeAccessInterface(MakeOptional(aEndpointId), Id), mDelegate(aDelegate), mFeature(aFeature)
56-
{
57-
/* set the base class delegates endpointId */
58-
mDelegate.SetEndpointId(aEndpointId);
59-
}
60-
~Instance() { Shutdown(); }
38+
Instance(const EndpointId & aEndpointId, const BitMask<Feature> & aFeature) :
39+
AttributeAccessInterface(MakeOptional(aEndpointId), Id), mEndpointId(aEndpointId), mFeature(aFeature) {}
40+
~Instance() override { Shutdown(); };
6141

6242
CHIP_ERROR Init();
6343
void Shutdown();
6444

6545
bool HasFeature(const Feature & aFeature) const;
6646

47+
// Attribute Accessors
48+
DataModel::Nullable<MeterTypeEnum> GetMeterType() { return mMeterType; }
49+
DataModel::Nullable<CharSpan> GetPointOfDelivery() { return mPointOfDelivery; }
50+
DataModel::Nullable<CharSpan> GetMeterSerialNumber() { return mMeterSerialNumber; }
51+
DataModel::Nullable<CharSpan> GetProtocolVersion() { return mProtocolVersion; }
52+
DataModel::Nullable<Structs::PowerThresholdStruct::Type> GetPowerThreshold() { return mPowerThreshold; }
53+
54+
// Internal Application API to set attribute values
55+
CHIP_ERROR SetMeterType(const DataModel::Nullable<MeterTypeEnum> & value);
56+
CHIP_ERROR SetPointOfDelivery(const DataModel::Nullable<CharSpan> & value);
57+
CHIP_ERROR SetMeterSerialNumber(const DataModel::Nullable<CharSpan> & value);
58+
CHIP_ERROR SetProtocolVersion(const DataModel::Nullable<CharSpan> & value);
59+
CHIP_ERROR SetPowerThreshold(const DataModel::Nullable<Structs::PowerThresholdStruct::Type> & value);
60+
6761
private:
68-
Delegate & mDelegate;
62+
// Attribute storage
63+
DataModel::Nullable<MeterTypeEnum> mMeterType;
64+
DataModel::Nullable<CharSpan> mPointOfDelivery;
65+
DataModel::Nullable<CharSpan> mMeterSerialNumber;
66+
DataModel::Nullable<CharSpan> mProtocolVersion;
67+
DataModel::Nullable<Structs::PowerThresholdStruct::Type> mPowerThreshold;
68+
EndpointId mEndpointId = 0;
6969
BitMask<Feature> mFeature;
7070

7171
// AttributeAccessInterface

0 commit comments

Comments
 (0)