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