1 /** @file
2  *  @brief Bluetooth VCP client 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 
15 #include <zephyr/autoconf.h>
16 #include <zephyr/bluetooth/audio/aics.h>
17 #include <zephyr/bluetooth/audio/vcp.h>
18 #include <zephyr/bluetooth/audio/vocs.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/shell/shell.h>
21 #include <zephyr/shell/shell_string_conv.h>
22 #include <zephyr/sys/util.h>
23 #include <zephyr/types.h>
24 
25 #include "host/shell/bt.h"
26 
27 static struct bt_vcp_vol_ctlr *vcp_vol_ctlr;
28 static struct bt_vcp_included vcp_included;
29 
vcs_discover_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err,uint8_t vocs_count,uint8_t aics_count)30 static void vcs_discover_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err,
31 			    uint8_t vocs_count, uint8_t aics_count)
32 {
33 	if (err != 0) {
34 		shell_error(ctx_shell, "VCP discover failed (%d)", err);
35 	} else {
36 		shell_print(ctx_shell, "VCP discover done with %u VOCS and %u AICS", vocs_count,
37 			    aics_count);
38 
39 		if (bt_vcp_vol_ctlr_included_get(vol_ctlr, &vcp_included)) {
40 			shell_error(ctx_shell, "Could not get VCP context");
41 		}
42 	}
43 }
44 
vcs_vol_down_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)45 static void vcs_vol_down_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
46 {
47 	if (err != 0) {
48 		shell_error(ctx_shell, "VCP vol_down failed (%d)", err);
49 	} else {
50 		shell_print(ctx_shell, "VCP vol_down done");
51 	}
52 }
53 
vcs_vol_up_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)54 static void vcs_vol_up_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
55 {
56 	if (err != 0) {
57 		shell_error(ctx_shell, "VCP vol_up failed (%d)", err);
58 	} else {
59 		shell_print(ctx_shell, "VCP vol_up done");
60 	}
61 }
62 
vcs_mute_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)63 static void vcs_mute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
64 {
65 	if (err != 0) {
66 		shell_error(ctx_shell, "VCP mute failed (%d)", err);
67 	} else {
68 		shell_print(ctx_shell, "VCP mute done");
69 	}
70 }
71 
vcs_unmute_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)72 static void vcs_unmute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
73 {
74 	if (err != 0) {
75 		shell_error(ctx_shell, "VCP unmute failed (%d)", err);
76 	} else {
77 		shell_print(ctx_shell, "VCP unmute done");
78 	}
79 }
80 
vcs_vol_down_unmute_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)81 static void vcs_vol_down_unmute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
82 {
83 	if (err != 0) {
84 		shell_error(ctx_shell, "VCP vol_down_unmute failed (%d)", err);
85 	} else {
86 		shell_print(ctx_shell, "VCP vol_down_unmute done");
87 	}
88 }
89 
vcs_vol_up_unmute_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)90 static void vcs_vol_up_unmute_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
91 {
92 	if (err != 0) {
93 		shell_error(ctx_shell, "VCP vol_up_unmute failed (%d)", err);
94 	} else {
95 		shell_print(ctx_shell, "VCP vol_up_unmute done");
96 	}
97 }
98 
vcs_vol_set_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err)99 static void vcs_vol_set_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err)
100 {
101 	if (err != 0) {
102 		shell_error(ctx_shell, "VCP vol_set failed (%d)", err);
103 	} else {
104 		shell_print(ctx_shell, "VCP vol_set done");
105 	}
106 }
107 
vcs_state_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err,uint8_t volume,uint8_t mute)108 static void vcs_state_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err,
109 			 uint8_t volume, uint8_t mute)
110 {
111 	if (err != 0) {
112 		shell_error(ctx_shell, "VCP state get failed (%d)", err);
113 	} else {
114 		shell_print(ctx_shell, "VCP volume %u, mute %u", volume, mute);
115 	}
116 }
117 
vcs_flags_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err,uint8_t flags)118 static void vcs_flags_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err,
119 			 uint8_t flags)
120 {
121 	if (err != 0) {
122 		shell_error(ctx_shell, "VCP flags get failed (%d)", err);
123 	} else {
124 		shell_print(ctx_shell, "VCP flags 0x%02X", flags);
125 	}
126 }
127 
128 #if CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST > 0
vcs_aics_set_gain_cb(struct bt_aics * inst,int err)129 static void vcs_aics_set_gain_cb(struct bt_aics *inst, int err)
130 {
131 	if (err != 0) {
132 		shell_error(ctx_shell, "Set gain failed (%d) for inst %p",
133 			    err, inst);
134 	} else {
135 		shell_print(ctx_shell, "Gain set for inst %p", inst);
136 	}
137 }
138 
vcs_aics_unmute_cb(struct bt_aics * inst,int err)139 static void vcs_aics_unmute_cb(struct bt_aics *inst, int err)
140 {
141 	if (err != 0) {
142 		shell_error(ctx_shell, "Unmute failed (%d) for inst %p",
143 			    err, inst);
144 	} else {
145 		shell_print(ctx_shell, "Unmuted inst %p", inst);
146 	}
147 }
148 
vcs_aics_mute_cb(struct bt_aics * inst,int err)149 static void vcs_aics_mute_cb(struct bt_aics *inst, int err)
150 {
151 	if (err != 0) {
152 		shell_error(ctx_shell, "Mute failed (%d) for inst %p",
153 			    err, inst);
154 	} else {
155 		shell_print(ctx_shell, "Muted inst %p", inst);
156 	}
157 }
158 
vcs_aics_set_manual_mode_cb(struct bt_aics * inst,int err)159 static void vcs_aics_set_manual_mode_cb(struct bt_aics *inst, int err)
160 {
161 	if (err != 0) {
162 		shell_error(ctx_shell,
163 			    "Set manual mode failed (%d) for inst %p",
164 			    err, inst);
165 	} else {
166 		shell_print(ctx_shell, "Manual mode set for inst %p", inst);
167 	}
168 }
169 
vcs_aics_automatic_mode_cb(struct bt_aics * inst,int err)170 static void vcs_aics_automatic_mode_cb(struct bt_aics *inst, int err)
171 {
172 	if (err != 0) {
173 		shell_error(ctx_shell,
174 			    "Set automatic mode failed (%d) for inst %p",
175 			    err, inst);
176 	} else {
177 		shell_print(ctx_shell, "Automatic mode set for inst %p",
178 			    inst);
179 	}
180 }
181 
vcs_aics_state_cb(struct bt_aics * inst,int err,int8_t gain,uint8_t mute,uint8_t mode)182 static void vcs_aics_state_cb(struct bt_aics *inst, int err, int8_t gain,
183 			      uint8_t mute, uint8_t mode)
184 {
185 	if (err != 0) {
186 		shell_error(ctx_shell, "AICS state get failed (%d) for inst %p",
187 			    err, inst);
188 	} else {
189 		shell_print(ctx_shell,
190 			    "AICS inst %p state gain %d, mute %u, mode %u",
191 			    inst, gain, mute, mode);
192 	}
193 }
194 
vcs_aics_gain_setting_cb(struct bt_aics * inst,int err,uint8_t units,int8_t minimum,int8_t maximum)195 static void vcs_aics_gain_setting_cb(struct bt_aics *inst, int err,
196 				     uint8_t units, int8_t minimum,
197 				     int8_t maximum)
198 {
199 	if (err != 0) {
200 		shell_error(ctx_shell,
201 			    "AICS gain settings get failed (%d) for inst %p",
202 			    err, inst);
203 	} else {
204 		shell_print(ctx_shell,
205 			    "AICS inst %p gain settings units %u, min %d, max %d",
206 			    inst, units, minimum, maximum);
207 	}
208 }
209 
vcs_aics_input_type_cb(struct bt_aics * inst,int err,uint8_t input_type)210 static void vcs_aics_input_type_cb(struct bt_aics *inst, int err,
211 				   uint8_t input_type)
212 {
213 	if (err != 0) {
214 		shell_error(ctx_shell,
215 			    "AICS input type get failed (%d) for inst %p",
216 			    err, inst);
217 	} else {
218 		shell_print(ctx_shell, "AICS inst %p input type %u",
219 			    inst, input_type);
220 	}
221 }
222 
vcs_aics_status_cb(struct bt_aics * inst,int err,bool active)223 static void vcs_aics_status_cb(struct bt_aics *inst, int err, bool active)
224 {
225 	if (err != 0) {
226 		shell_error(ctx_shell,
227 			    "AICS status get failed (%d) for inst %p",
228 			    err, inst);
229 	} else {
230 		shell_print(ctx_shell, "AICS inst %p status %s",
231 			    inst, active ? "active" : "inactive");
232 	}
233 
234 }
vcs_aics_description_cb(struct bt_aics * inst,int err,char * description)235 static void vcs_aics_description_cb(struct bt_aics *inst, int err,
236 				    char *description)
237 {
238 	if (err != 0) {
239 		shell_error(ctx_shell,
240 			    "AICS description get failed (%d) for inst %p",
241 			    err, inst);
242 	} else {
243 		shell_print(ctx_shell, "AICS inst %p description %s",
244 			    inst, description);
245 	}
246 }
247 #endif /* CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST > 0 */
248 
249 #if CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST > 0
vcs_vocs_set_offset_cb(struct bt_vocs * inst,int err)250 static void vcs_vocs_set_offset_cb(struct bt_vocs *inst, int err)
251 {
252 	if (err != 0) {
253 		shell_error(ctx_shell, "Set offset failed (%d) for inst %p",
254 			    err, inst);
255 	} else {
256 		shell_print(ctx_shell, "Offset set for inst %p", inst);
257 	}
258 }
259 
vcs_vocs_state_cb(struct bt_vocs * inst,int err,int16_t offset)260 static void vcs_vocs_state_cb(struct bt_vocs *inst, int err, int16_t offset)
261 {
262 	if (err != 0) {
263 		shell_error(ctx_shell, "VOCS state get failed (%d) for inst %p",
264 			    err, inst);
265 	} else {
266 		shell_print(ctx_shell, "VOCS inst %p offset %d", inst, offset);
267 	}
268 }
269 
vcs_vocs_location_cb(struct bt_vocs * inst,int err,uint32_t location)270 static void vcs_vocs_location_cb(struct bt_vocs *inst, int err,
271 				 uint32_t location)
272 {
273 	if (err != 0) {
274 		shell_error(ctx_shell,
275 			    "VOCS location get failed (%d) for inst %p",
276 			    err, inst);
277 	} else {
278 		shell_print(ctx_shell, "VOCS inst %p location %u",
279 			    inst, location);
280 	}
281 }
282 
vcs_vocs_description_cb(struct bt_vocs * inst,int err,char * description)283 static void vcs_vocs_description_cb(struct bt_vocs *inst, int err,
284 				    char *description)
285 {
286 	if (err != 0) {
287 		shell_error(ctx_shell,
288 			    "VOCS description get failed (%d) for inst %p",
289 			    err, inst);
290 	} else {
291 		shell_print(ctx_shell, "VOCS inst %p description %s",
292 			    inst, description);
293 	}
294 }
295 #endif /* CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST > 0 */
296 
297 static struct bt_vcp_vol_ctlr_cb vcp_cbs = {
298 	.discover = vcs_discover_cb,
299 	.vol_down = vcs_vol_down_cb,
300 	.vol_up = vcs_vol_up_cb,
301 	.mute = vcs_mute_cb,
302 	.unmute = vcs_unmute_cb,
303 	.vol_down_unmute = vcs_vol_down_unmute_cb,
304 	.vol_up_unmute = vcs_vol_up_unmute_cb,
305 	.vol_set = vcs_vol_set_cb,
306 
307 	.state = vcs_state_cb,
308 	.flags = vcs_flags_cb,
309 
310 	/* Audio Input Control Service */
311 #if CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST > 0
312 	.aics_cb = {
313 		.state = vcs_aics_state_cb,
314 		.gain_setting = vcs_aics_gain_setting_cb,
315 		.type = vcs_aics_input_type_cb,
316 		.status = vcs_aics_status_cb,
317 		.description = vcs_aics_description_cb,
318 		.set_gain = vcs_aics_set_gain_cb,
319 		.unmute = vcs_aics_unmute_cb,
320 		.mute = vcs_aics_mute_cb,
321 		.set_manual_mode = vcs_aics_set_manual_mode_cb,
322 		.set_auto_mode = vcs_aics_automatic_mode_cb,
323 	},
324 #endif /* CONFIG_BT_VCP_VOL_CTLR_MAX_AICS_INST > 0 */
325 #if CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST > 0
326 	.vocs_cb = {
327 		.state = vcs_vocs_state_cb,
328 		.location = vcs_vocs_location_cb,
329 		.description = vcs_vocs_description_cb,
330 		.set_offset = vcs_vocs_set_offset_cb,
331 	}
332 #endif /* CONFIG_BT_VCP_VOL_CTLR_MAX_VOCS_INST > 0 */
333 };
334 
cmd_vcp_vol_ctlr_discover(const struct shell * sh,size_t argc,char ** argv)335 static int cmd_vcp_vol_ctlr_discover(const struct shell *sh, size_t argc,
336 				   char **argv)
337 {
338 	static bool cb_registered;
339 	int result;
340 
341 	if (!ctx_shell) {
342 		ctx_shell = sh;
343 	}
344 
345 	if (!cb_registered) {
346 		result = bt_vcp_vol_ctlr_cb_register(&vcp_cbs);
347 		if (result != 0) {
348 			shell_print(sh, "CB register failed: %d", result);
349 			return result;
350 		}
351 
352 		cb_registered = true;
353 	}
354 
355 	if (default_conn == NULL) {
356 		shell_error(sh, "Not connected");
357 		return -ENOEXEC;
358 	}
359 
360 	result = bt_vcp_vol_ctlr_discover(default_conn, &vcp_vol_ctlr);
361 	if (result != 0) {
362 		shell_print(sh, "Fail: %d", result);
363 	}
364 
365 	return result;
366 }
367 
cmd_vcp_vol_ctlr_state_get(const struct shell * sh,size_t argc,char ** argv)368 static int cmd_vcp_vol_ctlr_state_get(const struct shell *sh, size_t argc,
369 				    char **argv)
370 {
371 	int result;
372 
373 	if (default_conn == NULL) {
374 		shell_error(sh, "Not connected");
375 		return -ENOEXEC;
376 	}
377 
378 	result = bt_vcp_vol_ctlr_read_state(vcp_vol_ctlr);
379 	if (result != 0) {
380 		shell_print(sh, "Fail: %d", result);
381 	}
382 
383 	return result;
384 }
385 
cmd_vcp_vol_ctlr_flags_get(const struct shell * sh,size_t argc,char ** argv)386 static int cmd_vcp_vol_ctlr_flags_get(const struct shell *sh, size_t argc,
387 				    char **argv)
388 {
389 	int result;
390 
391 	if (default_conn == NULL) {
392 		shell_error(sh, "Not connected");
393 		return -ENOEXEC;
394 	}
395 
396 	result = bt_vcp_vol_ctlr_read_flags(vcp_vol_ctlr);
397 	if (result != 0) {
398 		shell_print(sh, "Fail: %d", result);
399 	}
400 
401 	return result;
402 }
403 
cmd_vcp_vol_ctlr_volume_down(const struct shell * sh,size_t argc,char ** argv)404 static int cmd_vcp_vol_ctlr_volume_down(const struct shell *sh, size_t argc,
405 				      char **argv)
406 {
407 	int result;
408 
409 	if (default_conn == NULL) {
410 		shell_error(sh, "Not connected");
411 		return -ENOEXEC;
412 	}
413 
414 	result = bt_vcp_vol_ctlr_vol_down(vcp_vol_ctlr);
415 	if (result != 0) {
416 		shell_print(sh, "Fail: %d", result);
417 	}
418 
419 	return result;
420 }
421 
cmd_vcp_vol_ctlr_volume_up(const struct shell * sh,size_t argc,char ** argv)422 static int cmd_vcp_vol_ctlr_volume_up(const struct shell *sh, size_t argc,
423 				    char **argv)
424 
425 {
426 	int result;
427 
428 	if (default_conn == NULL) {
429 		shell_error(sh, "Not connected");
430 		return -ENOEXEC;
431 	}
432 
433 	result = bt_vcp_vol_ctlr_vol_up(vcp_vol_ctlr);
434 	if (result != 0) {
435 		shell_print(sh, "Fail: %d", result);
436 	}
437 
438 	return result;
439 }
440 
cmd_vcp_vol_ctlr_unmute_volume_down(const struct shell * sh,size_t argc,char ** argv)441 static int cmd_vcp_vol_ctlr_unmute_volume_down(const struct shell *sh,
442 					     size_t argc, char **argv)
443 {
444 	int result;
445 
446 	if (default_conn == NULL) {
447 		shell_error(sh, "Not connected");
448 		return -ENOEXEC;
449 	}
450 
451 	result = bt_vcp_vol_ctlr_unmute_vol_down(vcp_vol_ctlr);
452 	if (result != 0) {
453 		shell_print(sh, "Fail: %d", result);
454 	}
455 
456 	return result;
457 }
458 
cmd_vcp_vol_ctlr_unmute_volume_up(const struct shell * sh,size_t argc,char ** argv)459 static int cmd_vcp_vol_ctlr_unmute_volume_up(const struct shell *sh,
460 					   size_t argc, char **argv)
461 {
462 	int result;
463 
464 	if (default_conn == NULL) {
465 		shell_error(sh, "Not connected");
466 		return -ENOEXEC;
467 	}
468 
469 	result = bt_vcp_vol_ctlr_unmute_vol_up(vcp_vol_ctlr);
470 	if (result != 0) {
471 		shell_print(sh, "Fail: %d", result);
472 	}
473 
474 	return result;
475 }
476 
cmd_vcp_vol_ctlr_volume_set(const struct shell * sh,size_t argc,char ** argv)477 static int cmd_vcp_vol_ctlr_volume_set(const struct shell *sh, size_t argc,
478 				     char **argv)
479 
480 {
481 	unsigned long volume;
482 	int result = 0;
483 
484 	if (default_conn == NULL) {
485 		shell_error(sh, "Not connected");
486 		return -ENOEXEC;
487 	}
488 
489 	volume = shell_strtoul(argv[1], 0, &result);
490 	if (result != 0) {
491 		shell_error(sh, "Failed to parse volume: %d", result);
492 
493 		return -ENOEXEC;
494 	}
495 
496 	if (volume > UINT8_MAX) {
497 		shell_error(sh, "Volume shall be 0-255, was %lu", volume);
498 
499 		return -ENOEXEC;
500 	}
501 
502 	result = bt_vcp_vol_ctlr_set_vol(vcp_vol_ctlr, volume);
503 	if (result != 0) {
504 		shell_print(sh, "Fail: %d", result);
505 	}
506 
507 	return result;
508 }
509 
510 
cmd_vcp_vol_ctlr_unmute(const struct shell * sh,size_t argc,char ** argv)511 static int cmd_vcp_vol_ctlr_unmute(const struct shell *sh, size_t argc,
512 				 char **argv)
513 {
514 	int result;
515 
516 	if (default_conn == NULL) {
517 		shell_error(sh, "Not connected");
518 		return -ENOEXEC;
519 	}
520 
521 	result = bt_vcp_vol_ctlr_unmute(vcp_vol_ctlr);
522 	if (result != 0) {
523 		shell_print(sh, "Fail: %d", result);
524 	}
525 
526 	return result;
527 }
528 
cmd_vcp_vol_ctlr_mute(const struct shell * sh,size_t argc,char ** argv)529 static int cmd_vcp_vol_ctlr_mute(const struct shell *sh, size_t argc,
530 				 char **argv)
531 {
532 	int result;
533 
534 	if (default_conn == NULL) {
535 		shell_error(sh, "Not connected");
536 		return -ENOEXEC;
537 	}
538 
539 	result = bt_vcp_vol_ctlr_mute(vcp_vol_ctlr);
540 	if (result != 0) {
541 		shell_print(sh, "Fail: %d", result);
542 	}
543 
544 	return result;
545 }
546 
cmd_vcp_vol_ctlr_vocs_state_get(const struct shell * sh,size_t argc,char ** argv)547 static int cmd_vcp_vol_ctlr_vocs_state_get(const struct shell *sh, size_t argc,
548 					 char **argv)
549 {
550 	unsigned long index;
551 	int result = 0;
552 
553 	if (default_conn == NULL) {
554 		shell_error(sh, "Not connected");
555 		return -ENOEXEC;
556 	}
557 
558 	index = shell_strtoul(argv[1], 0, &result);
559 	if (result != 0) {
560 		shell_error(sh, "Failed to parse index: %d", result);
561 
562 		return -ENOEXEC;
563 	}
564 
565 	if (index >= vcp_included.vocs_cnt) {
566 		shell_error(sh, "Index shall be less than %u, was %lu",
567 			    vcp_included.vocs_cnt, index);
568 
569 		return -ENOEXEC;
570 	}
571 
572 	result = bt_vocs_state_get(vcp_included.vocs[index]);
573 	if (result != 0) {
574 		shell_print(sh, "Fail: %d", result);
575 	}
576 
577 	return result;
578 }
579 
cmd_vcp_vol_ctlr_vocs_location_get(const struct shell * sh,size_t argc,char ** argv)580 static int cmd_vcp_vol_ctlr_vocs_location_get(const struct shell *sh,
581 					    size_t argc, char **argv)
582 {
583 	unsigned long index;
584 	int result = 0;
585 
586 	if (default_conn == NULL) {
587 		shell_error(sh, "Not connected");
588 		return -ENOEXEC;
589 	}
590 
591 	index = shell_strtoul(argv[1], 0, &result);
592 	if (result != 0) {
593 		shell_error(sh, "Failed to parse index: %d", result);
594 
595 		return -ENOEXEC;
596 	}
597 
598 	if (index >= vcp_included.vocs_cnt) {
599 		shell_error(sh, "Index shall be less than %u, was %lu",
600 			    vcp_included.vocs_cnt, index);
601 
602 		return -ENOEXEC;
603 	}
604 
605 	result = bt_vocs_location_get(vcp_included.vocs[index]);
606 	if (result != 0) {
607 		shell_print(sh, "Fail: %d", result);
608 	}
609 
610 	return result;
611 }
612 
cmd_vcp_vol_ctlr_vocs_location_set(const struct shell * sh,size_t argc,char ** argv)613 static int cmd_vcp_vol_ctlr_vocs_location_set(const struct shell *sh,
614 					    size_t argc, char **argv)
615 {
616 	unsigned long location;
617 	unsigned long index;
618 	int result = 0;
619 
620 	if (default_conn == NULL) {
621 		shell_error(sh, "Not connected");
622 		return -ENOEXEC;
623 	}
624 
625 	index = shell_strtoul(argv[1], 0, &result);
626 	if (result != 0) {
627 		shell_error(sh, "Failed to parse index: %d", result);
628 
629 		return -ENOEXEC;
630 	}
631 
632 	if (index >= vcp_included.vocs_cnt) {
633 		shell_error(sh, "Index shall be less than %u, was %lu",
634 			    vcp_included.vocs_cnt, index);
635 
636 		return -ENOEXEC;
637 	}
638 
639 	location = shell_strtoul(argv[2], 0, &result);
640 	if (result != 0) {
641 		shell_error(sh, "Failed to parse location: %d", result);
642 
643 		return -ENOEXEC;
644 	}
645 
646 	if (location > UINT32_MAX) {
647 		shell_error(sh, "Invalid location %lu", location);
648 		return -ENOEXEC;
649 
650 	}
651 
652 	result = bt_vocs_location_set(vcp_included.vocs[index], location);
653 	if (result != 0) {
654 		shell_print(sh, "Fail: %d", result);
655 	}
656 
657 	return result;
658 }
659 
cmd_vcp_vol_ctlr_vocs_offset_set(const struct shell * sh,size_t argc,char ** argv)660 static int cmd_vcp_vol_ctlr_vocs_offset_set(const struct shell *sh,
661 					  size_t argc, char **argv)
662 {
663 	unsigned long index;
664 	int result = 0;
665 	long offset;
666 
667 	if (default_conn == NULL) {
668 		shell_error(sh, "Not connected");
669 		return -ENOEXEC;
670 	}
671 
672 	index = shell_strtoul(argv[1], 0, &result);
673 	if (result != 0) {
674 		shell_error(sh, "Failed to parse index: %d", result);
675 
676 		return -ENOEXEC;
677 	}
678 
679 	if (index >= vcp_included.vocs_cnt) {
680 		shell_error(sh, "Index shall be less than %u, was %lu",
681 			    vcp_included.vocs_cnt, index);
682 
683 		return -ENOEXEC;
684 	}
685 
686 	offset = shell_strtol(argv[2], 0, &result);
687 	if (result != 0) {
688 		shell_error(sh, "Failed to parse offset: %d", result);
689 
690 		return -ENOEXEC;
691 	}
692 
693 	if (!IN_RANGE(offset, BT_VOCS_MIN_OFFSET, BT_VOCS_MAX_OFFSET)) {
694 		shell_error(sh, "Offset shall be %d-%d, was %ld",
695 			    BT_VOCS_MIN_OFFSET, BT_VOCS_MAX_OFFSET, offset);
696 		return -ENOEXEC;
697 	}
698 
699 	result = bt_vocs_state_set(vcp_included.vocs[index],
700 				       offset);
701 	if (result != 0) {
702 		shell_print(sh, "Fail: %d", result);
703 	}
704 
705 	return result;
706 }
707 
cmd_vcp_vol_ctlr_vocs_output_description_get(const struct shell * sh,size_t argc,char ** argv)708 static int cmd_vcp_vol_ctlr_vocs_output_description_get(const struct shell *sh,
709 						      size_t argc, char **argv)
710 {
711 	unsigned long index;
712 	int result = 0;
713 
714 	if (default_conn == NULL) {
715 		shell_error(sh, "Not connected");
716 		return -ENOEXEC;
717 	}
718 
719 	index = shell_strtoul(argv[1], 0, &result);
720 	if (result != 0) {
721 		shell_error(sh, "Failed to parse index: %d", result);
722 
723 		return -ENOEXEC;
724 	}
725 
726 	if (index >= vcp_included.vocs_cnt) {
727 		shell_error(sh, "Index shall be less than %u, was %lu",
728 			    vcp_included.vocs_cnt, index);
729 
730 		return -ENOEXEC;
731 	}
732 
733 	result = bt_vocs_description_get(vcp_included.vocs[index]);
734 	if (result != 0) {
735 		shell_print(sh, "Fail: %d", result);
736 	}
737 
738 	return result;
739 }
740 
cmd_vcp_vol_ctlr_vocs_output_description_set(const struct shell * sh,size_t argc,char ** argv)741 static int cmd_vcp_vol_ctlr_vocs_output_description_set(const struct shell *sh,
742 						      size_t argc, char **argv)
743 {
744 	unsigned long index;
745 	int result = 0;
746 
747 	if (default_conn == NULL) {
748 		shell_error(sh, "Not connected");
749 		return -ENOEXEC;
750 	}
751 
752 	index = shell_strtoul(argv[1], 0, &result);
753 	if (result != 0) {
754 		shell_error(sh, "Failed to parse index: %d", result);
755 
756 		return -ENOEXEC;
757 	}
758 
759 	if (index >= vcp_included.vocs_cnt) {
760 		shell_error(sh, "Index shall be less than %u, was %lu",
761 			    vcp_included.vocs_cnt, index);
762 
763 		return -ENOEXEC;
764 	}
765 
766 	result = bt_vocs_description_set(vcp_included.vocs[index], argv[2]);
767 	if (result != 0) {
768 		shell_print(sh, "Fail: %d", result);
769 	}
770 
771 	return result;
772 }
773 
cmd_vcp_vol_ctlr_aics_input_state_get(const struct shell * sh,size_t argc,char ** argv)774 static int cmd_vcp_vol_ctlr_aics_input_state_get(const struct shell *sh,
775 					       size_t argc, char **argv)
776 {
777 	unsigned long index;
778 	int result = 0;
779 
780 	if (default_conn == NULL) {
781 		shell_error(sh, "Not connected");
782 		return -ENOEXEC;
783 	}
784 
785 	index = shell_strtoul(argv[1], 0, &result);
786 	if (result != 0) {
787 		shell_error(sh, "Failed to parse index: %d", result);
788 
789 		return -ENOEXEC;
790 	}
791 
792 	if (index >= vcp_included.aics_cnt) {
793 		shell_error(sh, "Index shall be less than %u, was %lu",
794 			    vcp_included.vocs_cnt, index);
795 
796 		return -ENOEXEC;
797 	}
798 
799 	result = bt_aics_state_get(vcp_included.aics[index]);
800 	if (result != 0) {
801 		shell_print(sh, "Fail: %d", result);
802 	}
803 
804 	return result;
805 }
806 
cmd_vcp_vol_ctlr_aics_gain_setting_get(const struct shell * sh,size_t argc,char ** argv)807 static int cmd_vcp_vol_ctlr_aics_gain_setting_get(const struct shell *sh,
808 						size_t argc, char **argv)
809 {
810 	unsigned long index;
811 	int result = 0;
812 
813 	if (default_conn == NULL) {
814 		shell_error(sh, "Not connected");
815 		return -ENOEXEC;
816 	}
817 
818 	index = shell_strtoul(argv[1], 0, &result);
819 	if (result != 0) {
820 		shell_error(sh, "Failed to parse index: %d", result);
821 
822 		return -ENOEXEC;
823 	}
824 
825 	if (index >= vcp_included.aics_cnt) {
826 		shell_error(sh, "Index shall be less than %u, was %lu",
827 			    vcp_included.vocs_cnt, index);
828 
829 		return -ENOEXEC;
830 	}
831 
832 	result = bt_aics_gain_setting_get(vcp_included.aics[index]);
833 	if (result != 0) {
834 		shell_print(sh, "Fail: %d", result);
835 	}
836 
837 	return result;
838 }
839 
cmd_vcp_vol_ctlr_aics_input_type_get(const struct shell * sh,size_t argc,char ** argv)840 static int cmd_vcp_vol_ctlr_aics_input_type_get(const struct shell *sh,
841 					      size_t argc, char **argv)
842 {
843 	unsigned long index;
844 	int result = 0;
845 
846 	if (default_conn == NULL) {
847 		shell_error(sh, "Not connected");
848 		return -ENOEXEC;
849 	}
850 
851 	index = shell_strtoul(argv[1], 0, &result);
852 	if (result != 0) {
853 		shell_error(sh, "Failed to parse index: %d", result);
854 
855 		return -ENOEXEC;
856 	}
857 
858 	if (index >= vcp_included.aics_cnt) {
859 		shell_error(sh, "Index shall be less than %u, was %lu",
860 			    vcp_included.vocs_cnt, index);
861 
862 		return -ENOEXEC;
863 	}
864 
865 	result = bt_aics_type_get(vcp_included.aics[index]);
866 	if (result != 0) {
867 		shell_print(sh, "Fail: %d", result);
868 	}
869 
870 	return result;
871 }
872 
cmd_vcp_vol_ctlr_aics_input_status_get(const struct shell * sh,size_t argc,char ** argv)873 static int cmd_vcp_vol_ctlr_aics_input_status_get(const struct shell *sh,
874 						size_t argc, char **argv)
875 {
876 	unsigned long index;
877 	int result = 0;
878 
879 	if (default_conn == NULL) {
880 		shell_error(sh, "Not connected");
881 		return -ENOEXEC;
882 	}
883 
884 	index = shell_strtoul(argv[1], 0, &result);
885 	if (result != 0) {
886 		shell_error(sh, "Failed to parse index: %d", result);
887 
888 		return -ENOEXEC;
889 	}
890 
891 	if (index >= vcp_included.aics_cnt) {
892 		shell_error(sh, "Index shall be less than %u, was %lu",
893 			    vcp_included.vocs_cnt, index);
894 
895 		return -ENOEXEC;
896 	}
897 
898 	result = bt_aics_status_get(vcp_included.aics[index]);
899 	if (result != 0) {
900 		shell_print(sh, "Fail: %d", result);
901 	}
902 
903 	return result;
904 }
905 
cmd_vcp_vol_ctlr_aics_input_unmute(const struct shell * sh,size_t argc,char ** argv)906 static int cmd_vcp_vol_ctlr_aics_input_unmute(const struct shell *sh,
907 					    size_t argc, char **argv)
908 {
909 	unsigned long index;
910 	int result = 0;
911 
912 	if (default_conn == NULL) {
913 		shell_error(sh, "Not connected");
914 		return -ENOEXEC;
915 	}
916 
917 	index = shell_strtoul(argv[1], 0, &result);
918 	if (result != 0) {
919 		shell_error(sh, "Failed to parse index: %d", result);
920 
921 		return -ENOEXEC;
922 	}
923 
924 	if (index >= vcp_included.aics_cnt) {
925 		shell_error(sh, "Index shall be less than %u, was %lu",
926 			    vcp_included.vocs_cnt, index);
927 
928 		return -ENOEXEC;
929 	}
930 
931 	result = bt_aics_unmute(vcp_included.aics[index]);
932 	if (result != 0) {
933 		shell_print(sh, "Fail: %d", result);
934 	}
935 
936 	return result;
937 }
938 
cmd_vcp_vol_ctlr_aics_input_mute(const struct shell * sh,size_t argc,char ** argv)939 static int cmd_vcp_vol_ctlr_aics_input_mute(const struct shell *sh,
940 					  size_t argc, char **argv)
941 {
942 	unsigned long index;
943 	int result = 0;
944 
945 	if (default_conn == NULL) {
946 		shell_error(sh, "Not connected");
947 		return -ENOEXEC;
948 	}
949 
950 	index = shell_strtoul(argv[1], 0, &result);
951 	if (result != 0) {
952 		shell_error(sh, "Failed to parse index: %d", result);
953 
954 		return -ENOEXEC;
955 	}
956 
957 	if (index >= vcp_included.aics_cnt) {
958 		shell_error(sh, "Index shall be less than %u, was %lu",
959 			    vcp_included.vocs_cnt, index);
960 
961 		return -ENOEXEC;
962 	}
963 
964 	result = bt_aics_mute(vcp_included.aics[index]);
965 	if (result != 0) {
966 		shell_print(sh, "Fail: %d", result);
967 	}
968 
969 	return result;
970 }
971 
cmd_vcp_vol_ctlr_aics_manual_input_gain_set(const struct shell * sh,size_t argc,char ** argv)972 static int cmd_vcp_vol_ctlr_aics_manual_input_gain_set(const struct shell *sh,
973 						     size_t argc, char **argv)
974 {
975 	unsigned long index;
976 	int result = 0;
977 
978 	if (default_conn == NULL) {
979 		shell_error(sh, "Not connected");
980 		return -ENOEXEC;
981 	}
982 
983 	index = shell_strtoul(argv[1], 0, &result);
984 	if (result != 0) {
985 		shell_error(sh, "Failed to parse index: %d", result);
986 
987 		return -ENOEXEC;
988 	}
989 
990 	if (index >= vcp_included.aics_cnt) {
991 		shell_error(sh, "Index shall be less than %u, was %lu",
992 			    vcp_included.vocs_cnt, index);
993 
994 		return -ENOEXEC;
995 	}
996 
997 	result = bt_aics_manual_gain_set(vcp_included.aics[index]);
998 	if (result != 0) {
999 		shell_print(sh, "Fail: %d", result);
1000 	}
1001 
1002 	return result;
1003 }
1004 
cmd_vcp_vol_ctlr_aics_auto_input_gain_set(const struct shell * sh,size_t argc,char ** argv)1005 static int cmd_vcp_vol_ctlr_aics_auto_input_gain_set(const struct shell *sh,
1006 						   size_t argc, char **argv)
1007 {
1008 	unsigned long index;
1009 	int result = 0;
1010 
1011 	if (default_conn == NULL) {
1012 		shell_error(sh, "Not connected");
1013 		return -ENOEXEC;
1014 	}
1015 
1016 	index = shell_strtoul(argv[1], 0, &result);
1017 	if (result != 0) {
1018 		shell_error(sh, "Failed to parse index: %d", result);
1019 
1020 		return -ENOEXEC;
1021 	}
1022 
1023 	if (index >= vcp_included.aics_cnt) {
1024 		shell_error(sh, "Index shall be less than %u, was %lu",
1025 			    vcp_included.vocs_cnt, index);
1026 
1027 		return -ENOEXEC;
1028 	}
1029 
1030 	result = bt_aics_automatic_gain_set(vcp_included.aics[index]);
1031 	if (result != 0) {
1032 		shell_print(sh, "Fail: %d", result);
1033 	}
1034 
1035 	return result;
1036 }
1037 
cmd_vcp_vol_ctlr_aics_gain_set(const struct shell * sh,size_t argc,char ** argv)1038 static int cmd_vcp_vol_ctlr_aics_gain_set(const struct shell *sh, size_t argc,
1039 					char **argv)
1040 {
1041 	unsigned long index;
1042 	int result = 0;
1043 	long gain;
1044 
1045 	if (default_conn == NULL) {
1046 		shell_error(sh, "Not connected");
1047 		return -ENOEXEC;
1048 	}
1049 
1050 	index = shell_strtoul(argv[1], 0, &result);
1051 	if (result != 0) {
1052 		shell_error(sh, "Could not parse index: %d", result);
1053 		return -ENOEXEC;
1054 	}
1055 
1056 	if (index >= vcp_included.aics_cnt) {
1057 		shell_error(sh, "Index shall be less than %u, was %lu",
1058 			    vcp_included.aics_cnt, index);
1059 		return -ENOEXEC;
1060 	}
1061 
1062 	gain = shell_strtol(argv[2], 0, &result);
1063 	if (result != 0) {
1064 		shell_error(sh, "Could not parse gain: %d", result);
1065 		return -ENOEXEC;
1066 	}
1067 
1068 	if (!IN_RANGE(gain, INT8_MIN, INT8_MAX)) {
1069 		shell_error(sh, "Gain shall be %d-%d, was %ld",
1070 			    INT8_MIN, INT8_MAX, gain);
1071 		return -ENOEXEC;
1072 	}
1073 
1074 	result = bt_aics_gain_set(vcp_included.aics[index], gain);
1075 	if (result != 0) {
1076 		shell_print(sh, "Fail: %d", result);
1077 	}
1078 
1079 	return result;
1080 }
1081 
cmd_vcp_vol_ctlr_aics_input_description_get(const struct shell * sh,size_t argc,char ** argv)1082 static int cmd_vcp_vol_ctlr_aics_input_description_get(const struct shell *sh,
1083 						     size_t argc, char **argv)
1084 {
1085 	unsigned long index;
1086 	int result = 0;
1087 
1088 	if (default_conn == NULL) {
1089 		shell_error(sh, "Not connected");
1090 		return -ENOEXEC;
1091 	}
1092 
1093 	index = shell_strtoul(argv[1], 0, &result);
1094 	if (result != 0) {
1095 		shell_error(sh, "Failed to parse index: %d", result);
1096 
1097 		return -ENOEXEC;
1098 	}
1099 
1100 	if (index >= vcp_included.aics_cnt) {
1101 		shell_error(sh, "Index shall be less than %u, was %lu",
1102 			    vcp_included.vocs_cnt, index);
1103 
1104 		return -ENOEXEC;
1105 	}
1106 
1107 	result = bt_aics_description_get(vcp_included.aics[index]);
1108 	if (result != 0) {
1109 		shell_print(sh, "Fail: %d", result);
1110 	}
1111 
1112 	return result;
1113 }
1114 
cmd_vcp_vol_ctlr_aics_input_description_set(const struct shell * sh,size_t argc,char ** argv)1115 static int cmd_vcp_vol_ctlr_aics_input_description_set(const struct shell *sh,
1116 						     size_t argc, char **argv)
1117 {
1118 	unsigned long index;
1119 	int result = 0;
1120 
1121 	if (default_conn == NULL) {
1122 		shell_error(sh, "Not connected");
1123 		return -ENOEXEC;
1124 	}
1125 
1126 	index = shell_strtoul(argv[1], 0, &result);
1127 	if (result != 0) {
1128 		shell_error(sh, "Failed to parse index: %d", result);
1129 
1130 		return -ENOEXEC;
1131 	}
1132 
1133 	if (index >= vcp_included.aics_cnt) {
1134 		shell_error(sh, "Index shall be less than %u, was %lu",
1135 			    vcp_included.vocs_cnt, index);
1136 
1137 		return -ENOEXEC;
1138 	}
1139 
1140 	result = bt_aics_description_set(vcp_included.aics[index], argv[2]);
1141 	if (result != 0) {
1142 		shell_print(sh, "Fail: %d", result);
1143 	}
1144 
1145 	return result;
1146 }
1147 
cmd_vcp_vol_ctlr(const struct shell * sh,size_t argc,char ** argv)1148 static int cmd_vcp_vol_ctlr(const struct shell *sh, size_t argc, char **argv)
1149 {
1150 	if (argc > 1) {
1151 		shell_error(sh, "%s unknown parameter: %s",
1152 			    argv[0], argv[1]);
1153 	} else {
1154 		shell_error(sh, "%s Missing subcommand", argv[0]);
1155 	}
1156 
1157 	return -ENOEXEC;
1158 }
1159 
1160 SHELL_STATIC_SUBCMD_SET_CREATE(vcp_vol_ctlr_cmds,
1161 	SHELL_CMD_ARG(discover, NULL,
1162 		      "Discover VCP and included services for current "
1163 		      "connection",
1164 		      cmd_vcp_vol_ctlr_discover, 1, 0),
1165 	SHELL_CMD_ARG(state_get, NULL,
1166 		      "Get volume state of the VCP server. Should be done "
1167 		      "before sending any control messages",
1168 		      cmd_vcp_vol_ctlr_state_get, 1, 0),
1169 	SHELL_CMD_ARG(flags_get, NULL,
1170 		      "Read volume flags",
1171 		      cmd_vcp_vol_ctlr_flags_get, 1, 0),
1172 	SHELL_CMD_ARG(volume_down, NULL,
1173 		      "Turn the volume down",
1174 		      cmd_vcp_vol_ctlr_volume_down, 1, 0),
1175 	SHELL_CMD_ARG(volume_up, NULL,
1176 		      "Turn the volume up",
1177 		      cmd_vcp_vol_ctlr_volume_up, 1, 0),
1178 	SHELL_CMD_ARG(unmute_volume_down, NULL,
1179 		      "Turn the volume down, and unmute",
1180 		      cmd_vcp_vol_ctlr_unmute_volume_down, 1, 0),
1181 	SHELL_CMD_ARG(unmute_volume_up, NULL,
1182 		      "Turn the volume up, and unmute",
1183 		      cmd_vcp_vol_ctlr_unmute_volume_up, 1, 0),
1184 	SHELL_CMD_ARG(volume_set, NULL,
1185 		      "Set an absolute volume <volume>",
1186 		      cmd_vcp_vol_ctlr_volume_set, 2, 0),
1187 	SHELL_CMD_ARG(unmute, NULL,
1188 		      "Unmute",
1189 		      cmd_vcp_vol_ctlr_unmute, 1, 0),
1190 	SHELL_CMD_ARG(mute, NULL,
1191 		      "Mute",
1192 		      cmd_vcp_vol_ctlr_mute, 1, 0),
1193 	SHELL_CMD_ARG(vocs_state_get, NULL,
1194 		      "Get the offset state of a VOCS instance <inst_index>",
1195 		      cmd_vcp_vol_ctlr_vocs_state_get, 2, 0),
1196 	SHELL_CMD_ARG(vocs_location_get, NULL,
1197 		      "Get the location of a VOCS instance <inst_index>",
1198 		      cmd_vcp_vol_ctlr_vocs_location_get, 2, 0),
1199 	SHELL_CMD_ARG(vocs_location_set, NULL,
1200 		      "Set the location of a VOCS instance <inst_index> "
1201 		      "<location>",
1202 		      cmd_vcp_vol_ctlr_vocs_location_set, 3, 0),
1203 	SHELL_CMD_ARG(vocs_offset_set, NULL,
1204 		      "Set the offset for a VOCS instance <inst_index> "
1205 		      "<offset>",
1206 		      cmd_vcp_vol_ctlr_vocs_offset_set, 3, 0),
1207 	SHELL_CMD_ARG(vocs_output_description_get, NULL,
1208 		      "Get the output description of a VOCS instance "
1209 		      "<inst_index>",
1210 		      cmd_vcp_vol_ctlr_vocs_output_description_get, 2, 0),
1211 	SHELL_CMD_ARG(vocs_output_description_set, NULL,
1212 		      "Set the output description of a VOCS instance "
1213 		      "<inst_index> <description>",
1214 		      cmd_vcp_vol_ctlr_vocs_output_description_set, 3, 0),
1215 	SHELL_CMD_ARG(aics_input_state_get, NULL,
1216 		      "Get the input state of a AICS instance <inst_index>",
1217 		      cmd_vcp_vol_ctlr_aics_input_state_get, 2, 0),
1218 	SHELL_CMD_ARG(aics_gain_setting_get, NULL,
1219 		      "Get the gain settings of a AICS instance <inst_index>",
1220 		      cmd_vcp_vol_ctlr_aics_gain_setting_get, 2, 0),
1221 	SHELL_CMD_ARG(aics_input_type_get, NULL,
1222 		      "Get the input type of a AICS instance <inst_index>",
1223 		      cmd_vcp_vol_ctlr_aics_input_type_get, 2, 0),
1224 	SHELL_CMD_ARG(aics_input_status_get, NULL,
1225 		      "Get the input status of a AICS instance <inst_index>",
1226 		      cmd_vcp_vol_ctlr_aics_input_status_get, 2, 0),
1227 	SHELL_CMD_ARG(aics_input_unmute, NULL,
1228 		      "Unmute the input of a AICS instance <inst_index>",
1229 		      cmd_vcp_vol_ctlr_aics_input_unmute, 2, 0),
1230 	SHELL_CMD_ARG(aics_input_mute, NULL,
1231 		      "Mute the input of a AICS instance <inst_index>",
1232 		      cmd_vcp_vol_ctlr_aics_input_mute, 2, 0),
1233 	SHELL_CMD_ARG(aics_manual_input_gain_set, NULL,
1234 		      "Set the gain mode of a AICS instance to manual "
1235 		      "<inst_index>",
1236 		      cmd_vcp_vol_ctlr_aics_manual_input_gain_set, 2, 0),
1237 	SHELL_CMD_ARG(aics_automatic_input_gain_set, NULL,
1238 		      "Set the gain mode of a AICS instance to automatic "
1239 		      "<inst_index>",
1240 		      cmd_vcp_vol_ctlr_aics_auto_input_gain_set, 2, 0),
1241 	SHELL_CMD_ARG(aics_gain_set, NULL,
1242 		      "Set the gain of a AICS instance <inst_index> <gain>",
1243 		      cmd_vcp_vol_ctlr_aics_gain_set, 3, 0),
1244 	SHELL_CMD_ARG(aics_input_description_get, NULL,
1245 		      "Read the input description of a AICS instance "
1246 		      "<inst_index>",
1247 		      cmd_vcp_vol_ctlr_aics_input_description_get, 2, 0),
1248 	SHELL_CMD_ARG(aics_input_description_set, NULL,
1249 		      "Set the input description of a AICS instance "
1250 		      "<inst_index> <description>",
1251 		      cmd_vcp_vol_ctlr_aics_input_description_set, 3, 0),
1252 	SHELL_SUBCMD_SET_END
1253 );
1254 
1255 SHELL_CMD_ARG_REGISTER(vcp_vol_ctlr, &vcp_vol_ctlr_cmds,
1256 		       "Bluetooth VCP client shell commands",
1257 		       cmd_vcp_vol_ctlr, 1, 1);
1258