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