blob: a4df375a85795585fdc6c1d78f3ff3bd85d2e098 [file]
/*
*
* 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.
*/
#pragma once
#include <app/clusters/camera-av-settings-user-level-management-server/CameraAvSettingsUserLevelManagementConstants.h>
#include <app/clusters/camera-av-settings-user-level-management-server/CameraAvSettingsUserLevelManagementLogic.h>
#include <app/server-cluster/DefaultServerCluster.h>
#include <protocols/interaction_model/StatusCode.h>
#include <string>
#include <vector>
namespace chip {
namespace app {
namespace Clusters {
constexpr size_t kMptzPositionStructMaxSerializedSize =
TLV::EstimateStructOverhead(sizeof(int16_t), sizeof(int16_t), sizeof(uint8_t));
class CameraAvSettingsUserLevelManagementCluster;
/** @brief
* Defines interfaces for implementing application-specific logic for various aspects of the CameraAvUserSettingsManagement
* Cluster. Specifically, it defines interfaces for the interaction with manual and digital pan, tilt, and zoom functions.
*/
class CameraAvSettingsUserLevelManagementDelegate
{
public:
CameraAvSettingsUserLevelManagementDelegate() = default;
virtual ~CameraAvSettingsUserLevelManagementDelegate() = default;
/**
* Allows the delegate to perform any specific functions such as timer cancellation on a shutdown, this is invoked prior to
* the destructor, it shall not be invoked as part of the destructor.
*/
virtual void ShutdownApp() = 0;
/**
* Allows the delegate to determine whether a change in MPTZ is possible given current device status
*/
virtual bool CanChangeMPTZ() = 0;
/**
* DPTZ Stream handling. Invoked on the delegate by an app, providing to the delegate the id of an
* allocated or deallocated stream, or the viewport when the device level viewport is updated.
* The delegate shall invoke the appropriate MoveCapableVideoStream methods on its instance of the server
*/
virtual void VideoStreamAllocated(uint16_t aStreamID) = 0;
virtual void VideoStreamDeallocated(uint16_t aStreamID) = 0;
virtual void DefaultViewportUpdated(Globals::Structs::ViewportStruct::Type aViewport) = 0;
/**
* Delegate command handlers
*/
/**
* Allows any needed app handling given provided and already validated pan, tilt, and zoom values that are to be set based on
* reception of an MPTZSetPosition command. Returns a failure status if the physical device cannot realize these values. The
* app shall not block on actual physical execution of the command, rather return success on initiation of the movement. On
* conclusion of the movement the app shall invoke the provided callback, at which time the server will update the server held
* attribute values for PTZ, if the motion succeeded.
* @param aPan The validated value of the pan that is to be set
* @param aTilt The validated value of the tilt that is to be set
* @param aZoom The validated value of the zoom that is to be set
* @param callback The callback to be invoked once the physical movement of the camera has completed.
* It is the delegate's responsibility to ensure liveness of this server cluster instance before invocation of
* the callback, which needs to take place in the Matter threading context.
*/
virtual Protocols::InteractionModel::Status
MPTZSetPosition(Optional<int16_t> aPan, Optional<int16_t> aTilt, Optional<uint8_t> aZoom,
CameraAvSettingsUserLevelManagement::PhysicalPTZCallback * callback) = 0;
/**
* Allows any needed app handling given provided and already validated pan, tilt, and zoom values that are to be set based on
* reception of an MPTZRelativeMove command. The server has already validated the received relative values, and provides the
* app with the new, requested settings for PTZ. Returns a failure status if the physical device cannot realize these values.
* The app shall not block on actual physical execution of the command, rather return success on initiation of the movement. On
* conclusion of the movement the app shall invoke the provided callback, at which time the server will update the server held
* attribute values for PTZ, if the motion succeeded.
* @param aPan The validated value of the pan that is to be set
* @param aTilt The validated value of the tilt that is to be set
* @param aZoom The validated value of the zoom that is to be set
* @param callback The callback to be invoked once the physical movement of the camera has completed.
* It is the delegate's responsibility to ensure liveness of this server cluster instance before invocation of
* the callback. which needs to take place in the Matter threading context.
*/
virtual Protocols::InteractionModel::Status
MPTZRelativeMove(Optional<int16_t> aPan, Optional<int16_t> aTilt, Optional<uint8_t> aZoom,
CameraAvSettingsUserLevelManagement::PhysicalPTZCallback * callback) = 0;
/**
* Allows any needed app handling given provided and already validated pan, tilt, and zoom values that are to be set based on
* reception of an MPTZMoveToPreset command. The server has already ensured the requested preset ID exists, and obtained the
* values for PTZ defined by that preset. Returns a failure status if the physical device cannot realize these values. The app
* shall not block on actual physical execution of the command, rather return success on initiation of the movement. On
* conclusion of the movement the app shall invoke the provided callback, at which time the server will update the server held
* attribute values for PTZ assuming success. Within the provided callback the server will update the server held attribute
* values for PTZ, if the motion succeeded.
* @param aPreset The preset ID associated with the provided PTZ values
* @param aPan The value for Pan associated with the preset
* @param aTilt The value for Tilt associated with the preset
* @param aZoom The value for Zoom associated with the preset
* @param callback The callback to be invoked once the physical movement of the camera has completed.
* it is the delegate's responsibility to ensure liveness of this server cluster instance before invocation of
* the callback. which needs to take place in the Matter threading context.
*/
virtual Protocols::InteractionModel::Status
MPTZMoveToPreset(uint8_t aPreset, Optional<int16_t> aPan, Optional<int16_t> aTilt, Optional<uint8_t> aZoom,
CameraAvSettingsUserLevelManagement::PhysicalPTZCallback * callback) = 0;
/**
* Informs the delegate that a request has been made to save the current PTZ values in a new (or updated) preset ID.
* The preset ID is provided, the delegate is already aware of the current PTZ values that will be saved. Allows any needed app
* handling and the possibility that the request is rejected depending on device state. On a success response the server will
* save the current values of PTZ against the preset ID.
* @param aPreset The preset ID that will be used for the saved values
*/
virtual Protocols::InteractionModel::Status MPTZSavePreset(uint8_t aPreset) = 0;
/**
* Informs the delegate that a request has been made to remove the preset indicated. Allows any needed app handling and the
* possibility that the request is rejected depending on device state. On a success response the server will erases the
* indicated preset and its associated values.
* @param aPreset The preset ID that will be used for the saved values
*/
virtual Protocols::InteractionModel::Status MPTZRemovePreset(uint8_t aPreset) = 0;
/**
* Informs the delegate that a request has been made to change the Viewport associated with the provided video stream ID. The
* server has already ensured that the video stream ID is for a valid video stream. The app needs to work with its AV Stream
* Managament instance to validate the stream ID, the provided new Viewport, ensure that the command is posssible, and apply the
* command logic to the camera.
* @param aVideoStreamID The ID for the videa stream that is subject to change
* @param aViewport The new values of Viewport that are to be set
*/
virtual Protocols::InteractionModel::Status DPTZSetViewport(uint16_t aVideoStreamID,
Globals::Structs::ViewportStruct::Type aViewport) = 0;
/**
* Informs the delegate that a request has been made to digitally alter the current rendered stream. The server has already
* validated that the Zoom Delta (if provided) is in range, and that the video stream ID is valid. The app needs to work with
* its AV Stream Managament instance to validate the stream ID, ensure that the command is posssible, and apply the command
* logic to the camera.
* @param aVideoStreamID The ID for the videa stream that is subject to change
* @param aDeltaX Number of pixels to move in the X plane
* @param aDeltaY Number of pixels to move in the Y plane
* @param aZoomDelta Relative change of digital zoom
*/
virtual Protocols::InteractionModel::Status DPTZRelativeMove(uint16_t aVideoStreamID, Optional<int16_t> aDeltaX,
Optional<int16_t> aDeltaY, Optional<int8_t> aZoomDelta,
Globals::Structs::ViewportStruct::Type & aViewport) = 0;
/**
* @brief Callback into the delegate once persistent attributes managed by
* the Cluster have been loaded from Storage.
*/
virtual CHIP_ERROR PersistentAttributesLoadedCallback() = 0;
private:
friend class CameraAvSettingsUserLevelManagementCluster;
CameraAvSettingsUserLevelManagementCluster * mServer = nullptr;
// Sets the Server pointer
void SetServer(CameraAvSettingsUserLevelManagementCluster * aServer) { mServer = aServer; }
protected:
CameraAvSettingsUserLevelManagementCluster * GetServer() const { return mServer; }
};
class CameraAvSettingsUserLevelManagementCluster : public DefaultServerCluster
{
public:
/**
* Creates a server instance. The Init() function needs to be called for this instance to be registered and
* called by the interaction model at the appropriate times.
* @param aEndpointId The endpoint on which this cluster exists. This must match the zap configuration.
* @param aFeatures The bitflags value that identifies which features are supported by this instance.
* @param aMaxPresets The maximum number of MPTZ presets supported.
*
* Note: the caller must ensure that the delegate lives throughout the instance's lifetime.
*/
CameraAvSettingsUserLevelManagementCluster(EndpointId aEndpointId,
BitFlags<CameraAvSettingsUserLevelManagement::Feature> aFeatures,
uint8_t aMaxPresets) :
DefaultServerCluster({ aEndpointId, CameraAvSettingsUserLevelManagement::Id }),
mLogic(aEndpointId, aFeatures, aMaxPresets)
{}
CameraAvSettingsUserLevelMgmtServerLogic & GetLogic() { return mLogic; }
void MarkAttributeDirty(AttributeId attributeId) { NotifyAttributeChanged(attributeId); }
void SetDelegate(CameraAvSettingsUserLevelManagementDelegate * delegate)
{
mLogic.SetDelegate(delegate);
if (delegate != nullptr)
{
delegate->SetServer(this);
}
}
CHIP_ERROR Init() { return mLogic.Init(); }
CHIP_ERROR Startup(ServerClusterContext & context) override;
// Handle any dynamic cleanup required prior to the destructor being called on an app shutdown. To be invoked by
// an app as part of its own shutdown sequence and prior to the destruction of the app/delegate.
void Shutdown(ClusterShutdownType shutdownType) override
{
DefaultServerCluster::Shutdown(shutdownType);
mLogic.Shutdown();
}
DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request,
AttributeValueEncoder & encoder) override;
std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
chip::TLV::TLVReader & input_arguments,
CommandHandler * handler) override;
CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & builder) override;
CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
// Attribute Mutators
CHIP_ERROR SetTiltMin(int16_t aTiltMin);
CHIP_ERROR SetTiltMax(int16_t aTiltMax);
CHIP_ERROR SetPanMin(int16_t aPanMin);
CHIP_ERROR SetPanMax(int16_t aPanMax);
CHIP_ERROR SetZoomMax(uint8_t aZoomMax);
/**
* Allows for a delegate or application to provide the ID and default Viewport of an allocated video stream that is capable of
* digital movement. This should be invoked by a delegate on the conclusion of allocating a video stream via the AV Stream
* Management cluster.
*/
void AddMoveCapableVideoStream(uint16_t aVideoStreamID, Globals::Structs::ViewportStruct::Type aViewport);
/**
* Allows for a delegate or application to update the viewport of an already allocated video stream.
* This should be invoked whenever a viewport is updated by DPTZSetVewport or DPTZRelativeMove
*/
void UpdateMoveCapableVideoStream(uint16_t aVideoStreamID, Globals::Structs::ViewportStruct::Type aViewport);
/**
* Allows for a delegate or application to update all of the viewports for all of the allocated video streams.
* This should be invoked whenever the device default viewport is updated via a write to Viewport on the
* AV Stream Management Cluster
*/
void UpdateMoveCapableVideoStreams(Globals::Structs::ViewportStruct::Type aViewport);
/**
* Allows for a delegate or application to remove a video stream from the set that is capable of digital movement.
* This should be invoked by a delegate on the conclusion of deallocating a video stream via the AV Stream Management cluster.
*/
void RemoveMoveCapableVideoStream(uint16_t aVideoStreamID);
private:
CameraAvSettingsUserLevelMgmtServerLogic mLogic;
// Holding variables for values subject to successful physical movement
Optional<int16_t> mTargetPan;
Optional<int16_t> mTargetTilt;
Optional<uint8_t> mTargetZoom;
};
} // namespace Clusters
} // namespace app
} // namespace chip