1 /*
2  * Copyright (c) 2020-2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdbool.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include <zephyr/autoconf.h>
12 #include <zephyr/bluetooth/audio/aics.h>
13 #include <zephyr/bluetooth/audio/micp.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/sys/printk.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/sys/util_macro.h>
18 
19 #include "bstests.h"
20 #include "common.h"
21 
22 #ifdef CONFIG_BT_MICP_MIC_DEV
23 extern enum bst_result_t bst_result;
24 
25 #if defined(CONFIG_BT_AICS)
26 #define AICS_DESC_SIZE CONFIG_BT_AICS_MAX_INPUT_DESCRIPTION_SIZE
27 #else
28 #define AICS_DESC_SIZE 0
29 #endif /* CONFIG_BT_AICS */
30 
31 static struct bt_micp_included micp_included;
32 
33 static volatile uint8_t g_mute;
34 static volatile int8_t g_aics_gain;
35 static volatile uint8_t g_aics_input_mute;
36 static volatile uint8_t g_aics_mode;
37 static volatile uint8_t g_aics_input_type;
38 static volatile uint8_t g_aics_units;
39 static volatile uint8_t g_aics_gain_max;
40 static volatile uint8_t g_aics_gain_min;
41 static volatile bool g_aics_active = true;
42 static char g_aics_desc[AICS_DESC_SIZE];
43 static volatile bool g_cb;
44 
micp_mute_cb(uint8_t mute)45 static void micp_mute_cb(uint8_t mute)
46 {
47 	g_mute = mute;
48 	g_cb = true;
49 }
50 
51 static struct bt_micp_mic_dev_cb micp_cb = {
52 	.mute = micp_mute_cb,
53 };
54 
55 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)56 static void aics_state_cb(struct bt_aics *inst, int err, int8_t gain,
57 			  uint8_t mute, uint8_t mode)
58 {
59 	if (err != 0) {
60 		FAIL("AICS state cb err (%d)", err);
61 		return;
62 	}
63 
64 	g_aics_gain = gain;
65 	g_aics_input_mute = mute;
66 	g_aics_mode = mode;
67 	g_cb = true;
68 }
69 
aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)70 static void aics_gain_setting_cb(struct bt_aics *inst, int err, uint8_t units,
71 				 int8_t minimum, int8_t maximum)
72 {
73 	if (err != 0) {
74 		FAIL("AICS gain setting cb err (%d)", err);
75 		return;
76 	}
77 
78 	g_aics_units = units;
79 	g_aics_gain_min = minimum;
80 	g_aics_gain_max = maximum;
81 	g_cb = true;
82 }
83 
aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)84 static void aics_input_type_cb(struct bt_aics *inst, int err,
85 			       uint8_t input_type)
86 {
87 	if (err != 0) {
88 		FAIL("AICS input type cb err (%d)", err);
89 		return;
90 	}
91 
92 	g_aics_input_type = input_type;
93 	g_cb = true;
94 }
95 
aics_status_cb(struct bt_aics * inst,int err,bool active)96 static void aics_status_cb(struct bt_aics *inst, int err, bool active)
97 {
98 	if (err != 0) {
99 		FAIL("AICS status cb err (%d)", err);
100 		return;
101 	}
102 
103 	g_aics_active = active;
104 	g_cb = true;
105 }
106 
aics_description_cb(struct bt_aics * inst,int err,char * description)107 static void aics_description_cb(struct bt_aics *inst, int err,
108 				char *description)
109 {
110 	if (err != 0) {
111 		FAIL("AICS description cb err (%d)", err);
112 		return;
113 	}
114 
115 
116 	strncpy(g_aics_desc, description, sizeof(g_aics_desc) - 1);
117 	g_aics_desc[sizeof(g_aics_desc) - 1] = '\0';
118 	g_cb = true;
119 }
120 
121 static struct bt_aics_cb aics_cb = {
122 	.state = aics_state_cb,
123 	.gain_setting = aics_gain_setting_cb,
124 	.type = aics_input_type_cb,
125 	.status = aics_status_cb,
126 	.description = aics_description_cb
127 };
128 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
129 
test_aics_server_only(void)130 static int test_aics_server_only(void)
131 {
132 	int err;
133 	int8_t expected_gain;
134 	uint8_t expected_input_mute;
135 	uint8_t expected_mode;
136 	uint8_t expected_input_type;
137 	bool expected_aics_active;
138 	char expected_aics_desc[AICS_DESC_SIZE];
139 
140 	printk("Deactivating AICS\n");
141 	expected_aics_active = false;
142 	err = bt_aics_deactivate(micp_included.aics[0]);
143 	if (err != 0) {
144 		FAIL("Could not deactivate AICS (err %d)\n", err);
145 		return err;
146 	}
147 	WAIT_FOR_COND(expected_aics_active == g_aics_active);
148 	printk("AICS deactivated\n");
149 
150 	printk("Activating AICS\n");
151 	expected_aics_active = true;
152 	err = bt_aics_activate(micp_included.aics[0]);
153 	if (err != 0) {
154 		FAIL("Could not activate AICS (err %d)\n", err);
155 		return err;
156 	}
157 	WAIT_FOR_COND(expected_aics_active == g_aics_active);
158 	printk("AICS activated\n");
159 
160 	printk("Getting AICS state\n");
161 	g_cb = false;
162 	err = bt_aics_state_get(micp_included.aics[0]);
163 	if (err != 0) {
164 		FAIL("Could not get AICS state (err %d)\n", err);
165 		return err;
166 	}
167 	WAIT_FOR_COND(g_cb);
168 	printk("AICS state get\n");
169 
170 	printk("Getting AICS gain setting\n");
171 	g_cb = false;
172 	err = bt_aics_gain_setting_get(micp_included.aics[0]);
173 	if (err != 0) {
174 		FAIL("Could not get AICS gain setting (err %d)\n", err);
175 		return err;
176 	}
177 	WAIT_FOR_COND(g_cb);
178 	printk("AICS gain setting get\n");
179 
180 	printk("Getting AICS input type\n");
181 	g_cb = false;
182 	expected_input_type = BT_AICS_INPUT_TYPE_DIGITAL;
183 	err = bt_aics_type_get(micp_included.aics[0]);
184 	if (err != 0) {
185 		FAIL("Could not get AICS input type (err %d)\n", err);
186 		return err;
187 	}
188 	/* Expect and wait for input_type from init */
189 	WAIT_FOR_COND(g_cb && expected_input_type == g_aics_input_type);
190 	printk("AICS input type get\n");
191 
192 	printk("Getting AICS status\n");
193 	g_cb = false;
194 	err = bt_aics_status_get(micp_included.aics[0]);
195 	if (err != 0) {
196 		FAIL("Could not get AICS status (err %d)\n", err);
197 		return err;
198 	}
199 	WAIT_FOR_COND(g_cb);
200 	printk("AICS status get\n");
201 
202 	printk("Getting AICS description\n");
203 	g_cb = false;
204 	err = bt_aics_description_get(micp_included.aics[0]);
205 	if (err != 0) {
206 		FAIL("Could not get AICS description (err %d)\n", err);
207 		return err;
208 	}
209 	WAIT_FOR_COND(g_cb);
210 	printk("AICS description get\n");
211 
212 	printk("Setting AICS mute\n");
213 	g_cb = false;
214 	expected_input_mute = BT_AICS_STATE_MUTED;
215 	err = bt_aics_mute(micp_included.aics[0]);
216 	if (err != 0) {
217 		FAIL("Could not set AICS mute (err %d)\n", err);
218 		return err;
219 	}
220 	WAIT_FOR_COND(g_cb && expected_input_mute == g_aics_input_mute);
221 	printk("AICS mute set\n");
222 
223 	printk("Setting AICS unmute\n");
224 	g_cb = false;
225 	expected_input_mute = BT_AICS_STATE_UNMUTED;
226 	err = bt_aics_unmute(micp_included.aics[0]);
227 	if (err != 0) {
228 		FAIL("Could not set AICS unmute (err %d)\n", err);
229 		return err;
230 	}
231 	WAIT_FOR_COND(g_cb && expected_input_mute == g_aics_input_mute);
232 	printk("AICS unmute set\n");
233 
234 	printk("Setting AICS auto mode\n");
235 	g_cb = false;
236 	expected_mode = BT_AICS_MODE_AUTO;
237 	err = bt_aics_automatic_gain_set(micp_included.aics[0]);
238 	if (err != 0) {
239 		FAIL("Could not set AICS auto mode (err %d)\n", err);
240 		return err;
241 	}
242 	WAIT_FOR_COND(g_cb && expected_mode == g_aics_mode);
243 	printk("AICS auto mode set\n");
244 
245 	printk("Setting AICS manual mode\n");
246 	g_cb = false;
247 	expected_mode = BT_AICS_MODE_MANUAL;
248 	err = bt_aics_manual_gain_set(micp_included.aics[0]);
249 	if (err != 0) {
250 		FAIL("Could not set AICS manual mode (err %d)\n", err);
251 		return err;
252 	}
253 	WAIT_FOR_COND(g_cb && expected_mode == g_aics_mode);
254 	printk("AICS manual mode set\n");
255 
256 	printk("Setting AICS gain\n");
257 	g_cb = false;
258 	expected_gain = g_aics_gain_max - 1;
259 	err = bt_aics_gain_set(micp_included.aics[0], expected_gain);
260 	if (err != 0) {
261 		FAIL("Could not set AICS gain (err %d)\n", err);
262 		return err;
263 	}
264 	WAIT_FOR_COND(g_cb && expected_gain == g_aics_gain);
265 	printk("AICS gain set\n");
266 
267 	printk("Setting AICS Description\n");
268 	g_cb = false;
269 	strncpy(expected_aics_desc, "New Input Description",
270 		sizeof(expected_aics_desc));
271 	expected_aics_desc[sizeof(expected_aics_desc) - 1] = '\0';
272 	err = bt_aics_description_set(micp_included.aics[0], expected_aics_desc);
273 	if (err != 0) {
274 		FAIL("Could not set AICS Description (err %d)\n", err);
275 		return err;
276 	}
277 	WAIT_FOR_COND(g_cb && !strncmp(expected_aics_desc, g_aics_desc,
278 				  sizeof(expected_aics_desc)));
279 	printk("AICS Description set\n");
280 
281 	return 0;
282 }
283 
test_mic_dev_only(void)284 static void test_mic_dev_only(void)
285 {
286 	int err;
287 	struct bt_micp_mic_dev_register_param micp_param;
288 	uint8_t expected_mute;
289 
290 	err = bt_enable(NULL);
291 	if (err != 0) {
292 		FAIL("Bluetooth init failed (err %d)\n", err);
293 		return;
294 	}
295 
296 	printk("Bluetooth initialized\n");
297 
298 	(void)memset(&micp_param, 0, sizeof(micp_param));
299 
300 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
301 	char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16];
302 
303 	for (int i = 0; i < ARRAY_SIZE(micp_param.aics_param); i++) {
304 		micp_param.aics_param[i].desc_writable = true;
305 		snprintf(input_desc[i], sizeof(input_desc[i]), "Input %d", i + 1);
306 		micp_param.aics_param[i].description = input_desc[i];
307 		micp_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL;
308 		micp_param.aics_param[i].status = g_aics_active;
309 		micp_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
310 		micp_param.aics_param[i].units = 1;
311 		micp_param.aics_param[i].min_gain = 0;
312 		micp_param.aics_param[i].max_gain = 100;
313 		micp_param.aics_param[i].cb = &aics_cb;
314 	}
315 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
316 
317 	micp_param.cb = &micp_cb;
318 
319 	err = bt_micp_mic_dev_register(&micp_param);
320 	if (err != 0) {
321 		FAIL("MICP init failed (err %d)\n", err);
322 		return;
323 	}
324 
325 	if (IS_ENABLED(CONFIG_BT_MICP_MIC_DEV_AICS)) {
326 		err = bt_micp_mic_dev_included_get(&micp_included);
327 		if (err != 0) {
328 			FAIL("MICP get failed (err %d)\n", err);
329 			return;
330 		}
331 	}
332 
333 	printk("MICP initialized\n");
334 
335 	printk("Getting MICP mute\n");
336 	g_cb = false;
337 	err = bt_micp_mic_dev_mute_get();
338 	if (err != 0) {
339 		FAIL("Could not get MICP mute (err %d)\n", err);
340 		return;
341 	}
342 	WAIT_FOR_COND(g_cb);
343 	printk("MICP mute get\n");
344 
345 	printk("Setting MICP mute\n");
346 	expected_mute = BT_MICP_MUTE_MUTED;
347 	err = bt_micp_mic_dev_mute();
348 	if (err != 0) {
349 		FAIL("MICP mute failed (err %d)\n", err);
350 		return;
351 	}
352 	WAIT_FOR_COND(expected_mute == g_mute);
353 	printk("MICP mute set\n");
354 
355 	printk("Setting MICP unmute\n");
356 	expected_mute = BT_MICP_MUTE_UNMUTED;
357 	err = bt_micp_mic_dev_unmute();
358 	if (err != 0) {
359 		FAIL("MICP unmute failed (err %d)\n", err);
360 		return;
361 	}
362 	WAIT_FOR_COND(expected_mute == g_mute);
363 	printk("MICP unmute set\n");
364 
365 	printk("Setting MICP disable\n");
366 	expected_mute = BT_MICP_MUTE_DISABLED;
367 	err = bt_micp_mic_dev_mute_disable();
368 	if (err != 0) {
369 		FAIL("MICP disable failed (err %d)\n", err);
370 		return;
371 	}
372 	WAIT_FOR_COND(expected_mute == g_mute);
373 	printk("MICP disable set\n");
374 
375 	if (CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT > 0) {
376 		if (test_aics_server_only()) {
377 			return;
378 		}
379 	}
380 
381 	PASS("MICP mic_dev passed\n");
382 }
383 
test_main(void)384 static void test_main(void)
385 {
386 	int err;
387 	struct bt_micp_mic_dev_register_param micp_param;
388 
389 	err = bt_enable(NULL);
390 	if (err != 0) {
391 		FAIL("Bluetooth init failed (err %d)\n", err);
392 		return;
393 	}
394 
395 	printk("Bluetooth initialized\n");
396 
397 	(void)memset(&micp_param, 0, sizeof(micp_param));
398 
399 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
400 	char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16];
401 
402 	for (int i = 0; i < ARRAY_SIZE(micp_param.aics_param); i++) {
403 		micp_param.aics_param[i].desc_writable = true;
404 		snprintf(input_desc[i], sizeof(input_desc[i]),
405 			 "Input %d", i + 1);
406 		micp_param.aics_param[i].description = input_desc[i];
407 		micp_param.aics_param[i].type = BT_AICS_INPUT_TYPE_UNSPECIFIED;
408 		micp_param.aics_param[i].status = g_aics_active;
409 		micp_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
410 		micp_param.aics_param[i].units = 1;
411 		micp_param.aics_param[i].min_gain = 0;
412 		micp_param.aics_param[i].max_gain = 100;
413 		micp_param.aics_param[i].cb = &aics_cb;
414 	}
415 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
416 
417 	micp_param.cb = &micp_cb;
418 
419 	err = bt_micp_mic_dev_register(&micp_param);
420 	if (err != 0) {
421 		FAIL("MICP init failed (err %d)\n", err);
422 		return;
423 	}
424 
425 	if (IS_ENABLED(CONFIG_BT_MICP_MIC_DEV_AICS)) {
426 		err = bt_micp_mic_dev_included_get(&micp_included);
427 		if (err != 0) {
428 			FAIL("MICP get failed (err %d)\n", err);
429 			return;
430 		}
431 	}
432 
433 	printk("MICP initialized\n");
434 
435 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, AD_SIZE, NULL, 0);
436 	if (err != 0) {
437 		FAIL("Advertising failed to start (err %d)\n", err);
438 		return;
439 	}
440 
441 	printk("Advertising successfully started\n");
442 
443 	WAIT_FOR_FLAG(flag_connected);
444 
445 	PASS("MICP mic_dev passed\n");
446 }
447 
448 static const struct bst_test_instance test_micp[] = {
449 	{
450 		.test_id = "micp_mic_dev_only",
451 		.test_pre_init_f = test_init,
452 		.test_tick_f = test_tick,
453 		.test_main_f = test_mic_dev_only
454 	},
455 	{
456 		.test_id = "micp_mic_dev",
457 		.test_pre_init_f = test_init,
458 		.test_tick_f = test_tick,
459 		.test_main_f = test_main
460 	},
461 	BSTEST_END_MARKER
462 };
463 
test_micp_install(struct bst_test_list * tests)464 struct bst_test_list *test_micp_install(struct bst_test_list *tests)
465 {
466 	return bst_add_tests(tests, test_micp);
467 }
468 #else
test_micp_install(struct bst_test_list * tests)469 struct bst_test_list *test_micp_install(struct bst_test_list *tests)
470 {
471 	return tests;
472 }
473 
474 #endif /* CONFIG_BT_MICP_MIC_DEV */
475