blob: 71bcfc5d432790c760a5d0ec3340fd72c4fe1219 [file]
/*
*
* Copyright (c) 2024-2026 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/service-area-server/CodegenIntegration.h>
#include <app/util/attribute-storage.h>
#include <app/util/endpoint-config-api.h>
#include <clusters/ServiceArea/Attributes.h>
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::ServiceArea;
namespace {
ServiceAreaCluster::OptionalAttributeSet BuildOptionalAttributes(EndpointId endpointId)
{
ServiceAreaCluster::OptionalAttributeSet optionalAttributes;
if (emberAfContainsAttribute(endpointId, Id, Attributes::SupportedMaps::Id))
{
optionalAttributes.template ForceSet<Attributes::SupportedMaps::Id>();
}
if (emberAfContainsAttribute(endpointId, Id, Attributes::CurrentArea::Id))
{
optionalAttributes.template ForceSet<Attributes::CurrentArea::Id>();
}
if (emberAfContainsAttribute(endpointId, Id, Attributes::EstimatedEndTime::Id))
{
optionalAttributes.template ForceSet<Attributes::EstimatedEndTime::Id>();
}
if (emberAfContainsAttribute(endpointId, Id, Attributes::Progress::Id))
{
optionalAttributes.template ForceSet<Attributes::Progress::Id>();
}
return optionalAttributes;
}
} // namespace
Instance::Instance(StorageDelegate * storageDelegate, Delegate * aDelegate, EndpointId aEndpointId,
BitMask<ServiceArea::Feature> aFeature) :
mStorageDelegate(storageDelegate),
mDelegate(aDelegate), mCluster(aEndpointId, *storageDelegate, *aDelegate, aFeature, BuildOptionalAttributes(aEndpointId))
{
ChipLogProgress(Zcl, "Service Area: Instance constructor");
aDelegate->SetInstance(this);
}
Instance::~Instance()
{
if (mRegistered)
{
ChipLogError(AppServer, "Service Area Instance destroyed without Init() completing shutdown; unregistering now.");
LogErrorOnFailure(CodegenDataModelProvider::Instance().Registry().Unregister(&mCluster.Cluster()));
mRegistered = false;
}
}
CHIP_ERROR Instance::Init()
{
ChipLogProgress(Zcl, "Service Area: INIT");
VerifyOrReturnError(emberAfContainsServer(mCluster.Cluster().GetPaths()[0].mEndpointId, Id), CHIP_ERROR_INVALID_ARGUMENT,
ChipLogError(Zcl, "Service Area: The cluster with Id %lu was not enabled in zap.", long(Id)));
VerifyOrReturnError(!mRegistered, CHIP_NO_ERROR);
ReturnErrorOnFailure(mStorageDelegate->Init());
ReturnErrorOnFailure(mDelegate->Init());
ReturnErrorOnFailure(CodegenDataModelProvider::Instance().Registry().Register(mCluster.Registration()));
mRegistered = true;
return CHIP_NO_ERROR;
}
uint32_t Instance::GetNumberOfSupportedAreas()
{
return mCluster.Cluster().GetNumberOfSupportedAreas();
}
bool Instance::GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea)
{
return mCluster.Cluster().GetSupportedAreaByIndex(listIndex, aSupportedArea);
}
bool Instance::GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea)
{
return mCluster.Cluster().GetSupportedAreaById(aAreaId, listIndex, aSupportedArea);
}
bool Instance::AddSupportedArea(AreaStructureWrapper & aNewArea)
{
return mCluster.Cluster().AddSupportedArea(aNewArea);
}
bool Instance::ModifySupportedArea(AreaStructureWrapper & aNewArea)
{
return mCluster.Cluster().ModifySupportedArea(aNewArea);
}
bool Instance::ClearSupportedAreas()
{
return mCluster.Cluster().ClearSupportedAreas();
}
bool Instance::RemoveSupportedArea(uint32_t areaId)
{
return mCluster.Cluster().RemoveSupportedArea(areaId);
}
uint32_t Instance::GetNumberOfSupportedMaps()
{
return mCluster.Cluster().GetNumberOfSupportedMaps();
}
bool Instance::GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap)
{
return mCluster.Cluster().GetSupportedMapByIndex(listIndex, aSupportedMap);
}
bool Instance::GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap)
{
return mCluster.Cluster().GetSupportedMapById(aMapId, listIndex, aSupportedMap);
}
bool Instance::AddSupportedMap(uint32_t aMapId, const CharSpan & aMapName)
{
return mCluster.Cluster().AddSupportedMap(aMapId, aMapName);
}
bool Instance::RenameSupportedMap(uint32_t aMapId, const CharSpan & newMapName)
{
return mCluster.Cluster().RenameSupportedMap(aMapId, newMapName);
}
bool Instance::ClearSupportedMaps()
{
return mCluster.Cluster().ClearSupportedMaps();
}
bool Instance::RemoveSupportedMap(uint32_t mapId)
{
return mCluster.Cluster().RemoveSupportedMap(mapId);
}
uint32_t Instance::GetNumberOfSelectedAreas()
{
return mCluster.Cluster().GetNumberOfSelectedAreas();
}
bool Instance::GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea)
{
return mCluster.Cluster().GetSelectedAreaByIndex(listIndex, selectedArea);
}
bool Instance::AddSelectedArea(uint32_t & aSelectedArea)
{
return mCluster.Cluster().AddSelectedArea(aSelectedArea);
}
bool Instance::ClearSelectedAreas()
{
return mCluster.Cluster().ClearSelectedAreas();
}
bool Instance::RemoveSelectedAreas(uint32_t areaId)
{
return mCluster.Cluster().RemoveSelectedAreas(areaId);
}
DataModel::Nullable<uint32_t> Instance::GetCurrentArea()
{
return mCluster.Cluster().GetCurrentArea();
}
bool Instance::SetCurrentArea(const DataModel::Nullable<uint32_t> & aCurrentArea)
{
return mCluster.Cluster().SetCurrentArea(aCurrentArea);
}
DataModel::Nullable<uint32_t> Instance::GetEstimatedEndTime()
{
return mCluster.Cluster().GetEstimatedEndTime();
}
bool Instance::SetEstimatedEndTime(const DataModel::Nullable<uint32_t> & aEstimatedEndTime)
{
return mCluster.Cluster().SetEstimatedEndTime(aEstimatedEndTime);
}
uint32_t Instance::GetNumberOfProgressElements()
{
return mCluster.Cluster().GetNumberOfProgressElements();
}
bool Instance::GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement)
{
return mCluster.Cluster().GetProgressElementByIndex(listIndex, aProgressElement);
}
bool Instance::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement)
{
return mCluster.Cluster().GetProgressElementById(aAreaId, listIndex, aProgressElement);
}
bool Instance::AddPendingProgressElement(uint32_t aAreaId)
{
return mCluster.Cluster().AddPendingProgressElement(aAreaId);
}
bool Instance::SetProgressStatus(uint32_t aAreaId, OperationalStatusEnum opStatus)
{
return mCluster.Cluster().SetProgressStatus(aAreaId, opStatus);
}
bool Instance::SetProgressTotalOperationalTime(uint32_t aAreaId, const DataModel::Nullable<uint32_t> & aTotalOperationalTime)
{
return mCluster.Cluster().SetProgressTotalOperationalTime(aAreaId, aTotalOperationalTime);
}
bool Instance::SetProgressEstimatedTime(uint32_t aAreaId, const DataModel::Nullable<uint32_t> & aEstimatedTime)
{
return mCluster.Cluster().SetProgressEstimatedTime(aAreaId, aEstimatedTime);
}
bool Instance::ClearProgress()
{
return mCluster.Cluster().ClearProgress();
}
bool Instance::RemoveProgressElement(uint32_t areaId)
{
return mCluster.Cluster().RemoveProgressElement(areaId);
}
bool Instance::HasFeature(ServiceArea::Feature feature) const
{
return mCluster.Cluster().HasFeature(feature);
}
// ZAP-generated plugin callbacks are left as stubs. Applications instantiate Instance directly
// (not through these callbacks) and register it with the codegen data model provider via Init().
void MatterServiceAreaClusterInitCallback(EndpointId endpointId) {}
void MatterServiceAreaClusterShutdownCallback(EndpointId endpointId, MatterClusterShutdownType shutdownType) {}