Skip to content

Commit 7fd0fb1

Browse files
committed
Refactoring
1 parent 1b6af28 commit 7fd0fb1

File tree

2 files changed

+192
-29
lines changed

2 files changed

+192
-29
lines changed

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

+168-5
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,68 @@ 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+
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+
3886
namespace chip {
3987
namespace app {
4088
namespace Clusters {
4189
namespace MeterIdentification {
4290

4391
CHIP_ERROR Instance::Init()
4492
{
93+
// Check if the cluster has been selected in zap
94+
VerifyOrDie(emberAfContainsServer(mEndpointId, Id));
95+
SetMeterType(std::nullopt);
96+
SetPointOfDelivery(std::nullopt);
97+
SetMeterSerialNumber(std::nullopt);
98+
SetProtocolVersion(std::nullopt);
99+
SetPowerThreshold(std::nullopt);
45100
VerifyOrReturnError(AttributeAccessInterfaceRegistry::Instance().Register(this), CHIP_ERROR_INCORRECT_STATE);
46101
return CHIP_NO_ERROR;
47102
}
@@ -56,6 +111,114 @@ bool Instance::HasFeature(const Feature & aFeature) const
56111
return mFeature.Has(aFeature);
57112
}
58113

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

73236
case PointOfDelivery::Id:
74-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPointOfDelivery()));
237+
ReturnErrorOnFailure(aEncoder.Encode(GetPointOfDelivery()));
75238
break;
76239

77240
case MeterSerialNumber::Id:
78-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetMeterSerialNumber()));
241+
ReturnErrorOnFailure(aEncoder.Encode(GetMeterSerialNumber()));;
79242
break;
80243

81244
case ProtocolVersion::Id:
82-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetProtocolVersion()));
245+
ReturnErrorOnFailure(aEncoder.Encode(GetProtocolVersion()));
83246
break;
84247

85248
case PowerThreshold::Id:
86249
if (HasFeature(Feature::kPowerThreshold))
87-
ReturnErrorOnFailure(aEncoder.Encode(mDelegate.GetPowerThreshold()));
250+
ReturnErrorOnFailure(aEncoder.Encode(GetPowerThreshold()));
88251
else
89252
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
90253
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)