1 /* test_unicast_start.c - unit test for unicast start procedure */
2
3 /*
4 * Copyright (c) 2024 Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <stddef.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/audio/audio.h>
16 #include <zephyr/bluetooth/audio/bap.h>
17 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
18 #include <zephyr/bluetooth/audio/cap.h>
19 #include <zephyr/bluetooth/hci_types.h>
20 #include <zephyr/fff.h>
21 #include <zephyr/sys/slist.h>
22 #include <zephyr/sys/util.h>
23 #include <sys/errno.h>
24
25 #include "bap_endpoint.h"
26 #include "cap_initiator.h"
27 #include "conn.h"
28 #include "expects_util.h"
29 #include "test_common.h"
30 #include "ztest_assert.h"
31 #include "ztest_test.h"
32
33 struct cap_initiator_test_unicast_start_fixture {
34 struct bt_cap_stream cap_streams[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
35 struct bt_bap_ep eps[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
36 struct bt_bap_unicast_group unicast_group;
37 struct bt_conn conns[CONFIG_BT_MAX_CONN];
38 struct bt_bap_lc3_preset preset;
39 };
40
cap_initiator_test_unicast_start_fixture_init(struct cap_initiator_test_unicast_start_fixture * fixture)41 static void cap_initiator_test_unicast_start_fixture_init(
42 struct cap_initiator_test_unicast_start_fixture *fixture)
43 {
44 fixture->preset = (struct bt_bap_lc3_preset)BT_BAP_LC3_UNICAST_PRESET_16_2_1(
45 BT_AUDIO_LOCATION_MONO_AUDIO, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
46
47 for (size_t i = 0U; i < ARRAY_SIZE(fixture->conns); i++) {
48 test_conn_init(&fixture->conns[i]);
49 }
50
51 for (size_t i = 0U; i < ARRAY_SIZE(fixture->cap_streams); i++) {
52 struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
53
54 sys_slist_append(&fixture->unicast_group.streams, &bap_stream->_node);
55 bap_stream->group = &fixture->unicast_group;
56 }
57
58 for (size_t i = 0U; i < ARRAY_SIZE(fixture->eps); i++) {
59 fixture->eps[i].dir = (i & 1) + 1; /* Makes it either 1 or 2 (sink or source)*/
60 }
61 }
62
cap_initiator_test_unicast_start_setup(void)63 static void *cap_initiator_test_unicast_start_setup(void)
64 {
65 struct cap_initiator_test_unicast_start_fixture *fixture;
66
67 fixture = malloc(sizeof(*fixture));
68 zassert_not_null(fixture);
69
70 return fixture;
71 }
72
cap_initiator_test_unicast_start_before(void * f)73 static void cap_initiator_test_unicast_start_before(void *f)
74 {
75 int err;
76
77 memset(f, 0, sizeof(struct cap_initiator_test_unicast_start_fixture));
78 cap_initiator_test_unicast_start_fixture_init(f);
79
80 err = bt_cap_initiator_register_cb(&mock_cap_initiator_cb);
81 zassert_equal(0, err, "Unexpected return value %d", err);
82 }
83
cap_initiator_test_unicast_start_after(void * f)84 static void cap_initiator_test_unicast_start_after(void *f)
85 {
86 struct cap_initiator_test_unicast_start_fixture *fixture = f;
87
88 bt_cap_initiator_unregister_cb(&mock_cap_initiator_cb);
89
90 for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
91 mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
92 }
93
94 /* In the case of a test failing, we cancel the procedure so that subsequent won't fail */
95 bt_cap_initiator_unicast_audio_cancel();
96 }
97
cap_initiator_test_unicast_start_teardown(void * f)98 static void cap_initiator_test_unicast_start_teardown(void *f)
99 {
100 free(f);
101 }
102
103 ZTEST_SUITE(cap_initiator_test_unicast_start, NULL, cap_initiator_test_unicast_start_setup,
104 cap_initiator_test_unicast_start_before, cap_initiator_test_unicast_start_after,
105 cap_initiator_test_unicast_start_teardown);
106
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start)107 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start)
108 {
109 struct bt_cap_unicast_audio_start_stream_param
110 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
111 const struct bt_cap_unicast_audio_start_param param = {
112 .type = BT_CAP_SET_TYPE_AD_HOC,
113 .count = ARRAY_SIZE(stream_params),
114 .stream_params = stream_params,
115 };
116 int err;
117
118 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
119 stream_params[i].stream = &fixture->cap_streams[i];
120 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
121 /* Distribute the streams equally among the connections */
122 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
123 stream_params[i].ep = &fixture->eps[i];
124 }
125
126 err = bt_cap_initiator_unicast_audio_start(¶m);
127 zassert_equal(err, 0, "Unexpected return value %d", err);
128
129 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 1,
130 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
131
132 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
133 const struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
134 const enum bt_bap_ep_state state = bap_stream->ep->status.state;
135
136 zassert_equal(state, BT_BAP_EP_STATE_STREAMING,
137 "[%zu]: Stream %p unexpected state: %d", i, bap_stream, state);
138 }
139 }
140
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_null)141 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_inval_param_null)
142 {
143 int err;
144
145 err = bt_cap_initiator_unicast_audio_start(NULL);
146 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
147
148 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
149 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
150 }
151
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_null_param)152 static ZTEST_F(cap_initiator_test_unicast_start,
153 test_initiator_unicast_start_inval_param_null_param)
154 {
155 const struct bt_cap_unicast_audio_start_param param = {
156 .type = BT_CAP_SET_TYPE_AD_HOC,
157 .count = CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT,
158 .stream_params = NULL,
159 };
160 int err;
161
162 err = bt_cap_initiator_unicast_audio_start(¶m);
163 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
164
165 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
166 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
167 }
168
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_null_member)169 static ZTEST_F(cap_initiator_test_unicast_start,
170 test_initiator_unicast_start_inval_param_null_member)
171 {
172 struct bt_cap_unicast_audio_start_stream_param
173 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
174 const struct bt_cap_unicast_audio_start_param param = {
175 .type = BT_CAP_SET_TYPE_AD_HOC,
176 .count = ARRAY_SIZE(stream_params),
177 .stream_params = stream_params,
178 };
179 int err;
180
181 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
182 stream_params[i].stream = &fixture->cap_streams[i];
183 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
184 stream_params[i].ep = &fixture->eps[i];
185 }
186
187 err = bt_cap_initiator_unicast_audio_start(¶m);
188 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
189
190 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
191 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
192 }
193
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_missing_cas)194 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_inval_missing_cas)
195 {
196 struct bt_cap_unicast_audio_start_stream_param
197 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
198 const struct bt_cap_unicast_audio_start_param param = {
199 .type = BT_CAP_SET_TYPE_CSIP, /* CSIP requires CAS */
200 .count = ARRAY_SIZE(stream_params),
201 .stream_params = stream_params,
202 };
203 int err;
204
205 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
206 stream_params[i].stream = &fixture->cap_streams[i];
207 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
208 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
209 stream_params[i].ep = &fixture->eps[i];
210 }
211
212 err = bt_cap_initiator_unicast_audio_start(¶m);
213 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
214
215 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
216 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
217 }
218
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_zero_count)219 static ZTEST_F(cap_initiator_test_unicast_start,
220 test_initiator_unicast_start_inval_param_zero_count)
221 {
222 struct bt_cap_unicast_audio_start_stream_param
223 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
224 const struct bt_cap_unicast_audio_start_param param = {
225 .type = BT_CAP_SET_TYPE_AD_HOC,
226 .count = 0U,
227 .stream_params = stream_params,
228 };
229 int err;
230
231 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
232 stream_params[i].stream = &fixture->cap_streams[i];
233 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
234 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
235 stream_params[i].ep = &fixture->eps[i];
236 }
237
238 err = bt_cap_initiator_unicast_audio_start(¶m);
239 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
240
241 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
242 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
243 }
244
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_count)245 static ZTEST_F(cap_initiator_test_unicast_start,
246 test_initiator_unicast_start_inval_param_inval_count)
247 {
248 struct bt_cap_unicast_audio_start_stream_param
249 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
250 const struct bt_cap_unicast_audio_start_param param = {
251 .type = BT_CAP_SET_TYPE_AD_HOC,
252 .count = CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT + 1U,
253 .stream_params = stream_params,
254 };
255 int err;
256
257 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
258 stream_params[i].stream = &fixture->cap_streams[i];
259 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
260 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
261 stream_params[i].ep = &fixture->eps[i];
262 }
263
264 err = bt_cap_initiator_unicast_audio_start(¶m);
265 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
266
267 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
268 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
269 }
270
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_stream_param_null_stream)271 static ZTEST_F(cap_initiator_test_unicast_start,
272 test_initiator_unicast_start_inval_param_inval_stream_param_null_stream)
273 {
274 struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
275 const struct bt_cap_unicast_audio_start_param param = {
276 .type = BT_CAP_SET_TYPE_AD_HOC,
277 .count = 1,
278 .stream_params = &stream_param,
279 };
280 int err;
281
282 stream_param.stream = NULL;
283 stream_param.codec_cfg = &fixture->preset.codec_cfg;
284 stream_param.member.member = &fixture->conns[0];
285 stream_param.ep = &fixture->eps[0];
286
287 err = bt_cap_initiator_unicast_audio_start(¶m);
288 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
289
290 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
291 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
292 }
293
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_stream_param_null_codec_cfg)294 static ZTEST_F(cap_initiator_test_unicast_start,
295 test_initiator_unicast_start_inval_param_inval_stream_param_null_codec_cfg)
296 {
297 struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
298 const struct bt_cap_unicast_audio_start_param param = {
299 .type = BT_CAP_SET_TYPE_AD_HOC,
300 .count = 1,
301 .stream_params = &stream_param,
302 };
303 int err;
304
305 stream_param.stream = &fixture->cap_streams[0];
306 stream_param.codec_cfg = NULL;
307 stream_param.member.member = &fixture->conns[0];
308 stream_param.ep = &fixture->eps[0];
309
310 err = bt_cap_initiator_unicast_audio_start(¶m);
311 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
312
313 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
314 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
315 }
316
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_stream_param_null_member)317 static ZTEST_F(cap_initiator_test_unicast_start,
318 test_initiator_unicast_start_inval_param_inval_stream_param_null_member)
319 {
320 struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
321 const struct bt_cap_unicast_audio_start_param param = {
322 .type = BT_CAP_SET_TYPE_AD_HOC,
323 .count = 1,
324 .stream_params = &stream_param,
325 };
326 int err;
327
328 stream_param.stream = &fixture->cap_streams[0];
329 stream_param.codec_cfg = &fixture->preset.codec_cfg;
330 stream_param.member.member = NULL;
331 stream_param.ep = &fixture->eps[0];
332
333 err = bt_cap_initiator_unicast_audio_start(¶m);
334 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
335
336 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
337 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
338 }
339
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_stream_param_null_ep)340 static ZTEST_F(cap_initiator_test_unicast_start,
341 test_initiator_unicast_start_inval_param_inval_stream_param_null_ep)
342 {
343 struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
344 const struct bt_cap_unicast_audio_start_param param = {
345 .type = BT_CAP_SET_TYPE_AD_HOC,
346 .count = 1,
347 .stream_params = &stream_param,
348 };
349 int err;
350
351 stream_param.stream = &fixture->cap_streams[0];
352 stream_param.codec_cfg = &fixture->preset.codec_cfg;
353 stream_param.member.member = &fixture->conns[0];
354 stream_param.ep = NULL;
355
356 err = bt_cap_initiator_unicast_audio_start(¶m);
357 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
358
359 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
360 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
361 }
362
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_inval_param_inval_stream_param_invalid_meta)363 static ZTEST_F(cap_initiator_test_unicast_start,
364 test_initiator_unicast_start_inval_param_inval_stream_param_invalid_meta)
365 {
366 struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
367 const struct bt_cap_unicast_audio_start_param param = {
368 .type = BT_CAP_SET_TYPE_AD_HOC,
369 .count = 1,
370 .stream_params = &stream_param,
371 };
372 int err;
373
374 stream_param.stream = &fixture->cap_streams[0];
375 stream_param.codec_cfg = &fixture->preset.codec_cfg;
376 stream_param.member.member = &fixture->conns[0];
377 stream_param.ep = &fixture->eps[0];
378
379 /* CAP requires stream context - Let's remove it */
380 memset(stream_param.codec_cfg->meta, 0, sizeof(stream_param.codec_cfg->meta));
381 stream_param.codec_cfg->meta_len = 0U;
382
383 err = bt_cap_initiator_unicast_audio_start(¶m);
384 zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
385
386 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
387 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
388 }
389
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_state_codec_configured)390 static ZTEST_F(cap_initiator_test_unicast_start,
391 test_initiator_unicast_start_state_codec_configured)
392 {
393 struct bt_cap_unicast_audio_start_stream_param
394 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
395 const struct bt_cap_unicast_audio_start_param param = {
396 .type = BT_CAP_SET_TYPE_AD_HOC,
397 .count = ARRAY_SIZE(stream_params),
398 .stream_params = stream_params,
399 };
400 int err;
401
402 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
403 stream_params[i].stream = &fixture->cap_streams[i];
404 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
405 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
406 stream_params[i].ep = &fixture->eps[i];
407
408 test_unicast_set_state(stream_params[i].stream, stream_params[i].member.member,
409 stream_params[i].ep, &fixture->preset,
410 BT_BAP_EP_STATE_CODEC_CONFIGURED);
411 }
412
413 err = bt_cap_initiator_unicast_audio_start(¶m);
414 zassert_equal(err, 0, "Unexpected return value %d", err);
415
416 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 1,
417 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
418
419 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
420 const struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
421 const enum bt_bap_ep_state state = bap_stream->ep->status.state;
422
423 zassert_equal(state, BT_BAP_EP_STATE_STREAMING,
424 "[%zu]: Stream %p unexpected state: %d", i, bap_stream, state);
425 }
426 }
427
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_state_qos_configured)428 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_state_qos_configured)
429 {
430 struct bt_cap_unicast_audio_start_stream_param
431 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
432 const struct bt_cap_unicast_audio_start_param param = {
433 .type = BT_CAP_SET_TYPE_AD_HOC,
434 .count = ARRAY_SIZE(stream_params),
435 .stream_params = stream_params,
436 };
437 int err;
438
439 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
440 stream_params[i].stream = &fixture->cap_streams[i];
441 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
442 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
443 stream_params[i].ep = &fixture->eps[i];
444
445 test_unicast_set_state(stream_params[i].stream, stream_params[i].member.member,
446 stream_params[i].ep, &fixture->preset,
447 BT_BAP_EP_STATE_QOS_CONFIGURED);
448 }
449
450 err = bt_cap_initiator_unicast_audio_start(¶m);
451 zassert_equal(err, 0, "Unexpected return value %d", err);
452
453 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 1,
454 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
455
456 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
457 const struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
458 const enum bt_bap_ep_state state = bap_stream->ep->status.state;
459
460 zassert_equal(state, BT_BAP_EP_STATE_STREAMING,
461 "[%zu]: Stream %p unexpected state: %d", i, bap_stream, state);
462 }
463 }
464
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_state_enabling)465 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_state_enabling)
466 {
467 struct bt_cap_unicast_audio_start_stream_param
468 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
469 const struct bt_cap_unicast_audio_start_param param = {
470 .type = BT_CAP_SET_TYPE_AD_HOC,
471 .count = ARRAY_SIZE(stream_params),
472 .stream_params = stream_params,
473 };
474 int err;
475
476 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
477 stream_params[i].stream = &fixture->cap_streams[i];
478 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
479 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
480 stream_params[i].ep = &fixture->eps[i];
481
482 test_unicast_set_state(stream_params[i].stream, stream_params[i].member.member,
483 stream_params[i].ep, &fixture->preset,
484 BT_BAP_EP_STATE_ENABLING);
485 }
486
487 err = bt_cap_initiator_unicast_audio_start(¶m);
488 zassert_equal(err, 0, "Unexpected return value %d", err);
489
490 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 1,
491 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
492
493 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
494 const struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
495 const enum bt_bap_ep_state state = bap_stream->ep->status.state;
496
497 zassert_equal(state, BT_BAP_EP_STATE_STREAMING,
498 "[%zu]: Stream %p unexpected state: %d", i, bap_stream, state);
499 }
500 }
501
ZTEST_F(cap_initiator_test_unicast_start,test_initiator_unicast_start_state_streaming)502 static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_state_streaming)
503 {
504 struct bt_cap_unicast_audio_start_stream_param
505 stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
506 const struct bt_cap_unicast_audio_start_param param = {
507 .type = BT_CAP_SET_TYPE_AD_HOC,
508 .count = ARRAY_SIZE(stream_params),
509 .stream_params = stream_params,
510 };
511 int err;
512
513 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
514 stream_params[i].stream = &fixture->cap_streams[i];
515 stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
516 stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
517 stream_params[i].ep = &fixture->eps[i];
518
519 test_unicast_set_state(stream_params[i].stream, stream_params[i].member.member,
520 stream_params[i].ep, &fixture->preset,
521 BT_BAP_EP_STATE_STREAMING);
522 }
523
524 err = bt_cap_initiator_unicast_audio_start(¶m);
525 zassert_equal(err, -EALREADY, "Unexpected return value %d", err);
526
527 zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
528 mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
529
530 for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
531 const struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
532 const enum bt_bap_ep_state state = bap_stream->ep->status.state;
533
534 zassert_equal(state, BT_BAP_EP_STATE_STREAMING,
535 "[%zu]: Stream %p unexpected state: %d", i, bap_stream, state);
536 }
537 }
538