1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2023 Codecoup
5  * Copyright (c) 2024 Demant A/S
6  * Copyright (c) 2024 Nordic Semiconductor ASA
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <zephyr/fff.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/bluetooth/audio/audio.h>
17 #include <zephyr/bluetooth/audio/bap.h>
18 #include <zephyr/bluetooth/audio/pacs.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/bluetooth/hci_types.h>
21 #include <zephyr/bluetooth/gatt.h>
22 #include <zephyr/bluetooth/uuid.h>
23 #include <zephyr/sys/util_macro.h>
24 
25 #include "assert.h"
26 #include "ascs_internal.h"
27 #include "bap_unicast_server.h"
28 #include "bap_unicast_server_expects.h"
29 #include "bap_stream.h"
30 #include "bap_stream_expects.h"
31 #include "conn.h"
32 #include "gatt.h"
33 #include "gatt_expects.h"
34 #include "iso.h"
35 #include "mock_kernel.h"
36 #include "pacs.h"
37 
38 #include "test_common.h"
39 #include "ztest_assert.h"
40 
41 DEFINE_FFF_GLOBALS;
42 
mock_init_rule_before(const struct ztest_unit_test * test,void * fixture)43 static void mock_init_rule_before(const struct ztest_unit_test *test, void *fixture)
44 {
45 	test_mocks_init();
46 }
47 
mock_destroy_rule_after(const struct ztest_unit_test * test,void * fixture)48 static void mock_destroy_rule_after(const struct ztest_unit_test *test, void *fixture)
49 {
50 	test_mocks_cleanup();
51 }
52 
53 ZTEST_RULE(mock_rule, mock_init_rule_before, mock_destroy_rule_after);
54 
55 struct ascs_test_suite_fixture {
56 	const struct bt_gatt_attr *ase_cp;
57 	struct bt_bap_stream stream;
58 	struct bt_conn conn;
59 	struct {
60 		uint8_t id;
61 		const struct bt_gatt_attr *attr;
62 	} ase_snk, ase_src;
63 };
64 
ascs_test_suite_fixture_init(struct ascs_test_suite_fixture * fixture)65 static void ascs_test_suite_fixture_init(struct ascs_test_suite_fixture *fixture)
66 {
67 	struct bt_bap_unicast_server_register_param param = {
68 		CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
69 		CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
70 	};
71 	int err;
72 
73 	memset(fixture, 0, sizeof(*fixture));
74 
75 	err = bt_bap_unicast_server_register(&param);
76 	zassert_equal(err, 0, "Unexpected err response %d", err);
77 
78 	fixture->ase_cp = test_ase_control_point_get();
79 
80 	test_conn_init(&fixture->conn);
81 
82 	test_ase_snk_get(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, &fixture->ase_snk.attr);
83 	if (fixture->ase_snk.attr != NULL) {
84 		fixture->ase_snk.id = test_ase_id_get(fixture->ase_snk.attr);
85 	}
86 
87 	test_ase_src_get(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, &fixture->ase_src.attr);
88 	if (fixture->ase_src.attr != NULL) {
89 		fixture->ase_src.id = test_ase_id_get(fixture->ase_src.attr);
90 	}
91 }
92 
ascs_test_suite_setup(void)93 static void *ascs_test_suite_setup(void)
94 {
95 	struct ascs_test_suite_fixture *fixture;
96 
97 	fixture = malloc(sizeof(*fixture));
98 	zassert_not_null(fixture);
99 
100 	return fixture;
101 }
102 
ascs_test_suite_before(void * f)103 static void ascs_test_suite_before(void *f)
104 {
105 	memset(f, 0, sizeof(struct ascs_test_suite_fixture));
106 	ascs_test_suite_fixture_init(f);
107 }
108 
ascs_test_suite_teardown(void * f)109 static void ascs_test_suite_teardown(void *f)
110 {
111 	free(f);
112 }
113 
ascs_test_suite_after(void * f)114 static void ascs_test_suite_after(void *f)
115 {
116 	int err;
117 
118 	/* If any of these fails, it's a fatal error for any tests running afterwards */
119 	err = bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb);
120 	zassert_true(err == 0 || err == -EALREADY, "Unexpected err response %d", err);
121 
122 	/* Sleep to trigger any pending state changes from unregister_cb */
123 	k_sleep(K_SECONDS(1));
124 
125 	err = bt_bap_unicast_server_unregister();
126 	zassert_equal(err, 0, "Unexpected err response %d", err);
127 }
128 
129 ZTEST_SUITE(ascs_test_suite, NULL, ascs_test_suite_setup, ascs_test_suite_before,
130 	    ascs_test_suite_after, ascs_test_suite_teardown);
131 
ZTEST_F(ascs_test_suite,test_has_sink_ase_chrc)132 ZTEST_F(ascs_test_suite, test_has_sink_ase_chrc)
133 {
134 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SNK);
135 
136 	zassert_not_null(fixture->ase_snk.attr);
137 }
138 
ZTEST_F(ascs_test_suite,test_has_source_ase_chrc)139 ZTEST_F(ascs_test_suite, test_has_source_ase_chrc)
140 {
141 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
142 
143 	zassert_not_null(fixture->ase_src.attr);
144 }
145 
ZTEST_F(ascs_test_suite,test_has_control_point_chrc)146 ZTEST_F(ascs_test_suite, test_has_control_point_chrc)
147 {
148 	zassert_not_null(fixture->ase_cp);
149 }
150 
ZTEST_F(ascs_test_suite,test_sink_ase_read_state_idle)151 ZTEST_F(ascs_test_suite, test_sink_ase_read_state_idle)
152 {
153 	const struct bt_gatt_attr *ase = fixture->ase_snk.attr;
154 	struct bt_conn *conn = &fixture->conn;
155 	struct test_ase_chrc_value_hdr hdr = { 0xff };
156 	ssize_t ret;
157 
158 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SNK);
159 	zexpect_not_null(fixture->ase_snk.attr);
160 
161 	ret = ase->read(conn, ase, &hdr, sizeof(hdr), 0);
162 	zassert_false(ret < 0, "attr->read returned unexpected (err 0x%02x)", BT_GATT_ERR(ret));
163 	zassert_equal(0x00, hdr.ase_state, "unexpected ASE_State 0x%02x", hdr.ase_state);
164 }
165 
ZTEST_F(ascs_test_suite,test_release_ase_on_callback_unregister)166 ZTEST_F(ascs_test_suite, test_release_ase_on_callback_unregister)
167 {
168 	const struct test_ase_chrc_value_hdr *hdr;
169 	const struct bt_gatt_attr *ase;
170 	struct bt_bap_stream *stream = &fixture->stream;
171 	struct bt_conn *conn = &fixture->conn;
172 	struct bt_gatt_notify_params *notify_params;
173 	uint8_t ase_id;
174 	int err;
175 
176 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
177 		ase = fixture->ase_snk.attr;
178 		ase_id = fixture->ase_snk.id;
179 	} else {
180 		ase = fixture->ase_src.attr;
181 		ase_id = fixture->ase_src.id;
182 	}
183 
184 	zexpect_not_null(ase);
185 	zexpect_true(ase_id != 0x00);
186 
187 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
188 	zassert_equal(err, 0, "unexpected err response %d", err);
189 
190 	/* Set ASE to non-idle state */
191 	test_ase_control_client_config_codec(conn, ase_id, stream);
192 
193 	/* Reset mock, as we expect ASE notification to be sent */
194 	bt_gatt_notify_cb_reset();
195 
196 	/* Unregister the callbacks - whis will clean up the ASCS */
197 	bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb);
198 
199 	/* Expected to notify the upper layers */
200 	expect_bt_bap_unicast_server_cb_release_called_once(stream);
201 	expect_bt_bap_stream_ops_released_called_once(stream);
202 
203 	/* Expected to notify the client */
204 	expect_bt_gatt_notify_cb_called_once(conn, ase->uuid, ase, EMPTY, sizeof(*hdr));
205 
206 	notify_params = mock_bt_gatt_notify_cb_fake.arg1_val;
207 	hdr = (void *)notify_params->data;
208 	zassert_equal(0x00, hdr->ase_state, "unexpected ASE_State 0x%02x", hdr->ase_state);
209 }
210 
ZTEST_F(ascs_test_suite,test_abort_client_operation_if_callback_not_registered)211 ZTEST_F(ascs_test_suite, test_abort_client_operation_if_callback_not_registered)
212 {
213 	const struct test_ase_cp_chrc_value_param *param;
214 	const struct test_ase_cp_chrc_value_hdr *hdr;
215 	const struct bt_gatt_attr *ase_cp = fixture->ase_cp;
216 	struct bt_bap_stream *stream = &fixture->stream;
217 	struct bt_conn *conn = &fixture->conn;
218 	struct bt_gatt_notify_params *notify_params;
219 	uint8_t ase_id;
220 
221 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
222 		ase_id = fixture->ase_snk.id;
223 	} else {
224 		ase_id = fixture->ase_src.id;
225 	}
226 
227 	zexpect_not_null(ase_cp);
228 	zexpect_true(ase_id != 0x00);
229 
230 	/* Set ASE to non-idle state */
231 	test_ase_control_client_config_codec(conn, ase_id, stream);
232 
233 	/* Expected ASE Control Point notification with Unspecified Error was sent */
234 	expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp,
235 					     EMPTY, TEST_ASE_CP_CHRC_VALUE_SIZE(1));
236 
237 	notify_params = mock_bt_gatt_notify_cb_fake.arg1_val;
238 	hdr = (void *)notify_params->data;
239 	zassert_equal(0x01, hdr->opcode, "unexpected Opcode 0x%02x", hdr->opcode);
240 	zassert_equal(0x01, hdr->number_of_ases, "unexpected Number_of_ASEs 0x%02x",
241 		      hdr->number_of_ases);
242 	param = (void *)hdr->params;
243 	zassert_equal(ase_id, param->ase_id, "unexpected ASE_ID 0x%02x", param->ase_id);
244 	/* Expect Unspecified Error */
245 	zassert_equal(0x0E, param->response_code, "unexpected Response_Code 0x%02x",
246 		      param->response_code);
247 	zassert_equal(0x00, param->reason, "unexpected Reason 0x%02x", param->reason);
248 }
249 
ZTEST_F(ascs_test_suite,test_release_ase_on_acl_disconnection)250 ZTEST_F(ascs_test_suite, test_release_ase_on_acl_disconnection)
251 {
252 	struct bt_bap_stream *stream = &fixture->stream;
253 	struct bt_conn *conn = &fixture->conn;
254 	const struct bt_gatt_attr *ase;
255 	struct bt_iso_chan *chan;
256 	uint8_t ase_id;
257 	int err;
258 
259 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
260 		ase = fixture->ase_snk.attr;
261 		ase_id = fixture->ase_snk.id;
262 	} else {
263 		ase = fixture->ase_src.attr;
264 		ase_id = fixture->ase_src.id;
265 	}
266 
267 	zexpect_not_null(ase);
268 	zexpect_true(ase_id != 0x00);
269 
270 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
271 	zassert_equal(err, 0, "unexpected err response %d", err);
272 
273 	/* Set ASE to non-idle state */
274 	test_preamble_state_streaming(conn, ase_id, stream, &chan,
275 				      !IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK));
276 
277 	/* Mock ACL disconnection */
278 	mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT);
279 
280 	/* Expected to notify the upper layers */
281 	expect_bt_bap_stream_ops_released_called_once(stream);
282 
283 	/* Mock CIS disconnection */
284 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT);
285 }
286 
ZTEST_F(ascs_test_suite,test_release_ase_pair_on_acl_disconnection)287 ZTEST_F(ascs_test_suite, test_release_ase_pair_on_acl_disconnection)
288 {
289 	const struct bt_gatt_attr *ase_snk, *ase_src;
290 	struct bt_bap_stream snk_stream, src_stream;
291 	struct bt_conn *conn = &fixture->conn;
292 	uint8_t ase_snk_id, ase_src_id;
293 	struct bt_iso_chan *chan;
294 	int err;
295 
296 	if (CONFIG_BT_ASCS_MAX_ACTIVE_ASES < 2) {
297 		ztest_test_skip();
298 	}
299 
300 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SNK);
301 	memset(&snk_stream, 0, sizeof(snk_stream));
302 	ase_snk = fixture->ase_snk.attr;
303 	zexpect_not_null(ase_snk);
304 	ase_snk_id = fixture->ase_snk.id;
305 	zexpect_true(ase_snk_id != 0x00);
306 
307 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
308 	memset(&src_stream, 0, sizeof(src_stream));
309 	ase_src = fixture->ase_src.attr;
310 	zexpect_not_null(ase_src);
311 	ase_src_id = fixture->ase_src.id;
312 	zexpect_true(ase_src_id != 0x00);
313 
314 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
315 	zassert_equal(err, 0, "unexpected err response %d", err);
316 
317 	test_ase_control_client_config_codec(conn, ase_snk_id, &snk_stream);
318 	test_ase_control_client_config_qos(conn, ase_snk_id);
319 	test_ase_control_client_enable(conn, ase_snk_id);
320 
321 	test_ase_control_client_config_codec(conn, ase_src_id, &src_stream);
322 	test_ase_control_client_config_qos(conn, ase_src_id);
323 	test_ase_control_client_enable(conn, ase_src_id);
324 
325 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
326 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
327 
328 	test_ase_control_client_receiver_start_ready(conn, ase_src_id);
329 
330 	err = bt_bap_stream_start(&snk_stream);
331 	zassert_equal(0, err, "bt_bap_stream_start err %d", err);
332 
333 	test_mocks_reset();
334 
335 	/* Mock ACL disconnection */
336 	mock_bt_conn_disconnected(conn, BT_HCI_ERR_CONN_TIMEOUT);
337 
338 	/* Expected to notify the upper layers */
339 	const struct bt_bap_stream *streams[2] = { &snk_stream, &src_stream };
340 
341 	expect_bt_bap_stream_ops_released_called(streams, 2);
342 
343 	/* Mock CIS disconnection */
344 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT);
345 }
346 
ZTEST_F(ascs_test_suite,test_recv_in_streaming_state)347 ZTEST_F(ascs_test_suite, test_recv_in_streaming_state)
348 {
349 	struct bt_bap_stream *stream = &fixture->stream;
350 	struct bt_conn *conn = &fixture->conn;
351 	uint8_t ase_id = fixture->ase_snk.id;
352 	struct bt_iso_recv_info info = {
353 		.seq_num = 1,
354 		.flags = BT_ISO_FLAGS_VALID,
355 	};
356 	struct bt_iso_chan *chan;
357 	struct net_buf buf;
358 	int err;
359 
360 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SNK);
361 
362 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
363 	zassert_equal(err, 0, "unexpected err response %d", err);
364 
365 	test_preamble_state_streaming(conn, ase_id, stream, &chan, false);
366 
367 	chan->ops->recv(chan, &info, &buf);
368 
369 	/* Verification */
370 	expect_bt_bap_stream_ops_recv_called_once(stream, &info, &buf);
371 }
372 
ZTEST_F(ascs_test_suite,test_recv_in_enabling_state)373 ZTEST_F(ascs_test_suite, test_recv_in_enabling_state)
374 {
375 	struct bt_bap_stream *stream = &fixture->stream;
376 	struct bt_conn *conn = &fixture->conn;
377 	uint8_t ase_id = fixture->ase_snk.id;
378 	struct bt_iso_recv_info info = {
379 		.seq_num = 1,
380 		.flags = BT_ISO_FLAGS_VALID,
381 	};
382 	struct bt_iso_chan *chan;
383 	struct net_buf buf;
384 	int err;
385 
386 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SNK);
387 
388 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
389 	zassert_equal(err, 0, "unexpected err response %d", err);
390 
391 	test_preamble_state_enabling(conn, ase_id, stream);
392 
393 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
394 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
395 
396 	test_mocks_reset();
397 
398 	chan->ops->recv(chan, &info, &buf);
399 
400 	/* Verification */
401 	expect_bt_bap_stream_ops_recv_not_called();
402 }
403 
ZTEST_F(ascs_test_suite,test_cis_link_loss_in_streaming_state)404 ZTEST_F(ascs_test_suite, test_cis_link_loss_in_streaming_state)
405 {
406 	struct bt_bap_stream *stream = &fixture->stream;
407 	struct bt_conn *conn = &fixture->conn;
408 	const struct bt_gatt_attr *ase;
409 	struct bt_iso_chan *chan;
410 	uint8_t ase_id;
411 	int err;
412 
413 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
414 		ase = fixture->ase_snk.attr;
415 		ase_id = fixture->ase_snk.id;
416 	} else {
417 		ase = fixture->ase_src.attr;
418 		ase_id = fixture->ase_src.id;
419 	}
420 	zexpect_not_null(ase);
421 	zexpect_true(ase_id != 0x00);
422 
423 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
424 	zassert_equal(err, 0, "unexpected err response %d", err);
425 
426 	test_preamble_state_streaming(conn, ase_id, stream, &chan,
427 				      !IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK));
428 
429 	/* Mock CIS disconnection */
430 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT);
431 
432 	/* Expected to notify the upper layers */
433 	expect_bt_bap_stream_ops_qos_set_called_once(stream);
434 	expect_bt_bap_stream_ops_disabled_called_once(stream);
435 	expect_bt_bap_stream_ops_released_not_called();
436 	expect_bt_bap_stream_ops_disconnected_called_once(stream);
437 }
438 
test_cis_link_loss_in_disabling_state(struct ascs_test_suite_fixture * fixture,bool streaming)439 static void test_cis_link_loss_in_disabling_state(struct ascs_test_suite_fixture *fixture,
440 						  bool streaming)
441 {
442 	struct bt_bap_stream *stream = &fixture->stream;
443 	struct bt_conn *conn = &fixture->conn;
444 	const struct bt_gatt_attr *ase;
445 	struct bt_iso_chan *chan;
446 	uint8_t ase_id;
447 	int err;
448 
449 	Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
450 
451 	ase = fixture->ase_src.attr;
452 	ase_id = fixture->ase_src.id;
453 	zexpect_not_null(ase);
454 	zexpect_true(ase_id != 0x00);
455 
456 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
457 	zassert_equal(err, 0, "unexpected err response %d", err);
458 
459 	test_preamble_state_enabling(conn, ase_id, stream);
460 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
461 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
462 
463 	if (streaming) {
464 		test_ase_control_client_receiver_start_ready(conn, ase_id);
465 	}
466 
467 	test_ase_control_client_disable(conn, ase_id);
468 
469 	expect_bt_bap_stream_ops_disabled_called_once(stream);
470 
471 	test_mocks_reset();
472 
473 	/* Mock CIS disconnection */
474 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT);
475 
476 	/* Expected to notify the upper layers */
477 	expect_bt_bap_stream_ops_qos_set_called_once(stream);
478 	expect_bt_bap_stream_ops_disabled_not_called();
479 	expect_bt_bap_stream_ops_released_not_called();
480 	expect_bt_bap_stream_ops_disconnected_called_once(stream);
481 }
482 
ZTEST_F(ascs_test_suite,test_cis_link_loss_in_disabling_state_v1)483 ZTEST_F(ascs_test_suite, test_cis_link_loss_in_disabling_state_v1)
484 {
485 	/* Enabling -> Streaming -> Disabling */
486 	test_cis_link_loss_in_disabling_state(fixture, true);
487 }
488 
ZTEST_F(ascs_test_suite,test_cis_link_loss_in_disabling_state_v2)489 ZTEST_F(ascs_test_suite, test_cis_link_loss_in_disabling_state_v2)
490 {
491 	/* Enabling -> Disabling */
492 	test_cis_link_loss_in_disabling_state(fixture, false);
493 }
494 
ZTEST_F(ascs_test_suite,test_cis_link_loss_in_enabling_state)495 ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state)
496 {
497 	struct bt_bap_stream *stream = &fixture->stream;
498 	struct bt_conn *conn = &fixture->conn;
499 	const struct bt_gatt_attr *ase;
500 	struct bt_iso_chan *chan;
501 	uint8_t ase_id;
502 	int err;
503 
504 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
505 		ase = fixture->ase_snk.attr;
506 		ase_id = fixture->ase_snk.id;
507 	} else {
508 		ase = fixture->ase_src.attr;
509 		ase_id = fixture->ase_src.id;
510 	}
511 	zexpect_not_null(ase);
512 	zexpect_true(ase_id != 0x00);
513 
514 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
515 	zassert_equal(err, 0, "unexpected err response %d", err);
516 
517 	test_preamble_state_enabling(conn, ase_id, stream);
518 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
519 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
520 
521 	/* Mock CIS disconnection */
522 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_TIMEOUT);
523 
524 	/* Expected no change in ASE state */
525 	expect_bt_bap_stream_ops_qos_set_not_called();
526 	expect_bt_bap_stream_ops_released_not_called();
527 	expect_bt_bap_stream_ops_disconnected_called_once(stream);
528 
529 	err = bt_bap_stream_disable(stream);
530 	zassert_equal(0, err, "Failed to disable stream: err %d", err);
531 
532 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
533 		expect_bt_bap_stream_ops_qos_set_called_once(stream);
534 		expect_bt_bap_stream_ops_disabled_called_once(stream);
535 	} else {
536 		/* Server-initiated disable operation that shall not cause transition to QoS */
537 		expect_bt_bap_stream_ops_qos_set_not_called();
538 	}
539 }
540 
ZTEST_F(ascs_test_suite,test_cis_link_loss_in_enabling_state_client_retries)541 ZTEST_F(ascs_test_suite, test_cis_link_loss_in_enabling_state_client_retries)
542 {
543 	struct bt_bap_stream *stream = &fixture->stream;
544 	struct bt_conn *conn = &fixture->conn;
545 	const struct bt_gatt_attr *ase;
546 	struct bt_iso_chan *chan;
547 	uint8_t ase_id;
548 	int err;
549 
550 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
551 		ase = fixture->ase_snk.attr;
552 		ase_id = fixture->ase_snk.id;
553 	} else {
554 		ase = fixture->ase_src.attr;
555 		ase_id = fixture->ase_src.id;
556 	}
557 	zexpect_not_null(ase);
558 	zexpect_true(ase_id != 0x00);
559 
560 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
561 	zassert_equal(err, 0, "unexpected err response %d", err);
562 
563 	test_preamble_state_enabling(conn, ase_id, stream);
564 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
565 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
566 	expect_bt_bap_stream_ops_connected_called_once(stream);
567 
568 	/* Mock CIS disconnection */
569 	mock_bt_iso_disconnected(chan, BT_HCI_ERR_CONN_FAIL_TO_ESTAB);
570 
571 	/* Expected to not notify the upper layers */
572 	expect_bt_bap_stream_ops_qos_set_not_called();
573 	expect_bt_bap_stream_ops_released_not_called();
574 	expect_bt_bap_stream_ops_disconnected_called_once(stream);
575 
576 	/* Client retries to establish CIS */
577 	err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
578 	zassert_equal(0, err, "Failed to connect iso: err %d", err);
579 	if (!IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
580 		test_ase_control_client_receiver_start_ready(conn, ase_id);
581 	} else {
582 		err = bt_bap_stream_start(stream);
583 		zassert_equal(0, err, "bt_bap_stream_start err %d", err);
584 	}
585 
586 	expect_bt_bap_stream_ops_connected_called_twice(stream);
587 	expect_bt_bap_stream_ops_started_called_once(stream);
588 }
589 
590 static struct bt_bap_stream *stream_allocated;
591 static const struct bt_bap_qos_cfg_pref qos_pref =
592 	BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000);
593 
unicast_server_cb_config_custom_fake(struct bt_conn * conn,const struct bt_bap_ep * ep,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_stream ** stream,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)594 static int unicast_server_cb_config_custom_fake(struct bt_conn *conn, const struct bt_bap_ep *ep,
595 						enum bt_audio_dir dir,
596 						const struct bt_audio_codec_cfg *codec_cfg,
597 						struct bt_bap_stream **stream,
598 						struct bt_bap_qos_cfg_pref *const pref,
599 						struct bt_bap_ascs_rsp *rsp)
600 {
601 	*stream = stream_allocated;
602 	*pref = qos_pref;
603 	*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
604 
605 	bt_bap_stream_cb_register(*stream, &mock_bap_stream_ops);
606 
607 	return 0;
608 }
609 
ZTEST_F(ascs_test_suite,test_ase_state_notification_retry)610 ZTEST_F(ascs_test_suite, test_ase_state_notification_retry)
611 {
612 	struct bt_bap_stream *stream = &fixture->stream;
613 	struct bt_conn *conn = &fixture->conn;
614 	const struct bt_gatt_attr *ase, *cp;
615 	struct bt_conn_info info;
616 	uint8_t ase_id;
617 	int err;
618 
619 	if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
620 		ase = fixture->ase_snk.attr;
621 		ase_id = fixture->ase_snk.id;
622 	} else {
623 		ase = fixture->ase_src.attr;
624 		ase_id = fixture->ase_src.id;
625 	}
626 
627 	zexpect_not_null(ase);
628 	zassert_not_equal(ase_id, 0x00);
629 
630 	cp = test_ase_control_point_get();
631 	zexpect_not_null(cp);
632 
633 	err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
634 	zassert_equal(err, 0, "unexpected err response %d", err);
635 
636 	stream_allocated = stream;
637 	mock_bap_unicast_server_cb_config_fake.custom_fake = unicast_server_cb_config_custom_fake;
638 
639 	/* Mock out of buffers case */
640 	mock_bt_gatt_notify_cb_fake.return_val = -ENOMEM;
641 
642 	const uint8_t buf[] = {
643 		0x01,           /* Opcode = Config Codec */
644 		0x01,           /* Number_of_ASEs */
645 		ase_id,         /* ASE_ID[0] */
646 		0x01,           /* Target_Latency[0] = Target low latency */
647 		0x02,           /* Target_PHY[0] = LE 2M PHY */
648 		0x06,           /* Codec_ID[0].Coding_Format = LC3 */
649 		0x00, 0x00,     /* Codec_ID[0].Company_ID */
650 		0x00, 0x00,     /* Codec_ID[0].Vendor_Specific_Codec_ID */
651 		0x00,           /* Codec_Specific_Configuration_Length[0] */
652 	};
653 
654 	cp->write(conn, cp, (void *)buf, sizeof(buf), 0, 0);
655 
656 	/* Verification */
657 	expect_bt_bap_stream_ops_configured_not_called();
658 
659 	mock_bt_gatt_notify_cb_fake.return_val = 0;
660 
661 	err = bt_conn_get_info(conn, &info);
662 	zassert_equal(err, 0);
663 
664 	/* Wait for ASE state notification retry */
665 	k_sleep(K_MSEC(BT_CONN_INTERVAL_TO_MS(info.le.interval)));
666 
667 	expect_bt_bap_stream_ops_configured_called_once(stream, EMPTY);
668 }
669