1 /** @file
2  *  @brief Bluetooth MICP Microphone Controller shell.
3  *
4  * Copyright (c) 2020 Bose Corporation
5  * Copyright (c) 2020-2022 Nordic Semiconductor ASA
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/audio/aics.h>
18 #include <zephyr/bluetooth/audio/micp.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/shell/shell.h>
21 #include <zephyr/shell/shell_string_conv.h>
22 #include <zephyr/types.h>
23 
24 #include "host/shell/bt.h"
25 
26 static struct bt_micp_mic_ctlr *micp_mic_ctlr;
27 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
28 static struct bt_micp_included micp_included;
29 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
30 
micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err,uint8_t aics_count)31 static void micp_mic_ctlr_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr,
32 				      int err, uint8_t aics_count)
33 {
34 	if (err != 0) {
35 		shell_error(ctx_shell, "Discovery failed (%d)", err);
36 	} else {
37 		shell_print(ctx_shell, "Discovery done with %u AICS",
38 			    aics_count);
39 
40 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
41 		if (bt_micp_mic_ctlr_included_get(mic_ctlr,
42 						  &micp_included) != 0) {
43 			shell_error(ctx_shell, "Could not get included services");
44 		}
45 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
46 	}
47 }
48 
micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err)49 static void micp_mic_ctlr_mute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr,
50 					  int err)
51 {
52 	if (err != 0) {
53 		shell_error(ctx_shell, "Mute write failed (%d)", err);
54 	} else {
55 		shell_print(ctx_shell, "Mute write completed");
56 	}
57 }
58 
micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err)59 static void micp_mic_ctlr_unmute_written_cb(struct bt_micp_mic_ctlr *mic_ctlr,
60 					    int err)
61 {
62 	if (err != 0) {
63 		shell_error(ctx_shell, "Unmute write failed (%d)", err);
64 	} else {
65 		shell_print(ctx_shell, "Unmute write completed");
66 	}
67 }
68 
micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err,uint8_t mute)69 static void micp_mic_ctlr_mute_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err,
70 				  uint8_t mute)
71 {
72 	if (err != 0) {
73 		shell_error(ctx_shell, "Mute get failed (%d)", err);
74 	} else {
75 		shell_print(ctx_shell, "Mute value %u", mute);
76 	}
77 }
78 
79 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
80 static struct bt_micp_included micp_included;
81 
micp_mic_ctlr_aics_set_gain_cb(struct bt_aics * inst,int err)82 static void micp_mic_ctlr_aics_set_gain_cb(struct bt_aics *inst, int err)
83 {
84 	if (err != 0) {
85 		shell_error(ctx_shell, "Set gain failed (%d) for inst %p",
86 			    err, inst);
87 	} else {
88 		shell_print(ctx_shell, "Gain set for inst %p", inst);
89 	}
90 }
91 
micp_mic_ctlr_aics_unmute_cb(struct bt_aics * inst,int err)92 static void micp_mic_ctlr_aics_unmute_cb(struct bt_aics *inst, int err)
93 {
94 	if (err != 0) {
95 		shell_error(ctx_shell, "Unmute failed (%d) for inst %p",
96 			    err, inst);
97 	} else {
98 		shell_print(ctx_shell, "Unmuted inst %p", inst);
99 	}
100 }
101 
micp_mic_ctlr_aics_mute_cb(struct bt_aics * inst,int err)102 static void micp_mic_ctlr_aics_mute_cb(struct bt_aics *inst, int err)
103 {
104 	if (err != 0) {
105 		shell_error(ctx_shell, "Mute failed (%d) for inst %p",
106 			    err, inst);
107 	} else {
108 		shell_print(ctx_shell, "Muted inst %p", inst);
109 	}
110 }
111 
micp_mic_ctlr_aics_set_manual_mode_cb(struct bt_aics * inst,int err)112 static void micp_mic_ctlr_aics_set_manual_mode_cb(struct bt_aics *inst, int err)
113 {
114 	if (err != 0) {
115 		shell_error(ctx_shell,
116 			    "Set manual mode failed (%d) for inst %p",
117 			    err, inst);
118 	} else {
119 		shell_print(ctx_shell, "Manual mode set for inst %p", inst);
120 	}
121 }
122 
micp_mic_ctlr_aics_automatic_mode_cb(struct bt_aics * inst,int err)123 static void micp_mic_ctlr_aics_automatic_mode_cb(struct bt_aics *inst, int err)
124 {
125 	if (err != 0) {
126 		shell_error(ctx_shell,
127 			    "Set automatic mode failed (%d) for inst %p",
128 			    err, inst);
129 	} else {
130 		shell_print(ctx_shell, "Automatic mode set for inst %p",
131 			    inst);
132 	}
133 }
134 
micp_mic_ctlr_aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)135 static void micp_mic_ctlr_aics_state_cb(struct bt_aics *inst, int err,
136 					int8_t gain, uint8_t mute, uint8_t mode)
137 {
138 	if (err != 0) {
139 		shell_error(ctx_shell, "AICS state get failed (%d) for "
140 			    "inst %p", err, inst);
141 	} else {
142 		shell_print(ctx_shell, "AICS inst %p state gain %d, mute %u, "
143 			    "mode %u", inst, gain, mute, mode);
144 	}
145 
146 }
147 
micp_mic_ctlr_aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)148 static void micp_mic_ctlr_aics_gain_setting_cb(struct bt_aics *inst, int err,
149 					       uint8_t units, int8_t minimum,
150 					       int8_t maximum)
151 {
152 	if (err != 0) {
153 		shell_error(ctx_shell, "AICS gain settings get failed (%d) for "
154 			    "inst %p", err, inst);
155 	} else {
156 		shell_print(ctx_shell, "AICS inst %p gain settings units %u, "
157 			    "min %d, max %d", inst, units, minimum,
158 			    maximum);
159 	}
160 
161 }
162 
micp_mic_ctlr_aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)163 static void micp_mic_ctlr_aics_input_type_cb(struct bt_aics *inst, int err,
164 					     uint8_t input_type)
165 {
166 	if (err != 0) {
167 		shell_error(ctx_shell, "AICS input type get failed (%d) for "
168 			    "inst %p", err, inst);
169 	} else {
170 		shell_print(ctx_shell, "AICS inst %p input type %u",
171 			    inst, input_type);
172 	}
173 
174 }
175 
micp_mic_ctlr_aics_status_cb(struct bt_aics * inst,int err,bool active)176 static void micp_mic_ctlr_aics_status_cb(struct bt_aics *inst, int err,
177 					 bool active)
178 {
179 	if (err != 0) {
180 		shell_error(ctx_shell, "AICS status get failed (%d) for "
181 			    "inst %p", err, inst);
182 	} else {
183 		shell_print(ctx_shell, "AICS inst %p status %s",
184 			    inst, active ? "active" : "inactive");
185 	}
186 
187 }
188 
micp_mic_ctlr_aics_description_cb(struct bt_aics * inst,int err,char * description)189 static void micp_mic_ctlr_aics_description_cb(struct bt_aics *inst, int err,
190 					      char *description)
191 {
192 	if (err != 0) {
193 		shell_error(ctx_shell, "AICS description get failed (%d) for "
194 			    "inst %p", err, inst);
195 	} else {
196 		shell_print(ctx_shell, "AICS inst %p description %s",
197 			    inst, description);
198 	}
199 }
200 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
201 
202 static struct bt_micp_mic_ctlr_cb micp_cbs = {
203 	.discover = micp_mic_ctlr_discover_cb,
204 	.mute_written = micp_mic_ctlr_mute_written_cb,
205 	.unmute_written = micp_mic_ctlr_unmute_written_cb,
206 	.mute = micp_mic_ctlr_mute_cb,
207 
208 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
209 	/* Audio Input Control Service */
210 	.aics_cb = {
211 		.state = micp_mic_ctlr_aics_state_cb,
212 		.gain_setting = micp_mic_ctlr_aics_gain_setting_cb,
213 		.type = micp_mic_ctlr_aics_input_type_cb,
214 		.status = micp_mic_ctlr_aics_status_cb,
215 		.description = micp_mic_ctlr_aics_description_cb,
216 		.set_gain = micp_mic_ctlr_aics_set_gain_cb,
217 		.unmute = micp_mic_ctlr_aics_unmute_cb,
218 		.mute = micp_mic_ctlr_aics_mute_cb,
219 		.set_manual_mode = micp_mic_ctlr_aics_set_manual_mode_cb,
220 		.set_auto_mode = micp_mic_ctlr_aics_automatic_mode_cb,
221 	}
222 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
223 };
224 
cmd_micp_mic_ctlr_discover(const struct shell * sh,size_t argc,char ** argv)225 static int cmd_micp_mic_ctlr_discover(const struct shell *sh, size_t argc,
226 				    char **argv)
227 {
228 	int result;
229 
230 	if (ctx_shell == NULL) {
231 		ctx_shell = sh;
232 	}
233 
234 	result = bt_micp_mic_ctlr_cb_register(&micp_cbs);
235 	if (result != 0) {
236 		shell_print(sh, "Failed to register callbacks: %d", result);
237 	}
238 
239 	if (default_conn == NULL) {
240 		return -ENOTCONN;
241 	}
242 
243 	result = bt_micp_mic_ctlr_discover(default_conn, &micp_mic_ctlr);
244 	if (result != 0) {
245 		shell_print(sh, "Fail: %d", result);
246 	}
247 
248 	return result;
249 }
250 
cmd_micp_mic_ctlr_mute_get(const struct shell * sh,size_t argc,char ** argv)251 static int cmd_micp_mic_ctlr_mute_get(const struct shell *sh, size_t argc,
252 				    char **argv)
253 {
254 	int result;
255 
256 	if (micp_mic_ctlr == NULL) {
257 		return -ENOENT;
258 	}
259 
260 	result = bt_micp_mic_ctlr_mute_get(micp_mic_ctlr);
261 
262 	if (result != 0) {
263 		shell_print(sh, "Fail: %d", result);
264 	}
265 
266 	return result;
267 }
268 
cmd_micp_mic_ctlr_mute(const struct shell * sh,size_t argc,char ** argv)269 static int cmd_micp_mic_ctlr_mute(const struct shell *sh, size_t argc,
270 				char **argv)
271 {
272 	int result;
273 
274 	if (micp_mic_ctlr == NULL) {
275 		return -ENOENT;
276 	}
277 
278 	result = bt_micp_mic_ctlr_mute(micp_mic_ctlr);
279 
280 	if (result != 0) {
281 		shell_print(sh, "Fail: %d", result);
282 	}
283 
284 	return result;
285 }
286 
cmd_micp_mic_ctlr_unmute(const struct shell * sh,size_t argc,char ** argv)287 static int cmd_micp_mic_ctlr_unmute(const struct shell *sh, size_t argc,
288 				  char **argv)
289 {
290 	int result;
291 
292 	if (micp_mic_ctlr == NULL) {
293 		return -ENOENT;
294 	}
295 
296 	result = bt_micp_mic_ctlr_unmute(micp_mic_ctlr);
297 
298 	if (result != 0) {
299 		shell_print(sh, "Fail: %d", result);
300 	}
301 
302 	return result;
303 }
304 
305 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
cmd_micp_mic_ctlr_aics_input_state_get(const struct shell * sh,size_t argc,char ** argv)306 static int cmd_micp_mic_ctlr_aics_input_state_get(const struct shell *sh,
307 						size_t argc, char **argv)
308 {
309 	unsigned long index;
310 	int result = 0;
311 
312 	index = shell_strtoul(argv[1], 0, &result);
313 	if (result != 0) {
314 		shell_error(sh, "Could not parse index: %d", result);
315 
316 		return -ENOEXEC;
317 	}
318 
319 	if (index >= micp_included.aics_cnt) {
320 		shell_error(sh, "Index shall be less than %u, was %lu",
321 			    micp_included.aics_cnt, index);
322 
323 		return -ENOEXEC;
324 	}
325 
326 	if (micp_mic_ctlr == NULL) {
327 		return -ENOENT;
328 	}
329 
330 	result = bt_aics_state_get(micp_included.aics[index]);
331 	if (result != 0) {
332 		shell_print(sh, "Fail: %d", result);
333 	}
334 
335 	return result;
336 }
337 
cmd_micp_mic_ctlr_aics_gain_setting_get(const struct shell * sh,size_t argc,char ** argv)338 static int cmd_micp_mic_ctlr_aics_gain_setting_get(const struct shell *sh,
339 						 size_t argc, char **argv)
340 {
341 	unsigned long index;
342 	int result = 0;
343 
344 	index = shell_strtoul(argv[1], 0, &result);
345 	if (result != 0) {
346 		shell_error(sh, "Could not parse index: %d", result);
347 
348 		return -ENOEXEC;
349 	}
350 
351 	if (index >= micp_included.aics_cnt) {
352 		shell_error(sh, "Index shall be less than %u, was %lu",
353 			    micp_included.aics_cnt, index);
354 
355 		return -ENOEXEC;
356 	}
357 
358 	if (micp_mic_ctlr == NULL) {
359 		return -ENOENT;
360 	}
361 
362 	result = bt_aics_gain_setting_get(micp_included.aics[index]);
363 	if (result != 0) {
364 		shell_print(sh, "Fail: %d", result);
365 	}
366 
367 	return result;
368 }
369 
cmd_micp_mic_ctlr_aics_input_type_get(const struct shell * sh,size_t argc,char ** argv)370 static int cmd_micp_mic_ctlr_aics_input_type_get(const struct shell *sh,
371 					       size_t argc, char **argv)
372 {
373 	unsigned long index;
374 	int result = 0;
375 
376 	index = shell_strtoul(argv[1], 0, &result);
377 	if (result != 0) {
378 		shell_error(sh, "Could not parse index: %d", result);
379 
380 		return -ENOEXEC;
381 	}
382 
383 	if (index >= micp_included.aics_cnt) {
384 		shell_error(sh, "Index shall be less than %u, was %lu",
385 			    micp_included.aics_cnt, index);
386 
387 		return -ENOEXEC;
388 	}
389 
390 	if (micp_mic_ctlr == NULL) {
391 		return -ENOENT;
392 	}
393 
394 	result = bt_aics_type_get(micp_included.aics[index]);
395 	if (result != 0) {
396 		shell_print(sh, "Fail: %d", result);
397 	}
398 
399 	return result;
400 }
401 
cmd_micp_mic_ctlr_aics_input_status_get(const struct shell * sh,size_t argc,char ** argv)402 static int cmd_micp_mic_ctlr_aics_input_status_get(const struct shell *sh,
403 						 size_t argc, char **argv)
404 {
405 	unsigned long index;
406 	int result = 0;
407 
408 	index = shell_strtoul(argv[1], 0, &result);
409 	if (result != 0) {
410 		shell_error(sh, "Could not parse index: %d", result);
411 
412 		return -ENOEXEC;
413 	}
414 
415 	if (index >= micp_included.aics_cnt) {
416 		shell_error(sh, "Index shall be less than %u, was %lu",
417 			    micp_included.aics_cnt, index);
418 
419 		return -ENOEXEC;
420 	}
421 
422 	if (micp_mic_ctlr == NULL) {
423 		return -ENOENT;
424 	}
425 
426 	result = bt_aics_status_get(micp_included.aics[index]);
427 	if (result != 0) {
428 		shell_print(sh, "Fail: %d", result);
429 	}
430 
431 	return result;
432 }
433 
cmd_micp_mic_ctlr_aics_input_unmute(const struct shell * sh,size_t argc,char ** argv)434 static int cmd_micp_mic_ctlr_aics_input_unmute(const struct shell *sh,
435 					     size_t argc, char **argv)
436 {
437 	unsigned long index;
438 	int result = 0;
439 
440 	index = shell_strtoul(argv[1], 0, &result);
441 	if (result != 0) {
442 		shell_error(sh, "Could not parse index: %d", result);
443 
444 		return -ENOEXEC;
445 	}
446 
447 	if (index >= micp_included.aics_cnt) {
448 		shell_error(sh, "Index shall be less than %u, was %lu",
449 			    micp_included.aics_cnt, index);
450 
451 		return -ENOEXEC;
452 	}
453 
454 	result = bt_aics_unmute(micp_included.aics[index]);
455 	if (result != 0) {
456 		shell_print(sh, "Fail: %d", result);
457 	}
458 
459 	return result;
460 }
461 
cmd_micp_mic_ctlr_aics_input_mute(const struct shell * sh,size_t argc,char ** argv)462 static int cmd_micp_mic_ctlr_aics_input_mute(const struct shell *sh,
463 					   size_t argc, char **argv)
464 {
465 	unsigned long index;
466 	int result = 0;
467 
468 	index = shell_strtoul(argv[1], 0, &result);
469 	if (result != 0) {
470 		shell_error(sh, "Could not parse index: %d", result);
471 
472 		return -ENOEXEC;
473 	}
474 
475 	if (index >= micp_included.aics_cnt) {
476 		shell_error(sh, "Index shall be less than %u, was %lu",
477 			    micp_included.aics_cnt, index);
478 
479 		return -ENOEXEC;
480 	}
481 
482 	if (micp_mic_ctlr == NULL) {
483 		return -ENOENT;
484 	}
485 
486 	result = bt_aics_mute(micp_included.aics[index]);
487 	if (result != 0) {
488 		shell_print(sh, "Fail: %d", result);
489 	}
490 
491 	return result;
492 }
493 
cmd_micp_mic_ctlr_aics_manual_input_gain_set(const struct shell * sh,size_t argc,char ** argv)494 static int cmd_micp_mic_ctlr_aics_manual_input_gain_set(const struct shell *sh,
495 						      size_t argc, char **argv)
496 {
497 	unsigned long index;
498 	int result = 0;
499 
500 	index = shell_strtoul(argv[1], 0, &result);
501 	if (result != 0) {
502 		shell_error(sh, "Could not parse index: %d", result);
503 
504 		return -ENOEXEC;
505 	}
506 
507 	if (index >= micp_included.aics_cnt) {
508 		shell_error(sh, "Index shall be less than %u, was %lu",
509 			    micp_included.aics_cnt, index);
510 
511 		return -ENOEXEC;
512 	}
513 
514 	if (micp_mic_ctlr == NULL) {
515 		return -ENOENT;
516 	}
517 
518 	result = bt_aics_manual_gain_set(micp_included.aics[index]);
519 	if (result != 0) {
520 		shell_print(sh, "Fail: %d", result);
521 	}
522 
523 	return result;
524 }
525 
cmd_micp_mic_ctlr_aics_automatic_input_gain_set(const struct shell * sh,size_t argc,char ** argv)526 static int cmd_micp_mic_ctlr_aics_automatic_input_gain_set(const struct shell *sh,
527 							 size_t argc,
528 							 char **argv)
529 {
530 	unsigned long index;
531 	int result = 0;
532 
533 	index = shell_strtoul(argv[1], 0, &result);
534 	if (result != 0) {
535 		shell_error(sh, "Could not parse index: %d", result);
536 
537 		return -ENOEXEC;
538 	}
539 
540 	if (index >= micp_included.aics_cnt) {
541 		shell_error(sh, "Index shall be less than %u, was %lu",
542 			    micp_included.aics_cnt, index);
543 
544 		return -ENOEXEC;
545 	}
546 
547 	if (micp_mic_ctlr == NULL) {
548 		return -ENOENT;
549 	}
550 
551 	result = bt_aics_automatic_gain_set(micp_included.aics[index]);
552 	if (result != 0) {
553 		shell_print(sh, "Fail: %d", result);
554 	}
555 
556 	return result;
557 }
558 
cmd_micp_mic_ctlr_aics_gain_set(const struct shell * sh,size_t argc,char ** argv)559 static int cmd_micp_mic_ctlr_aics_gain_set(const struct shell *sh, size_t argc,
560 					 char **argv)
561 {
562 	unsigned long index;
563 	int result = 0;
564 	long gain;
565 
566 	index = shell_strtoul(argv[1], 0, &result);
567 	if (result != 0) {
568 		shell_error(sh, "Could not parse index: %d", result);
569 
570 		return -ENOEXEC;
571 	}
572 
573 	if (index >= micp_included.aics_cnt) {
574 		shell_error(sh, "Index shall be less than %u, was %lu",
575 			    micp_included.aics_cnt, index);
576 
577 		return -ENOEXEC;
578 	}
579 
580 	gain = shell_strtol(argv[2], 0, &result);
581 	if (result != 0) {
582 		shell_error(sh, "Could not parse gain: %d", result);
583 
584 		return -ENOEXEC;
585 	}
586 
587 	if (gain > INT8_MAX || gain < INT8_MIN) {
588 		shell_error(sh, "Gain shall be %d-%d, was %ld",
589 			    INT8_MIN, INT8_MAX, gain);
590 
591 		return -ENOEXEC;
592 	}
593 
594 	if (micp_mic_ctlr == NULL) {
595 		return -ENOENT;
596 	}
597 
598 	result = bt_aics_gain_set(micp_included.aics[index], gain);
599 	if (result != 0) {
600 		shell_print(sh, "Fail: %d", result);
601 	}
602 
603 	return result;
604 }
605 
cmd_micp_mic_ctlr_aics_input_description_get(const struct shell * sh,size_t argc,char ** argv)606 static int cmd_micp_mic_ctlr_aics_input_description_get(const struct shell *sh,
607 						      size_t argc, char **argv)
608 {
609 	unsigned long index;
610 	int result = 0;
611 
612 	index = shell_strtoul(argv[1], 0, &result);
613 	if (result != 0) {
614 		shell_error(sh, "Could not parse index: %d", result);
615 
616 		return -ENOEXEC;
617 	}
618 
619 	if (index >= micp_included.aics_cnt) {
620 		shell_error(sh, "Index shall be less than %u, was %lu",
621 			    micp_included.aics_cnt, index);
622 
623 		return -ENOEXEC;
624 	}
625 
626 	if (micp_mic_ctlr == NULL) {
627 		return -ENOENT;
628 	}
629 
630 	result = bt_aics_description_get(micp_included.aics[index]);
631 	if (result != 0) {
632 		shell_print(sh, "Fail: %d", result);
633 	}
634 
635 	return result;
636 }
637 
cmd_micp_mic_ctlr_aics_input_description_set(const struct shell * sh,size_t argc,char ** argv)638 static int cmd_micp_mic_ctlr_aics_input_description_set(const struct shell *sh,
639 						      size_t argc, char **argv)
640 {
641 	unsigned long index;
642 	int result = 0;
643 
644 	index = shell_strtoul(argv[1], 0, &result);
645 	if (result != 0) {
646 		shell_error(sh, "Could not parse index: %d", result);
647 
648 		return -ENOEXEC;
649 	}
650 
651 	if (index >= micp_included.aics_cnt) {
652 		shell_error(sh, "Index shall be less than %u, was %lu",
653 			    micp_included.aics_cnt, index);
654 
655 		return -ENOEXEC;
656 	}
657 
658 	if (micp_mic_ctlr == NULL) {
659 		return -ENOENT;
660 	}
661 
662 	result = bt_aics_description_set(micp_included.aics[index], argv[2]);
663 	if (result != 0) {
664 		shell_print(sh, "Fail: %d", result);
665 	}
666 
667 	return result;
668 }
669 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
670 
cmd_micp_mic_ctlr(const struct shell * sh,size_t argc,char ** argv)671 static int cmd_micp_mic_ctlr(const struct shell *sh, size_t argc, char **argv)
672 {
673 	if (argc > 1) {
674 		shell_error(sh, "%s unknown parameter: %s",
675 			    argv[0], argv[1]);
676 	} else {
677 		shell_error(sh, "%s Missing subcommand", argv[0]);
678 	}
679 
680 	return -ENOEXEC;
681 }
682 
683 SHELL_STATIC_SUBCMD_SET_CREATE(micp_mic_ctlr_cmds,
684 	SHELL_CMD_ARG(discover, NULL,
685 		      "Discover MICS on remote device",
686 		      cmd_micp_mic_ctlr_discover, 1, 0),
687 	SHELL_CMD_ARG(mute_get, NULL,
688 		      "Read the mute state of the Microphone Device server.",
689 		      cmd_micp_mic_ctlr_mute_get, 1, 0),
690 	SHELL_CMD_ARG(mute, NULL,
691 		      "Mute the Microphone Device server",
692 		      cmd_micp_mic_ctlr_mute, 1, 0),
693 	SHELL_CMD_ARG(unmute, NULL,
694 		      "Unmute the Microphone Device server",
695 		      cmd_micp_mic_ctlr_unmute, 1, 0),
696 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
697 	SHELL_CMD_ARG(aics_input_state_get, NULL,
698 		      "Read the input state of a AICS instance <inst_index>",
699 		      cmd_micp_mic_ctlr_aics_input_state_get, 2, 0),
700 	SHELL_CMD_ARG(aics_gain_setting_get, NULL,
701 		      "Read the gain settings of a AICS instance <inst_index>",
702 		      cmd_micp_mic_ctlr_aics_gain_setting_get, 2, 0),
703 	SHELL_CMD_ARG(aics_input_type_get, NULL,
704 		      "Read the input type of a AICS instance <inst_index>",
705 		      cmd_micp_mic_ctlr_aics_input_type_get, 2, 0),
706 	SHELL_CMD_ARG(aics_input_status_get, NULL,
707 		      "Read the input status of a AICS instance <inst_index>",
708 		      cmd_micp_mic_ctlr_aics_input_status_get, 2, 0),
709 	SHELL_CMD_ARG(aics_input_unmute, NULL,
710 		      "Unmute the input of a AICS instance <inst_index>",
711 		      cmd_micp_mic_ctlr_aics_input_unmute, 2, 0),
712 	SHELL_CMD_ARG(aics_input_mute, NULL,
713 		      "Mute the input of a AICS instance <inst_index>",
714 		      cmd_micp_mic_ctlr_aics_input_mute, 2, 0),
715 	SHELL_CMD_ARG(aics_manual_input_gain_set, NULL,
716 		      "Set the gain mode of a AICS instance to manual "
717 		      "<inst_index>",
718 		      cmd_micp_mic_ctlr_aics_manual_input_gain_set, 2, 0),
719 	SHELL_CMD_ARG(aics_automatic_input_gain_set, NULL,
720 		      "Set the gain mode of a AICS instance to automatic "
721 		      "<inst_index>",
722 		      cmd_micp_mic_ctlr_aics_automatic_input_gain_set, 2, 0),
723 	SHELL_CMD_ARG(aics_gain_set, NULL,
724 		      "Set the gain of a AICS instance <inst_index> <gain>",
725 		      cmd_micp_mic_ctlr_aics_gain_set, 3, 0),
726 	SHELL_CMD_ARG(aics_input_description_get, NULL,
727 		      "Read the input description of a AICS instance "
728 		      "<inst_index>",
729 		      cmd_micp_mic_ctlr_aics_input_description_get, 2, 0),
730 	SHELL_CMD_ARG(aics_input_description_set, NULL,
731 		      "Set the input description of a AICS instance "
732 		      "<inst_index> <description>",
733 		      cmd_micp_mic_ctlr_aics_input_description_set, 3, 0),
734 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
735 	SHELL_SUBCMD_SET_END
736 );
737 
738 SHELL_CMD_ARG_REGISTER(micp_mic_ctlr, &micp_mic_ctlr_cmds,
739 		       "Bluetooth Microphone Controller shell commands",
740 		       cmd_micp_mic_ctlr, 1, 1);
741