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