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