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