Skip to content

Commit 7c9b126

Browse files
Enable PushAV server cluster TCs for CI build. (project-chip#40821)
* Enable PushAV server cluster TCs for CI build. Signed-off-by: Raveendra Karu <[email protected]> * Refactor TC 1,2,3,9 according to TestBase Co-author: Sambhavi <[email protected]> Signed-off-by: Raveendra Karu <[email protected]> * Restyled by autopep8 * Restyled by isort * Log change in TC9 Co-author: Sambhavi <[email protected]> Signed-off-by: Raveendra Karu <[email protected]> * Fix Lint Error Co-author: Sambhavi <[email protected]> Signed-off-by: Raveendra Karu <[email protected]> * Restyled by isort * Fix TC failure Signed-off-by: Raveendra Karu <[email protected]> * Changes for TC5 Signed-off-by: Raveendra Karu <[email protected]> * Test script issue fix Signed-off-by: Raveendra Karu <[email protected]> * Comment Addressing * Tls endpoint support to testcase Sambhavi <[email protected]> Signed-off-by: Raveendra Karu <[email protected]> * Restyled by whitespace * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Fix build fail Signed-off-by: Raveendra Karu <[email protected]> * Fix build fail Signed-off-by: Raveendra Karu <[email protected]> * Check for build check Signed-off-by: Raveendra Karu <[email protected]> * Restyled by clang-format * Fix build fail Signed-off-by: Raveendra Karu <[email protected]> --------- Signed-off-by: Raveendra Karu <[email protected]> Co-authored-by: Restyled.io <[email protected]>
1 parent 48cc305 commit 7c9b126

File tree

20 files changed

+740
-630
lines changed

20 files changed

+740
-630
lines changed

examples/all-clusters-app/all-clusters-common/include/push-av-stream-transport-delegate-impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ class PushAvStreamTransportManager : public PushAvStreamTransportDelegate
7474

7575
Protocols::InteractionModel::Status ValidateAudioStream(uint16_t audioStreamId) override;
7676

77+
Protocols::InteractionModel::Status ValidateZoneId(uint16_t zoneId) override;
78+
79+
bool ValidateMotionZoneSize(uint16_t zoneSize) override;
80+
7781
PushAvStreamTransportStatusEnum GetTransportBusyStatus(const uint16_t connectionID) override;
7882

7983
void OnAttributeChanged(AttributeId attributeId) override;

examples/all-clusters-app/all-clusters-common/src/push-av-stream-transport-delegate-impl.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ Protocols::InteractionModel::Status PushAvStreamTransportManager::ValidateAudioS
155155
return Status::Success;
156156
}
157157

158+
Protocols::InteractionModel::Status PushAvStreamTransportManager::ValidateZoneId(uint16_t zoneId)
159+
{
160+
// TODO: Validate zoneId from the allocated zones
161+
// Returning Status::Success to pass through checks in the Server Implementation.
162+
return Status::Success;
163+
}
164+
165+
bool PushAvStreamTransportManager::ValidateMotionZoneSize(uint16_t zoneSize)
166+
{
167+
// TODO: Validate motion zone size
168+
// Returning true to pass through checks in the Server Implementation.
169+
return true;
170+
}
171+
158172
PushAvStreamTransportStatusEnum PushAvStreamTransportManager::GetTransportBusyStatus(const uint16_t connectionID)
159173
{
160174
for (PushAvStream & stream : pushavStreams)

examples/camera-app/linux/include/clusters/push-av-stream-transport/push-av-stream-manager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ class PushAvStreamTransportManager : public PushAvStreamTransportDelegate
7979
ValidateBandwidthLimit(StreamUsageEnum streamUsage, const Optional<DataModel::Nullable<uint16_t>> & videoStreamId,
8080
const Optional<DataModel::Nullable<uint16_t>> & audioStreamId) override;
8181

82+
Protocols::InteractionModel::Status ValidateZoneId(uint16_t zoneId) override;
83+
84+
bool ValidateMotionZoneSize(uint16_t zoneSize) override;
85+
8286
Protocols::InteractionModel::Status SelectVideoStream(StreamUsageEnum streamUsage, uint16_t & videoStreamId) override;
8387

8488
Protocols::InteractionModel::Status SelectAudioStream(StreamUsageEnum streamUsage, uint16_t & audioStreamId) override;

examples/camera-app/linux/src/clusters/push-av-stream-transport/push-av-stream-manager.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,40 @@ Protocols::InteractionModel::Status PushAvStreamTransportManager::SelectAudioStr
323323
return Status::Failure;
324324
}
325325

