1 /* test_ase_control_params.c - ASE Control Operations with invalid arguments */
2
3 /*
4 * Copyright (c) 2023 Codecoup
5 * Copyright (c) 2024 Demant A/S
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <zephyr/bluetooth/gap.h>
13 #include <zephyr/bluetooth/iso.h>
14 #include <zephyr/bluetooth/uuid.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/toolchain.h>
17 #include <zephyr/types.h>
18 #include <zephyr/bluetooth/audio/audio.h>
19 #include <zephyr/bluetooth/audio/bap.h>
20 #include <zephyr/bluetooth/conn.h>
21 #include <zephyr/bluetooth/gatt.h>
22 #include <zephyr/sys/util_macro.h>
23 #include <zephyr/ztest_assert.h>
24 #include <zephyr/ztest_test.h>
25 #include <sys/types.h>
26
27 #include "bap_unicast_server.h"
28 #include "bap_stream.h"
29 #include "conn.h"
30 #include "gatt_expects.h"
31 #include "iso.h"
32
33 #include "test_common.h"
34
35 struct test_ase_control_params_fixture {
36 struct bt_conn conn;
37 struct bt_bap_stream stream;
38 const struct bt_gatt_attr *ase_cp;
39 const struct bt_gatt_attr *ase;
40 };
41
test_ase_control_params_setup(void)42 static void *test_ase_control_params_setup(void)
43 {
44 struct test_ase_control_params_fixture *fixture;
45
46 fixture = malloc(sizeof(*fixture));
47 zassert_not_null(fixture);
48
49 return fixture;
50 }
51
test_ase_control_params_before(void * f)52 static void test_ase_control_params_before(void *f)
53 {
54 struct test_ase_control_params_fixture *fixture = f;
55 struct bt_bap_unicast_server_register_param param = {
56 CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
57 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
58 };
59 int err;
60
61 ARG_UNUSED(fixture);
62
63 err = bt_bap_unicast_server_register(¶m);
64 zassert_equal(err, 0, "unexpected err response %d", err);
65
66 err = bt_bap_unicast_server_register_cb(&mock_bap_unicast_server_cb);
67 zassert_equal(err, 0, "unexpected err response %d", err);
68
69 test_conn_init(&fixture->conn);
70 fixture->ase_cp = test_ase_control_point_get();
71
72 if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SNK)) {
73 test_ase_snk_get(CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT, &fixture->ase);
74 } else {
75 test_ase_src_get(CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT, &fixture->ase);
76 }
77
78 }
79
test_ase_control_params_after(void * f)80 static void test_ase_control_params_after(void *f)
81 {
82 int err;
83
84 err = bt_bap_unicast_server_unregister_cb(&mock_bap_unicast_server_cb);
85 zassert_equal(err, 0, "unexpected err response %d", err);
86
87 /* Sleep to trigger any pending state changes from unregister_cb */
88 k_sleep(K_SECONDS(1));
89
90 err = bt_bap_unicast_server_unregister();
91 zassert_equal(err, 0, "Unexpected err response %d", err);
92 }
93
test_ase_control_params_teardown(void * f)94 static void test_ase_control_params_teardown(void *f)
95 {
96 struct test_ase_control_params_fixture *fixture = f;
97
98 free(fixture);
99 }
100
101 ZTEST_SUITE(test_ase_control_params, NULL, test_ase_control_params_setup,
102 test_ase_control_params_before, test_ase_control_params_after,
103 test_ase_control_params_teardown);
104
ZTEST_F(test_ase_control_params,test_sink_ase_control_operation_zero_length_write)105 ZTEST_F(test_ase_control_params, test_sink_ase_control_operation_zero_length_write)
106 {
107 uint8_t buf[] = {};
108 ssize_t ret;
109
110 ret = fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, (void *)buf, 0, 0, 0);
111 zassert_true(ret < 0, "ase_cp_attr->write returned unexpected (err 0x%02x)",
112 BT_GATT_ERR(ret));
113 }
114
test_expect_unsupported_opcode(struct test_ase_control_params_fixture * fixture,uint8_t opcode)115 static void test_expect_unsupported_opcode(struct test_ase_control_params_fixture *fixture,
116 uint8_t opcode)
117 {
118 const uint8_t buf[] = {
119 opcode, /* Opcode */
120 0x01, /* Number_of_ASEs */
121 0x01, /* ASE_ID[0] */
122 };
123 const uint8_t data_expected[] = {
124 opcode, /* Opcode */
125 0xFF, /* Number_of_ASEs */
126 0x00, /* ASE_ID[0] */
127 0x01, /* Response_Code[0] = Unsupported Opcode */
128 0x00, /* Reason[0] */
129 };
130
131 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, (void *)buf, sizeof(buf), 0, 0);
132
133 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
134 fixture->ase_cp, data_expected, sizeof(data_expected));
135 }
136
ZTEST_F(test_ase_control_params,test_unsupported_opcode_0x00)137 ZTEST_F(test_ase_control_params, test_unsupported_opcode_0x00)
138 {
139 test_expect_unsupported_opcode(fixture, 0x00);
140 }
141
ZTEST_F(test_ase_control_params,test_unsupported_opcode_rfu)142 ZTEST_F(test_ase_control_params, test_unsupported_opcode_rfu)
143 {
144 test_expect_unsupported_opcode(fixture, 0x09);
145 }
146
test_codec_configure_expect_invalid_length(struct test_ase_control_params_fixture * fixture,const uint8_t * buf,size_t len)147 static void test_codec_configure_expect_invalid_length(
148 struct test_ase_control_params_fixture *fixture, const uint8_t *buf, size_t len)
149 {
150 const uint8_t data_expected[] = {
151 0x01, /* Opcode = Config Codec */
152 0xFF, /* Number_of_ASEs */
153 0x00, /* ASE_ID[0] */
154 0x02, /* Response_Code[0] = Invalid Length */
155 0x00, /* Reason[0] */
156 };
157
158 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, len, 0, 0);
159
160 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
161 fixture->ase_cp, data_expected, sizeof(data_expected));
162 }
163
164 /*
165 * Test correctly formatted ASE Control Point 'Invalid Length' notification is sent
166 *
167 * ASCS_v1.0; 5 ASE Control operations
168 * "A client-initiated ASE Control operation shall be defined as an invalid length operation
169 * if the Number_of_ASEs parameter value is less than 1"
170 *
171 * Constraints:
172 * - Number_of_ASEs is set to 0
173 * - Config Codec operation parameter array is valid
174 *
175 * Expected behaviour:
176 * - "If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be set to 0xFF."
177 * - ASE Control Point notification is correctly formatted
178 */
ZTEST_F(test_ase_control_params,test_codec_configure_number_of_ases_0x00)179 ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_0x00)
180 {
181 const uint8_t buf[] = {
182 0x01, /* Opcode = Config Codec */
183 0x00, /* Number_of_ASEs */
184 0x01, /* ASE_ID[0] */
185 0x01, /* Target_Latency[0] = Target low latency */
186 0x02, /* Target_PHY[0] = LE 2M PHY */
187 0x06, /* Codec_ID[0].Coding_Format = LC3 */
188 0x00, 0x00, /* Codec_ID[0].Company_ID */
189 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
190 0x00, /* Codec_Specific_Configuration_Length[0] */
191 };
192
193 test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf));
194 }
195
ZTEST_F(test_ase_control_params,test_codec_configure_number_of_ases_above_max)196 ZTEST_F(test_ase_control_params, test_codec_configure_number_of_ases_above_max)
197 {
198 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
199 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
200
201 /* Skip if number of ASEs configured is high enough to support any value in the write req */
202 if (ase_cnt > UINT8_MAX) {
203 ztest_test_skip();
204 }
205
206 const uint8_t buf[] = {
207 0x01, /* Opcode = Config Codec */
208 (uint8_t)ase_cnt, /* Number_of_ASEs */
209 0x01, /* ASE_ID[0] */
210 0x01, /* Target_Latency[0] = Target low latency */
211 0x02, /* Target_PHY[0] = LE 2M PHY */
212 0x06, /* Codec_ID[0].Coding_Format = LC3 */
213 0x00, 0x00, /* Codec_ID[0].Company_ID */
214 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
215 0x00, /* Codec_Specific_Configuration_Length[0] */
216 };
217
218 test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf));
219 }
220
221 /*
222 * Test correctly formatted ASE Control Point 'Invalid Length' notification is sent
223 *
224 * ASCS_v1.0; 5 ASE Control operations
225 * "A client-initiated ASE Control operation shall be defined as an invalid length operation(...)
226 * if the Number_of_ASEs parameter value does not match the number of parameter arrays written by
227 * the client"
228 *
229 * Constraints:
230 * - Number_of_ASEs is set to 1
231 * - Config Codec operation parameter arrays != Number_of_ASEs and is set to 2
232 *
233 * Expected behaviour:
234 * - "If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be set to 0xFF."
235 * - ASE Control Point notification is correctly formatted
236 */
ZTEST_F(test_ase_control_params,test_codec_configure_too_many_parameter_arrays)237 ZTEST_F(test_ase_control_params, test_codec_configure_too_many_parameter_arrays)
238 {
239 const uint8_t buf[] = {
240 0x01, /* Opcode = Config Codec */
241 0x01, /* Number_of_ASEs */
242 0x01, /* ASE_ID[0] */
243 0x01, /* Target_Latency[0] = Target low latency */
244 0x02, /* Target_PHY[0] = LE 2M PHY */
245 0x06, /* Codec_ID[0].Coding_Format = LC3 */
246 0x00, 0x00, /* Codec_ID[0].Company_ID */
247 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
248 0x00, /* Codec_Specific_Configuration_Length[0] */
249 0x02, /* ASE_ID[1] */
250 0x01, /* Target_Latency[1] = Target low latency */
251 0x02, /* Target_PHY[1] = LE 2M PHY */
252 0x06, /* Codec_ID[1].Coding_Format = LC3 */
253 0x00, 0x00, /* Codec_ID[1].Company_ID */
254 0x00, 0x00, /* Codec_ID[1].Vendor_Specific_Codec_ID */
255 0x00, /* Codec_Specific_Configuration_Length[1] */
256 };
257
258 test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf));
259 }
260
261 /*
262 * Test correctly formatted ASE Control Point 'Invalid Length' notification is sent
263 *
264 * ASCS_v1.0; 5 ASE Control operations
265 * "A client-initiated ASE Control operation shall be defined as an invalid length operation
266 * if the total length of all parameters written by the client is not equal to the total length
267 * of all fixed parameters plus the length of any variable length parameters for that operation"
268 *
269 * Constraints:
270 * - Number_of_ASEs is set to 1
271 * - Config Codec operation parameter arrays == Number_of_ASEs
272 * - Codec_Specific_Configuration_Length[i] > sizeof(Codec_Specific_Configuration[i])
273 *
274 * Expected behaviour:
275 * - "If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be set to 0xFF."
276 * - ASE Control Point notification is correctly formatted
277 */
ZTEST_F(test_ase_control_params,test_codec_specific_configuration_too_short)278 ZTEST_F(test_ase_control_params, test_codec_specific_configuration_too_short)
279 {
280 const uint8_t buf[] = {
281 0x01, /* Opcode = Config Codec */
282 0x01, /* Number_of_ASEs */
283 0x01, /* ASE_ID[0] */
284 0x01, /* Target_Latency[0] = Target low latency */
285 0x02, /* Target_PHY[0] = LE 2M PHY */
286 0x06, /* Codec_ID[0].Coding_Format = LC3 */
287 0x00, 0x00, /* Codec_ID[0].Company_ID */
288 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
289 0x05, /* Codec_Specific_Configuration_Length[0] */
290 0x00, 0x00, /* Codec_Specific_Configuration[0] */
291 0x00, 0x00,
292 };
293
294 test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf));
295 }
296
297 /*
298 * Test correctly formatted ASE Control Point 'Invalid Length' notification is sent
299 *
300 * ASCS_v1.0; 5 ASE Control operations
301 * "A client-initiated ASE Control operation shall be defined as an invalid length operation
302 * if the total length of all parameters written by the client is not equal to the total length
303 * of all fixed parameters plus the length of any variable length parameters for that operation"
304 *
305 * Constraints:
306 * - Number_of_ASEs is set to 1
307 * - Config Codec operation parameter arrays == Number_of_ASEs
308 * - Codec_Specific_Configuration_Length[i] < sizeof(Codec_Specific_Configuration[i])
309 *
310 * Expected behaviour:
311 * - "If the Response_Code value is 0x01 or 0x02, Number_of_ASEs shall be set to 0xFF."
312 * - ASE Control Point notification is correctly formatted
313 */
ZTEST_F(test_ase_control_params,test_codec_specific_configuration_too_long)314 ZTEST_F(test_ase_control_params, test_codec_specific_configuration_too_long)
315 {
316 const uint8_t buf[] = {
317 0x01, /* Opcode = Config Codec */
318 0x01, /* Number_of_ASEs */
319 0x01, /* ASE_ID[0] */
320 0x01, /* Target_Latency[0] = Target low latency */
321 0x02, /* Target_PHY[0] = LE 2M PHY */
322 0x06, /* Codec_ID[0].Coding_Format = LC3 */
323 0x00, 0x00, /* Codec_ID[0].Company_ID */
324 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
325 0x05, /* Codec_Specific_Configuration_Length[0] */
326 0x00, 0x00, /* Codec_Specific_Configuration[0] */
327 0x00, 0x00,
328 0x00, 0x00,
329 };
330
331 test_codec_configure_expect_invalid_length(fixture, buf, sizeof(buf));
332 }
333
334 /*
335 * Test correctly formatted ASE Control Point 'Invalid ASE_ID' notification is sent
336 *
337 * Constraints:
338 * - Number_of_ASEs is set to 1
339 * - Requested ASE_ID is not present on the server.
340 *
341 * Expected behaviour:
342 * - Correctly formatted ASE Control Point notification is sent with Invalid ASE_ID response code.
343 */
ZTEST_F(test_ase_control_params,test_codec_configure_invalid_ase_id_0x00)344 ZTEST_F(test_ase_control_params, test_codec_configure_invalid_ase_id_0x00)
345 {
346 const uint8_t ase_id_invalid = 0x00;
347 const uint8_t buf[] = {
348 0x01, /* Opcode = Config Codec */
349 0x01, /* Number_of_ASEs */
350 ase_id_invalid, /* ASE_ID[0] */
351 0x01, /* Target_Latency[0] = Target low latency */
352 0x02, /* Target_PHY[0] = LE 2M PHY */
353 0x06, /* Codec_ID[0].Coding_Format = LC3 */
354 0x00, 0x00, /* Codec_ID[0].Company_ID */
355 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
356 0x00, /* Codec_Specific_Configuration_Length[0] */
357 };
358 const uint8_t data_expected[] = {
359 0x01, /* Opcode = Config Codec */
360 0x01, /* Number_of_ASEs */
361 ase_id_invalid, /* ASE_ID[0] */
362 0x03, /* Response_Code[0] = Invalid ASE_ID */
363 0x00, /* Reason[0] */
364 };
365
366 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
367
368 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
369 fixture->ase_cp, data_expected, sizeof(data_expected));
370 }
371
372 static struct bt_bap_stream test_stream;
373 static const struct bt_bap_qos_cfg_pref qos_pref =
374 BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000);
375
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)376 static int unicast_server_cb_config_custom_fake(struct bt_conn *conn, const struct bt_bap_ep *ep,
377 enum bt_audio_dir dir,
378 const struct bt_audio_codec_cfg *codec_cfg,
379 struct bt_bap_stream **stream,
380 struct bt_bap_qos_cfg_pref *const pref,
381 struct bt_bap_ascs_rsp *rsp)
382 {
383 *stream = &test_stream;
384 *pref = qos_pref;
385 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
386
387 bt_bap_stream_cb_register(*stream, &mock_bap_stream_ops);
388
389 return 0;
390 }
391
ZTEST_F(test_ase_control_params,test_codec_configure_invalid_ase_id_unavailable)392 ZTEST_F(test_ase_control_params, test_codec_configure_invalid_ase_id_unavailable)
393 {
394 /* Test requires support for at least 2 ASEs */
395 if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) {
396 ztest_test_skip();
397 }
398
399 const uint8_t ase_id_valid = 0x01;
400 const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
401 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
402 const uint8_t buf[] = {
403 0x01, /* Opcode = Config Codec */
404 0x02, /* Number_of_ASEs */
405 ase_id_invalid, /* ASE_ID[0] */
406 0x01, /* Target_Latency[0] = Target low latency */
407 0x02, /* Target_PHY[0] = LE 2M PHY */
408 0x06, /* Codec_ID[0].Coding_Format = LC3 */
409 0x00, 0x00, /* Codec_ID[0].Company_ID */
410 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
411 0x04, /* Codec_Specific_Configuration_Length[0] */
412 0x00, 0x00, /* Codec_Specific_Configuration[0] */
413 0x00, 0x00,
414 ase_id_valid, /* ASE_ID[1] */
415 0x01, /* Target_Latency[1] = Target low latency */
416 0x02, /* Target_PHY[1] = LE 2M PHY */
417 0x06, /* Codec_ID[1].Coding_Format = LC3 */
418 0x00, 0x00, /* Codec_ID[1].Company_ID */
419 0x00, 0x00, /* Codec_ID[1].Vendor_Specific_Codec_ID */
420 0x00, /* Codec_Specific_Configuration_Length[1] */
421 };
422 const uint8_t data_expected[] = {
423 0x01, /* Opcode = Config Codec */
424 0x02, /* Number_of_ASEs */
425 ase_id_invalid, /* ASE_ID[0] */
426 0x03, /* Response_Code[0] = Invalid ASE_ID */
427 0x00, /* Reason[0] */
428 ase_id_valid, /* ASE_ID[1] */
429 0x00, /* Response_Code[1] = Success */
430 0x00, /* Reason[1] */
431 };
432
433 mock_bap_unicast_server_cb_config_fake.custom_fake = unicast_server_cb_config_custom_fake;
434
435 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
436
437 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
438 fixture->ase_cp, data_expected, sizeof(data_expected));
439 }
440
test_target_latency_out_of_range(struct test_ase_control_params_fixture * fixture,uint8_t target_latency)441 static void test_target_latency_out_of_range(struct test_ase_control_params_fixture *fixture,
442 uint8_t target_latency)
443 {
444 const uint8_t buf[] = {
445 0x01, /* Opcode = Config Codec */
446 0x01, /* Number_of_ASEs */
447 0x01, /* ASE_ID[0] */
448 target_latency, /* Target_Latency[0] */
449 0x02, /* Target_PHY[0] = LE 2M PHY */
450 0x06, /* Codec_ID[0].Coding_Format = LC3 */
451 0x00, 0x00, /* Codec_ID[0].Company_ID */
452 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
453 0x00, /* Codec_Specific_Configuration_Length[0] */
454 };
455 const uint8_t data_expected[] = {
456 0x01, /* Opcode = Config Codec */
457 0x01, /* Number_of_ASEs */
458 0x01, /* ASE_ID[0] */
459 0x00, /* Response_Code[0] = Success */
460 0x00, /* Reason[0] */
461 };
462
463 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
464
465 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
466 fixture->ase_cp, data_expected, sizeof(data_expected));
467 }
468
ZTEST_F(test_ase_control_params,test_target_latency_out_of_range_0x00)469 ZTEST_F(test_ase_control_params, test_target_latency_out_of_range_0x00)
470 {
471 /* TODO: Remove once resolved */
472 Z_TEST_SKIP_IFNDEF(BUG_55794);
473
474 test_target_latency_out_of_range(fixture, 0x00);
475 }
476
ZTEST_F(test_ase_control_params,test_target_latency_out_of_range_0x04)477 ZTEST_F(test_ase_control_params, test_target_latency_out_of_range_0x04)
478 {
479 /* TODO: Remove once resolved */
480 Z_TEST_SKIP_IFNDEF(BUG_55794);
481
482 test_target_latency_out_of_range(fixture, 0x04);
483 }
484
test_target_phy_out_of_range(struct test_ase_control_params_fixture * fixture,uint8_t target_phy)485 static void test_target_phy_out_of_range(struct test_ase_control_params_fixture *fixture,
486 uint8_t target_phy)
487 {
488 const uint8_t buf[] = {
489 0x01, /* Opcode = Config Codec */
490 0x01, /* Number_of_ASEs */
491 0x01, /* ASE_ID[0] */
492 0x01, /* Target_Latency[0] */
493 target_phy, /* Target_PHY[0] */
494 0x06, /* Codec_ID[0].Coding_Format = LC3 */
495 0x00, 0x00, /* Codec_ID[0].Company_ID */
496 0x00, 0x00, /* Codec_ID[0].Vendor_Specific_Codec_ID */
497 0x00, /* Codec_Specific_Configuration_Length[0] */
498 };
499 const uint8_t data_expected[] = {
500 0x01, /* Opcode = Config Codec */
501 0x01, /* Number_of_ASEs */
502 0x01, /* ASE_ID[0] */
503 0x00, /* Response_Code[0] = Success */
504 0x00, /* Reason[0] */
505 };
506
507 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
508
509 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
510 fixture->ase_cp, data_expected, sizeof(data_expected));
511 }
512
ZTEST_F(test_ase_control_params,test_target_phy_out_of_range_0x00)513 ZTEST_F(test_ase_control_params, test_target_phy_out_of_range_0x00)
514 {
515 /* TODO: Remove once resolved */
516 Z_TEST_SKIP_IFNDEF(BUG_55794);
517
518 test_target_phy_out_of_range(fixture, 0x00);
519 }
520
ZTEST_F(test_ase_control_params,test_target_phy_out_of_range_0x04)521 ZTEST_F(test_ase_control_params, test_target_phy_out_of_range_0x04)
522 {
523 /* TODO: Remove once resolved */
524 Z_TEST_SKIP_IFNDEF(BUG_55794);
525
526 test_target_phy_out_of_range(fixture, 0x04);
527 }
528
test_config_qos_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)529 static void test_config_qos_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
530 const struct bt_gatt_attr *ase_cp,
531 struct bt_bap_stream *stream,
532 const uint8_t *buf, size_t len)
533 {
534 const uint8_t data_expected[] = {
535 0x02, /* Opcode = Config QoS */
536 0xFF, /* Number_of_ASEs */
537 0x00, /* ASE_ID[0] */
538 0x02, /* Response_Code[0] = Invalid Length */
539 0x00, /* Reason[0] */
540 };
541
542 test_preamble_state_codec_configured(conn, ase_id, stream);
543
544 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
545
546 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
547 sizeof(data_expected));
548 }
549
ZTEST_F(test_ase_control_params,test_config_qos_number_of_ases_0x00)550 ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_0x00)
551 {
552 const uint8_t ase_id = test_ase_id_get(fixture->ase);
553 const uint8_t buf[] = {
554 0x02, /* Opcode = Config QoS */
555 0x00, /* Number_of_ASEs */
556 ase_id, /* ASE_ID[0] */
557 0x01, /* CIG_ID[0] */
558 0x01, /* CIS_ID[0] */
559 0xFF, 0x00, 0x00, /* SDU_Interval[0] */
560 0x00, /* Framing[0] */
561 0x02, /* PHY[0] */
562 0x64, 0x00, /* Max_SDU[0] */
563 0x02, /* Retransmission_Number[0] */
564 0x0A, 0x00, /* Max_Transport_Latency[0] */
565 0x40, 0x9C, 0x00, /* Presentation_Delay[0] */
566 };
567
568 test_config_qos_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
569 &fixture->stream, buf, sizeof(buf));
570 }
571
ZTEST_F(test_ase_control_params,test_config_qos_number_of_ases_above_max)572 ZTEST_F(test_ase_control_params, test_config_qos_number_of_ases_above_max)
573 {
574 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
575 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
576
577 /* Skip if number of ASEs configured is high enough to support any value in the write req */
578 if (ase_cnt > UINT8_MAX) {
579 ztest_test_skip();
580 }
581
582 const uint8_t ase_id = test_ase_id_get(fixture->ase);
583 const uint8_t buf[] = {
584 0x02, /* Opcode = Config QoS */
585 (uint8_t)ase_cnt, /* Number_of_ASEs */
586 ase_id, /* ASE_ID[0] */
587 0x01, /* CIG_ID[0] */
588 0x01, /* CIS_ID[0] */
589 0xFF, 0x00, 0x00, /* SDU_Interval[0] */
590 0x00, /* Framing[0] */
591 0x02, /* PHY[0] */
592 0x64, 0x00, /* Max_SDU[0] */
593 0x02, /* Retransmission_Number[0] */
594 0x0A, 0x00, /* Max_Transport_Latency[0] */
595 0x40, 0x9C, 0x00, /* Presentation_Delay[0] */
596 };
597
598 test_config_qos_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
599 &fixture->stream, buf, sizeof(buf));
600 }
601
ZTEST_F(test_ase_control_params,test_config_qos_too_short)602 ZTEST_F(test_ase_control_params, test_config_qos_too_short)
603 {
604 const uint8_t ase_id = test_ase_id_get(fixture->ase);
605 const uint8_t buf[] = {
606 0x02, /* Opcode = Config QoS */
607 0x01, /* Number_of_ASEs */
608 ase_id, /* ASE_ID[0] */
609 0x01, /* CIG_ID[0] */
610 0x01, /* CIS_ID[0] */
611 0xFF, 0x00, 0x00, /* SDU_Interval[0] */
612 0x00, /* Framing[0] */
613 0x02, /* PHY[0] */
614 0x64, 0x00, /* Max_SDU[0] */
615 0x02, /* Retransmission_Number[0] */
616 0x0A, 0x00, /* Max_Transport_Latency[0] */
617 0x40, 0x9C, 0x00, /* Presentation_Delay[0] */
618 0x00,
619 };
620
621 test_config_qos_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
622 &fixture->stream, buf, sizeof(buf));
623 }
624
ZTEST_F(test_ase_control_params,test_config_qos_too_long)625 ZTEST_F(test_ase_control_params, test_config_qos_too_long)
626 {
627 const uint8_t ase_id = test_ase_id_get(fixture->ase);
628 const uint8_t buf[] = {
629 0x02, /* Opcode = Config QoS */
630 0x01, /* Number_of_ASEs */
631 ase_id, /* ASE_ID[0] */
632 0x01, /* CIG_ID[0] */
633 0x01, /* CIS_ID[0] */
634 0xFF, 0x00, 0x00, /* SDU_Interval[0] */
635 0x00, /* Framing[0] */
636 0x02, /* PHY[0] */
637 0x64, 0x00, /* Max_SDU[0] */
638 0x02, /* Retransmission_Number[0] */
639 0x0A, 0x00, /* Max_Transport_Latency[0] */
640 0x40, 0x9C, /* Presentation_Delay[0] */
641 };
642
643 test_config_qos_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
644 &fixture->stream, buf, sizeof(buf));
645 }
646
test_enable_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)647 static void test_enable_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
648 const struct bt_gatt_attr *ase_cp,
649 struct bt_bap_stream *stream,
650 const uint8_t *buf, size_t len)
651 {
652 const uint8_t data_expected[] = {
653 0x03, /* Opcode = Enable */
654 0xFF, /* Number_of_ASEs */
655 0x00, /* ASE_ID[0] */
656 0x02, /* Response_Code[0] = Invalid Length */
657 0x00, /* Reason[0] */
658 };
659
660 test_preamble_state_qos_configured(conn, ase_id, stream);
661
662 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
663
664 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
665 sizeof(data_expected));
666 }
667
ZTEST_F(test_ase_control_params,test_enable_number_of_ases_0x00)668 ZTEST_F(test_ase_control_params, test_enable_number_of_ases_0x00)
669 {
670 const uint8_t ase_id = test_ase_id_get(fixture->ase);
671 const uint8_t buf[] = {
672 0x03, /* Opcode = Enable */
673 0x00, /* Number_of_ASEs */
674 ase_id, /* ASE_ID[0] */
675 0x00, /* Metadata_Length[0] */
676 };
677
678 test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream,
679 buf, sizeof(buf));
680 }
681
ZTEST_F(test_ase_control_params,test_enable_number_of_ases_above_max)682 ZTEST_F(test_ase_control_params, test_enable_number_of_ases_above_max)
683 {
684 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
685 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
686
687 /* Skip if number of ASEs configured is high enough to support any value in the write req */
688 if (ase_cnt > UINT8_MAX) {
689 ztest_test_skip();
690 }
691
692 const uint8_t ase_id = test_ase_id_get(fixture->ase);
693 const uint8_t buf[] = {
694 0x03, /* Opcode = Enable */
695 (uint8_t)ase_cnt, /* Number_of_ASEs */
696 ase_id, /* ASE_ID[0] */
697 0x00, /* Metadata_Length[0] */
698 };
699
700 test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream,
701 buf, sizeof(buf));
702 }
703
ZTEST_F(test_ase_control_params,test_enable_too_long)704 ZTEST_F(test_ase_control_params, test_enable_too_long)
705 {
706 const uint8_t ase_id = test_ase_id_get(fixture->ase);
707 const uint8_t buf[] = {
708 0x03, /* Opcode = Enable */
709 0x01, /* Number_of_ASEs */
710 ase_id, /* ASE_ID[0] */
711 0x00, /* Metadata_Length[0] */
712 0x00,
713 };
714
715 test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream,
716 buf, sizeof(buf));
717 }
718
ZTEST_F(test_ase_control_params,test_enable_too_short)719 ZTEST_F(test_ase_control_params, test_enable_too_short)
720 {
721 const uint8_t ase_id = test_ase_id_get(fixture->ase);
722 const uint8_t buf[] = {
723 0x03, /* Opcode = Enable */
724 0x01, /* Number_of_ASEs */
725 ase_id, /* ASE_ID[0] */
726 };
727
728 test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream,
729 buf, sizeof(buf));
730 }
731
ZTEST_F(test_ase_control_params,test_enable_metadata_too_short)732 ZTEST_F(test_ase_control_params, test_enable_metadata_too_short)
733 {
734 const uint8_t ase_id = test_ase_id_get(fixture->ase);
735 const uint8_t buf[] = {
736 0x03, /* Opcode = Enable */
737 0x01, /* Number_of_ASEs */
738 ase_id, /* ASE_ID[0] */
739 0x03, /* Metadata_Length[0] */
740 0x02, 0x02, /* Metadata[0] */
741 };
742
743 test_enable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp, &fixture->stream,
744 buf, sizeof(buf));
745 }
746
ZTEST_F(test_ase_control_params,test_enable_invalid_ase_id)747 ZTEST_F(test_ase_control_params, test_enable_invalid_ase_id)
748 {
749 /* Test requires support for at least 2 ASEs */
750 if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) {
751 ztest_test_skip();
752 }
753
754 const uint8_t ase_id_valid = 0x01;
755 const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
756 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
757 const uint8_t buf[] = {
758 0x03, /* Opcode = Enable */
759 0x02, /* Number_of_ASEs */
760 ase_id_invalid, /* ASE_ID[0] */
761 0x04, /* Metadata_Length[0] */
762 0x03, 0x02, 0x04, 0x00, /* Metadata[0] = Streaming Context (Media) */
763 ase_id_valid, /* ASE_ID[1] */
764 0x04, /* Metadata_Length[0] */
765 0x03, 0x02, 0x04, 0x00, /* Metadata[0] = Streaming Context (Media) */
766 };
767 const uint8_t data_expected[] = {
768 0x03, /* Opcode = Enable */
769 0x02, /* Number_of_ASEs */
770 ase_id_invalid, /* ASE_ID[0] */
771 0x03, /* Response_Code[0] = Invalid ASE_ID */
772 0x00, /* Reason[0] */
773 ase_id_valid, /* ASE_ID[1] */
774 0x00, /* Response_Code[1] = Success */
775 0x00, /* Reason[1] */
776 };
777
778 test_preamble_state_qos_configured(&fixture->conn, ase_id_valid, &fixture->stream);
779
780 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
781
782 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
783 fixture->ase_cp, data_expected, sizeof(data_expected));
784 }
785
ZTEST_F(test_ase_control_params,test_enable_metadata_prohibited_context)786 ZTEST_F(test_ase_control_params, test_enable_metadata_prohibited_context)
787 {
788 const uint8_t ase_id_valid = 0x01;
789 const uint8_t buf[] = {
790 0x03, /* Opcode = Enable */
791 0x01, /* Number_of_ASEs */
792 ase_id_valid, /* ASE_ID[0] */
793 0x04, /* Metadata_Length[0] */
794 0x03, 0x02, 0x00, 0x00, /* Metadata[0] = Streaming Context (Prohibited) */
795 };
796 const uint8_t data_expected[] = {
797 0x03, /* Opcode = Enable */
798 0x01, /* Number_of_ASEs */
799 ase_id_valid, /* ASE_ID[0] */
800 0x0C, /* Response_Code[0] = Invalid Metadata */
801 0x02, /* Reason[0] = Streaming Context */
802 };
803
804 test_preamble_state_qos_configured(&fixture->conn, ase_id_valid, &fixture->stream);
805
806 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
807
808 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
809 fixture->ase_cp, data_expected, sizeof(data_expected));
810 }
811
test_receiver_start_ready_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)812 static void test_receiver_start_ready_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
813 const struct bt_gatt_attr *ase_cp,
814 struct bt_bap_stream *stream,
815 const uint8_t *buf, size_t len)
816 {
817 const uint8_t data_expected[] = {
818 0x04, /* Opcode = Receiver Start Ready */
819 0xFF, /* Number_of_ASEs */
820 0x00, /* ASE_ID[0] */
821 0x02, /* Response_Code[0] = Invalid Length */
822 0x00, /* Reason[0] */
823 };
824 struct bt_iso_chan *chan;
825 int err;
826
827 test_preamble_state_enabling(conn, ase_id, stream);
828
829 err = mock_bt_iso_accept(conn, 0x01, 0x01, &chan);
830 zassert_equal(0, err, "Failed to connect iso: err %d", err);
831
832 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
833
834 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
835 sizeof(data_expected));
836 }
837
ZTEST_F(test_ase_control_params,test_receiver_start_ready_number_of_ases_0x00)838 ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_0x00)
839 {
840 const struct bt_gatt_attr *ase;
841 uint8_t ase_id;
842
843 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
844
845 test_ase_src_get(1, &ase);
846 zassume_not_null(ase);
847 ase_id = test_ase_id_get(ase);
848
849 const uint8_t buf[] = {
850 0x04, /* Opcode = Receiver Start Ready */
851 0x00, /* Number_of_ASEs */
852 ase_id, /* ASE_ID[0] */
853 };
854
855 test_receiver_start_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
856 &fixture->stream, buf, sizeof(buf));
857 }
858
ZTEST_F(test_ase_control_params,test_receiver_start_ready_number_of_ases_above_max)859 ZTEST_F(test_ase_control_params, test_receiver_start_ready_number_of_ases_above_max)
860 {
861 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
862 const struct bt_gatt_attr *ase;
863
864 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
865
866 /* Skip if number of ASEs configured is high enough to support any value in the write req */
867 if (ase_cnt > UINT8_MAX) {
868 ztest_test_skip();
869 }
870
871 test_ase_src_get(1, &ase);
872 zassume_not_null(ase);
873 const uint8_t ase_id = test_ase_id_get(ase);
874
875 const uint8_t buf[] = {
876 0x04, /* Opcode = Receiver Start Ready */
877 (uint8_t)ase_cnt, /* Number_of_ASEs */
878 ase_id, /* ASE_ID[0] */
879 };
880
881 test_receiver_start_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
882 &fixture->stream, buf, sizeof(buf));
883 }
884
ZTEST_F(test_ase_control_params,test_receiver_start_ready_too_long)885 ZTEST_F(test_ase_control_params, test_receiver_start_ready_too_long)
886 {
887 const struct bt_gatt_attr *ase;
888 uint8_t ase_id;
889
890 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
891
892 test_ase_src_get(1, &ase);
893 zassume_not_null(ase);
894 ase_id = test_ase_id_get(fixture->ase);
895
896 const uint8_t buf[] = {
897 0x04, /* Opcode = Receiver Start Ready */
898 0x01, /* Number_of_ASEs */
899 ase_id, /* ASE_ID[0] */
900 0x00,
901 };
902
903 test_receiver_start_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
904 &fixture->stream, buf, sizeof(buf));
905 }
906
ZTEST_F(test_ase_control_params,test_receiver_start_ready_too_short)907 ZTEST_F(test_ase_control_params, test_receiver_start_ready_too_short)
908 {
909 const uint8_t buf[] = {
910 0x04, /* Opcode = Receiver Start Ready */
911 0x01, /* Number_of_ASEs */
912 };
913 const struct bt_gatt_attr *ase;
914 uint8_t ase_id;
915
916 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
917
918 test_ase_src_get(1, &ase);
919 zassume_not_null(ase);
920 ase_id = test_ase_id_get(fixture->ase);
921
922 test_receiver_start_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
923 &fixture->stream, buf, sizeof(buf));
924 }
925
test_disable_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)926 static void test_disable_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
927 const struct bt_gatt_attr *ase_cp,
928 struct bt_bap_stream *stream,
929 const uint8_t *buf, size_t len)
930 {
931 const uint8_t data_expected[] = {
932 0x05, /* Opcode = Disable */
933 0xFF, /* Number_of_ASEs */
934 0x00, /* ASE_ID[0] */
935 0x02, /* Response_Code[0] = Invalid Length */
936 0x00, /* Reason[0] */
937 };
938
939 test_preamble_state_enabling(conn, ase_id, stream);
940
941 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
942
943 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
944 sizeof(data_expected));
945 }
946
ZTEST_F(test_ase_control_params,test_disable_number_of_ases_0x00)947 ZTEST_F(test_ase_control_params, test_disable_number_of_ases_0x00)
948 {
949 const uint8_t ase_id = test_ase_id_get(fixture->ase);
950 const uint8_t buf[] = {
951 0x05, /* Opcode = Disable */
952 0x00, /* Number_of_ASEs */
953 ase_id, /* ASE_ID[0] */
954 };
955
956 test_disable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
957 &fixture->stream, buf, sizeof(buf));
958 }
959
ZTEST_F(test_ase_control_params,test_disable_number_of_ases_above_max)960 ZTEST_F(test_ase_control_params, test_disable_number_of_ases_above_max)
961 {
962 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
963 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
964
965 /* Skip if number of ASEs configured is high enough to support any value in the write req */
966 if (ase_cnt > UINT8_MAX) {
967 ztest_test_skip();
968 }
969
970 const uint8_t ase_id = test_ase_id_get(fixture->ase);
971 const uint8_t buf[] = {
972 0x05, /* Opcode = Disable */
973 (uint8_t)ase_cnt, /* Number_of_ASEs */
974 ase_id, /* ASE_ID[0] */
975 };
976
977 test_disable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
978 &fixture->stream, buf, sizeof(buf));
979 }
980
ZTEST_F(test_ase_control_params,test_disable_too_long)981 ZTEST_F(test_ase_control_params, test_disable_too_long)
982 {
983 const uint8_t ase_id = test_ase_id_get(fixture->ase);
984 const uint8_t buf[] = {
985 0x05, /* Opcode = Disable */
986 0x01, /* Number_of_ASEs */
987 ase_id, /* ASE_ID[0] */
988 0x00,
989 };
990
991 test_disable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
992 &fixture->stream, buf, sizeof(buf));
993 }
994
ZTEST_F(test_ase_control_params,test_disable_too_short)995 ZTEST_F(test_ase_control_params, test_disable_too_short)
996 {
997 uint8_t ase_id = test_ase_id_get(fixture->ase);
998 const uint8_t buf[] = {
999 0x05, /* Opcode = Disable */
1000 0x01, /* Number_of_ASEs */
1001 };
1002
1003 test_disable_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1004 &fixture->stream, buf, sizeof(buf));
1005 }
1006
test_receiver_stop_ready_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)1007 static void test_receiver_stop_ready_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
1008 const struct bt_gatt_attr *ase_cp,
1009 struct bt_bap_stream *stream,
1010 const uint8_t *buf, size_t len)
1011 {
1012 const uint8_t data_expected[] = {
1013 0x06, /* Opcode = Receiver Stop Ready */
1014 0xFF, /* Number_of_ASEs */
1015 0x00, /* ASE_ID[0] */
1016 0x02, /* Response_Code[0] = Invalid Length */
1017 0x00, /* Reason[0] */
1018 };
1019 struct bt_iso_chan *chan;
1020
1021 test_preamble_state_disabling(conn, ase_id, stream, &chan);
1022
1023 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
1024
1025 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
1026 sizeof(data_expected));
1027 }
1028
ZTEST_F(test_ase_control_params,test_receiver_stop_ready_number_of_ases_0x00)1029 ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_0x00)
1030 {
1031 const struct bt_gatt_attr *ase;
1032 uint8_t ase_id;
1033
1034 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
1035
1036 test_ase_src_get(1, &ase);
1037 zassume_not_null(ase);
1038 ase_id = test_ase_id_get(ase);
1039
1040 const uint8_t buf[] = {
1041 0x06, /* Opcode = Receiver Stop Ready */
1042 0x00, /* Number_of_ASEs */
1043 ase_id, /* ASE_ID[0] */
1044 };
1045
1046 test_receiver_stop_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1047 &fixture->stream, buf, sizeof(buf));
1048 }
1049
ZTEST_F(test_ase_control_params,test_receiver_stop_ready_number_of_ases_above_max)1050 ZTEST_F(test_ase_control_params, test_receiver_stop_ready_number_of_ases_above_max)
1051 {
1052 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
1053 const struct bt_gatt_attr *ase;
1054
1055 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
1056
1057 /* Skip if number of ASEs configured is high enough to support any value in the write req */
1058 if (ase_cnt > UINT8_MAX) {
1059 ztest_test_skip();
1060 }
1061
1062 test_ase_src_get(1, &ase);
1063 zassume_not_null(ase);
1064 const uint8_t ase_id = test_ase_id_get(ase);
1065
1066 const uint8_t buf[] = {
1067 0x06, /* Opcode = Receiver Stop Ready */
1068 (uint8_t)ase_cnt, /* Number_of_ASEs */
1069 ase_id, /* ASE_ID[0] */
1070 };
1071
1072 test_receiver_stop_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1073 &fixture->stream, buf, sizeof(buf));
1074 }
1075
ZTEST_F(test_ase_control_params,test_receiver_stop_ready_too_long)1076 ZTEST_F(test_ase_control_params, test_receiver_stop_ready_too_long)
1077 {
1078 const struct bt_gatt_attr *ase;
1079 uint8_t ase_id;
1080
1081 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
1082
1083 test_ase_src_get(1, &ase);
1084 zassume_not_null(ase);
1085 ase_id = test_ase_id_get(fixture->ase);
1086
1087 const uint8_t buf[] = {
1088 0x06, /* Opcode = Receiver Stop Ready */
1089 0x01, /* Number_of_ASEs */
1090 ase_id, /* ASE_ID[0] */
1091 0x00,
1092 };
1093
1094 test_receiver_stop_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1095 &fixture->stream, buf, sizeof(buf));
1096 }
1097
ZTEST_F(test_ase_control_params,test_receiver_stop_ready_too_short)1098 ZTEST_F(test_ase_control_params, test_receiver_stop_ready_too_short)
1099 {
1100 const uint8_t buf[] = {
1101 0x06, /* Opcode = Receiver Stop Ready */
1102 0x01, /* Number_of_ASEs */
1103 };
1104 const struct bt_gatt_attr *ase;
1105 uint8_t ase_id;
1106
1107 Z_TEST_SKIP_IFNDEF(CONFIG_BT_ASCS_ASE_SRC);
1108
1109 test_ase_src_get(1, &ase);
1110 zassume_not_null(ase);
1111 ase_id = test_ase_id_get(fixture->ase);
1112
1113 test_receiver_stop_ready_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1114 &fixture->stream, buf, sizeof(buf));
1115 }
1116
test_update_metadata_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)1117 static void test_update_metadata_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
1118 const struct bt_gatt_attr *ase_cp,
1119 struct bt_bap_stream *stream,
1120 const uint8_t *buf, size_t len)
1121 {
1122 const uint8_t data_expected[] = {
1123 0x07, /* Opcode = Update Metadata */
1124 0xFF, /* Number_of_ASEs */
1125 0x00, /* ASE_ID[0] */
1126 0x02, /* Response_Code[0] = Invalid Length */
1127 0x00, /* Reason[0] */
1128 };
1129
1130 test_preamble_state_enabling(conn, ase_id, stream);
1131
1132 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
1133
1134 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
1135 sizeof(data_expected));
1136 }
1137
ZTEST_F(test_ase_control_params,test_update_metadata_number_of_ases_0x00)1138 ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_0x00)
1139 {
1140 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1141 const uint8_t buf[] = {
1142 0x07, /* Opcode = Update Metadata */
1143 0x00, /* Number_of_ASEs */
1144 ase_id, /* ASE_ID[0] */
1145 0x00, /* Metadata_Length[0] */
1146 };
1147
1148 test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1149 &fixture->stream, buf, sizeof(buf));
1150 }
1151
ZTEST_F(test_ase_control_params,test_update_metadata_number_of_ases_above_max)1152 ZTEST_F(test_ase_control_params, test_update_metadata_number_of_ases_above_max)
1153 {
1154 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
1155 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
1156
1157 /* Skip if number of ASEs configured is high enough to support any value in the write req */
1158 if (ase_cnt > UINT8_MAX) {
1159 ztest_test_skip();
1160 }
1161
1162 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1163 const uint8_t buf[] = {
1164 0x07, /* Opcode = Update Metadata */
1165 (uint8_t)ase_cnt, /* Number_of_ASEs */
1166 ase_id, /* ASE_ID[0] */
1167 0x00, /* Metadata_Length[0] */
1168 };
1169
1170 test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1171 &fixture->stream, buf, sizeof(buf));
1172 }
1173
ZTEST_F(test_ase_control_params,test_update_metadata_too_long)1174 ZTEST_F(test_ase_control_params, test_update_metadata_too_long)
1175 {
1176 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1177 const uint8_t buf[] = {
1178 0x07, /* Opcode = Update Metadata */
1179 0x01, /* Number_of_ASEs */
1180 ase_id, /* ASE_ID[0] */
1181 0x00, /* Metadata_Length[0] */
1182 0x00,
1183 };
1184
1185 test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1186 &fixture->stream, buf, sizeof(buf));
1187 }
1188
ZTEST_F(test_ase_control_params,test_update_metadata_too_short)1189 ZTEST_F(test_ase_control_params, test_update_metadata_too_short)
1190 {
1191 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1192 const uint8_t buf[] = {
1193 0x07, /* Opcode = Update Metadata */
1194 0x01, /* Number_of_ASEs */
1195 ase_id, /* ASE_ID[0] */
1196 };
1197
1198 test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1199 &fixture->stream, buf, sizeof(buf));
1200 }
1201
ZTEST_F(test_ase_control_params,test_update_metadata_metadata_too_short)1202 ZTEST_F(test_ase_control_params, test_update_metadata_metadata_too_short)
1203 {
1204 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1205 const uint8_t buf[] = {
1206 0x07, /* Opcode = Update Metadata */
1207 0x01, /* Number_of_ASEs */
1208 ase_id, /* ASE_ID[0] */
1209 0x03, /* Metadata_Length[0] */
1210 0x02, 0x02, /* Metadata[0] */
1211 };
1212
1213 test_update_metadata_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1214 &fixture->stream, buf, sizeof(buf));
1215 }
1216
ZTEST_F(test_ase_control_params,test_update_metadata_invalid_ase_id)1217 ZTEST_F(test_ase_control_params, test_update_metadata_invalid_ase_id)
1218 {
1219 /* Test requires support for at least 2 ASEs */
1220 if (CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT < 2) {
1221 ztest_test_skip();
1222 }
1223
1224 const uint8_t ase_id_valid = 0x01;
1225 const uint8_t ase_id_invalid = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
1226 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
1227 const uint8_t buf[] = {
1228 0x07, /* Opcode = Update Metadata */
1229 0x02, /* Number_of_ASEs */
1230 ase_id_invalid, /* ASE_ID[0] */
1231 0x04, /* Metadata_Length[0] */
1232 0x03, 0x02, 0x04, 0x00, /* Metadata[0] = Streaming Context (Media) */
1233 ase_id_valid, /* ASE_ID[1] */
1234 0x04, /* Metadata_Length[0] */
1235 0x03, 0x02, 0x04, 0x00, /* Metadata[0] = Streaming Context (Media) */
1236 };
1237 const uint8_t data_expected[] = {
1238 0x07, /* Opcode = Update Metadata */
1239 0x02, /* Number_of_ASEs */
1240 ase_id_invalid, /* ASE_ID[0] */
1241 0x03, /* Response_Code[0] = Invalid ASE_ID */
1242 0x00, /* Reason[0] */
1243 ase_id_valid, /* ASE_ID[1] */
1244 0x00, /* Response_Code[1] = Success */
1245 0x00, /* Reason[1] */
1246 };
1247
1248 test_preamble_state_enabling(&fixture->conn, ase_id_valid, &fixture->stream);
1249
1250 fixture->ase_cp->write(&fixture->conn, fixture->ase_cp, buf, sizeof(buf), 0, 0);
1251
1252 expect_bt_gatt_notify_cb_called_once(&fixture->conn, BT_UUID_ASCS_ASE_CP,
1253 fixture->ase_cp, data_expected, sizeof(data_expected));
1254 }
1255
test_release_expect_invalid_length(struct bt_conn * conn,uint8_t ase_id,const struct bt_gatt_attr * ase_cp,struct bt_bap_stream * stream,const uint8_t * buf,size_t len)1256 static void test_release_expect_invalid_length(struct bt_conn *conn, uint8_t ase_id,
1257 const struct bt_gatt_attr *ase_cp,
1258 struct bt_bap_stream *stream,
1259 const uint8_t *buf, size_t len)
1260 {
1261 const uint8_t data_expected[] = {
1262 0x08, /* Opcode = Release */
1263 0xFF, /* Number_of_ASEs */
1264 0x00, /* ASE_ID[0] */
1265 0x02, /* Response_Code[0] = Invalid Length */
1266 0x00, /* Reason[0] */
1267 };
1268
1269 test_preamble_state_enabling(conn, ase_id, stream);
1270
1271 ase_cp->write(conn, ase_cp, buf, len, 0, 0);
1272
1273 expect_bt_gatt_notify_cb_called_once(conn, BT_UUID_ASCS_ASE_CP, ase_cp, data_expected,
1274 sizeof(data_expected));
1275 }
1276
ZTEST_F(test_ase_control_params,test_release_number_of_ases_0x00)1277 ZTEST_F(test_ase_control_params, test_release_number_of_ases_0x00)
1278 {
1279 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1280 const uint8_t buf[] = {
1281 0x08, /* Opcode = Release */
1282 0x00, /* Number_of_ASEs */
1283 ase_id, /* ASE_ID[0] */
1284 };
1285
1286 test_release_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1287 &fixture->stream, buf, sizeof(buf));
1288 }
1289
ZTEST_F(test_ase_control_params,test_release_number_of_ases_above_max)1290 ZTEST_F(test_ase_control_params, test_release_number_of_ases_above_max)
1291 {
1292 const uint16_t ase_cnt = CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT +
1293 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT + 1;
1294
1295 /* Skip if number of ASEs configured is high enough to support any value in the write req */
1296 if (ase_cnt > UINT8_MAX) {
1297 ztest_test_skip();
1298 }
1299
1300 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1301 const uint8_t buf[] = {
1302 0x08, /* Opcode = Release */
1303 (uint8_t)ase_cnt, /* Number_of_ASEs */
1304 ase_id, /* ASE_ID[0] */
1305 };
1306
1307 test_release_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1308 &fixture->stream, buf, sizeof(buf));
1309 }
1310
ZTEST_F(test_ase_control_params,test_release_too_long)1311 ZTEST_F(test_ase_control_params, test_release_too_long)
1312 {
1313 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1314 const uint8_t buf[] = {
1315 0x08, /* Opcode = Release */
1316 0x01, /* Number_of_ASEs */
1317 ase_id, /* ASE_ID[0] */
1318 0x00,
1319 };
1320
1321 test_release_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1322 &fixture->stream, buf, sizeof(buf));
1323 }
1324
ZTEST_F(test_ase_control_params,test_release_too_short)1325 ZTEST_F(test_ase_control_params, test_release_too_short)
1326 {
1327 const uint8_t ase_id = test_ase_id_get(fixture->ase);
1328 const uint8_t buf[] = {
1329 0x08, /* Opcode = Release */
1330 0x01, /* Number_of_ASEs */
1331 };
1332
1333 test_release_expect_invalid_length(&fixture->conn, ase_id, fixture->ase_cp,
1334 &fixture->stream, buf, sizeof(buf));
1335 }
1336