1 /** @file
2  *  @brief Media Controller shell implementation
3  *
4  */
5 
6 /*
7  * Copyright (c) 2021 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <errno.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <string.h>
17 
18 #include <zephyr/autoconf.h>
19 #include <zephyr/bluetooth/audio/mcs.h>
20 #include <zephyr/bluetooth/audio/media_proxy.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/services/ots.h>
24 #include <zephyr/logging/log.h>
25 #include <zephyr/shell/shell.h>
26 #include <zephyr/shell/shell_string_conv.h>
27 #include <zephyr/sys/util.h>
28 
29 #include "../media_proxy_internal.h" /* For MPL_NO_TRACK_ID - TODO: Fix */
30 
31 #include "host/shell/bt.h"
32 
33 LOG_MODULE_REGISTER(bt_media_controller_shell, CONFIG_BT_MCS_LOG_LEVEL);
34 
35 static struct media_proxy_ctrl_cbs cbs;
36 
37 /* Media player instances - the local player, the remote player and
38  * the current player (pointing to either the local or the remote)
39  *
40  * TODO: Add command to select player, ensure that the player pointer is used
41  */
42 static struct media_player *local_player;
43 static struct media_player *remote_player;
44 static struct media_player *current_player;
45 
local_player_instance_cb(struct media_player * plr,int err)46 static void local_player_instance_cb(struct media_player *plr, int err)
47 {
48 	if (err) {
49 		shell_error(ctx_shell, "Local player instance failed (%d)", err);
50 		return;
51 	}
52 
53 	local_player = plr;
54 	shell_print(ctx_shell, "Local player instance: %p", local_player);
55 
56 	if (!current_player) {
57 		current_player = local_player;
58 	}
59 }
60 
61 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL
discover_player_cb(struct media_player * plr,int err)62 static void discover_player_cb(struct media_player *plr, int err)
63 {
64 	if (err) {
65 		shell_error(ctx_shell, "Discover player failed (%d)", err);
66 		return;
67 	}
68 
69 	remote_player = plr;
70 	shell_print(ctx_shell, "Discovered player instance: %p", remote_player);
71 
72 	/* Assuming that since discovery was called, the remote player is wanted */
73 	current_player = remote_player;
74 }
75 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
76 
player_name_cb(struct media_player * plr,int err,const char * name)77 static void player_name_cb(struct media_player *plr, int err, const char *name)
78 {
79 	if (err) {
80 		shell_error(ctx_shell, "Player: %p, Player name failed (%d)", plr, err);
81 		return;
82 	}
83 
84 	shell_print(ctx_shell, "Player: %p, Player name: %s", plr, name);
85 }
86 
icon_id_cb(struct media_player * plr,int err,uint64_t id)87 static void icon_id_cb(struct media_player *plr, int err, uint64_t id)
88 {
89 	char str[BT_OTS_OBJ_ID_STR_LEN];
90 
91 	if (err) {
92 		shell_error(ctx_shell, "Player: %p, Icon ID failed (%d)", plr, err);
93 		return;
94 	}
95 
96 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
97 	shell_print(ctx_shell, "Player: %p, Icon Object ID: %s", plr, str);
98 }
99 
icon_url_cb(struct media_player * plr,int err,const char * url)100 static void icon_url_cb(struct media_player *plr, int err, const char *url)
101 {
102 	if (err) {
103 		shell_error(ctx_shell, "Player: %p, Icon URL failed (%d)", plr, err);
104 		return;
105 	}
106 
107 	shell_print(ctx_shell, "Player: %p, Icon URL: %s", plr, url);
108 }
109 
track_changed_cb(struct media_player * plr,int err)110 static void track_changed_cb(struct media_player *plr, int err)
111 {
112 	if (err) {
113 		shell_error(ctx_shell, "Player: %p, Track change failed (%d)", plr, err);
114 		return;
115 	}
116 
117 	shell_print(ctx_shell, "Player: %p, Track changed", plr);
118 }
119 
track_title_cb(struct media_player * plr,int err,const char * title)120 static void track_title_cb(struct media_player *plr, int err, const char *title)
121 {
122 	if (err) {
123 		shell_error(ctx_shell, "Player: %p, Track title failed (%d)", plr, err);
124 		return;
125 	}
126 
127 	shell_print(ctx_shell, "Player: %p, Track title: %s", plr, title);
128 }
129 
track_duration_cb(struct media_player * plr,int err,int32_t duration)130 static void track_duration_cb(struct media_player *plr, int err, int32_t duration)
131 {
132 	if (err) {
133 		shell_error(ctx_shell, "Player: %p, Track duration failed (%d)", plr, err);
134 		return;
135 	}
136 
137 	shell_print(ctx_shell, "Player: %p, Track duration: %d", plr, duration);
138 }
139 
track_position_recv_cb(struct media_player * plr,int err,int32_t position)140 static void track_position_recv_cb(struct media_player *plr, int err, int32_t position)
141 {
142 	if (err) {
143 		shell_error(ctx_shell, "Player: %p, Track position receive failed (%d)", plr, err);
144 		return;
145 	}
146 
147 	shell_print(ctx_shell, "Player: %p, Track Position received: %d", plr, position);
148 }
149 
track_position_write_cb(struct media_player * plr,int err,int32_t position)150 static void track_position_write_cb(struct media_player *plr, int err, int32_t position)
151 {
152 	if (err) {
153 		shell_error(ctx_shell, "Player: %p, Track position write failed (%d)", plr, err);
154 		return;
155 	}
156 
157 	shell_print(ctx_shell, "Player: %p, Track Position write: %d", plr, position);
158 }
159 
playback_speed_recv_cb(struct media_player * plr,int err,int8_t speed)160 static void playback_speed_recv_cb(struct media_player *plr, int err, int8_t speed)
161 {
162 	if (err) {
163 		shell_error(ctx_shell, "Player: %p, Playback speed receive failed (%d)", plr, err);
164 		return;
165 	}
166 
167 	shell_print(ctx_shell, "Player: %p, Playback speed received: %d", plr, speed);
168 }
169 
playback_speed_write_cb(struct media_player * plr,int err,int8_t speed)170 static void playback_speed_write_cb(struct media_player *plr, int err, int8_t speed)
171 {
172 	if (err) {
173 		shell_error(ctx_shell, "Player: %p, Playback speed write failed (%d)", plr, err);
174 		return;
175 	}
176 
177 	shell_print(ctx_shell, "Player: %p, Playback speed write: %d", plr, speed);
178 }
179 
seeking_speed_cb(struct media_player * plr,int err,int8_t speed)180 static void seeking_speed_cb(struct media_player *plr, int err, int8_t speed)
181 {
182 	if (err) {
183 		shell_error(ctx_shell, "Player: %p, Seeking speed failed (%d)", plr, err);
184 		return;
185 	}
186 
187 	shell_print(ctx_shell, "Player: %p, Seeking speed: %d", plr, speed);
188 }
189 
190 #ifdef CONFIG_BT_OTS
track_segments_id_cb(struct media_player * plr,int err,uint64_t id)191 static void track_segments_id_cb(struct media_player *plr, int err, uint64_t id)
192 {
193 	char str[BT_OTS_OBJ_ID_STR_LEN];
194 
195 	if (err) {
196 		shell_error(ctx_shell, "Player: %p, Track segments ID failed (%d)", plr, err);
197 		return;
198 	}
199 
200 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
201 	shell_print(ctx_shell, "Player: %p, Track Segments Object ID: %s", plr, str);
202 }
203 
current_track_id_cb(struct media_player * plr,int err,uint64_t id)204 static void current_track_id_cb(struct media_player *plr, int err, uint64_t id)
205 {
206 	char str[BT_OTS_OBJ_ID_STR_LEN];
207 
208 	if (err) {
209 		shell_error(ctx_shell, "Player: %p, Current track ID failed (%d)", plr, err);
210 		return;
211 	}
212 
213 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
214 	shell_print(ctx_shell, "Player: %p, Current Track Object ID: %s", plr, str);
215 }
216 
next_track_id_cb(struct media_player * plr,int err,uint64_t id)217 static void next_track_id_cb(struct media_player *plr, int err, uint64_t id)
218 {
219 	char str[BT_OTS_OBJ_ID_STR_LEN];
220 
221 	if (err) {
222 		shell_error(ctx_shell, "Player: %p, Next track ID failed (%d)", plr, err);
223 		return;
224 	}
225 
226 	if (id == MPL_NO_TRACK_ID) {
227 		shell_print(ctx_shell, "Player: %p, Next Track Object ID is empty", plr);
228 	} else {
229 		(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
230 		shell_print(ctx_shell, "Player: %p, Next Track Object ID: %s", plr, str);
231 	}
232 }
233 
current_group_id_cb(struct media_player * plr,int err,uint64_t id)234 static void current_group_id_cb(struct media_player *plr, int err, uint64_t id)
235 {
236 	char str[BT_OTS_OBJ_ID_STR_LEN];
237 
238 	if (err) {
239 		shell_error(ctx_shell, "Player: %p, Current group ID failed (%d)", plr, err);
240 		return;
241 	}
242 
243 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
244 	shell_print(ctx_shell, "Player: %p, Current Group Object ID: %s", plr, str);
245 }
246 
parent_group_id_cb(struct media_player * plr,int err,uint64_t id)247 static void parent_group_id_cb(struct media_player *plr, int err, uint64_t id)
248 {
249 	char str[BT_OTS_OBJ_ID_STR_LEN];
250 
251 	if (err) {
252 		shell_error(ctx_shell, "Player: %p, Parent group ID failed (%d)", plr, err);
253 		return;
254 	}
255 
256 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
257 	shell_print(ctx_shell, "Player: %p, Parent Group Object ID: %s", plr, str);
258 }
259 #endif /* CONFIG_BT_OTS */
260 
playing_order_recv_cb(struct media_player * plr,int err,uint8_t order)261 static void playing_order_recv_cb(struct media_player *plr, int err, uint8_t order)
262 {
263 	if (err) {
264 		shell_error(ctx_shell, "Player: %p, Playing order receive_failed (%d)", plr, err);
265 		return;
266 	}
267 
268 	shell_print(ctx_shell, "Player: %p, Playing received: %u", plr, order);
269 }
270 
playing_order_write_cb(struct media_player * plr,int err,uint8_t order)271 static void playing_order_write_cb(struct media_player *plr, int err, uint8_t order)
272 {
273 	if (err) {
274 		shell_error(ctx_shell, "Player: %p, Playing order write_failed (%d)", plr, err);
275 		return;
276 	}
277 
278 	shell_print(ctx_shell, "Player: %p, Playing written: %u", plr, order);
279 }
280 
playing_orders_supported_cb(struct media_player * plr,int err,uint16_t orders)281 static void playing_orders_supported_cb(struct media_player *plr, int err, uint16_t orders)
282 {
283 	if (err) {
284 		shell_error(ctx_shell, "Player: %p, Playing orders supported failed (%d)",
285 			    plr, err);
286 		return;
287 	}
288 
289 	shell_print(ctx_shell, "Player: %p, Playing orders supported: %u", plr, orders);
290 	/* TODO: Parse bitmap and output list of playing orders */
291 }
292 
media_state_cb(struct media_player * plr,int err,uint8_t state)293 static void media_state_cb(struct media_player *plr, int err, uint8_t state)
294 {
295 	if (err) {
296 		shell_error(ctx_shell, "Player: %p, Media state failed (%d)", plr, err);
297 		return;
298 	}
299 
300 	shell_print(ctx_shell, "Player: %p, Media State: %u", plr, state);
301 	/* TODO: Parse state and output state name (e.g. "Playing") */
302 }
303 
command_send_cb(struct media_player * plr,int err,const struct mpl_cmd * cmd)304 static void command_send_cb(struct media_player *plr, int err, const struct mpl_cmd *cmd)
305 {
306 	if (err) {
307 		shell_error(ctx_shell, "Player: %p, Command send failed (%d)", plr, err);
308 		return;
309 	}
310 
311 	shell_print(ctx_shell, "Player: %p, Command opcode sent: %u", plr, cmd->opcode);
312 }
313 
command_recv_cb(struct media_player * plr,int err,const struct mpl_cmd_ntf * cmd_ntf)314 static void command_recv_cb(struct media_player *plr, int err, const struct mpl_cmd_ntf *cmd_ntf)
315 {
316 	if (err) {
317 		shell_error(ctx_shell, "Player: %p, Command failed (%d)", plr, err);
318 		return;
319 	}
320 
321 	shell_print(ctx_shell, "Player: %p, Command opcode: %u, result: %u",
322 		    plr, cmd_ntf->requested_opcode, cmd_ntf->result_code);
323 }
324 
commands_supported_cb(struct media_player * plr,int err,uint32_t opcodes)325 static void commands_supported_cb(struct media_player *plr, int err, uint32_t opcodes)
326 {
327 	if (err) {
328 		shell_error(ctx_shell, "Player: %p, Commands supported failed (%d)", plr, err);
329 		return;
330 	}
331 
332 	shell_print(ctx_shell, "Player: %p, Command opcodes supported: %u", plr, opcodes);
333 	/* TODO: Parse bitmap and output list of opcodes */
334 }
335 
336 #ifdef CONFIG_BT_OTS
search_send_cb(struct media_player * plr,int err,const struct mpl_search * search)337 static void search_send_cb(struct media_player *plr, int err, const struct mpl_search *search)
338 {
339 	if (err) {
340 		shell_error(ctx_shell, "Player: %p, Search send failed (%d)", plr, err);
341 		return;
342 	}
343 
344 	shell_print(ctx_shell, "Player: %p, Search sent with len %u", plr, search->len);
345 }
346 
search_recv_cb(struct media_player * plr,int err,uint8_t result_code)347 static void search_recv_cb(struct media_player *plr, int err, uint8_t result_code)
348 {
349 	if (err) {
350 		shell_error(ctx_shell, "Player: %p, Search failed (%d)", plr, err);
351 		return;
352 	}
353 
354 	shell_print(ctx_shell, "Player: %p, Search result code: %u", plr, result_code);
355 }
356 
search_results_id_cb(struct media_player * plr,int err,uint64_t id)357 static void search_results_id_cb(struct media_player *plr, int err, uint64_t id)
358 {
359 	char str[BT_OTS_OBJ_ID_STR_LEN];
360 
361 	if (err) {
362 		shell_error(ctx_shell, "Player: %p, Search results ID failed (%d)", plr, err);
363 		return;
364 	}
365 
366 	if (id == 0) {
367 		shell_print(ctx_shell, "Player: %p, Search result not available", plr);
368 	}
369 
370 	(void)bt_ots_obj_id_to_str(id, str, sizeof(str));
371 	shell_print(ctx_shell, "Player: %p, Search Results Object ID: %s", plr, str);
372 }
373 #endif /* CONFIG_BT_OTS */
374 
content_ctrl_id_cb(struct media_player * plr,int err,uint8_t ccid)375 static void content_ctrl_id_cb(struct media_player *plr, int err, uint8_t ccid)
376 {
377 	if (err) {
378 		shell_error(ctx_shell, "Player: %p, Content control ID failed (%d)", plr, err);
379 		return;
380 	}
381 
382 	shell_print(ctx_shell, "Player: %p, Content Control ID: %u", plr, ccid);
383 }
384 
cmd_media_init(const struct shell * sh,size_t argc,char * argv[])385 static int cmd_media_init(const struct shell *sh, size_t argc, char *argv[])
386 {
387 	int err;
388 
389 	if (!ctx_shell) {
390 		ctx_shell = sh;
391 	}
392 
393 	err = media_proxy_pl_init();  /* TODO: Fix direct call to player */
394 	if (err) {
395 		shell_error(ctx_shell, "Could not init mpl");
396 	}
397 
398 	/* Set up the callback structure */
399 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL
400 	cbs.discover_player               = discover_player_cb;
401 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
402 	cbs.local_player_instance         = local_player_instance_cb;
403 	cbs.player_name_recv              = player_name_cb;
404 	cbs.icon_id_recv                  = icon_id_cb;
405 	cbs.icon_url_recv                 = icon_url_cb;
406 	cbs.track_changed_recv            = track_changed_cb;
407 	cbs.track_title_recv              = track_title_cb;
408 	cbs.track_duration_recv           = track_duration_cb;
409 	cbs.track_position_recv           = track_position_recv_cb;
410 	cbs.track_position_write          = track_position_write_cb;
411 	cbs.playback_speed_recv           = playback_speed_recv_cb;
412 	cbs.playback_speed_write          = playback_speed_write_cb;
413 	cbs.seeking_speed_recv            = seeking_speed_cb;
414 #ifdef CONFIG_BT_OTS
415 	cbs.track_segments_id_recv        = track_segments_id_cb;
416 	cbs.current_track_id_recv         = current_track_id_cb;
417 	cbs.next_track_id_recv            = next_track_id_cb;
418 	cbs.current_group_id_recv         = current_group_id_cb;
419 	cbs.parent_group_id_recv          = parent_group_id_cb;
420 #endif /* CONFIG_BT_OTS */
421 	cbs.playing_order_recv            = playing_order_recv_cb;
422 	cbs.playing_order_write           = playing_order_write_cb;
423 	cbs.playing_orders_supported_recv = playing_orders_supported_cb;
424 	cbs.media_state_recv              = media_state_cb;
425 	cbs.command_send                  = command_send_cb;
426 	cbs.command_recv                  = command_recv_cb;
427 	cbs.commands_supported_recv       = commands_supported_cb;
428 #ifdef CONFIG_BT_OTS
429 	cbs.search_send                   = search_send_cb;
430 	cbs.search_recv                   = search_recv_cb;
431 	cbs.search_results_id_recv        = search_results_id_cb;
432 #endif /* CONFIG_BT_OTS */
433 	cbs.content_ctrl_id_recv          = content_ctrl_id_cb;
434 
435 	err = media_proxy_ctrl_register(&cbs);
436 	if (err) {
437 		shell_error(ctx_shell, "Could not register media shell as controller");
438 	}
439 
440 	return err;
441 }
442 
cmd_media_set_player(const struct shell * sh,size_t argc,char * argv[])443 static int cmd_media_set_player(const struct shell *sh, size_t argc, char *argv[])
444 {
445 	if (!strcmp(argv[1], "local")) {
446 		if (local_player) {
447 			current_player = local_player;
448 			shell_print(ctx_shell, "Current player set to local player: %p",
449 				    current_player);
450 			return 0;
451 		}
452 
453 		shell_print(ctx_shell, "No local player");
454 		return -EOPNOTSUPP;
455 
456 	} else if (!strcmp(argv[1], "remote")) {
457 		if (remote_player) {
458 			current_player = remote_player;
459 			shell_print(ctx_shell, "Current player set to remote player: %p",
460 				    current_player);
461 			return 0;
462 		}
463 
464 		shell_print(ctx_shell, "No remote player");
465 		return -EOPNOTSUPP;
466 
467 	} else {
468 		shell_error(ctx_shell, "Input argument must be either \"local\" or \"remote\"");
469 		return -EINVAL;
470 	}
471 }
472 
cmd_media_show_players(const struct shell * sh,size_t argc,char * argv[])473 static int cmd_media_show_players(const struct shell *sh, size_t argc, char *argv[])
474 {
475 	shell_print(ctx_shell, "Local player: %p", local_player);
476 	shell_print(ctx_shell, "Remote player: %p", remote_player);
477 
478 	if (current_player == NULL) {
479 		shell_print(ctx_shell, "Current player is not set");
480 	} else if (current_player == local_player) {
481 		shell_print(ctx_shell, "Current player is set to local player: %p",
482 			    current_player);
483 	} else if (current_player == remote_player) {
484 		shell_print(ctx_shell, "Current player is set to remote player: %p",
485 			    current_player);
486 	} else {
487 		shell_print(ctx_shell, "Current player is not set to valid player");
488 	}
489 
490 	return 0;
491 }
492 
493 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL
cmd_media_discover_player(const struct shell * sh,size_t argc,char * argv[])494 static int cmd_media_discover_player(const struct shell *sh, size_t argc, char *argv[])
495 {
496 	int err = media_proxy_ctrl_discover_player(default_conn);
497 
498 	if (err) {
499 		shell_error(ctx_shell, "Discover player failed (%d)", err);
500 	}
501 
502 	return err;
503 }
504 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
505 
cmd_media_read_player_name(const struct shell * sh,size_t argc,char * argv[])506 static int cmd_media_read_player_name(const struct shell *sh, size_t argc, char *argv[])
507 {
508 	int err = media_proxy_ctrl_get_player_name(current_player);
509 
510 	if (err) {
511 		shell_error(ctx_shell, "Player name get failed (%d)", err);
512 	}
513 
514 	return err;
515 }
516 
517 #ifdef CONFIG_BT_OTS
cmd_media_read_icon_obj_id(const struct shell * sh,size_t argc,char * argv[])518 static int cmd_media_read_icon_obj_id(const struct shell *sh, size_t argc, char *argv[])
519 {
520 	int err = media_proxy_ctrl_get_icon_id(current_player);
521 
522 	if (err) {
523 		shell_error(ctx_shell, "Icon ID get failed (%d)", err);
524 	}
525 
526 	return err;
527 }
528 #endif /* CONFIG_BT_OTS */
529 
cmd_media_read_icon_url(const struct shell * sh,size_t argc,char * argv[])530 static int cmd_media_read_icon_url(const struct shell *sh, size_t argc, char *argv[])
531 {
532 	int err = media_proxy_ctrl_get_icon_url(current_player);
533 
534 	if (err) {
535 		shell_error(ctx_shell, "Icon URL get failed (%d)", err);
536 	}
537 
538 	return err;
539 }
540 
cmd_media_read_track_title(const struct shell * sh,size_t argc,char * argv[])541 static int cmd_media_read_track_title(const struct shell *sh, size_t argc, char *argv[])
542 {
543 	int err = media_proxy_ctrl_get_track_title(current_player);
544 
545 	if (err) {
546 		shell_error(ctx_shell, "Track title get failed (%d)", err);
547 	}
548 
549 	return err;
550 }
551 
cmd_media_read_track_duration(const struct shell * sh,size_t argc,char * argv[])552 static int cmd_media_read_track_duration(const struct shell *sh, size_t argc, char *argv[])
553 {
554 	int err = media_proxy_ctrl_get_track_duration(current_player);
555 
556 	if (err) {
557 		shell_error(ctx_shell, "Track duration get failed (%d)", err);
558 	}
559 
560 	return err;
561 }
562 
cmd_media_read_track_position(const struct shell * sh,size_t argc,char * argv[])563 static int cmd_media_read_track_position(const struct shell *sh, size_t argc, char *argv[])
564 {
565 	int err = media_proxy_ctrl_get_track_position(current_player);
566 
567 	if (err) {
568 		shell_error(ctx_shell, "Track position get failed (%d)", err);
569 	}
570 
571 	return err;
572 }
573 
cmd_media_set_track_position(const struct shell * sh,size_t argc,char * argv[])574 static int cmd_media_set_track_position(const struct shell *sh, size_t argc,
575 			       char *argv[])
576 {
577 	long position;
578 	int err = 0;
579 
580 	position = shell_strtol(argv[1], 0, &err);
581 	if (err != 0) {
582 		shell_error(sh, "Could not parse position: %d", err);
583 
584 		return -ENOEXEC;
585 	}
586 
587 	if (sizeof(long) != sizeof(int32_t) && !IN_RANGE(position, INT32_MIN, INT32_MAX)) {
588 		shell_error(sh, "Invalid position: %ld", position);
589 
590 		return -ENOEXEC;
591 	}
592 
593 	err = media_proxy_ctrl_set_track_position(current_player, position);
594 	if (err) {
595 		shell_error(ctx_shell, "Track position set failed (%d)", err);
596 	}
597 
598 	return err;
599 }
600 
cmd_media_read_playback_speed(const struct shell * sh,size_t argc,char * argv[])601 static int cmd_media_read_playback_speed(const struct shell *sh, size_t argc, char *argv[])
602 {
603 	int err = media_proxy_ctrl_get_playback_speed(current_player);
604 
605 	if (err) {
606 		shell_error(ctx_shell, "Playback speed get failed (%d)", err);
607 	}
608 
609 	return err;
610 }
611 
612 
cmd_media_set_playback_speed(const struct shell * sh,size_t argc,char * argv[])613 static int cmd_media_set_playback_speed(const struct shell *sh, size_t argc, char *argv[])
614 {
615 	long speed;
616 	int err = 0;
617 
618 	speed = shell_strtol(argv[1], 0, &err);
619 	if (err != 0) {
620 		shell_error(sh, "Could not parse speed: %d", err);
621 
622 		return -ENOEXEC;
623 	}
624 
625 	if (!IN_RANGE(speed, INT8_MIN, INT8_MAX)) {
626 		shell_error(sh, "Invalid speed: %ld", speed);
627 
628 		return -ENOEXEC;
629 	}
630 
631 	err = media_proxy_ctrl_set_playback_speed(current_player, speed);
632 	if (err) {
633 		shell_error(ctx_shell, "Playback speed set failed (%d)", err);
634 	}
635 
636 	return err;
637 }
638 
cmd_media_read_seeking_speed(const struct shell * sh,size_t argc,char * argv[])639 static int cmd_media_read_seeking_speed(const struct shell *sh, size_t argc, char *argv[])
640 {
641 	int err = media_proxy_ctrl_get_seeking_speed(current_player);
642 
643 	if (err) {
644 		shell_error(ctx_shell, "Seeking speed get failed (%d)", err);
645 	}
646 
647 	return err;
648 }
649 
650 #ifdef CONFIG_BT_OTS
cmd_media_read_track_segments_obj_id(const struct shell * sh,size_t argc,char * argv[])651 static int cmd_media_read_track_segments_obj_id(const struct shell *sh, size_t argc, char *argv[])
652 {
653 	int err = media_proxy_ctrl_get_track_segments_id(current_player);
654 
655 	if (err) {
656 		shell_error(ctx_shell, "Track segments ID get failed (%d)", err);
657 	}
658 
659 	return err;
660 }
661 
cmd_media_read_current_track_obj_id(const struct shell * sh,size_t argc,char * argv[])662 static int cmd_media_read_current_track_obj_id(const struct shell *sh, size_t argc, char *argv[])
663 {
664 	int err = media_proxy_ctrl_get_current_track_id(current_player);
665 
666 	if (err) {
667 		shell_error(ctx_shell, "Current track ID get failed (%d)", err);
668 	}
669 
670 	return err;
671 }
672 
673 /* TODO: cmd_media_set_current_track_obj_id */
674 
cmd_media_read_next_track_obj_id(const struct shell * sh,size_t argc,char * argv[])675 static int cmd_media_read_next_track_obj_id(const struct shell *sh, size_t argc, char *argv[])
676 {
677 	int err = media_proxy_ctrl_get_next_track_id(current_player);
678 
679 	if (err) {
680 		shell_error(ctx_shell, "Next track ID get failed (%d)", err);
681 	}
682 
683 	return err;
684 }
685 
cmd_media_read_current_group_obj_id(const struct shell * sh,size_t argc,char * argv[])686 static int cmd_media_read_current_group_obj_id(const struct shell *sh, size_t argc, char *argv[])
687 {
688 	int err = media_proxy_ctrl_get_current_group_id(current_player);
689 
690 	if (err) {
691 		shell_error(ctx_shell, "Current group ID get failed (%d)", err);
692 
693 	}
694 
695 	return err;
696 }
697 
cmd_media_read_parent_group_obj_id(const struct shell * sh,size_t argc,char * argv[])698 static int cmd_media_read_parent_group_obj_id(const struct shell *sh, size_t argc, char *argv[])
699 {
700 	int err = media_proxy_ctrl_get_parent_group_id(current_player);
701 
702 	if (err) {
703 		shell_error(ctx_shell, "Parent group ID get failed (%d)", err);
704 	}
705 
706 	return err;
707 }
708 #endif /* CONFIG_BT_OTS */
709 
cmd_media_read_playing_order(const struct shell * sh,size_t argc,char * argv[])710 static int cmd_media_read_playing_order(const struct shell *sh, size_t argc, char *argv[])
711 {
712 	int err = media_proxy_ctrl_get_playing_order(current_player);
713 
714 	if (err) {
715 		shell_error(ctx_shell, "Playing order get failed (%d)", err);
716 	}
717 
718 	return err;
719 }
720 
cmd_media_set_playing_order(const struct shell * sh,size_t argc,char * argv[])721 static int cmd_media_set_playing_order(const struct shell *sh, size_t argc, char *argv[])
722 {
723 	unsigned long order;
724 	int err = 0;
725 
726 	order = shell_strtoul(argv[1], 0, &err);
727 	if (err != 0) {
728 		shell_error(sh, "Could not parse order: %d", err);
729 
730 		return -ENOEXEC;
731 	}
732 
733 	if (order > UINT8_MAX) {
734 		shell_error(sh, "Invalid order: %ld", order);
735 
736 		return -ENOEXEC;
737 	}
738 
739 	err = media_proxy_ctrl_set_playing_order(current_player, order);
740 	if (err) {
741 		shell_error(ctx_shell, "Playing order set failed (%d)", err);
742 	}
743 
744 	return err;
745 }
746 
cmd_media_read_playing_orders_supported(const struct shell * sh,size_t argc,char * argv[])747 static int cmd_media_read_playing_orders_supported(const struct shell *sh, size_t argc,
748 						   char *argv[])
749 {
750 	int err = media_proxy_ctrl_get_playing_orders_supported(current_player);
751 
752 	if (err) {
753 		shell_error(ctx_shell, "Icon URL get failed (%d)", err);
754 	}
755 
756 	return err;
757 }
758 
cmd_media_read_media_state(const struct shell * sh,size_t argc,char * argv[])759 static int cmd_media_read_media_state(const struct shell *sh, size_t argc, char *argv[])
760 {
761 	int err = media_proxy_ctrl_get_media_state(current_player);
762 
763 	if (err) {
764 		shell_error(ctx_shell, "Icon URL get failed (%d)", err);
765 	}
766 
767 	return err;
768 }
769 
cmd_media_play(const struct shell * sh,size_t argc,char * argv[])770 static int cmd_media_play(const struct shell *sh, size_t argc, char *argv[])
771 {
772 	const struct mpl_cmd cmd = {
773 		.opcode = BT_MCS_OPC_PLAY,
774 		.use_param = false,
775 		.param = 0,
776 	};
777 	int err;
778 
779 	err = media_proxy_ctrl_send_command(current_player, &cmd);
780 	if (err != 0) {
781 		shell_error(sh, "Media Controller play failed: %d", err);
782 	}
783 
784 	return err;
785 }
786 
cmd_media_pause(const struct shell * sh,size_t argc,char * argv[])787 static int cmd_media_pause(const struct shell *sh, size_t argc, char *argv[])
788 {
789 	const struct mpl_cmd cmd = {
790 		.opcode = BT_MCS_OPC_PAUSE,
791 		.use_param = false,
792 		.param = 0,
793 	};
794 	int err;
795 
796 	err = media_proxy_ctrl_send_command(current_player, &cmd);
797 	if (err != 0) {
798 		shell_error(sh, "Media Controller pause failed: %d", err);
799 	}
800 
801 	return err;
802 }
803 
cmd_media_fast_rewind(const struct shell * sh,size_t argc,char * argv[])804 static int cmd_media_fast_rewind(const struct shell *sh, size_t argc,
805 				 char *argv[])
806 {
807 	const struct mpl_cmd cmd = {
808 		.opcode = BT_MCS_OPC_FAST_REWIND,
809 		.use_param = false,
810 		.param = 0,
811 	};
812 	int err;
813 
814 	err = media_proxy_ctrl_send_command(current_player, &cmd);
815 	if (err != 0) {
816 		shell_error(sh, "Media Controller fast rewind failed: %d", err);
817 	}
818 
819 	return err;
820 }
821 
cmd_media_fast_forward(const struct shell * sh,size_t argc,char * argv[])822 static int cmd_media_fast_forward(const struct shell *sh, size_t argc,
823 				  char *argv[])
824 {
825 	const struct mpl_cmd cmd = {
826 		.opcode = BT_MCS_OPC_FAST_FORWARD,
827 		.use_param = false,
828 		.param = 0,
829 	};
830 	int err;
831 
832 	err = media_proxy_ctrl_send_command(current_player, &cmd);
833 	if (err != 0) {
834 		shell_error(sh, "Media Controller fast forward failed: %d",
835 			    err);
836 	}
837 
838 	return err;
839 }
840 
cmd_media_stop(const struct shell * sh,size_t argc,char * argv[])841 static int cmd_media_stop(const struct shell *sh, size_t argc, char *argv[])
842 {
843 	const struct mpl_cmd cmd = {
844 		.opcode = BT_MCS_OPC_STOP,
845 		.use_param = false,
846 		.param = 0,
847 	};
848 	int err;
849 
850 	err = media_proxy_ctrl_send_command(current_player, &cmd);
851 	if (err != 0) {
852 		shell_error(sh, "Media Controller stop failed: %d", err);
853 	}
854 
855 	return err;
856 }
857 
cmd_media_move_relative(const struct shell * sh,size_t argc,char * argv[])858 static int cmd_media_move_relative(const struct shell *sh, size_t argc,
859 				   char *argv[])
860 {
861 	struct mpl_cmd cmd = {
862 		.opcode = BT_MCS_OPC_MOVE_RELATIVE,
863 		.use_param = true,
864 	};
865 	long offset;
866 	int err;
867 
868 	err = 0;
869 	offset = shell_strtol(argv[1], 10, &err);
870 	if (err != 0) {
871 		shell_error(sh, "Failed to parse offset: %d", err);
872 
873 		return err;
874 	}
875 
876 	if (sizeof(long) != sizeof(int32_t) && !IN_RANGE(offset, INT32_MIN, INT32_MAX)) {
877 		shell_error(sh, "Invalid offset: %ld", offset);
878 
879 		return -ENOEXEC;
880 	}
881 
882 	cmd.param = (int32_t)offset;
883 
884 	err = media_proxy_ctrl_send_command(current_player, &cmd);
885 	if (err != 0) {
886 		shell_error(sh, "Media Controller move relative failed: %d",
887 			    err);
888 	}
889 
890 	return err;
891 }
892 
cmd_media_prev_segment(const struct shell * sh,size_t argc,char * argv[])893 static int cmd_media_prev_segment(const struct shell *sh, size_t argc,
894 				  char *argv[])
895 {
896 	const struct mpl_cmd cmd = {
897 		.opcode = BT_MCS_OPC_PREV_SEGMENT,
898 		.use_param = false,
899 		.param = 0,
900 	};
901 	int err;
902 
903 	err = media_proxy_ctrl_send_command(current_player, &cmd);
904 	if (err != 0) {
905 		shell_error(sh, "Media Controller previous segment failed: %d",
906 			    err);
907 	}
908 
909 	return err;
910 }
911 
cmd_media_next_segment(const struct shell * sh,size_t argc,char * argv[])912 static int cmd_media_next_segment(const struct shell *sh, size_t argc,
913 				  char *argv[])
914 {
915 	const struct mpl_cmd cmd = {
916 		.opcode = BT_MCS_OPC_NEXT_SEGMENT,
917 		.use_param = false,
918 		.param = 0,
919 	};
920 	int err;
921 
922 	err = media_proxy_ctrl_send_command(current_player, &cmd);
923 	if (err != 0) {
924 		shell_error(sh, "Media Controller next segment failed: %d",
925 			    err);
926 	}
927 
928 	return err;
929 }
930 
cmd_media_first_segment(const struct shell * sh,size_t argc,char * argv[])931 static int cmd_media_first_segment(const struct shell *sh, size_t argc,
932 				   char *argv[])
933 {
934 	const struct mpl_cmd cmd = {
935 		.opcode = BT_MCS_OPC_FIRST_SEGMENT,
936 		.use_param = false,
937 		.param = 0,
938 	};
939 	int err;
940 
941 	err = media_proxy_ctrl_send_command(current_player, &cmd);
942 	if (err != 0) {
943 		shell_error(sh, "Media Controller first segment failed: %d",
944 			    err);
945 	}
946 
947 	return err;
948 }
949 
cmd_media_last_segment(const struct shell * sh,size_t argc,char * argv[])950 static int cmd_media_last_segment(const struct shell *sh, size_t argc,
951 				  char *argv[])
952 {
953 	const struct mpl_cmd cmd = {
954 		.opcode = BT_MCS_OPC_LAST_SEGMENT,
955 		.use_param = false,
956 		.param = 0,
957 	};
958 	int err;
959 
960 	err = media_proxy_ctrl_send_command(current_player, &cmd);
961 	if (err != 0) {
962 		shell_error(sh, "Media Controller last segment failed: %d",
963 			    err);
964 	}
965 
966 	return err;
967 }
968 
cmd_media_goto_segment(const struct shell * sh,size_t argc,char * argv[])969 static int cmd_media_goto_segment(const struct shell *sh, size_t argc,
970 				  char *argv[])
971 {
972 	struct mpl_cmd cmd = {
973 		.opcode = BT_MCS_OPC_GOTO_SEGMENT,
974 		.use_param = true,
975 	};
976 	long segment;
977 	int err;
978 
979 	err = 0;
980 	segment = shell_strtol(argv[1], 10, &err);
981 	if (err != 0) {
982 		shell_error(sh, "Failed to parse segment: %d", err);
983 
984 		return err;
985 	}
986 
987 	if (sizeof(long) != sizeof(int32_t) && !IN_RANGE(segment, INT32_MIN, INT32_MAX)) {
988 		shell_error(sh, "Invalid segment: %ld", segment);
989 
990 		return -ENOEXEC;
991 	}
992 
993 	cmd.param = (int32_t)segment;
994 
995 	err = media_proxy_ctrl_send_command(current_player, &cmd);
996 	if (err != 0) {
997 		shell_error(sh, "Media Controller goto segment failed: %d",
998 			    err);
999 	}
1000 
1001 	return err;
1002 }
1003 
cmd_media_prev_track(const struct shell * sh,size_t argc,char * argv[])1004 static int cmd_media_prev_track(const struct shell *sh, size_t argc,
1005 				char *argv[])
1006 {
1007 	const struct mpl_cmd cmd = {
1008 		.opcode = BT_MCS_OPC_PREV_TRACK,
1009 		.use_param = false,
1010 		.param = 0,
1011 	};
1012 	int err;
1013 
1014 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1015 	if (err != 0) {
1016 		shell_error(sh, "Media Controller previous track failed: %d",
1017 			    err);
1018 	}
1019 
1020 	return err;
1021 }
1022 
cmd_media_next_track(const struct shell * sh,size_t argc,char * argv[])1023 static int cmd_media_next_track(const struct shell *sh, size_t argc,
1024 				char *argv[])
1025 {
1026 	const struct mpl_cmd cmd = {
1027 		.opcode = BT_MCS_OPC_NEXT_TRACK,
1028 		.use_param = false,
1029 		.param = 0,
1030 	};
1031 	int err;
1032 
1033 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1034 	if (err != 0) {
1035 		shell_error(sh, "Media Controller next track failed: %d",
1036 			    err);
1037 	}
1038 
1039 	return err;
1040 }
1041 
cmd_media_first_track(const struct shell * sh,size_t argc,char * argv[])1042 static int cmd_media_first_track(const struct shell *sh, size_t argc,
1043 				 char *argv[])
1044 {
1045 	const struct mpl_cmd cmd = {
1046 		.opcode = BT_MCS_OPC_FIRST_TRACK,
1047 		.use_param = false,
1048 		.param = 0,
1049 	};
1050 	int err;
1051 
1052 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1053 	if (err != 0) {
1054 		shell_error(sh, "Media Controller first track failed: %d",
1055 			    err);
1056 	}
1057 
1058 	return err;
1059 }
1060 
cmd_media_last_track(const struct shell * sh,size_t argc,char * argv[])1061 static int cmd_media_last_track(const struct shell *sh, size_t argc,
1062 				char *argv[])
1063 {
1064 	const struct mpl_cmd cmd = {
1065 		.opcode = BT_MCS_OPC_LAST_TRACK,
1066 		.use_param = false,
1067 		.param = 0,
1068 	};
1069 	int err;
1070 
1071 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1072 	if (err != 0) {
1073 		shell_error(sh, "Media Controller last track failed: %d", err);
1074 	}
1075 
1076 	return err;
1077 }
1078 
cmd_media_goto_track(const struct shell * sh,size_t argc,char * argv[])1079 static int cmd_media_goto_track(const struct shell *sh, size_t argc,
1080 				char *argv[])
1081 {
1082 	struct mpl_cmd cmd = {
1083 		.opcode = BT_MCS_OPC_GOTO_TRACK,
1084 		.use_param = true,
1085 	};
1086 	long track;
1087 	int err;
1088 
1089 	err = 0;
1090 	track = shell_strtol(argv[1], 10, &err);
1091 	if (err != 0) {
1092 		shell_error(sh, "Failed to parse track: %d", err);
1093 
1094 		return err;
1095 	}
1096 
1097 	if (sizeof(long) != sizeof(int32_t) && !IN_RANGE(track, INT32_MIN, INT32_MAX)) {
1098 		shell_error(sh, "Invalid track: %ld", track);
1099 
1100 		return -ENOEXEC;
1101 	}
1102 
1103 	cmd.param = (int32_t)track;
1104 
1105 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1106 	if (err != 0) {
1107 		shell_error(sh, "Media Controller goto track failed: %d",
1108 			    err);
1109 	}
1110 
1111 	return err;
1112 }
1113 
cmd_media_prev_group(const struct shell * sh,size_t argc,char * argv[])1114 static int cmd_media_prev_group(const struct shell *sh, size_t argc,
1115 				char *argv[])
1116 {
1117 	const struct mpl_cmd cmd = {
1118 		.opcode = BT_MCS_OPC_PREV_GROUP,
1119 		.use_param = false,
1120 		.param = 0,
1121 	};
1122 	int err;
1123 
1124 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1125 	if (err != 0) {
1126 		shell_error(sh, "Media Controller previous group failed: %d",
1127 			    err);
1128 	}
1129 
1130 	return err;
1131 }
1132 
cmd_media_next_group(const struct shell * sh,size_t argc,char * argv[])1133 static int cmd_media_next_group(const struct shell *sh, size_t argc,
1134 				char *argv[])
1135 {
1136 	const struct mpl_cmd cmd = {
1137 		.opcode = BT_MCS_OPC_NEXT_GROUP,
1138 		.use_param = false,
1139 		.param = 0,
1140 	};
1141 	int err;
1142 
1143 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1144 	if (err != 0) {
1145 		shell_error(sh, "Media Controller next group failed: %d", err);
1146 	}
1147 
1148 	return err;
1149 }
1150 
cmd_media_first_group(const struct shell * sh,size_t argc,char * argv[])1151 static int cmd_media_first_group(const struct shell *sh, size_t argc,
1152 				 char *argv[])
1153 {
1154 	const struct mpl_cmd cmd = {
1155 		.opcode = BT_MCS_OPC_FIRST_GROUP,
1156 		.use_param = false,
1157 		.param = 0,
1158 	};
1159 	int err;
1160 
1161 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1162 	if (err != 0) {
1163 		shell_error(sh, "Media Controller first group failed: %d", err);
1164 	}
1165 
1166 	return err;
1167 }
1168 
cmd_media_last_group(const struct shell * sh,size_t argc,char * argv[])1169 static int cmd_media_last_group(const struct shell *sh, size_t argc,
1170 				char *argv[])
1171 {
1172 	const struct mpl_cmd cmd = {
1173 		.opcode = BT_MCS_OPC_LAST_GROUP,
1174 		.use_param = false,
1175 		.param = 0,
1176 	};
1177 	int err;
1178 
1179 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1180 	if (err != 0) {
1181 		shell_error(sh, "Media Controller last group failed: %d", err);
1182 	}
1183 
1184 	return err;
1185 }
1186 
cmd_media_goto_group(const struct shell * sh,size_t argc,char * argv[])1187 static int cmd_media_goto_group(const struct shell *sh, size_t argc,
1188 				char *argv[])
1189 {
1190 	struct mpl_cmd cmd = {
1191 		.opcode = BT_MCS_OPC_GOTO_GROUP,
1192 		.use_param = true,
1193 	};
1194 	long group;
1195 	int err;
1196 
1197 	err = 0;
1198 	group = shell_strtol(argv[1], 10, &err);
1199 	if (err != 0) {
1200 		shell_error(sh, "Failed to parse group: %d", err);
1201 
1202 		return err;
1203 	}
1204 
1205 	if (sizeof(long) != sizeof(int32_t) && !IN_RANGE(group, INT32_MIN, INT32_MAX)) {
1206 		shell_error(sh, "Invalid group: %ld", group);
1207 
1208 		return -ENOEXEC;
1209 	}
1210 
1211 	cmd.param = (int32_t)group;
1212 
1213 	err = media_proxy_ctrl_send_command(current_player, &cmd);
1214 	if (err != 0) {
1215 		shell_error(sh, "Media Controller goto group failed: %d",
1216 			    err);
1217 	}
1218 
1219 	return err;
1220 }
1221 
cmd_media_read_commands_supported(const struct shell * sh,size_t argc,char * argv[])1222 static int cmd_media_read_commands_supported(const struct shell *sh, size_t argc, char *argv[])
1223 {
1224 	int err = media_proxy_ctrl_get_commands_supported(current_player);
1225 
1226 	if (err) {
1227 		shell_error(ctx_shell, "Commands supported read failed (%d)", err);
1228 	}
1229 
1230 	return err;
1231 }
1232 
1233 #ifdef CONFIG_BT_OTS
cmd_media_set_search(const struct shell * sh,size_t argc,char * argv[])1234 static int cmd_media_set_search(const struct shell *sh, size_t argc, char *argv[])
1235 {
1236 	/* TODO: Currently takes the raw search as input - add parameters
1237 	 * and build the search item here
1238 	 */
1239 
1240 	struct mpl_search search;
1241 	size_t len;
1242 	int err;
1243 
1244 	len = strlen(argv[1]);
1245 	if (len > sizeof(search.search)) {
1246 		shell_print(sh, "Fail: Invalid argument");
1247 		return -EINVAL;
1248 	}
1249 
1250 	search.len = len;
1251 	memcpy(search.search, argv[1], search.len);
1252 	LOG_DBG("Search string: %s", argv[1]);
1253 
1254 	err = media_proxy_ctrl_send_search(current_player, &search);
1255 	if (err) {
1256 		shell_error(ctx_shell, "Search send failed (%d)", err);
1257 	}
1258 
1259 	return err;
1260 }
1261 
cmd_media_read_search_results_obj_id(const struct shell * sh,size_t argc,char * argv[])1262 static int cmd_media_read_search_results_obj_id(const struct shell *sh, size_t argc,
1263 						char *argv[])
1264 {
1265 	int err = media_proxy_ctrl_get_search_results_id(current_player);
1266 
1267 	if (err) {
1268 		shell_error(ctx_shell, "Search results ID get failed (%d)", err);
1269 	}
1270 
1271 	return err;
1272 }
1273 #endif /* CONFIG_BT_OTS */
1274 
cmd_media_read_content_control_id(const struct shell * sh,size_t argc,char * argv[])1275 static int cmd_media_read_content_control_id(const struct shell *sh, size_t argc,
1276 					     char *argv[])
1277 {
1278 	int err = media_proxy_ctrl_get_content_ctrl_id(current_player);
1279 
1280 	if (err) {
1281 		shell_error(ctx_shell, "Content control ID get failed (%d)", err);
1282 	}
1283 
1284 	return err;
1285 }
1286 
cmd_media(const struct shell * sh,size_t argc,char ** argv)1287 static int cmd_media(const struct shell *sh, size_t argc, char **argv)
1288 {
1289 	shell_error(ctx_shell, "%s unknown parameter: %s", argv[0], argv[1]);
1290 
1291 	return -ENOEXEC;
1292 }
1293 
1294 SHELL_STATIC_SUBCMD_SET_CREATE(media_cmds,
1295 	SHELL_CMD_ARG(init, NULL,
1296 		      "Initialize media player",
1297 		      cmd_media_init, 1, 0),
1298 	SHELL_CMD_ARG(set_player, NULL, "Set current player [local || remote]",
1299 		      cmd_media_set_player, 2, 0),
1300 	SHELL_CMD_ARG(show_players, NULL, "Show local, remote and current player",
1301 		      cmd_media_show_players, 1, 0),
1302 #ifdef CONFIG_BT_MCC
1303 	SHELL_CMD_ARG(discover_player, NULL, "Discover remote media player",
1304 		      cmd_media_discover_player, 1, 0),
1305 #endif /* CONFIG_BT_MCC */
1306 	SHELL_CMD_ARG(read_player_name, NULL, "Read Media Player Name",
1307 		      cmd_media_read_player_name, 1, 0),
1308 #ifdef CONFIG_BT_OTS
1309 	SHELL_CMD_ARG(read_icon_obj_id, NULL, "Read Icon Object ID",
1310 		      cmd_media_read_icon_obj_id, 1, 0),
1311 #endif /* CONFIG_BT_OTS */
1312 	SHELL_CMD_ARG(read_icon_url, NULL, "Read Icon URL",
1313 		      cmd_media_read_icon_url, 1, 0),
1314 	SHELL_CMD_ARG(read_track_title, NULL, "Read Track Title",
1315 		      cmd_media_read_track_title, 1, 0),
1316 	SHELL_CMD_ARG(read_track_duration, NULL, "Read Track Duration",
1317 		      cmd_media_read_track_duration, 1, 0),
1318 	SHELL_CMD_ARG(read_track_position, NULL, "Read Track Position",
1319 		      cmd_media_read_track_position, 1, 0),
1320 	SHELL_CMD_ARG(set_track_position, NULL, "Set Track position <position>",
1321 		      cmd_media_set_track_position, 2, 0),
1322 	SHELL_CMD_ARG(read_playback_speed, NULL, "Read Playback Speed",
1323 		      cmd_media_read_playback_speed, 1, 0),
1324 	SHELL_CMD_ARG(set_playback_speed, NULL, "Set Playback Speed <speed>",
1325 		      cmd_media_set_playback_speed, 2, 0),
1326 	SHELL_CMD_ARG(read_seeking_speed, NULL, "Read Seeking Speed",
1327 		      cmd_media_read_seeking_speed, 1, 0),
1328 #ifdef CONFIG_BT_OTS
1329 	SHELL_CMD_ARG(read_track_segments_obj_id, NULL,
1330 		      "Read Track Segments Object ID",
1331 		      cmd_media_read_track_segments_obj_id, 1, 0),
1332 	SHELL_CMD_ARG(read_current_track_obj_id, NULL,
1333 		      "Read Current Track Object ID",
1334 		      cmd_media_read_current_track_obj_id, 1, 0),
1335 	SHELL_CMD_ARG(read_next_track_obj_id, NULL,
1336 		      "Read Next Track Object ID",
1337 		      cmd_media_read_next_track_obj_id, 1, 0),
1338 	SHELL_CMD_ARG(read_current_group_obj_id, NULL,
1339 		      "Read Current Group Object ID",
1340 		      cmd_media_read_current_group_obj_id, 1, 0),
1341 	SHELL_CMD_ARG(read_parent_group_obj_id, NULL,
1342 		      "Read Parent Group Object ID",
1343 		      cmd_media_read_parent_group_obj_id, 1, 0),
1344 #endif /* CONFIG_BT_OTS */
1345 	SHELL_CMD_ARG(read_playing_order, NULL, "Read Playing Order",
1346 		      cmd_media_read_playing_order, 1, 0),
1347 	SHELL_CMD_ARG(set_playing_order, NULL, "Set Playing Order <order>",
1348 		      cmd_media_set_playing_order, 2, 0),
1349 	SHELL_CMD_ARG(read_playing_orders_supported, NULL,
1350 		     "Read Playing Orders Supported",
1351 		      cmd_media_read_playing_orders_supported, 1, 0),
1352 	SHELL_CMD_ARG(read_media_state, NULL, "Read Media State",
1353 		      cmd_media_read_media_state, 1, 0),
1354 	SHELL_CMD_ARG(play, NULL, "Send the play command", cmd_media_play, 1,
1355 		      0),
1356 	SHELL_CMD_ARG(pause, NULL, "Send the pause command",
1357 		      cmd_media_pause, 1, 0),
1358 	SHELL_CMD_ARG(fast_rewind, NULL, "Send the fast rewind command",
1359 		      cmd_media_fast_rewind, 1, 0),
1360 	SHELL_CMD_ARG(fast_forward, NULL, "Send the fast forward command",
1361 		      cmd_media_fast_forward, 1, 0),
1362 	SHELL_CMD_ARG(stop, NULL, "Send the stop command", cmd_media_stop, 1,
1363 		      0),
1364 	SHELL_CMD_ARG(move_relative, NULL,
1365 		      "Send the move relative command <int32_t: offset>",
1366 		      cmd_media_move_relative, 2, 0),
1367 	SHELL_CMD_ARG(prev_segment, NULL, "Send the prev segment command",
1368 		      cmd_media_prev_segment, 1, 0),
1369 	SHELL_CMD_ARG(next_segment, NULL, "Send the next segment command",
1370 		      cmd_media_next_segment, 1, 0),
1371 	SHELL_CMD_ARG(first_segment, NULL, "Send the first segment command",
1372 		      cmd_media_first_segment, 1, 0),
1373 	SHELL_CMD_ARG(last_segment, NULL, "Send the last segment command",
1374 		      cmd_media_last_segment, 1, 0),
1375 	SHELL_CMD_ARG(goto_segment, NULL,
1376 		      "Send the goto segment command <int32_t: segment>",
1377 		      cmd_media_goto_segment, 2, 0),
1378 	SHELL_CMD_ARG(prev_track, NULL, "Send the prev track command",
1379 		      cmd_media_prev_track, 1, 0),
1380 	SHELL_CMD_ARG(next_track, NULL, "Send the next track command",
1381 		      cmd_media_next_track, 1, 0),
1382 	SHELL_CMD_ARG(first_track, NULL, "Send the first track command",
1383 		      cmd_media_first_track, 1, 0),
1384 	SHELL_CMD_ARG(last_track, NULL, "Send the last track command",
1385 		      cmd_media_last_track, 1, 0),
1386 	SHELL_CMD_ARG(goto_track, NULL,
1387 		      "Send the goto track command  <int32_t: track>",
1388 		      cmd_media_goto_track, 2, 0),
1389 	SHELL_CMD_ARG(prev_group, NULL, "Send the prev group command",
1390 		      cmd_media_prev_group, 1, 0),
1391 	SHELL_CMD_ARG(next_group, NULL, "Send the next group command",
1392 		      cmd_media_next_group, 1, 0),
1393 	SHELL_CMD_ARG(first_group, NULL, "Send the first group command",
1394 		      cmd_media_first_group, 1, 0),
1395 	SHELL_CMD_ARG(last_group, NULL, "Send the last group command",
1396 		      cmd_media_last_group, 1, 0),
1397 	SHELL_CMD_ARG(goto_group, NULL,
1398 		      "Send the goto group command <int32_t: group>",
1399 		      cmd_media_goto_group, 2, 0),
1400 	SHELL_CMD_ARG(read_commands_supported, NULL, "Read Commands Supported",
1401 		      cmd_media_read_commands_supported, 1, 0),
1402 #ifdef CONFIG_BT_OTS
1403 	SHELL_CMD_ARG(set_search, NULL, "Set search <search control item sequence>",
1404 		      cmd_media_set_search, 2, 0),
1405 	SHELL_CMD_ARG(read_search_results_obj_id, NULL,
1406 		      "Read Search Results Object ID",
1407 		      cmd_media_read_search_results_obj_id, 1, 0),
1408 #endif /* CONFIG_BT_OTS */
1409 	SHELL_CMD_ARG(read_content_control_id, NULL, "Read Content Control ID",
1410 		      cmd_media_read_content_control_id, 1, 0),
1411 	SHELL_SUBCMD_SET_END
1412 );
1413 
1414 SHELL_CMD_ARG_REGISTER(media, &media_cmds, "Media commands",
1415 		       cmd_media, 1, 1);
1416