Skip to content

Commit 325fbbd

Browse files
authored
Fix StreamUsage constraint checks for Audio and Video stream allocation (project-chip#40617)
* Fix StreamUsage constraint checks for Audio and Video stream allocation * Adjust test scripts for the new constraints around StreamUsage enum. * Return DynamicConstraintError if the StreamUSage for the de-allocated streamID is Internal.
1 parent 5df24e6 commit 325fbbd

File tree

5 files changed

+69
-22
lines changed

5 files changed

+69
-22
lines changed

examples/camera-app/linux/src/clusters/camera-avstream-mgmt/camera-av-stream-manager.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ Protocols::InteractionModel::Status CameraAVStreamManager::VideoStreamDeallocate
193193
ChipLogError(Camera, "Video stream with ID: %d still in use", streamID);
194194
return Status::InvalidInState;
195195
}
196+
197+
if (stream.videoStreamParams.streamUsage == Globals::StreamUsageEnum::kInternal)
198+
{
199+
ChipLogError(Camera, "Video stream with ID: %d is Internal", streamID);
200+
return Status::DynamicConstraintError;
201+
}
202+
196203
// Stop the video stream
197204
mCameraDeviceHAL->GetCameraHALInterface().StopVideoStream(streamID);
198205

@@ -250,6 +257,13 @@ Protocols::InteractionModel::Status CameraAVStreamManager::AudioStreamDeallocate
250257
ChipLogError(Camera, "Audio stream with ID: %d still in use", streamID);
251258
return Status::InvalidInState;
252259
}
260+
261+
if (stream.audioStreamParams.streamUsage == Globals::StreamUsageEnum::kInternal)
262+
{
263+
ChipLogError(Camera, "Audio stream with ID: %d is Internal", streamID);
264+
return Status::DynamicConstraintError;
265+
}
266+
253267
// Stop the audio stream
254268
mCameraDeviceHAL->GetCameraHALInterface().StopAudioStream(streamID);
255269

src/app/clusters/camera-av-stream-management-server/camera-av-stream-management-server.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,10 +1726,13 @@ void CameraAVStreamMgmtServer::HandleVideoStreamAllocate(HandlerContext & ctx,
17261726
VerifyOrReturn((HasFeature(Feature::kOnScreenDisplay) == commandData.OSDEnabled.HasValue()),
17271727
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand));
17281728

1729-
VerifyOrReturn(commandData.streamUsage != Globals::StreamUsageEnum::kUnknownEnumValue, {
1730-
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid stream usage", mEndpointId);
1731-
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError);
1732-
});
1729+
VerifyOrReturn(commandData.streamUsage == Globals::StreamUsageEnum::kRecording ||
1730+
commandData.streamUsage == Globals::StreamUsageEnum::kAnalysis ||
1731+
commandData.streamUsage == Globals::StreamUsageEnum::kLiveView,
1732+
{
1733+
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid stream usage", mEndpointId);
1734+
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError);
1735+
});
17331736

