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