1 /* test_vcp.c - unit test for volume settings */
2 
3 /*
4  * Copyright (c) 2024 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/cap.h>
14 #include <zephyr/bluetooth/audio/vcp.h>
15 #include <zephyr/bluetooth/audio/vocs.h>
16 #include <zephyr/bluetooth/hci_types.h>
17 #include <zephyr/fff.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/ztest_assert.h>
20 #include <zephyr/ztest_test.h>
21 
22 #include "cap_commander.h"
23 #include "conn.h"
24 #include "expects_util.h"
25 #include "cap_mocks.h"
26 #include "test_common.h"
27 
28 #define FFF_GLOBALS
29 
30 struct cap_commander_test_vcp_fixture {
31 	struct bt_conn conns[CONFIG_BT_MAX_CONN];
32 };
33 
cap_commander_test_vcp_fixture_init(struct cap_commander_test_vcp_fixture * fixture)34 static void cap_commander_test_vcp_fixture_init(struct cap_commander_test_vcp_fixture *fixture)
35 {
36 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
37 		test_conn_init(&fixture->conns[i]);
38 	}
39 }
40 
cap_commander_test_vcp_setup(void)41 static void *cap_commander_test_vcp_setup(void)
42 {
43 	struct cap_commander_test_vcp_fixture *fixture;
44 
45 	fixture = malloc(sizeof(*fixture));
46 	zassert_not_null(fixture);
47 
48 	return fixture;
49 }
50 
cap_commander_test_vcp_before(void * f)51 static void cap_commander_test_vcp_before(void *f)
52 {
53 	memset(f, 0, sizeof(struct cap_commander_test_vcp_fixture));
54 	cap_commander_test_vcp_fixture_init(f);
55 }
56 
cap_commander_test_vcp_after(void * f)57 static void cap_commander_test_vcp_after(void *f)
58 {
59 	struct cap_commander_test_vcp_fixture *fixture = f;
60 
61 	bt_cap_commander_unregister_cb(&mock_cap_commander_cb);
62 
63 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
64 		mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
65 	}
66 }
67 
cap_commander_test_vcp_teardown(void * f)68 static void cap_commander_test_vcp_teardown(void *f)
69 {
70 	free(f);
71 }
72 
73 ZTEST_SUITE(cap_commander_test_vcp, NULL, cap_commander_test_vcp_setup,
74 	    cap_commander_test_vcp_before, cap_commander_test_vcp_after,
75 	    cap_commander_test_vcp_teardown);
76 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume)77 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume)
78 {
79 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
80 	const struct bt_cap_commander_change_volume_param param = {
81 		.type = BT_CAP_SET_TYPE_AD_HOC,
82 		.members = members,
83 		.count = ARRAY_SIZE(fixture->conns),
84 		.volume = 177,
85 	};
86 	int err;
87 
88 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
89 		members[i].member = &fixture->conns[i];
90 	}
91 
92 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
93 	zassert_equal(0, err, "Unexpected return value %d", err);
94 
95 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
96 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
97 
98 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
99 		zassert_equal(0, err, "Unexpected return value %d", err);
100 	}
101 
102 	err = bt_cap_commander_change_volume(&param);
103 	zassert_equal(0, err, "Unexpected return value %d", err);
104 
105 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 1,
106 			   mock_cap_commander_volume_changed_cb_fake.call_count);
107 }
108 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_double)109 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_double)
110 {
111 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
112 	const struct bt_cap_commander_change_volume_param param = {
113 		.type = BT_CAP_SET_TYPE_AD_HOC,
114 		.members = members,
115 		.count = ARRAY_SIZE(fixture->conns),
116 		.volume = 177,
117 	};
118 	int err;
119 
120 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
121 		members[i].member = &fixture->conns[i];
122 	}
123 
124 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
125 	zassert_equal(0, err, "Unexpected return value %d", err);
126 
127 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
128 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
129 
130 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
131 		zassert_equal(0, err, "Unexpected return value %d", err);
132 	}
133 
134 	err = bt_cap_commander_change_volume(&param);
135 	zassert_equal(0, err, "Unexpected return value %d", err);
136 
137 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 1,
138 			   mock_cap_commander_volume_changed_cb_fake.call_count);
139 
140 	/* Verify that it still works as expected if we set the same value twice */
141 	err = bt_cap_commander_change_volume(&param);
142 	zassert_equal(0, err, "Unexpected return value %d", err);
143 
144 	zexpect_call_count("bt_cap_commander_cb.volume_changed", 2,
145 			   mock_cap_commander_volume_changed_cb_fake.call_count);
146 }
147 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null)148 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null)
149 {
150 	int err;
151 
152 	err = bt_cap_commander_change_volume(NULL);
153 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
154 }
155 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null_members)156 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_members)
157 {
158 	const struct bt_cap_commander_change_volume_param param = {
159 		.type = BT_CAP_SET_TYPE_AD_HOC,
160 		.members = NULL,
161 		.count = ARRAY_SIZE(fixture->conns),
162 		.volume = 177,
163 	};
164 	int err;
165 
166 	err = bt_cap_commander_change_volume(&param);
167 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
168 }
169 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_null_member)170 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_member)
171 {
172 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
173 	const struct bt_cap_commander_change_volume_param param = {
174 		.type = BT_CAP_SET_TYPE_AD_HOC,
175 		.members = members,
176 		.count = ARRAY_SIZE(fixture->conns),
177 		.volume = 177,
178 	};
179 	int err;
180 
181 	for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) {
182 		members[i].member = &fixture->conns[i];
183 	}
184 	members[ARRAY_SIZE(members) - 1].member = NULL;
185 
186 	err = bt_cap_commander_change_volume(&param);
187 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
188 }
189 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_missing_cas)190 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_cas)
191 {
192 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
193 	const struct bt_cap_commander_change_volume_param param = {
194 		.type = BT_CAP_SET_TYPE_CSIP,
195 		.members = members,
196 		.count = ARRAY_SIZE(fixture->conns),
197 		.volume = 177,
198 	};
199 	int err;
200 
201 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
202 		members[i].member = &fixture->conns[i];
203 	}
204 
205 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
206 	zassert_equal(0, err, "Unexpected return value %d", err);
207 
208 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
209 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
210 
211 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
212 		zassert_equal(0, err, "Unexpected return value %d", err);
213 	}
214 
215 	err = bt_cap_commander_change_volume(&param);
216 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
217 }
218 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_missing_vcs)219 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_vcs)
220 {
221 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
222 	const struct bt_cap_commander_change_volume_param param = {
223 		.type = BT_CAP_SET_TYPE_AD_HOC,
224 		.members = members,
225 		.count = ARRAY_SIZE(fixture->conns),
226 		.volume = 177,
227 	};
228 	int err;
229 
230 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
231 		members[i].member = &fixture->conns[i];
232 	}
233 
234 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
235 	zassert_equal(0, err, "Unexpected return value %d", err);
236 
237 	err = bt_cap_commander_change_volume(&param);
238 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
239 }
240 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_zero_count)241 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_zero_count)
242 {
243 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
244 	const struct bt_cap_commander_change_volume_param param = {
245 		.type = BT_CAP_SET_TYPE_AD_HOC,
246 		.members = members,
247 		.count = 0U,
248 		.volume = 177,
249 	};
250 	int err;
251 
252 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
253 		members[i].member = &fixture->conns[i];
254 	}
255 
256 	err = bt_cap_commander_change_volume(&param);
257 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
258 }
259 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_inval_param_inval_count)260 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_inval_count)
261 {
262 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
263 	const struct bt_cap_commander_change_volume_param param = {
264 		.type = BT_CAP_SET_TYPE_AD_HOC,
265 		.members = members,
266 		.count = CONFIG_BT_MAX_CONN + 1,
267 		.volume = 177,
268 	};
269 	int err;
270 
271 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
272 		members[i].member = &fixture->conns[i];
273 	}
274 
275 	err = bt_cap_commander_change_volume(&param);
276 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
277 }
278 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset)279 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset)
280 {
281 	struct bt_cap_commander_change_volume_offset_member_param
282 		member_params[ARRAY_SIZE(fixture->conns)];
283 	const struct bt_cap_commander_change_volume_offset_param param = {
284 		.type = BT_CAP_SET_TYPE_AD_HOC,
285 		.param = member_params,
286 		.count = ARRAY_SIZE(member_params),
287 	};
288 	int err;
289 
290 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
291 		member_params[i].member.member = &fixture->conns[i];
292 		member_params[i].offset = 100 + i;
293 	}
294 
295 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
296 	zassert_equal(0, err, "Unexpected return value %d", err);
297 
298 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
299 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
300 
301 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
302 		zassert_equal(0, err, "Unexpected return value %d", err);
303 	}
304 
305 	err = bt_cap_commander_change_volume_offset(&param);
306 	zassert_equal(0, err, "Unexpected return value %d", err);
307 
308 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1,
309 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
310 }
311 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_double)312 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_double)
313 {
314 	struct bt_cap_commander_change_volume_offset_member_param
315 		member_params[ARRAY_SIZE(fixture->conns)];
316 	const struct bt_cap_commander_change_volume_offset_param param = {
317 		.type = BT_CAP_SET_TYPE_AD_HOC,
318 		.param = member_params,
319 		.count = ARRAY_SIZE(member_params),
320 	};
321 	int err;
322 
323 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
324 		member_params[i].member.member = &fixture->conns[i];
325 		member_params[i].offset = 100 + i;
326 	}
327 
328 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
329 	zassert_equal(0, err, "Unexpected return value %d", err);
330 
331 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
332 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
333 
334 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
335 		zassert_equal(0, err, "Unexpected return value %d", err);
336 	}
337 
338 	err = bt_cap_commander_change_volume_offset(&param);
339 	zassert_equal(0, err, "Unexpected return value %d", err);
340 
341 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1,
342 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
343 
344 	/* Verify that it still works as expected if we set the same value twice */
345 	err = bt_cap_commander_change_volume_offset(&param);
346 	zassert_equal(0, err, "Unexpected return value %d", err);
347 
348 	zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 2,
349 			   mock_cap_commander_volume_offset_changed_cb_fake.call_count);
350 }
351 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null)352 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null)
353 {
354 	int err;
355 
356 	err = bt_cap_commander_change_volume_offset(NULL);
357 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
358 }
359 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null_param)360 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_param)
361 {
362 	const struct bt_cap_commander_change_volume_offset_param param = {
363 		.type = BT_CAP_SET_TYPE_AD_HOC,
364 		.param = NULL,
365 		.count = ARRAY_SIZE(fixture->conns),
366 	};
367 	int err;
368 
369 	err = bt_cap_commander_change_volume_offset(&param);
370 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
371 }
372 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_null_member)373 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_member)
374 {
375 	struct bt_cap_commander_change_volume_offset_member_param
376 		member_params[ARRAY_SIZE(fixture->conns)];
377 	const struct bt_cap_commander_change_volume_offset_param param = {
378 		.type = BT_CAP_SET_TYPE_AD_HOC,
379 		.param = member_params,
380 		.count = ARRAY_SIZE(member_params),
381 	};
382 	int err;
383 
384 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
385 		member_params[i].member.member = &fixture->conns[i];
386 		member_params[i].offset = 100 + i;
387 	}
388 	member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL;
389 
390 	err = bt_cap_commander_change_volume_offset(&param);
391 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
392 }
393 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_missing_cas)394 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_cas)
395 {
396 	struct bt_cap_commander_change_volume_offset_member_param
397 		member_params[ARRAY_SIZE(fixture->conns)];
398 	const struct bt_cap_commander_change_volume_offset_param param = {
399 		.type = BT_CAP_SET_TYPE_CSIP,
400 		.param = member_params,
401 		.count = ARRAY_SIZE(member_params),
402 	};
403 	int err;
404 
405 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
406 		member_params[i].member.member = &fixture->conns[i];
407 		member_params[i].offset = 100 + i;
408 	}
409 
410 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
411 	zassert_equal(0, err, "Unexpected return value %d", err);
412 
413 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
414 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
415 
416 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
417 		zassert_equal(0, err, "Unexpected return value %d", err);
418 	}
419 
420 	err = bt_cap_commander_change_volume_offset(&param);
421 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
422 }
423 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_missing_vocs)424 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_vocs)
425 {
426 	struct bt_cap_commander_change_volume_offset_member_param
427 		member_params[ARRAY_SIZE(fixture->conns)];
428 	const struct bt_cap_commander_change_volume_offset_param param = {
429 		.type = BT_CAP_SET_TYPE_AD_HOC,
430 		.param = member_params,
431 		.count = ARRAY_SIZE(member_params),
432 	};
433 	int err;
434 
435 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
436 		member_params[i].member.member = &fixture->conns[i];
437 		member_params[i].offset = 100 + i;
438 	}
439 
440 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
441 	zassert_equal(0, err, "Unexpected return value %d", err);
442 
443 	err = bt_cap_commander_change_volume_offset(&param);
444 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
445 }
446 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_zero_count)447 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_zero_count)
448 {
449 	struct bt_cap_commander_change_volume_offset_member_param
450 		member_params[ARRAY_SIZE(fixture->conns)];
451 	const struct bt_cap_commander_change_volume_offset_param param = {
452 		.type = BT_CAP_SET_TYPE_AD_HOC,
453 		.param = member_params,
454 		.count = 0U,
455 	};
456 	int err;
457 
458 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
459 		member_params[i].member.member = &fixture->conns[i];
460 		member_params[i].offset = 100 + i;
461 	}
462 
463 	err = bt_cap_commander_change_volume_offset(&param);
464 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
465 }
466 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_count)467 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_count)
468 {
469 	struct bt_cap_commander_change_volume_offset_member_param
470 		member_params[ARRAY_SIZE(fixture->conns)];
471 	const struct bt_cap_commander_change_volume_offset_param param = {
472 		.type = BT_CAP_SET_TYPE_AD_HOC,
473 		.param = member_params,
474 		.count = CONFIG_BT_MAX_CONN + 1,
475 	};
476 	int err;
477 
478 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
479 		member_params[i].member.member = &fixture->conns[i];
480 		member_params[i].offset = 100 + i;
481 	}
482 
483 	err = bt_cap_commander_change_volume_offset(&param);
484 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
485 }
486 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_offset_max)487 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_max)
488 {
489 	struct bt_cap_commander_change_volume_offset_member_param
490 		member_params[ARRAY_SIZE(fixture->conns)];
491 	const struct bt_cap_commander_change_volume_offset_param param = {
492 		.type = BT_CAP_SET_TYPE_AD_HOC,
493 		.param = member_params,
494 		.count = ARRAY_SIZE(member_params),
495 	};
496 	int err;
497 
498 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
499 		member_params[i].member.member = &fixture->conns[i];
500 		member_params[i].offset = BT_VOCS_MAX_OFFSET + 1;
501 	}
502 
503 	err = bt_cap_commander_change_volume_offset(&param);
504 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
505 }
506 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_offset_inval_param_inval_offset_min)507 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_min)
508 {
509 	struct bt_cap_commander_change_volume_offset_member_param
510 		member_params[ARRAY_SIZE(fixture->conns)];
511 	const struct bt_cap_commander_change_volume_offset_param param = {
512 		.type = BT_CAP_SET_TYPE_AD_HOC,
513 		.param = member_params,
514 		.count = ARRAY_SIZE(member_params),
515 	};
516 	int err;
517 
518 	for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) {
519 		member_params[i].member.member = &fixture->conns[i];
520 		member_params[i].offset = BT_VOCS_MIN_OFFSET - 1;
521 	}
522 
523 	err = bt_cap_commander_change_volume_offset(&param);
524 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
525 }
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state)526 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state)
527 {
528 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
529 	const struct bt_cap_commander_change_volume_mute_state_param param = {
530 		.type = BT_CAP_SET_TYPE_AD_HOC,
531 		.members = members,
532 		.count = ARRAY_SIZE(fixture->conns),
533 		.mute = true,
534 	};
535 	int err;
536 
537 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
538 		members[i].member = &fixture->conns[i];
539 	}
540 
541 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
542 	zassert_equal(0, err, "Unexpected return value %d", err);
543 
544 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
545 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
546 
547 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
548 		zassert_equal(0, err, "Unexpected return value %d", err);
549 	}
550 
551 	err = bt_cap_commander_change_volume_mute_state(&param);
552 	zassert_equal(0, err, "Unexpected return value %d", err);
553 
554 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1,
555 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
556 }
557 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_double)558 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_double)
559 {
560 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
561 	const struct bt_cap_commander_change_volume_mute_state_param param = {
562 		.type = BT_CAP_SET_TYPE_AD_HOC,
563 		.members = members,
564 		.count = ARRAY_SIZE(fixture->conns),
565 		.mute = true,
566 	};
567 	int err;
568 
569 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
570 		members[i].member = &fixture->conns[i];
571 	}
572 
573 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
574 	zassert_equal(0, err, "Unexpected return value %d", err);
575 
576 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
577 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
578 
579 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
580 		zassert_equal(0, err, "Unexpected return value %d", err);
581 	}
582 
583 	err = bt_cap_commander_change_volume_mute_state(&param);
584 	zassert_equal(0, err, "Unexpected return value %d", err);
585 
586 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1,
587 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
588 
589 	/* Verify that it still works as expected if we set the same value twice */
590 	err = bt_cap_commander_change_volume_mute_state(&param);
591 	zassert_equal(0, err, "Unexpected return value %d", err);
592 
593 	zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 2,
594 			   mock_cap_commander_volume_mute_changed_cb_fake.call_count);
595 }
596 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null)597 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null)
598 {
599 	int err;
600 
601 	err = bt_cap_commander_change_volume_mute_state(NULL);
602 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
603 }
604 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null_members)605 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_members)
606 {
607 	const struct bt_cap_commander_change_volume_mute_state_param param = {
608 		.type = BT_CAP_SET_TYPE_AD_HOC,
609 		.members = NULL,
610 		.count = ARRAY_SIZE(fixture->conns),
611 		.mute = true,
612 	};
613 	int err;
614 
615 	err = bt_cap_commander_change_volume_mute_state(&param);
616 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
617 }
618 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_null_member)619 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_member)
620 {
621 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
622 	const struct bt_cap_commander_change_volume_mute_state_param param = {
623 		.type = BT_CAP_SET_TYPE_AD_HOC,
624 		.members = members,
625 		.count = ARRAY_SIZE(fixture->conns),
626 		.mute = true,
627 	};
628 	int err;
629 
630 	for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) {
631 		members[i].member = &fixture->conns[i];
632 	}
633 	members[ARRAY_SIZE(members) - 1].member = NULL;
634 
635 	err = bt_cap_commander_change_volume_mute_state(&param);
636 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
637 }
638 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_missing_cas)639 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_cas)
640 {
641 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
642 	const struct bt_cap_commander_change_volume_mute_state_param param = {
643 		.type = BT_CAP_SET_TYPE_CSIP,
644 		.members = members,
645 		.count = ARRAY_SIZE(fixture->conns),
646 		.mute = true,
647 	};
648 	int err;
649 
650 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
651 		members[i].member = &fixture->conns[i];
652 	}
653 
654 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
655 	zassert_equal(0, err, "Unexpected return value %d", err);
656 
657 	for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
658 		struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */
659 
660 		err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr);
661 		zassert_equal(0, err, "Unexpected return value %d", err);
662 	}
663 
664 	err = bt_cap_commander_change_volume_mute_state(&param);
665 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
666 }
667 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_missing_vcs)668 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_vcs)
669 {
670 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
671 	const struct bt_cap_commander_change_volume_mute_state_param param = {
672 		.type = BT_CAP_SET_TYPE_AD_HOC,
673 		.members = members,
674 		.count = ARRAY_SIZE(fixture->conns),
675 		.mute = true,
676 	};
677 	int err;
678 
679 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
680 		members[i].member = &fixture->conns[i];
681 	}
682 
683 	err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
684 	zassert_equal(0, err, "Unexpected return value %d", err);
685 
686 	err = bt_cap_commander_change_volume_mute_state(&param);
687 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
688 }
689 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_zero_count)690 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_zero_count)
691 {
692 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
693 	const struct bt_cap_commander_change_volume_mute_state_param param = {
694 		.type = BT_CAP_SET_TYPE_AD_HOC,
695 		.members = members,
696 		.count = 0U,
697 		.mute = true,
698 	};
699 	int err;
700 
701 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
702 		members[i].member = &fixture->conns[i];
703 	}
704 
705 	err = bt_cap_commander_change_volume_mute_state(&param);
706 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
707 }
708 
ZTEST_F(cap_commander_test_vcp,test_commander_change_volume_mute_state_inval_param_inval_count)709 ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_inval_count)
710 {
711 	union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
712 	const struct bt_cap_commander_change_volume_mute_state_param param = {
713 		.type = BT_CAP_SET_TYPE_AD_HOC,
714 		.members = members,
715 		.count = CONFIG_BT_MAX_CONN + 1,
716 		.mute = true,
717 	};
718 	int err;
719 
720 	for (size_t i = 0U; i < ARRAY_SIZE(members); i++) {
721 		members[i].member = &fixture->conns[i];
722 	}
723 
724 	err = bt_cap_commander_change_volume_mute_state(&param);
725 	zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
726 }
727