blob: 7fe40bb8fe16f410e4ad3a50f4fca6ca47245b8e [file] [log] [blame]
/*
*
* Copyright (c) 2024 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.
*/
#pragma once
#include "service-area-cluster-objects.h"
namespace chip {
namespace app {
namespace Clusters {
namespace ServiceArea {
class Instance;
// *****************************************************************************
// cluster constraints
constexpr size_t kMaxNumSupportedAreas = 255;
constexpr size_t kMaxNumSupportedMaps = 255;
constexpr size_t kMaxNumSelectedAreas = 255;
constexpr size_t kMaxNumProgressElements = 255;
constexpr size_t kMaxSizeStatusText = 256;
/**
* ServiceArea::Delegate Defines methods for implementing application-specific
* logic for the Service Area Cluster.
*/
class Delegate
{
public:
Delegate() = default;
virtual ~Delegate() = default;
/**
* Due to the coupling between the Delegate and Instance classes via the references they have to each other,
* copying a Delegate object might make things confusing.
*/
Delegate(const Delegate &) = delete;
Delegate & operator=(const Delegate &) = delete;
/**
* @brief This method will be called during the ServiceArea server initialization after the Instance information has been
* validated and the Instance has been registered. This can be used to initialise app logic.
*/
virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; };
//*************************************************************************
// Command handling support
/**
* @brief Can the selected locations be set by the client in the current operating mode?
* @param[out] statusText text describing why selected locations cannot be set (if return is false).
* @return true if the current device state allows selected locations to be set by user.
*
* @note The statusText field SHOULD indicate why the request is not allowed, given the current mode
* of the device, which may involve other clusters.
*/
virtual bool IsSetSelectedAreasAllowed(MutableCharSpan & statusText) = 0;
/**
* Given a set of locations to be set to the SelectedAreas attribute, this method should check that
* the set of locations as a whole is valid and reachable by the device.
* If the set of locations is invalid, the locationStatus should be set to InvalidSet and
* the statusText SHALL include a vendor-defined error description.
*
* The caller of this method will ensure that there are no duplicates in the list
* and that all the locations in the set are valid supported locations.
*
* @param[in] selectedAreas List of new selected locations.
* @param[out] locationStatus Success if all checks pass, error code if failure.
* @param[out] statusText text describing failure (see description above), size kMaxSizeStatusText.
* @return true if success.
*
* @note If the SelectAreas command is allowed when the device is operating and the selected locations change to none, the
* device must stop.
*/
virtual bool IsValidSelectAreasSet(const Span<const uint32_t> & selectedAreas, SelectAreasStatus & locationStatus,
MutableCharSpan & statusText) = 0;
/**
* @brief The server instance ensures that the SelectedAreas and CurrentArea attributes are not null before
* calling this method.
* @param[in] skippedArea the area ID to skip.
* @param[out] skipStatusText text describing why current location cannot be skipped.
* @return true if command is successful, false if the received skip request cannot be handled due to the current mode of the
* device.
*
* @note skipStatusText must be filled out by the function on failure.
*
* @note If the device accepts the request:
* - If the device is currently operating at the area identified by SkippedArea, as indicated by either the CurrentArea or
* the Progress attributes, if implemented, the device SHALL stop operating at that area.
* - If the Progress attribute is implemented, the entry corresponding to SkippedArea SHALL be updated to indicate that the
* area was skipped.
* - The server SHALL attempt to operate only at the areas in the SelectedAreas attribute list where operating has not been
* skipped or completed, using a vendor defined order.
* - If the server has either skipped or completed operating at all areas on the SelectedAreas attribute list, the server
* SHALL stop operating.
*
* @note If the Status field is set to InvalidAreaList, the StatusText field SHALL be an empty string.
* If the Status field is not set to Success, or InvalidAreaList, the StatusText field SHALL include a vendor defined
* error description which can be used to explain the error to the user. For example, if the Status field is set to
* InvalidInMode, the StatusText field SHOULD indicate why the request is not allowed, given the current mode of the
* device, which may involve other clusters.
*/
virtual bool HandleSkipArea(uint32_t skippedArea, MutableCharSpan & skipStatusText)
{
// device support of this command is optional
CopyCharSpanToMutableCharSpan("Skip Current Area command not supported by device"_span, skipStatusText);
return false;
}
//*************************************************************************
// Supported Areas accessors
/**
* @return true if the current device state allows the SupportedAreas attribute to be updated.
*
* @note The SupportedAreas attribute list changes (adding or deleting entries,
* changing their MapID fields, changing the AreaID fields, or nulling the entire list)
* SHOULD NOT be allowed while the device is operating, to reduce the impact on the clients,
* and the potential confusion for the users.
*
* @note The device implementation MAY allow supported location changes while operating if the device
* repopulates the SupportedMaps, SupportedAreas, CurrentArea, and Progress attributes with
* data matching the constraints listed in the requirements for each attribute.
*/
virtual bool IsSupportedAreasChangeAllowed() = 0;
virtual uint32_t GetNumberOfSupportedAreas() = 0;
/**
* @brief Get a supported area using the position in the list.
* @param[in] listIndex the position in the list.
* @param[out] aSupportedArea a copy of the area contents, if found.
* @return true if an area is found, false otherwise.
*/
virtual bool GetSupportedAreaByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedArea) = 0;
/**
* @brief Get a supported area that matches a areaID.
* @param[in] aAreaId the areaID to search for.
* @param[out] listIndex the area's index in the list, if found.
* @param[out] aSupportedArea a copy of the area contents, if found.
* @return true if an area is found, false otherwise.
*
* @note may be overloaded in device implementation for optimization, if desired.
*/
virtual bool GetSupportedAreaById(uint32_t aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedArea);
/**
* This method is called by the server instance to add a new area to the list.
* The server instance will ensure that the newArea is a valid, unique area.
* @param [in] newArea new area to add.
* @param [out] listIndex filled with the list index for the new area, if successful.
* @return true if successful, false otherwise.
* @note this method SHOULD double check that the added area won't exceed the maximum list size.
*/
virtual bool AddSupportedArea(const AreaStructureWrapper & newArea, uint32_t & listIndex) = 0;
/**
* This method is called by the server instance to modify an existing area in the list.
* The server instance will ensure that the modifiedArea is a valid, unique area.
* @param[in] listIndex The index of the area being modified.
* @param[in] modifiedArea An area with the modified contents.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that newArea's areaID matches the object at listIndex.
*/
virtual bool ModifySupportedArea(uint32_t listIndex, const AreaStructureWrapper & modifiedArea) = 0;
/**
* @return true if supported locations was not already null, false otherwise.
*/
virtual bool ClearSupportedAreas() = 0;
/**
* @brief Ensure that when the Supported locations is modified, the required restrictions for the SelectedAreas,
* CurrentArea, and Progress attributes are maintained.
*
* This method will be called by the SDK whenever the adherence to the restrictions for these attributes cannot be guaranteed.
* For example, if there are deletions in the SupportedMops or SupportedAreas attributes, or if there are changes to their
* IDs. This method will no be called if the changes made to the SupportedMops or SupportedAreas attributes, ensure that the
* restrictions are adhered. For example, if there are additions or the modifications do not involve changing IDs in the
* SupportedMops or SupportedAreas attributes.
*
* The default implementation will set the SelectedAreas, CurrentArea, and Progress attributes to null.
*
* The user is free the redefine this method as their device may have more information on what has changed and may be able to
* maintain the restrictions on these attributes by selectively editing them.
*/
virtual void HandleSupportedAreasUpdated();
//*************************************************************************
// Supported Maps accessors
/**
* @return true if the current device state allows the SupportedMaps attribute to be updated.
*
* @note The SupportedMaps attribute list changes (adding or deleting entries,
* changing their MapID fields, or nulling the entire list)
* SHOULD NOT be allowed while the device is operating, to reduce the impact on the clients,
* and the potential confusion for the users.
*
* @note The device implementation MAY allow supported maps changes while operating if the device
* repopulates the SupportedAreas, CurrentArea, and Progress attributes with
* data matching the constraints listed in the requirements for each attribute.
*/
virtual bool IsSupportedMapChangeAllowed() = 0;
virtual uint32_t GetNumberOfSupportedMaps() = 0;
/**
* @brief Get a supported map using the position in the list.
* @param[in] listIndex the position in the list.
* @param[out] aSupportedMap copy of the map contents, if found.
* @return true if a supported map is found, false otherwise.
*/
virtual bool GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) = 0;
/**
* @brief Get a supported map that matches a mapID.
* @param[in] aMapId the mapID to search for.
* @param[out] listIndex the map's index in the list, if found.
* @param[out] aSupportedMap copy of the location contents, if found.
* @return true if a supported map is found, false otherwise.
*
* @note may be overloaded in device implementation for optimization, if desired.
*/
virtual bool GetSupportedMapById(uint32_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap);
/**
* This method is called by the server instance to add a new map to the list.
* The server instance will ensure that the newMap is a valid, unique map.
* @param[in] newMap The new map to add.
* @param[out] listIndex filled with the list index of the new map, if successful.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that the added map won't exceed the maximum list size
*/
virtual bool AddSupportedMap(const MapStructureWrapper & newMap, uint32_t & listIndex) = 0;
/**
* This method is called by the server instance to modify an existing map in the list.
* The server instance will ensure that the modifiedMap is a valid, unique map.
* @param[in] listIndex The index of the map being modified.
* @param[in] modifiedMapA map with the modified contents.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that modifiedMap's mapID matches the object at listIndex.
*/
virtual bool ModifySupportedMap(uint32_t listIndex, const MapStructureWrapper & modifiedMap) = 0;
/**
* @return true if supported maps was not already null, false otherwise.
*/
virtual bool ClearSupportedMaps() = 0;
//*************************************************************************
// Selected Areas accessors
virtual uint32_t GetNumberOfSelectedAreas() = 0;
/**
* @brief Get a selected area using the position in the list.
* @param[in] listIndex the position in the list.
* @param[out] selectedArea the selected area value, if found.
* @return true if a selected area is found, false otherwise.
*/
virtual bool GetSelectedAreaByIndex(uint32_t listIndex, uint32_t & selectedArea) = 0;
/**
* @return true if the aAreaId areaID is found in the SelectedAreas list, false otherwise.
*
* @note may be overloaded in device implementation for optimization, if desired.
*/
virtual bool IsSelectedArea(uint32_t aAreaId);
/**
* This method is called by the server instance to add a new selected area to the list.
* The server instance will ensure that the aAreaId references a SUPPORTED area, and is unique within selected
* areas.
* @param[in] aAreaId The new areaID to add.
* @param[out] listIndex filled with the list index of the new area, if successful.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that the added area won't exceed the maximum list size.
*/
virtual bool AddSelectedArea(uint32_t aAreaId, uint32_t & listIndex) = 0;
/**
* @return true if selected locations was not already null, false otherwise.
*/
virtual bool ClearSelectedAreas() = 0;
//*************************************************************************
// Progress accessors
virtual uint32_t GetNumberOfProgressElements() = 0;
/**
* @brief Get a progress element using the position in the list.
* @param[in] listIndex the position in the list.
* @param[out] aProgressElement copy of the progress element contents, if found.
* @return true if a progress element is found, false otherwise.
*/
virtual bool GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) = 0;
/**
* @brief Get a progress element that matches a areaID.
* @param[in] aAreaId the areaID to search for.
* @param[out] listIndex the location's index in the list, if found.
* @param[out] aProgressElement copy of the progress element contents, if found.
* @return true if a progress element is found, false otherwise.
*
* @note may be overloaded in device implementation for optimization, if desired.
*/
virtual bool GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement);
/**
* @brief Is the progress element in the progress list?
* @param[in] aAreaId location id of the progress element.
* @return true if the progress element identified by Id is in the progress list.
*/
virtual bool IsProgressElement(uint32_t aAreaId);
/**
* This method is called by the server instance to add a new progress element to the list.
* The server instance will ensure that the newProgressElement is a valid, unique progress element.
* @param[in] newProgressElement The new element to add.
* @param[out] listIndex is filled with the list index for the new element, if successful.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that the added element won't exceed the maximum list size.
*/
virtual bool AddProgressElement(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) = 0;
/**
* This method is called by the server instance to modify an existing progress element in the list.
* The server instance will ensure that the modifiedProgressElement is a valid and unique progress element.
* @param[in] listIndex The list index of the progress element being modified.
* @param[in] modifiedProgressElement modified element's contents.
* @return true if successful, false otherwise.
*
* @note this function SHOULD double check that modifiedProgressElement's areaID matches the object at listIndex
*/
virtual bool ModifyProgressElement(uint32_t listIndex, const Structs::ProgressStruct::Type & modifiedProgressElement) = 0;
/**
* @return true if progress list was not already null, false otherwise.
*/
virtual bool ClearProgress() = 0;
Instance * GetInstance() { return mInstance; }
void SetInstance(Instance * aInstance) { mInstance = aInstance; }
private:
Instance * mInstance = nullptr;
};
} // namespace ServiceArea
} // namespace Clusters
} // namespace app
} // namespace chip