blob: 16100bb81ede2233abbf39e9ea81950e568859dd [file] [log] [blame]
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <app/clusters/meter-identification-server/MeterIdentificationTestEventTriggerHandler.h>
#include <meter-identification-instance.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::MeterIdentification;
namespace {
class OldMeterIdentificationAttributes
{
private:
Instance * mInstance = nullptr;
static constexpr size_t kMaximumStringSize = 64;
char mPointOfDeliveryBuf[kMaximumStringSize] = {};
char mMeterSerialNumberBuf[kMaximumStringSize] = {};
char mProtocolVersionBuf[kMaximumStringSize] = {};
DataModel::Nullable<MeterTypeEnum> mMeterType;
DataModel::Nullable<CharSpan> mPointOfDelivery;
DataModel::Nullable<CharSpan> mMeterSerialNumber;
DataModel::Nullable<CharSpan> mProtocolVersion;
DataModel::Nullable<Globals::Structs::PowerThresholdStruct::Type> mPowerThreshold;
struct DataPresets_s
{
DataModel::Nullable<MeterTypeEnum> meterType;
DataModel::Nullable<CharSpan> pointOfDelivery;
DataModel::Nullable<CharSpan> meterSerialNumber;
DataModel::Nullable<CharSpan> protocolVersion;
DataModel::Nullable<Globals::Structs::PowerThresholdStruct::Type> powerThreshold;
};
static constexpr uint8_t kMaxPresetItems = 2u;
uint8_t mPresetsIdx;
const DataPresets_s TestsDataPresets[kMaxPresetItems] = {
{ .meterType = DataModel::MakeNullable(MeterTypeEnum::kUtility),
.pointOfDelivery = DataModel::MakeNullable(CharSpan::fromCharString("Test delivery point")),
.meterSerialNumber = DataModel::MakeNullable(CharSpan::fromCharString("TST-123456789")),
.protocolVersion = DataModel::MakeNullable(CharSpan::fromCharString("1.2.3")),
.powerThreshold = DataModel::MakeNullable(Globals::Structs::PowerThresholdStruct::Type(
{ Optional<int64_t>(2400000), Optional<int64_t>(120), Globals::PowerThresholdSourceEnum::kContract })) },
{ .meterType = DataModel::MakeNullable(MeterTypeEnum::kPrivate),
.pointOfDelivery = DataModel::MakeNullable(CharSpan::fromCharString("New delivery point")),
.meterSerialNumber = DataModel::MakeNullable(CharSpan::fromCharString("NEW-987654321")),
.protocolVersion = DataModel::MakeNullable(CharSpan::fromCharString("3.4.5")),
.powerThreshold = DataModel::MakeNullable(Globals::Structs::PowerThresholdStruct::Type(
{ Optional<int64_t>(4800000), Optional<int64_t>(240), Globals::PowerThresholdSourceEnum::kRegulator })) }
};
static bool NullableCharSpansEqual(const DataModel::Nullable<CharSpan> & a, const DataModel::Nullable<CharSpan> & b)
{
if (a.IsNull() && b.IsNull())
{
return true;
}
if (!a.IsNull() && !b.IsNull())
{
return a.Value().data_equal(b.Value());
}
return false;
}
void SavePointOfDelivery(const DataModel::Nullable<CharSpan> & newValue)
{
if (NullableCharSpansEqual(newValue, mPointOfDelivery))
{
return;
}
if (!mPointOfDelivery.IsNull())
{
mPointOfDelivery.SetNull();
}
if (!newValue.IsNull())
{
const size_t len = newValue.IsNull() ? 0
: newValue.Value().size() < kMaximumStringSize ? newValue.Value().size()
: kMaximumStringSize;
memmove(mPointOfDeliveryBuf, newValue.Value().data(), len);
mPointOfDelivery = DataModel::MakeNullable(CharSpan(mPointOfDeliveryBuf, len));
}
}
void SaveMeterSerialNumber(const DataModel::Nullable<CharSpan> & newValue)
{
if (NullableCharSpansEqual(newValue, mMeterSerialNumber))
{
return;
}
if (!mMeterSerialNumber.IsNull())
{
mMeterSerialNumber.SetNull();
}
if (!newValue.IsNull())
{
const size_t len = newValue.IsNull() ? 0
: newValue.Value().size() < kMaximumStringSize ? newValue.Value().size()
: kMaximumStringSize;
memmove(mMeterSerialNumberBuf, newValue.Value().data(), len);
mMeterSerialNumber = DataModel::MakeNullable(CharSpan(mMeterSerialNumberBuf, len));
}
}
void SaveProtocolVersion(const DataModel::Nullable<CharSpan> & newValue)
{
if (NullableCharSpansEqual(newValue, mProtocolVersion))
{
return;
}
if (!mProtocolVersion.IsNull())
{
mProtocolVersion.SetNull();
}
if (!newValue.IsNull())
{
const size_t len = newValue.IsNull() ? 0
: newValue.Value().size() < kMaximumStringSize ? newValue.Value().size()
: kMaximumStringSize;
memmove(mProtocolVersionBuf, newValue.Value().data(), len);
mProtocolVersion = DataModel::MakeNullable(CharSpan(mProtocolVersionBuf, len));
}
}
void SaveAttributes()
{
mInstance = GetInstance();
VerifyOrDieWithMsg(mInstance, AppServer, "Meter Identification instance is null");
mMeterType = mInstance->GetMeterType();
SavePointOfDelivery(mInstance->GetPointOfDelivery());
SaveMeterSerialNumber(mInstance->GetMeterSerialNumber());
SaveProtocolVersion(mInstance->GetProtocolVersion());
mPowerThreshold = mInstance->GetPowerThreshold();
}
void ClearAttributes()
{
mPointOfDelivery.SetNull();
mMeterSerialNumber.SetNull();
mProtocolVersion.SetNull();
mMeterType.SetNull();
mPowerThreshold.SetNull();
mInstance = nullptr;
}
void RestoreAttributes() const
{
if (mInstance)
{
mInstance->SetMeterType(mMeterType);
mInstance->SetPointOfDelivery(mPointOfDelivery);
mInstance->SetMeterSerialNumber(mMeterSerialNumber);
mInstance->SetProtocolVersion(mProtocolVersion);
mInstance->SetPowerThreshold(mPowerThreshold);
}
}
void UpdAttrsByPresetIdx()
{
mInstance->SetMeterType(TestsDataPresets[mPresetsIdx].meterType);
mInstance->SetPointOfDelivery(TestsDataPresets[mPresetsIdx].pointOfDelivery);
mInstance->SetMeterSerialNumber(TestsDataPresets[mPresetsIdx].meterSerialNumber);
mInstance->SetProtocolVersion(TestsDataPresets[mPresetsIdx].protocolVersion);
mInstance->SetPowerThreshold(TestsDataPresets[mPresetsIdx].powerThreshold);
mPresetsIdx = !mPresetsIdx;
}
public:
OldMeterIdentificationAttributes() { mPresetsIdx = 0; };
~OldMeterIdentificationAttributes() = default;
void Update()
{
if (!mInstance)
{
SaveAttributes();
}
UpdAttrsByPresetIdx();
}
void Clear()
{
RestoreAttributes();
ClearAttributes();
}
};
OldMeterIdentificationAttributes mOldMeterIdentificationAttributes;
} // namespace
bool HandleMeterIdentificationTestEventTrigger(uint64_t eventTrigger)
{
MeterIdentificationTrigger trigger = static_cast<MeterIdentificationTrigger>(eventTrigger);
switch (trigger)
{
case MeterIdentificationTrigger::kAttributesValueUpdate:
ChipLogProgress(Support, "[MTRID-Test-Event] => Attributes value update");
mOldMeterIdentificationAttributes.Update();
break;
case MeterIdentificationTrigger::kAttributesValueUpdateClear:
ChipLogProgress(Support, "[MTRID-Test-Event] => Attributes value clear");
mOldMeterIdentificationAttributes.Clear();
break;
default:
return false;
}
return true;
}