1 /*
2  * Copyright (c) 2019 Bose Corporation
3  * Copyright (c) 2022 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/aics.h>
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/vcp.h>
16 #include <zephyr/bluetooth/audio/vocs.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/sys/printk.h>
19 #include <zephyr/sys/util.h>
20 
21 #include "bstests.h"
22 #include "common.h"
23 
24 #ifdef CONFIG_BT_VCP_VOL_REND
25 extern enum bst_result_t bst_result;
26 
27 #if defined(CONFIG_BT_VOCS)
28 #define VOCS_DESC_SIZE CONFIG_BT_VOCS_MAX_OUTPUT_DESCRIPTION_SIZE
29 #else
30 #define VOCS_DESC_SIZE 0
31 #endif /* CONFIG_BT_VOCS */
32 
33 #if defined(CONFIG_BT_AICS)
34 #define AICS_DESC_SIZE CONFIG_BT_AICS_MAX_INPUT_DESCRIPTION_SIZE
35 #else
36 #define AICS_DESC_SIZE 0
37 #endif /* CONFIG_BT_AICS */
38 
39 static struct bt_vcp_included vcp_included;
40 
41 static volatile uint8_t g_volume;
42 static volatile uint8_t g_mute;
43 static volatile uint8_t g_flags;
44 static volatile int16_t g_vocs_offset;
45 static volatile uint32_t g_vocs_location;
46 static char g_vocs_desc[VOCS_DESC_SIZE];
47 static volatile int8_t g_aics_gain;
48 static volatile uint8_t g_aics_input_mute;
49 static volatile uint8_t g_aics_mode;
50 static volatile uint8_t g_aics_input_type;
51 static volatile uint8_t g_aics_units;
52 static volatile uint8_t g_aics_gain_max;
53 static volatile uint8_t g_aics_gain_min;
54 static volatile bool g_aics_active = 1;
55 static char g_aics_desc[AICS_DESC_SIZE];
56 static volatile bool g_cb;
57 
vcs_state_cb(struct bt_conn * conn,int err,uint8_t volume,uint8_t mute)58 static void vcs_state_cb(struct bt_conn *conn, int err, uint8_t volume, uint8_t mute)
59 {
60 	if (err != 0) {
61 		FAIL("VCP state cb err (%d)", err);
62 		return;
63 	}
64 
65 	g_volume = volume;
66 	g_mute = mute;
67 	g_cb = true;
68 }
69 
vcs_flags_cb(struct bt_conn * conn,int err,uint8_t flags)70 static void vcs_flags_cb(struct bt_conn *conn, int err, uint8_t flags)
71 {
72 	if (err != 0) {
73 		FAIL("VCP flags cb err (%d)", err);
74 		return;
75 	}
76 
77 	g_flags = flags;
78 	g_cb = true;
79 }
80 
vocs_state_cb(struct bt_vocs * inst,int err,int16_t offset)81 static void vocs_state_cb(struct bt_vocs *inst, int err, int16_t offset)
82 {
83 	if (err != 0) {
84 		FAIL("VOCS state cb err (%d)", err);
85 		return;
86 	}
87 
88 	g_vocs_offset = offset;
89 	g_cb = true;
90 }
91 
vocs_location_cb(struct bt_vocs * inst,int err,uint32_t location)92 static void vocs_location_cb(struct bt_vocs *inst, int err, uint32_t location)
93 {
94 	if (err != 0) {
95 		FAIL("VOCS location cb err (%d)", err);
96 		return;
97 	}
98 
99 	g_vocs_location = location;
100 	g_cb = true;
101 }
102 
vocs_description_cb(struct bt_vocs * inst,int err,char * description)103 static void vocs_description_cb(struct bt_vocs *inst, int err,
104 				char *description)
105 {
106 	if (err != 0) {
107 		FAIL("VOCS description cb err (%d)", err);
108 		return;
109 	}
110 
111 	strncpy(g_vocs_desc, description, sizeof(g_vocs_desc) - 1);
112 	g_vocs_desc[sizeof(g_vocs_desc) - 1] = '\0';
113 	g_cb = true;
114 }
115 
aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)116 static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain,
117 			  uint8_t mute, uint8_t mode)
118 {
119 	if (err != 0) {
120 		FAIL("AICS state cb err (%d)", err);
121 		return;
122 	}
123 
124 	g_aics_gain = gain;
125 	g_aics_input_mute = mute;
126 	g_aics_mode = mode;
127 	g_cb = true;
128 }
129 
aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)130 static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units,
131 				 int8_t minimum, int8_t maximum)
132 {
133 	if (err != 0) {
134 		FAIL("AICS gain setting cb err (%d)", err);
135 		return;
136 	}
137 
138 	g_aics_units = units;
139 	g_aics_gain_min = minimum;
140 	g_aics_gain_max = maximum;
141 	g_cb = true;
142 }
143 
aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)144 static void aics_input_type_cb(struct bt_aics *inst, int err,
145 			       uint8_t input_type)
146 {
147 	if (err != 0) {
148 		FAIL("AICS input type cb err (%d)", err);
149 		return;
150 	}
151 
152 	g_aics_input_type = input_type;
153 	g_cb = true;
154 }
155 
aics_status_cb(struct bt_aics * inst,int err,bool active)156 static void aics_status_cb(struct bt_aics *inst, int err, bool active)
157 {
158 	if (err != 0) {
159 		FAIL("AICS status cb err (%d)", err);
160 		return;
161 	}
162 
163 	g_aics_active = active;
164 	g_cb = true;
165 }
166 
aics_description_cb(struct bt_aics * inst,int err,char * description)167 static void aics_description_cb(struct bt_aics *inst, int err,
168 				char *description)
169 {
170 	if (err != 0) {
171 		FAIL("AICS description cb err (%d)", err);
172 		return;
173 	}
174 
175 	strncpy(g_aics_desc, description, sizeof(g_aics_desc) - 1);
176 	g_aics_desc[sizeof(g_aics_desc) - 1] = '\0';
177 	g_cb = true;
178 }
179 
180 static struct bt_vcp_vol_rend_cb vcs_cb = {
181 	.state = vcs_state_cb,
182 	.flags = vcs_flags_cb,
183 };
184 
185 static struct bt_vocs_cb vocs_cb = {
186 	.state = vocs_state_cb,
187 	.location = vocs_location_cb,
188 	.description = vocs_description_cb
189 };
190 
191 static struct bt_aics_cb aics_cb = {
192 	.state = aics_state_cb,
193 	.gain_setting = aics_gain_setting_cb,
194 	.type = aics_input_type_cb,
195 	.status = aics_status_cb,
196 	.description = aics_description_cb
197 };
198 
test_aics_deactivate(void)199 static void test_aics_deactivate(void)
200 {
201 	const bool expected_aics_active = false;
202 	int err;
203 
204 	/* Invalid behavior */
205 	err = bt_aics_deactivate(NULL);
206 	if (err == 0) {
207 		FAIL("bt_aics_deactivate with NULL inst pointer did not fail");
208 		return;
209 	}
210 
211 	/* Valid behavior */
212 	printk("Deactivating AICS\n");
213 	err = bt_aics_deactivate(vcp_included.aics[0]);
214 	if (err != 0) {
215 		FAIL("Could not deactivate AICS (err %d)\n", err);
216 		return;
217 	}
218 
219 	WAIT_FOR_COND(expected_aics_active == g_aics_active);
220 	printk("AICS deactivated\n");
221 }
222 
test_aics_activate(void)223 static void test_aics_activate(void)
224 {
225 	const bool expected_aics_active = true;
226 	int err;
227 
228 	/* Invalid behavior */
229 	err = bt_aics_activate(NULL);
230 	if (err == 0) {
231 		FAIL("bt_aics_activate with NULL inst pointer did not fail");
232 		return;
233 	}
234 
235 	/* Valid behavior */
236 	printk("Activating AICS\n");
237 	err = bt_aics_activate(vcp_included.aics[0]);
238 	if (err != 0) {
239 		FAIL("Could not activate AICS (err %d)\n", err);
240 		return;
241 	}
242 
243 	WAIT_FOR_COND(expected_aics_active == g_aics_active);
244 	printk("AICS activated\n");
245 }
246 
test_aics_state_get(void)247 static void test_aics_state_get(void)
248 {
249 	int err;
250 
251 	/* Invalid behavior */
252 	err = bt_aics_state_get(NULL);
253 	if (err == 0) {
254 		FAIL("bt_aics_state_get with NULL inst pointer did not fail");
255 		return;
256 	}
257 
258 	/* Valid behavior */
259 	printk("Getting AICS state\n");
260 	g_cb = false;
261 
262 	err = bt_aics_state_get(vcp_included.aics[0]);
263 	if (err != 0) {
264 		FAIL("Could not get AICS state (err %d)\n", err);
265 		return;
266 	}
267 
268 	WAIT_FOR_COND(g_cb);
269 	printk("AICS state get\n");
270 }
271 
aics_gain_setting_get(void)272 static void aics_gain_setting_get(void)
273 {
274 	int err;
275 
276 	/* Invalid behavior */
277 	err = bt_aics_gain_setting_get(NULL);
278 	if (err == 0) {
279 		FAIL("bt_aics_gain_setting_get with NULL inst pointer did not fail");
280 		return;
281 	}
282 
283 	/* Valid behavior */
284 	printk("Getting AICS gain setting\n");
285 	g_cb = false;
286 
287 	err = bt_aics_gain_setting_get(vcp_included.aics[0]);
288 	if (err != 0) {
289 		FAIL("Could not get AICS gain setting (err %d)\n", err);
290 		return;
291 	}
292 
293 	WAIT_FOR_COND(g_cb);
294 	printk("AICS gain setting get\n");
295 }
296 
aics_type_get(void)297 static void aics_type_get(void)
298 {
299 	const uint8_t expected_input_type = BT_AICS_INPUT_TYPE_DIGITAL;
300 	int err;
301 
302 	/* Invalid behavior */
303 	err = bt_aics_type_get(NULL);
304 	if (err == 0) {
305 		FAIL("bt_aics_type_get with NULL inst pointer did not fail");
306 		return;
307 	}
308 
309 	/* Valid behavior */
310 	printk("Getting AICS input type\n");
311 
312 	err = bt_aics_type_get(vcp_included.aics[0]);
313 	if (err != 0) {
314 		FAIL("Could not get AICS input type (err %d)\n", err);
315 		return;
316 	}
317 
318 	/* Expect and wait for input_type from init */
319 	WAIT_FOR_COND(expected_input_type == g_aics_input_type);
320 	printk("AICS input type get\n");
321 }
322 
aics_status_get(void)323 static void aics_status_get(void)
324 {
325 	int err;
326 
327 	/* Invalid behavior */
328 	err = bt_aics_status_get(NULL);
329 	if (err == 0) {
330 		FAIL("bt_aics_status_get with NULL inst pointer did not fail");
331 		return;
332 	}
333 
334 	/* Valid behavior */
335 	printk("Getting AICS status\n");
336 	g_cb = false;
337 
338 	err = bt_aics_status_get(vcp_included.aics[0]);
339 	if (err != 0) {
340 		FAIL("Could not get AICS status (err %d)\n", err);
341 		return;
342 	}
343 
344 	WAIT_FOR_COND(g_cb);
345 	printk("AICS status get\n");
346 }
347 
aics_get_description(void)348 static void aics_get_description(void)
349 {
350 	int err;
351 
352 	/* Invalid behavior */
353 	err = bt_aics_description_get(NULL);
354 	if (err == 0) {
355 		FAIL("bt_aics_description_get with NULL inst pointer did not fail");
356 		return;
357 	}
358 
359 	/* Valid behavior */
360 	printk("Getting AICS description\n");
361 	g_cb = false;
362 
363 	err = bt_aics_description_get(vcp_included.aics[0]);
364 	if (err != 0) {
365 		FAIL("Could not get AICS description (err %d)\n", err);
366 		return;
367 	}
368 
369 	WAIT_FOR_COND(g_cb);
370 	printk("AICS description get\n");
371 }
372 
test_aics_mute(void)373 static void test_aics_mute(void)
374 {
375 	const uint8_t expected_input_mute = BT_AICS_STATE_MUTED;
376 	int err;
377 
378 	/* Invalid behavior */
379 	err = bt_aics_mute(NULL);
380 	if (err == 0) {
381 		FAIL("bt_aics_mute with NULL inst pointer did not fail");
382 		return;
383 	}
384 
385 	/* Valid behavior */
386 	printk("Setting AICS mute\n");
387 
388 	err = bt_aics_mute(vcp_included.aics[0]);
389 	if (err != 0) {
390 		FAIL("Could not set AICS mute (err %d)\n", err);
391 		return;
392 	}
393 
394 	WAIT_FOR_COND(expected_input_mute == g_aics_input_mute);
395 	printk("AICS mute set\n");
396 }
397 
test_aics_unmute(void)398 static void test_aics_unmute(void)
399 {
400 	const uint8_t expected_input_mute = BT_AICS_STATE_UNMUTED;
401 	int err;
402 
403 	/* Invalid behavior */
404 	err = bt_aics_unmute(NULL);
405 	if (err == 0) {
406 		FAIL("bt_aics_unmute with NULL inst pointer did not fail");
407 		return;
408 	}
409 
410 	/* Valid behavior */
411 	printk("Setting AICS unmute\n");
412 
413 	err = bt_aics_unmute(vcp_included.aics[0]);
414 	if (err != 0) {
415 		FAIL("Could not set AICS unmute (err %d)\n", err);
416 		return;
417 	}
418 
419 	WAIT_FOR_COND(expected_input_mute == g_aics_input_mute);
420 	printk("AICS unmute set\n");
421 }
422 
test_aics_automatic_gain_set(void)423 static void test_aics_automatic_gain_set(void)
424 {
425 	const uint8_t expected_mode = BT_AICS_MODE_AUTO;
426 	int err;
427 
428 	/* Invalid behavior */
429 	err = bt_aics_automatic_gain_set(NULL);
430 	if (err == 0) {
431 		FAIL("bt_aics_automatic_gain_set with NULL inst pointer did not fail");
432 		return;
433 	}
434 
435 	/* Valid behavior */
436 	printk("Setting AICS auto mode\n");
437 
438 	err = bt_aics_automatic_gain_set(vcp_included.aics[0]);
439 	if (err != 0) {
440 		FAIL("Could not set AICS auto mode (err %d)\n", err);
441 		return;
442 	}
443 
444 	WAIT_FOR_COND(expected_mode == g_aics_mode);
445 	printk("AICS auto mode set\n");
446 }
447 
test_aics_manual_gain_set(void)448 static void test_aics_manual_gain_set(void)
449 {
450 	const uint8_t expected_mode = BT_AICS_MODE_MANUAL;
451 	int err;
452 
453 	/* Invalid behavior */
454 	err = bt_aics_manual_gain_set(NULL);
455 	if (err == 0) {
456 		FAIL("bt_aics_manual_gain_set with NULL inst pointer did not fail");
457 		return;
458 	}
459 
460 	/* Valid behavior */
461 	printk("Setting AICS manual mode\n");
462 
463 	err = bt_aics_manual_gain_set(vcp_included.aics[0]);
464 	if (err != 0) {
465 		FAIL("Could not set AICS manual mode (err %d)\n", err);
466 		return;
467 	}
468 
469 	WAIT_FOR_COND(expected_mode == g_aics_mode);
470 	printk("AICS manual mode set\n");
471 }
472 
test_aics_gain_set(void)473 static void test_aics_gain_set(void)
474 {
475 	const int8_t expected_gain = g_aics_gain_max - 1;
476 	int err;
477 
478 	/* Invalid behavior */
479 	err = bt_aics_gain_set(NULL, expected_gain);
480 	if (err == 0) {
481 		FAIL("bt_aics_gain_set with NULL inst pointer did not fail");
482 		return;
483 	}
484 
485 	/* Valid behavior */
486 	printk("Setting AICS gain\n");
487 
488 	err = bt_aics_gain_set(vcp_included.aics[0], expected_gain);
489 	if (err != 0) {
490 		FAIL("Could not set AICS gain (err %d)\n", err);
491 		return;
492 	}
493 
494 	WAIT_FOR_COND(expected_gain == g_aics_gain);
495 	printk("AICS gain set\n");
496 }
497 
test_aics_description_set(void)498 static void test_aics_description_set(void)
499 {
500 	const char *expected_aics_desc = "New Input Description";
501 	int err;
502 
503 	/* Invalid behavior */
504 	err = bt_aics_description_set(NULL, expected_aics_desc);
505 	if (err == 0) {
506 		FAIL("bt_aics_description_set with NULL inst pointer did not fail");
507 		return;
508 	}
509 
510 	err = bt_aics_description_set(vcp_included.aics[0], NULL);
511 	if (err == 0) {
512 		FAIL("bt_aics_description_set with NULL description pointer did not fail");
513 		return;
514 	}
515 
516 	/* Valid behavior */
517 	printk("Setting AICS Description\n");
518 	g_cb = false;
519 
520 	err = bt_aics_description_set(vcp_included.aics[0], expected_aics_desc);
521 	if (err != 0) {
522 		FAIL("Could not set AICS Description (err %d)\n", err);
523 		return;
524 	}
525 
526 	WAIT_FOR_COND(g_cb &&
527 		      strncmp(expected_aics_desc, g_aics_desc, strlen(expected_aics_desc)) == 0);
528 	printk("AICS Description set\n");
529 }
530 
test_aics_standalone(void)531 static void test_aics_standalone(void)
532 {
533 	test_aics_deactivate();
534 	test_aics_activate();
535 	test_aics_state_get();
536 	aics_gain_setting_get();
537 	aics_type_get();
538 	aics_status_get();
539 	aics_get_description();
540 	test_aics_mute();
541 	test_aics_unmute();
542 	test_aics_automatic_gain_set();
543 	test_aics_manual_gain_set();
544 	test_aics_gain_set();
545 	test_aics_description_set();
546 }
547 
test_vocs_state_get(void)548 static void test_vocs_state_get(void)
549 {
550 	int err;
551 
552 	/* Invalid behavior */
553 	err = bt_vocs_state_get(NULL);
554 	if (err == 0) {
555 		FAIL("bt_vocs_state_get with NULL inst pointer did not fail");
556 		return;
557 	}
558 
559 	/* Valid behavior */
560 	printk("Getting VOCS state\n");
561 	g_cb = false;
562 
563 	err = bt_vocs_state_get(vcp_included.vocs[0]);
564 	if (err != 0) {
565 		FAIL("Could not get VOCS state (err %d)\n", err);
566 		return;
567 	}
568 
569 	WAIT_FOR_COND(g_cb);
570 	printk("VOCS state get\n");
571 }
572 
test_vocs_location_get(void)573 static void test_vocs_location_get(void)
574 {
575 	int err;
576 
577 	/* Invalid behavior */
578 	err = bt_vocs_location_get(NULL);
579 	if (err == 0) {
580 		FAIL("bt_vocs_location_get with NULL inst pointer did not fail");
581 		return;
582 	}
583 
584 	/* Valid behavior */
585 	printk("Getting VOCS location\n");
586 	g_cb = false;
587 
588 	err = bt_vocs_location_get(vcp_included.vocs[0]);
589 	if (err != 0) {
590 		FAIL("Could not get VOCS location (err %d)\n", err);
591 		return;
592 	}
593 
594 	WAIT_FOR_COND(g_cb);
595 	printk("VOCS location get\n");
596 }
597 
test_vocs_description_get(void)598 static void test_vocs_description_get(void)
599 {
600 	int err;
601 
602 	/* Invalid behavior */
603 	err = bt_vocs_description_get(NULL);
604 	if (err == 0) {
605 		FAIL("bt_vocs_description_get with NULL inst pointer did not fail");
606 		return;
607 	}
608 
609 	/* Valid behavior */
610 	printk("Getting VOCS description\n");
611 	g_cb = false;
612 
613 	err = bt_vocs_description_get(vcp_included.vocs[0]);
614 	if (err != 0) {
615 		FAIL("Could not get VOCS description (err %d)\n", err);
616 		return;
617 	}
618 
619 	WAIT_FOR_COND(g_cb);
620 	printk("VOCS description get\n");
621 }
622 
test_vocs_location_set(void)623 static void test_vocs_location_set(void)
624 {
625 	const uint32_t expected_location = g_vocs_location + 1;
626 	uint32_t invalid_location;
627 	int err;
628 
629 	/* Invalid behavior */
630 	err = bt_vocs_location_set(NULL, expected_location);
631 	if (err == 0) {
632 		FAIL("bt_vocs_location_set with NULL inst pointer did not fail");
633 		return;
634 	}
635 
636 	invalid_location = BT_AUDIO_LOCATION_ANY + 1;
637 
638 	err = bt_vocs_location_set(vcp_included.vocs[0], invalid_location);
639 	if (err == 0) {
640 		FAIL("bt_vocs_location_set with location 0x%08X did not fail", invalid_location);
641 		return;
642 	}
643 
644 	/* Valid behavior */
645 	printk("Setting VOCS location\n");
646 
647 	err = bt_vocs_location_set(vcp_included.vocs[0], expected_location);
648 	if (err != 0) {
649 		FAIL("Could not set VOCS location (err %d)\n", err);
650 		return;
651 	}
652 
653 	WAIT_FOR_COND(expected_location == g_vocs_location);
654 	printk("VOCS location set\n");
655 }
656 
test_vocs_state_set(void)657 static void test_vocs_state_set(void)
658 {
659 	const int16_t expected_offset = g_vocs_offset + 1;
660 	int16_t invalid_offset;
661 	int err;
662 
663 	/* Invalid behavior */
664 	err = bt_vocs_state_set(NULL, expected_offset);
665 	if (err == 0) {
666 		FAIL("bt_vocs_state_set with NULL inst pointer did not fail");
667 		return;
668 	}
669 
670 	invalid_offset = BT_VOCS_MIN_OFFSET - 1;
671 
672 	err = bt_vocs_state_set(vcp_included.vocs[0], invalid_offset);
673 	if (err == 0) {
674 		FAIL("bt_vocs_state_set with NULL offset %d did not fail", invalid_offset);
675 		return;
676 	}
677 
678 	invalid_offset = BT_VOCS_MAX_OFFSET + 1;
679 
680 	err = bt_vocs_state_set(vcp_included.vocs[0], invalid_offset);
681 	if (err == 0) {
682 		FAIL("bt_vocs_state_set with NULL offset %d did not fail", invalid_offset);
683 		return;
684 	}
685 
686 	/* Valid behavior */
687 	printk("Setting VOCS state\n");
688 
689 	err = bt_vocs_state_set(vcp_included.vocs[0], expected_offset);
690 	if (err != 0) {
691 		FAIL("Could not set VOCS state (err %d)\n", err);
692 		return;
693 	}
694 
695 	WAIT_FOR_COND(expected_offset == g_vocs_offset);
696 	printk("VOCS state set\n");
697 }
698 
test_vocs_description_set(void)699 static void test_vocs_description_set(void)
700 {
701 	const char *expected_vocs_desc = "New Output Description";
702 	int err;
703 
704 	/* Invalid behavior */
705 	err = bt_vocs_description_set(NULL, expected_vocs_desc);
706 	if (err == 0) {
707 		FAIL("bt_vocs_description_set with NULL inst pointer did not fail");
708 		return;
709 	}
710 
711 	err = bt_vocs_description_set(vcp_included.vocs[0], NULL);
712 	if (err == 0) {
713 		FAIL("bt_vocs_description_set with NULL description pointer did not fail");
714 		return;
715 	}
716 
717 	/* Valid behavior */
718 	printk("Setting VOCS description\n");
719 	g_cb = false;
720 
721 	err = bt_vocs_description_set(vcp_included.vocs[0], expected_vocs_desc);
722 	if (err != 0) {
723 		FAIL("Could not set VOCS description (err %d)\n", err);
724 		return;
725 	}
726 
727 	WAIT_FOR_COND(g_cb &&
728 		      strncmp(expected_vocs_desc, g_vocs_desc, strlen(expected_vocs_desc)) == 0);
729 	printk("VOCS description set\n");
730 }
731 
test_vocs_standalone(void)732 static void test_vocs_standalone(void)
733 {
734 	test_vocs_state_get();
735 	test_vocs_location_get();
736 	test_vocs_description_get();
737 	test_vocs_location_set();
738 	test_vocs_state_set();
739 	test_vocs_description_set();
740 }
741 
test_register(void)742 static void test_register(void)
743 {
744 	char output_desc[CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT][16];
745 	char input_desc[CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT][16];
746 	struct bt_vcp_vol_rend_register_param vcp_register_param;
747 	int err;
748 
749 	memset(&vcp_register_param, 0, sizeof(vcp_register_param));
750 
751 	for (int i = 0; i < ARRAY_SIZE(vcp_register_param.vocs_param); i++) {
752 		vcp_register_param.vocs_param[i].location_writable = true;
753 		vcp_register_param.vocs_param[i].desc_writable = true;
754 		snprintf(output_desc[i], sizeof(output_desc[i]),
755 			 "Output %d", i + 1);
756 		vcp_register_param.vocs_param[i].output_desc = output_desc[i];
757 		vcp_register_param.vocs_param[i].cb = &vocs_cb;
758 	}
759 
760 	for (int i = 0; i < ARRAY_SIZE(vcp_register_param.aics_param); i++) {
761 		vcp_register_param.aics_param[i].desc_writable = true;
762 		snprintf(input_desc[i], sizeof(input_desc[i]),
763 			 "Input %d", i + 1);
764 		vcp_register_param.aics_param[i].description = input_desc[i];
765 		vcp_register_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL;
766 		vcp_register_param.aics_param[i].status = g_aics_active;
767 		vcp_register_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
768 		vcp_register_param.aics_param[i].units = 1;
769 		vcp_register_param.aics_param[i].min_gain = 0;
770 		vcp_register_param.aics_param[i].max_gain = 100;
771 		vcp_register_param.aics_param[i].cb = &aics_cb;
772 	}
773 
774 	vcp_register_param.step = 1;
775 	vcp_register_param.mute = BT_VCP_STATE_UNMUTED;
776 	vcp_register_param.volume = 100;
777 	vcp_register_param.cb = &vcs_cb;
778 
779 	/* Invalid behavior */
780 	err = bt_vcp_vol_rend_register(NULL);
781 	if (err == 0) {
782 		FAIL("bt_vcp_vol_rend_register with NULL pointer did not fail");
783 		return;
784 	}
785 
786 	/* Valid behavior */
787 	err = bt_vcp_vol_rend_register(&vcp_register_param);
788 	if (err != 0) {
789 		FAIL("VCP register failed (err %d)\n", err);
790 		return;
791 	}
792 }
793 
test_included_get(void)794 static void test_included_get(void)
795 {
796 	int err;
797 
798 	/* Invalid behavior */
799 	err = bt_vcp_vol_rend_included_get(NULL);
800 	if (err == 0) {
801 		FAIL("bt_vcp_vol_rend_included_get with NULL pointer did not fail");
802 		return;
803 	}
804 
805 	/* Valid behavior */
806 	err = bt_vcp_vol_rend_included_get(&vcp_included);
807 	if (err != 0) {
808 		FAIL("VCP included get failed (err %d)\n", err);
809 		return;
810 	}
811 }
812 
test_set_step(uint8_t volume_step)813 static void test_set_step(uint8_t volume_step)
814 {
815 	int err;
816 
817 	/* Invalid behavior */
818 	err = bt_vcp_vol_rend_set_step(0);
819 	if (err == 0) {
820 		FAIL("bt_vcp_vol_rend_set_step with step size 0 did not fail");
821 		return;
822 	}
823 
824 	/* Valid behavior */
825 	printk("Setting VCP step\n");
826 
827 	err = bt_vcp_vol_rend_set_step(volume_step);
828 	if (err != 0) {
829 		FAIL("VCP step set failed (err %d)\n", err);
830 		return;
831 	}
832 
833 	printk("VCP step set\n");
834 }
835 
test_get_state(void)836 static void test_get_state(void)
837 {
838 	int err;
839 
840 	printk("Getting VCP volume state\n");
841 	g_cb = false;
842 
843 	err = bt_vcp_vol_rend_get_state();
844 	if (err != 0) {
845 		FAIL("Could not get VCP volume (err %d)\n", err);
846 		return;
847 	}
848 
849 	WAIT_FOR_COND(g_cb);
850 	printk("VCP volume get\n");
851 }
852 
test_get_flags(void)853 static void test_get_flags(void)
854 {
855 	int err;
856 
857 	printk("Getting VCP flags\n");
858 	g_cb = false;
859 
860 	err = bt_vcp_vol_rend_get_flags();
861 	if (err != 0) {
862 		FAIL("Could not get VCP flags (err %d)\n", err);
863 		return;
864 	}
865 
866 	WAIT_FOR_COND(g_cb);
867 	printk("VCP flags get\n");
868 }
869 
test_vol_down(uint8_t volume_step)870 static void test_vol_down(uint8_t volume_step)
871 {
872 	const uint8_t expected_volume = g_volume > volume_step ? g_volume - volume_step : 0;
873 	int err;
874 
875 	printk("Downing VCP volume\n");
876 
877 	err = bt_vcp_vol_rend_vol_down();
878 	if (err != 0) {
879 		FAIL("Could not get down VCP volume (err %d)\n", err);
880 		return;
881 	}
882 
883 	WAIT_FOR_COND(expected_volume == g_volume);
884 	printk("VCP volume downed\n");
885 }
886 
test_vol_up(uint8_t volume_step)887 static void test_vol_up(uint8_t volume_step)
888 {
889 	const uint8_t expected_volume = MIN((uint16_t)g_volume + volume_step, UINT8_MAX);
890 	int err;
891 
892 	printk("Upping VCP volume\n");
893 
894 	err = bt_vcp_vol_rend_vol_up();
895 	if (err != 0) {
896 		FAIL("Could not up VCP volume (err %d)\n", err);
897 		return;
898 	}
899 
900 	WAIT_FOR_COND(expected_volume == g_volume);
901 	printk("VCP volume upped\n");
902 }
903 
test_mute(void)904 static void test_mute(void)
905 {
906 	const uint8_t expected_mute = BT_VCP_STATE_MUTED;
907 	int err;
908 
909 	printk("Muting VCP\n");
910 
911 	err = bt_vcp_vol_rend_mute();
912 	if (err != 0) {
913 		FAIL("Could not mute VCP (err %d)\n", err);
914 		return;
915 	}
916 
917 	WAIT_FOR_COND(expected_mute == g_mute);
918 	printk("VCP muted\n");
919 }
920 
test_unmute_vol_down(uint8_t volume_step)921 static void test_unmute_vol_down(uint8_t volume_step)
922 {
923 	const uint8_t expected_volume = g_volume > volume_step ? g_volume - volume_step : 0;
924 	const uint8_t expected_mute = BT_VCP_STATE_UNMUTED;
925 	int err;
926 
927 	printk("Downing and unmuting VCP\n");
928 
929 	err = bt_vcp_vol_rend_unmute_vol_down();
930 	if (err != 0) {
931 		FAIL("Could not down and unmute VCP (err %d)\n", err);
932 		return;
933 	}
934 
935 	WAIT_FOR_COND(expected_volume == g_volume && expected_mute == g_mute);
936 	printk("VCP volume downed and unmuted\n");
937 }
938 
test_unmute_vol_up(uint8_t volume_step)939 static void test_unmute_vol_up(uint8_t volume_step)
940 {
941 	const uint8_t expected_volume = MIN((uint16_t)g_volume + volume_step, UINT8_MAX);
942 	const uint8_t expected_mute = BT_VCP_STATE_UNMUTED;
943 	int err;
944 
945 	printk("Upping and unmuting VCP\n");
946 
947 	err = bt_vcp_vol_rend_unmute_vol_up();
948 	if (err != 0) {
949 		FAIL("Could not up and unmute VCP (err %d)\n", err);
950 		return;
951 	}
952 
953 	WAIT_FOR_COND(expected_volume == g_volume && expected_mute == g_mute);
954 	printk("VCP volume upped and unmuted\n");
955 }
956 
test_unmute(void)957 static void test_unmute(void)
958 {
959 	const uint8_t expected_mute = BT_VCP_STATE_UNMUTED;
960 	int err;
961 
962 	printk("Unmuting VCP\n");
963 
964 	err = bt_vcp_vol_rend_unmute();
965 	if (err != 0) {
966 		FAIL("Could not unmute VCP (err %d)\n", err);
967 		return;
968 	}
969 
970 	WAIT_FOR_COND(expected_mute == g_mute);
971 	printk("VCP volume unmuted\n");
972 }
973 
test_set_vol(void)974 static void test_set_vol(void)
975 {
976 	const uint8_t expected_volume = g_volume - 5; /* any underflow is fine too */
977 	int err;
978 
979 	err = bt_vcp_vol_rend_set_vol(expected_volume);
980 	if (err != 0) {
981 		FAIL("Could not set VCP volume (err %d)\n", err);
982 		return;
983 	}
984 
985 	WAIT_FOR_COND(expected_volume == g_volume);
986 	printk("VCP volume set\n");
987 }
988 
test_standalone(void)989 static void test_standalone(void)
990 {
991 	const uint8_t volume_step = 5;
992 	int err;
993 
994 	err = bt_enable(NULL);
995 	if (err != 0) {
996 		FAIL("Bluetooth init failed (err %d)\n", err);
997 		return;
998 	}
999 
1000 	printk("Bluetooth initialized\n");
1001 
1002 	test_register();
1003 	test_included_get();
1004 
1005 	printk("VCP initialized\n");
1006 	test_set_step(volume_step);
1007 	test_get_state();
1008 	test_get_flags();
1009 	test_vol_down(volume_step);
1010 	test_vol_up(volume_step);
1011 	test_mute();
1012 	test_unmute_vol_down(volume_step);
1013 	test_mute();
1014 	test_unmute_vol_up(volume_step);
1015 	test_mute();
1016 	test_unmute();
1017 	test_set_vol();
1018 
1019 	if (CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT > 0) {
1020 		test_vocs_standalone();
1021 	}
1022 
1023 	if (CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT > 0) {
1024 		test_aics_standalone();
1025 	}
1026 
1027 	PASS("VCP passed\n");
1028 }
1029 
test_main(void)1030 static void test_main(void)
1031 {
1032 	int err;
1033 
1034 	err = bt_enable(NULL);
1035 	if (err != 0) {
1036 		FAIL("Bluetooth init failed (err %d)\n", err);
1037 		return;
1038 	}
1039 
1040 	printk("Bluetooth initialized\n");
1041 
1042 	test_register();
1043 	test_included_get();
1044 
1045 	printk("VCP initialized\n");
1046 
1047 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, AD_SIZE, NULL, 0);
1048 	if (err != 0) {
1049 		FAIL("Advertising failed to start (err %d)\n", err);
1050 		return;
1051 	}
1052 
1053 	printk("Advertising successfully started\n");
1054 
1055 	WAIT_FOR_FLAG(flag_connected);
1056 
1057 	PASS("VCP volume renderer passed\n");
1058 }
1059 
1060 static const struct bst_test_instance test_vcs[] = {
1061 	{
1062 		.test_id = "vcp_vol_rend_standalone",
1063 		.test_pre_init_f = test_init,
1064 		.test_tick_f = test_tick,
1065 		.test_main_f = test_standalone
1066 	},
1067 	{
1068 		.test_id = "vcp_vol_rend",
1069 		.test_pre_init_f = test_init,
1070 		.test_tick_f = test_tick,
1071 		.test_main_f = test_main
1072 	},
1073 	BSTEST_END_MARKER
1074 };
1075 
test_vcp_install(struct bst_test_list * tests)1076 struct bst_test_list *test_vcp_install(struct bst_test_list *tests)
1077 {
1078 	return bst_add_tests(tests, test_vcs);
1079 }
1080 #else
test_vcp_install(struct bst_test_list * tests)1081 struct bst_test_list *test_vcp_install(struct bst_test_list *tests)
1082 {
1083 	return tests;
1084 }
1085 
1086 #endif /* CONFIG_BT_VCP_VOL_REND */
1087