326+
Protocols::InteractionModel::Status PushAvStreamTransportManager::ValidateZoneId(uint16_t zoneId)
327+
{
328+
if (mCameraDevice == nullptr)
329+
{
330+
ChipLogError(Camera, "CameraDeviceInterface not initialized");
331+
return Status::Failure;
332+
}
333+
auto & zones = mCameraDevice->GetZoneManagementDelegate().GetZoneMgmtServer()->GetZones();
334+
335+
for (const auto & zone : zones)
336+
{
337+
if (zone.zoneID == zoneId)
338+
{
339+
return Status::Success;
340+
}
341+
}
342+
return Status::Failure;
343+
}
344+
345+
bool PushAvStreamTransportManager::ValidateMotionZoneSize(uint16_t zoneSize)
346+
{
347+
if (mCameraDevice == nullptr)
348+
{
349+
ChipLogError(Camera, "CameraDeviceInterface not initialized");
350+
return false;
351+
}
352+
auto maxZones = mCameraDevice->GetZoneManagementDelegate().GetZoneMgmtServer()->GetMaxZones();
353+
if (zoneSize >= maxZones)
354+
{
355+
return false;
356+
}
357+
return true;
358+
}
359+
326360
Protocols::InteractionModel::Status PushAvStreamTransportManager::ValidateVideoStream(uint16_t videoStreamId)
327361
{
328362
if (mCameraDevice == nullptr)

src/app/clusters/push-av-stream-transport-server/push-av-stream-transport-delegate.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,23 @@ class PushAvStreamTransportDelegate
204204
*/
205205
virtual Protocols::InteractionModel::Status ValidateAudioStream(uint16_t audioStreamId) = 0;
206206

207+
/**
208+
* @brief Validates that the zone corresponding to zoneId exists.
209+
*
210+
* @param zoneId Identifier for the requested zone
211+
* @return Status::Success if zone exists;
212+
* Status::InvalidZone if no zone with zoneId exists
213+
*/
214+
virtual Protocols::InteractionModel::Status ValidateZoneId(uint16_t zoneId) = 0;
215+
216+
/**
217+
* @brief Validates size of motion zone List.
218+
*
219+
* @param zoneSize Size for the requested zone list
220+
* @return true if URL is valid, false otherwise
221+
*/
222+
virtual bool ValidateMotionZoneSize(uint16_t zoneSize) = 0;
223+
207224
/**
208225
* @brief Gets the status of the transport.
209226
*

src/app/clusters/push-av-stream-transport-server/push-av-stream-transport-logic.cpp

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,40 @@ PushAvStreamTransportServerLogic::HandleAllocatePushTransport(CommandHandler & h
541541
Commands::AllocatePushTransportResponse::Type response;
542542
auto & transportOptions = commandData.transportOptions;
543543

544+
IngestMethodsEnum ingestMethod = commandData.transportOptions.ingestMethod;
545+
546+
bool isFormatSupported = false;
547+
548+
for (auto & supportsFormat : mSupportedFormats)
549+
{
550+
if ((supportsFormat.ingestMethod == ingestMethod) &&
551+
(supportsFormat.containerFormat == commandData.transportOptions.containerOptions.containerType))
552+
{
553+
isFormatSupported = true;
554+
}
555+
}
556+
557+
if (isFormatSupported == false)
558+
{
559+
auto status = to_underlying(StatusCodeEnum::kInvalidCombination);
560+
ChipLogError(Zcl,
561+
"HandleAllocatePushTransport[ep=%d]: Invalid Ingest Method and Container Format Combination : (Ingest Method: "
562+
"%02X and Container Format: %02X)",
563+
mEndpointId, to_underlying(ingestMethod),
564+
to_underlying(commandData.transportOptions.containerOptions.containerType));
565+
handler.AddClusterSpecificFailure(commandPath, status);
566+
return std::nullopt;
567+
}
568+
569+
/*Spec issue for invalid Trigger Type: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/11701*/
570+
if (transportOptions.triggerOptions.triggerType == TransportTriggerTypeEnum::kUnknownEnumValue)
571+
{
572+
auto status = to_underlying(StatusCodeEnum::kInvalidTriggerType);
573+
ChipLogError(Zcl, "HandleAllocatePushTransport[ep=%d]: Invalid Trigger type", mEndpointId);
574+
handler.AddClusterSpecificFailure(commandPath, status);
575+
return std::nullopt;
576+
}
577+
544578
Status transportOptionsValidityStatus = ValidateIncomingTransportOptions(transportOptions);
545579

546580
VerifyOrDo(transportOptionsValidityStatus == Status::Success, {
@@ -571,29 +605,36 @@ PushAvStreamTransportServerLogic::HandleAllocatePushTransport(CommandHandler & h
571605
return std::nullopt;
572606
}
573607

574-
IngestMethodsEnum ingestMethod = commandData.transportOptions.ingestMethod;
575-
576-
bool isFormatSupported = false;
577-
578-
for (auto & supportsFormat : mSupportedFormats)
608+
// here add check for valid zoneid
609+
if ((transportOptions.triggerOptions.triggerType == TransportTriggerTypeEnum::kMotion) &&
610+
(transportOptions.triggerOptions.motionZones.HasValue()) && (!transportOptions.triggerOptions.motionZones.Value().IsNull()))
579611
{
580-
if ((supportsFormat.ingestMethod == ingestMethod) &&
581-
(supportsFormat.containerFormat == commandData.transportOptions.containerOptions.containerType))
612+
613+
auto & motionZonesList = transportOptions.triggerOptions.motionZones;
614+
auto iter = motionZonesList.Value().Value().begin();
615+
uint16_t zonesize = 0;
616+
auto itsz = motionZonesList.Value().Value().begin();
617+
while (itsz.Next())
582618
{
583-
isFormatSupported = true;
619+
zonesize += 1;
584620
}
585-
}
621+
bool isValidZoneSize = mDelegate->ValidateMotionZoneSize(zonesize);
622+
VerifyOrReturnValue(
623+
isValidZoneSize, Status::ConstraintError,
624+
ChipLogError(Zcl, "Transport Options verification from command data[ep=%d]: Invalid Motion Zone Size ", mEndpointId));
586625

587-
if (isFormatSupported == false)
588-
{
589-
auto status = to_underlying(StatusCodeEnum::kInvalidCombination);
590-
ChipLogError(Zcl,
591-
"HandleAllocatePushTransport[ep=%d]: Invalid Ingest Method and Container Format Combination : (Ingest Method: "
592-
"%02X and Container Format: %02X)",
593-
mEndpointId, to_underlying(ingestMethod),
594-
to_underlying(commandData.transportOptions.containerOptions.containerType));
595-
handler.AddClusterSpecificFailure(commandPath, status);
596-
return std::nullopt;
626+
while (iter.Next())
627+
{
628+
auto & transportZoneOption = iter.GetValue();
629+
Status zoneIdStatus = mDelegate->ValidateZoneId(transportZoneOption.zone.Value());
630+
if (zoneIdStatus != Status::Success)
631+
{
632+
auto status = to_underlying(StatusCodeEnum::kInvalidZone);
633+
ChipLogError(Zcl, "HandleAllocatePushTransport[ep=%d]: Invalid ZoneId", mEndpointId);
634+
handler.AddClusterSpecificFailure(commandPath, status);
635+
return std::nullopt;
636+
}
637+
}
597638
}
598639

599640
bool isValidUrl = mDelegate->ValidateUrl(std::string(transportOptions.url.data(), transportOptions.url.size()));
@@ -606,15 +647,6 @@ PushAvStreamTransportServerLogic::HandleAllocatePushTransport(CommandHandler & h
606647
return std::nullopt;
607648
}
608649

609-
/*Spec issue for invalid Trigger Type: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/11701*/
610-
if (transportOptions.triggerOptions.triggerType == TransportTriggerTypeEnum::kUnknownEnumValue)
611-
{
612-
auto status = to_underlying(StatusCodeEnum::kInvalidTriggerType);
613-
ChipLogError(Zcl, "HandleAllocatePushTransport[ep=%d]: Invalid Trigger type", mEndpointId);
614-
handler.AddClusterSpecificFailure(commandPath, status);
615-
return std::nullopt;
616-
}
617-
618650
bool isValidStreamUsage = mDelegate->ValidateStreamUsage(transportOptions.streamUsage);
619651
if (isValidStreamUsage == false)
620652
{
@@ -670,7 +702,9 @@ PushAvStreamTransportServerLogic::HandleAllocatePushTransport(CommandHandler & h
670702

671703
if (!delegateStatus.IsSuccess())
672704
{
673-
handler.AddStatus(commandPath, delegateStatus);
705+
auto cluster_status = to_underlying(StatusCodeEnum::kInvalidStream);
706+
ChipLogError(Zcl, "HandleAllocatePushTransport[ep=%d]: Invalid Video Stream ", mEndpointId);
707+
handler.AddClusterSpecificFailure(commandPath, cluster_status);
674708
return std::nullopt;
675709
}
676710
}
@@ -700,7 +734,9 @@ PushAvStreamTransportServerLogic::HandleAllocatePushTransport(CommandHandler & h
700734

701735
if (!delegateStatus.IsSuccess())
702736
{
703-
handler.AddStatus(commandPath, delegateStatus);
737+
auto cluster_status = to_underlying(StatusCodeEnum::kInvalidStream);
738+
ChipLogError(Zcl, "HandleAllocatePushTransport[ep=%d]: Invalid Audio Stream ", mEndpointId);
739+
handler.AddClusterSpecificFailure(commandPath, cluster_status);
704740
return std::nullopt;
705741
}
706742
}

src/app/clusters/push-av-stream-transport-server/tests/TestPushAVStreamTransportCluster.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,20 @@ class TestPushAVStreamTransportDelegateImpl : public PushAvStreamTransportDelega
326326
return Status::Success;
327327
}
328328

329+
Protocols::InteractionModel::Status ValidateZoneId(uint16_t zoneId) override
330+
{
331+
// TODO: Validate zoneId from the allocated zones
332+
// Returning Status::Success to pass through checks in the Server Implementation.
333+
return Status::Success;
334+
}
335+
336+
bool ValidateMotionZoneSize(uint16_t zoneSize) override
337+
{
338+
// TODO: Validate motion zone size
339+
// Returning true to pass through checks in the Server Implementation.
340+
return true;
341+
}
342+
329343
PushAvStreamTransportStatusEnum GetTransportBusyStatus(const uint16_t connectionID) override
330344
{
331345
for (PushAvStream & stream : pushavStreams)

src/app/clusters/zone-management-server/zone-management-server.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ class Delegate
217217

218218
virtual CHIP_ERROR LoadTriggers(std::vector<ZoneTriggerControlStruct> & aTriggers) = 0;
219219

220+
ZoneMgmtServer * GetZoneMgmtServer() const { return mZoneMgmtServer; }
221+
220222
private:
221223
friend class ZoneMgmtServer;
222224

@@ -230,9 +232,6 @@ class Delegate
230232
* @param aZoneMgmtServer A pointer to the ZoneMgmtServer object related to this delegate object.
231233
*/
232234
void SetZoneMgmtServer(ZoneMgmtServer * aZoneMgmtServer) { mZoneMgmtServer = aZoneMgmtServer; }
233-
234-
protected:
235-
ZoneMgmtServer * GetZoneMgmtServer() const { return mZoneMgmtServer; }
236235
};
237236

238237
class ZoneMgmtServer : public CommandHandlerInterface, public AttributeAccessInterface

src/python_testing/TC_PAVSTI_Utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class PushAvServerProcess(Subprocess):
4747

4848
# By default this points to the push_av_server in Test Harness
4949
# TCs utilizing this should expect th_server_app_path otherwise
50-
DEFAULT_SERVER_PATH = "/root/apps/push_av_server/server.py"
50+
DEFAULT_SERVER_PATH = "src/tools/push_av_server/server.py"
5151

5252
def __init__(
5353
self,

src/python_testing/TC_PAVSTTestBase.py

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import matter.clusters as Clusters
2424
from matter import ChipDeviceCtrl
25+
from matter.clusters.Types import Nullable
2526
from matter.interaction_model import InteractionModelError, Status
2627

2728
logger = logging.getLogger(__name__)
@@ -185,7 +186,9 @@ async def validate_allocated_audio_stream(self, audioStreamID):
185186
asserts.fail(f"Audio Stream with ID {audioStreamID} not found as expected")
186187

187188
async def allocate_one_pushav_transport(self, endpoint, triggerType=Clusters.PushAvStreamTransport.Enums.TransportTriggerTypeEnum.kContinuous,
188-
trigger_Options=None):
189+
trigger_Options=None, ingestMethod=Clusters.PushAvStreamTransport.Enums.IngestMethodsEnum.kCMAFIngest,
190+
url="https://localhost:1234/streams/1", stream_Usage=None, container_Options=None,
191+
videoStream_ID=None, audioStream_ID=None, expected_cluster_status=None, tlsEndPoint=1, expiryTime=10):
189192
endpoint = self.get_endpoint(default=1)
190193
cluster = Clusters.PushAvStreamTransport
191194

@@ -209,6 +212,33 @@ async def allocate_one_pushav_transport(self, endpoint, triggerType=Clusters.Pus
209212
)
210213
asserts.assert_greater(len(aStreamUsagePriorities), 0, "StreamUsagePriorities is empty")
211214

215+
streamUsage = aStreamUsagePriorities[0]
216+
if (stream_Usage is not None):
217+
streamUsage = stream_Usage
218+
219+
videoStreamID = aAllocatedVideoStream
220+
if (videoStream_ID is not None):
221+
if (videoStream_ID == Nullable()):
222+
videoStreamID = videoStream_ID
223+
else:
224+
videoStreamID = aAllocatedVideoStream + 1
225+
226+
audioStreamID = aAllocatedAudioStream
227+
if (audioStream_ID is not None):
228+
if (audioStream_ID == Nullable()):
229+
audioStreamID = audioStream_ID
230+
else:
231+
audioStreamID = aAllocatedAudioStream + 1
232+
233+
containerOptions = {
234+
"containerType": cluster.Enums.ContainerFormatEnum.kCmaf,
235+
"CMAFContainerOptions": {"CMAFInterface": cluster.Enums.CMAFInterfaceEnum.kInterface1, "chunkDuration": 4, "segmentDuration": 500,
236+
"sessionGroup": 3, "trackName": " "},
237+
}
238+
239+
if (container_Options is not None):
240+
containerOptions = container_Options
241+
212242
triggerOptions = {"triggerType": triggerType}
213243
if (trigger_Options is not None):
214244
triggerOptions = trigger_Options
@@ -217,26 +247,28 @@ async def allocate_one_pushav_transport(self, endpoint, triggerType=Clusters.Pus
217247
await self.send_single_cmd(
218248
cmd=cluster.Commands.AllocatePushTransport(
219249
{
220-
"streamUsage": aStreamUsagePriorities[0],
221-
"videoStreamID": aAllocatedVideoStream,
222-
"audioStreamID": aAllocatedAudioStream,
223-
"endpointID": endpoint,
224-
"url": "https://localhost:1234/streams/1",
250+
"streamUsage": streamUsage,
251+
"videoStreamID": videoStreamID,
252+
"audioStreamID": audioStreamID,
253+
"endpointID": tlsEndPoint,
254+
"url": url,
225255
"triggerOptions": triggerOptions,
226-
"ingestMethod": cluster.Enums.IngestMethodsEnum.kCMAFIngest,
227-
"containerOptions": {
228-
"containerType": cluster.Enums.ContainerFormatEnum.kCmaf,
229-
"CMAFContainerOptions": {"CMAFInterface": cluster.Enums.CMAFInterfaceEnum.kInterface1, "chunkDuration": 4, "segmentDuration": 3,
230-
"sessionGroup": 3, "trackName": ""},
231-
},
232-
"expiryTime": 5,
256+
"ingestMethod": ingestMethod,
257+
"containerOptions": containerOptions,
258+
"expiryTime": expiryTime,
233259
}
234260
),
235261
endpoint=endpoint,
236262
)
237263
return Status.Success
238264
except InteractionModelError as e:
239265
asserts.assert_not_equal(e.status, Status.Success, "Unexpected error returned")
266+
if (expected_cluster_status is not None):
267+
asserts.assert_true(
268+
e.clusterStatus == expected_cluster_status, "Unexpected error returned"
269+
)
270+
return e.clusterStatus
271+
return e.status
240272
pass
241273

242274
async def check_and_delete_all_push_av_transports(self, endpoint, attribute):

0 commit comments

Comments
 (0)