17341737
VerifyOrReturn(commandData.videoCodec != VideoCodecEnum::kUnknownEnumValue, {
17351738
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid video codec", mEndpointId);
@@ -1862,10 +1865,13 @@ void CameraAVStreamMgmtServer::HandleAudioStreamAllocate(HandlerContext & ctx,
18621865
Commands::AudioStreamAllocateResponse::Type response;
18631866
uint16_t audioStreamID = 0;
18641867

1865-
VerifyOrReturn(commandData.streamUsage != Globals::StreamUsageEnum::kUnknownEnumValue, {
1866-
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid stream usage", mEndpointId);
1867-
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError);
1868-
});
1868+
VerifyOrReturn(commandData.streamUsage == Globals::StreamUsageEnum::kRecording ||
1869+
commandData.streamUsage == Globals::StreamUsageEnum::kAnalysis ||
1870+
commandData.streamUsage == Globals::StreamUsageEnum::kLiveView,
1871+
{
1872+
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid stream usage", mEndpointId);
1873+
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError);
1874+
});
18691875

18701876
VerifyOrReturn(commandData.audioCodec != AudioCodecEnum::kUnknownEnumValue, {
18711877
ChipLogError(Zcl, "CameraAVStreamMgmt[ep=%d]: Invalid audio codec", mEndpointId);

src/python_testing/TC_AVSM_2_11.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ async def test_TC_AVSM_2_11(self):
178178

179179
self.step(8)
180180
try:
181-
notSupportedStreamUsage = next((e for e in Globals.Enums.StreamUsageEnum if e not in aSupportedStreamUsages), None)
181+
notSupportedStreamUsage = next(
182+
(e for e in Globals.Enums.StreamUsageEnum if e not in aSupportedStreamUsages and e != Globals.Enums.StreamUsageEnum.kInternal), None)
182183
await self.send_single_cmd(
183184
endpoint=endpoint, cmd=commands.SetStreamPriorities(streamPriorities=([notSupportedStreamUsage]))
184185
)

src/python_testing/TC_AVSM_2_5.py

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,31 +90,36 @@ def steps_TC_AVSM_2_5(self) -> list[TestStep]:
9090
),
9191
TestStep(
9292
8,
93+
"TH sends the AudioStreamAllocate command with values from step 6 except with StreamUsage set to Internal",
94+
"DUT responds with a CONSTRAINT_ERROR status code.",
95+
),
96+
TestStep(
97+
9,
9398
"TH sends the AudioStreamAllocate command with values from step 6 except with StreamUsage set to a value not in aStreamUsagePriorities",
9499
"DUT responds with a INVALID_IN_STATE status code.",
95100
),
96101
TestStep(
97-
9,
102+
10,
98103
"TH sends the AudioStreamAllocate command with values from step 6 except with ChannelCount set to 16(outside of valid range)",
99104
"DUT responds with a CONSTRAINT_ERROR status code.",
100105
),
101106
TestStep(
102-
10,
107+
11,
103108
"TH sends the AudioStreamAllocate command with values from step 6 except with BitDepth set to 48(outside of valid range)",
104109
"DUT responds with a CONSTRAINT_ERROR status code.",
105110
),
106111
TestStep(
107-
11,
112+
12,
108113
"TH sends the AudioStreamAllocate command with values from step 6 except with Samplerate set to 0(outside of valid range)",
109114
"DUT responds with a CONSTRAINT_ERROR status code.",
110115
),
111116
TestStep(
112-
12,
117+
13,
113118
"TH sends the AudioStreamAllocate command with values from step 6 except with BitRate set to 0(outside of valid range)",
114119
"DUT responds with a CONSTRAINT_ERROR status code.",
115120
),
116121
TestStep(
117-
13,
122+
14,
118123
"TH sends the AudioStreamAllocate command with values from step 6 except with AudioCodec set to 10(outside of valid range)",
119124
"DUT responds with a CONSTRAINT_ERROR status code.",
120125
),
@@ -193,12 +198,33 @@ async def test_TC_AVSM_2_5(self):
193198
logger.info(f"Rx'd AllocatedAudioStreams: {aAllocatedAudioStreams}")
194199
asserts.assert_equal(len(aAllocatedAudioStreams), 1, "The number of allocated audio streams in the list is not 1.")
195200

201+
self.step(8)
202+
outOfConstraintStreamUsage = Globals.Enums.StreamUsageEnum.kInternal
203+
try:
204+
adoStreamAllocateCmd = commands.AudioStreamAllocate(
205+
streamUsage=outOfConstraintStreamUsage,
206+
audioCodec=aMicrophoneCapabilities.supportedCodecs[0],
207+
channelCount=aMicrophoneCapabilities.maxNumberOfChannels,
208+
sampleRate=aMicrophoneCapabilities.supportedSampleRates[0],
209+
bitRate=aBitRate,
210+
bitDepth=aMicrophoneCapabilities.supportedBitDepths[0],
211+
)
212+
await self.send_single_cmd(endpoint=endpoint, cmd=adoStreamAllocateCmd)
213+
asserts.fail("Unexpected success when expecting CONSTRAINT_ERROR due to invalid StreamUsage")
214+
except InteractionModelError as e:
215+
asserts.assert_equal(
216+
e.status,
217+
Status.ConstraintError,
218+
"Unexpected status returned when expecting CONSTRAINT_ERROR due to invalid StreamUsage",
219+
)
220+
pass
221+
196222
notSupportedStreamUsage = next(
197-
(e for e in Globals.Enums.StreamUsageEnum if e not in aStreamUsagePriorities),
223+
(e for e in Globals.Enums.StreamUsageEnum if e not in aStreamUsagePriorities and e != Globals.Enums.StreamUsageEnum.kInternal),
198224
Globals.Enums.StreamUsageEnum.kUnknownEnumValue,
199225
)
200226

201-
self.step(8)
227+
self.step(9)
202228
try:
203229
adoStreamAllocateCmd = commands.AudioStreamAllocate(
204230
streamUsage=notSupportedStreamUsage,
@@ -218,7 +244,7 @@ async def test_TC_AVSM_2_5(self):
218244
)
219245
pass
220246

221-
self.step(9)
247+
self.step(10)
222248
try:
223249
adoStreamAllocateCmd = commands.AudioStreamAllocate(
224250
streamUsage=aStreamUsagePriorities[0],
@@ -238,7 +264,7 @@ async def test_TC_AVSM_2_5(self):
238264
)
239265
pass
240266

241-
self.step(10)
267+
self.step(11)
242268
try:
243269
adoStreamAllocateCmd = commands.AudioStreamAllocate(
244270
streamUsage=aStreamUsagePriorities[0],
@@ -258,7 +284,7 @@ async def test_TC_AVSM_2_5(self):
258284
)
259285
pass
260286

261-
self.step(11)
287+
self.step(12)
262288
try:
263289
adoStreamAllocateCmd = commands.AudioStreamAllocate(
264290
streamUsage=aStreamUsagePriorities[0],
@@ -278,7 +304,7 @@ async def test_TC_AVSM_2_5(self):
278304
)
279305
pass
280306

281-
self.step(12)
307+
self.step(13)
282308
try:
283309
adoStreamAllocateCmd = commands.AudioStreamAllocate(
284310
streamUsage=aStreamUsagePriorities[0],
@@ -298,7 +324,7 @@ async def test_TC_AVSM_2_5(self):
298324
)
299325
pass
300326

301-
self.step(13)
327+
self.step(14)
302328
try:
303329
adoStreamAllocateCmd = commands.AudioStreamAllocate(
304330
streamUsage=aStreamUsagePriorities[0],

src/python_testing/TC_AVSM_2_7.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ async def test_TC_AVSM_2_7(self):
345345
self.step(17)
346346
try:
347347
notSupportedStreamUsage = next(
348-
(e for e in Globals.Enums.StreamUsageEnum if e not in aStreamUsagePriorities),
348+
(e for e in Globals.Enums.StreamUsageEnum if e not in aStreamUsagePriorities and e != Globals.Enums.StreamUsageEnum.kInternal),
349349
Globals.Enums.StreamUsageEnum.kUnknownEnumValue,
350350
)
351351
videoStreamAllocateCmd = commands.VideoStreamAllocate(

0 commit comments

Comments
 (0)