1 /** @file
2  *  @brief Media player shell
3  *
4  */
5 
6 /*
7  * Copyright (c) 2020 - 2021 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <errno.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/audio/media_proxy.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/conn.h>
20 #include <zephyr/logging/log.h>
21 #include <zephyr/shell/shell.h>
22 #include <zephyr/shell/shell_string_conv.h>
23 
24 #include "shell/bt.h"
25 
26 #include "../mpl_internal.h"
27 
28 LOG_MODULE_REGISTER(bt_mpl_shell, CONFIG_BT_MPL_LOG_LEVEL);
29 
30 #if defined(CONFIG_BT_MPL)
31 
32 #if defined(CONFIG_BT_MPL_LOG_LEVEL_DBG) && defined(CONFIG_BT_TESTING)
cmd_mpl_test_set_media_state(const struct shell * sh,size_t argc,char * argv[])33 int cmd_mpl_test_set_media_state(const struct shell *sh, size_t argc,
34 				 char *argv[])
35 {
36 	unsigned long state;
37 	int err = 0;
38 
39 	state = shell_strtoul(argv[1], 0, &err);
40 	if (err != 0) {
41 		shell_error(sh, "Could not parse state: %d", err);
42 
43 		return -ENOEXEC;
44 	}
45 
46 	if (state > UINT8_MAX) {
47 		shell_error(sh, "Invalid state %lu", state);
48 
49 		return -ENOEXEC;
50 	}
51 
52 	mpl_test_media_state_set(state);
53 
54 	return 0;
55 }
56 
57 #ifdef CONFIG_BT_MPL_OBJECTS
cmd_mpl_test_unset_parent_group(const struct shell * sh,size_t argc,char * argv[])58 int cmd_mpl_test_unset_parent_group(const struct shell *sh, size_t argc,
59 				    char *argv[])
60 {
61 	mpl_test_unset_parent_group();
62 
63 	return 0;
64 }
65 #endif /* CONFIG_BT_MPL_OBJECTS */
66 #endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG && CONFIG_BT_TESTING */
67 
68 #if defined(CONFIG_BT_MPL_LOG_LEVEL_DBG)
cmd_mpl_debug_dump_state(const struct shell * sh,size_t argc,char * argv[])69 int cmd_mpl_debug_dump_state(const struct shell *sh, size_t argc,
70 			     char *argv[])
71 {
72 	mpl_debug_dump_state();
73 
74 	return 0;
75 }
76 #endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG */
77 
cmd_media_proxy_pl_init(const struct shell * sh,size_t argc,char * argv[])78 int cmd_media_proxy_pl_init(const struct shell *sh, size_t argc, char *argv[])
79 {
80 	if (!ctx_shell) {
81 		ctx_shell = sh;
82 	}
83 
84 	int err = media_proxy_pl_init();
85 
86 	if (err) {
87 		shell_error(sh, "Could not init mpl");
88 	}
89 
90 	return err;
91 }
92 
cmd_mpl_test_player_name_cb(const struct shell * sh,size_t argc,char * argv[])93 int cmd_mpl_test_player_name_cb(const struct shell *sh, size_t argc,
94 				char *argv[])
95 {
96 	mpl_test_player_name_changed_cb();
97 
98 	return 0;
99 }
100 
cmd_mpl_test_player_icon_url_cb(const struct shell * sh,size_t argc,char * argv[])101 int cmd_mpl_test_player_icon_url_cb(const struct shell *sh, size_t argc,
102 				    char *argv[])
103 {
104 	mpl_test_player_icon_url_changed_cb();
105 
106 	return 0;
107 }
108 
cmd_mpl_test_track_changed_cb(const struct shell * sh,size_t argc,char * argv[])109 int cmd_mpl_test_track_changed_cb(const struct shell *sh, size_t argc,
110 				  char *argv[])
111 {
112 	mpl_test_track_changed_cb();
113 	return 0;
114 }
115 
cmd_mpl_test_title_changed_cb(const struct shell * sh,size_t argc,char * argv[])116 int cmd_mpl_test_title_changed_cb(const struct shell *sh, size_t argc,
117 				  char *argv[])
118 {
119 	mpl_test_title_changed_cb();
120 	return 0;
121 }
122 
cmd_mpl_test_duration_changed_cb(const struct shell * sh,size_t argc,char * argv[])123 int cmd_mpl_test_duration_changed_cb(const struct shell *sh, size_t argc,
124 				     char *argv[])
125 {
126 	mpl_test_duration_changed_cb();
127 	return 0;
128 }
129 
cmd_mpl_test_position_changed_cb(const struct shell * sh,size_t argc,char * argv[])130 int cmd_mpl_test_position_changed_cb(const struct shell *sh, size_t argc,
131 				     char *argv[])
132 {
133 	mpl_test_position_changed_cb();
134 	return 0;
135 }
136 
cmd_mpl_test_playback_speed_changed_cb(const struct shell * sh,size_t argc,char * argv[])137 int cmd_mpl_test_playback_speed_changed_cb(const struct shell *sh, size_t argc,
138 					   char *argv[])
139 {
140 	mpl_test_playback_speed_changed_cb();
141 	return 0;
142 }
143 
cmd_mpl_test_seeking_speed_changed_cb(const struct shell * sh,size_t argc,char * argv[])144 int cmd_mpl_test_seeking_speed_changed_cb(const struct shell *sh, size_t argc,
145 					  char *argv[])
146 {
147 	mpl_test_seeking_speed_changed_cb();
148 	return 0;
149 }
150 
151 #ifdef CONFIG_BT_MPL_OBJECTS
cmd_mpl_test_current_track_id_changed_cb(const struct shell * sh,size_t argc,char * argv[])152 int cmd_mpl_test_current_track_id_changed_cb(const struct shell *sh, size_t argc,
153 					     char *argv[])
154 {
155 	mpl_test_current_track_id_changed_cb();
156 	return 0;
157 }
158 
cmd_mpl_test_next_track_id_changed_cb(const struct shell * sh,size_t argc,char * argv[])159 int cmd_mpl_test_next_track_id_changed_cb(const struct shell *sh, size_t argc,
160 					  char *argv[])
161 {
162 	mpl_test_next_track_id_changed_cb();
163 	return 0;
164 }
165 
cmd_mpl_test_current_group_id_changed_cb(const struct shell * sh,size_t argc,char * argv[])166 int cmd_mpl_test_current_group_id_changed_cb(const struct shell *sh, size_t argc,
167 					     char *argv[])
168 {
169 	mpl_test_current_group_id_changed_cb();
170 	return 0;
171 }
172 
cmd_mpl_test_parent_group_id_changed_cb(const struct shell * sh,size_t argc,char * argv[])173 int cmd_mpl_test_parent_group_id_changed_cb(const struct shell *sh, size_t argc,
174 					    char *argv[])
175 {
176 	mpl_test_parent_group_id_changed_cb();
177 	return 0;
178 }
179 #endif /* CONFIG_BT_MPL_OBJECTS */
180 
cmd_mpl_test_playing_order_changed_cb(const struct shell * sh,size_t argc,char * argv[])181 int cmd_mpl_test_playing_order_changed_cb(const struct shell *sh, size_t argc,
182 					  char *argv[])
183 {
184 	mpl_test_playing_order_changed_cb();
185 	return 0;
186 }
187 
cmd_mpl_test_state_changed_cb(const struct shell * sh,size_t argc,char * argv[])188 int cmd_mpl_test_state_changed_cb(const struct shell *sh, size_t argc,
189 				  char *argv[])
190 {
191 	mpl_test_media_state_changed_cb();
192 	return 0;
193 }
194 
cmd_mpl_test_media_opcodes_supported_changed_cb(const struct shell * sh,size_t argc,char * argv[])195 int cmd_mpl_test_media_opcodes_supported_changed_cb(const struct shell *sh, size_t argc,
196 						    char *argv[])
197 {
198 	mpl_test_opcodes_supported_changed_cb();
199 	return 0;
200 }
201 
202 #ifdef CONFIG_BT_MPL_OBJECTS
cmd_mpl_test_search_results_changed_cb(const struct shell * sh,size_t argc,char * argv[])203 int cmd_mpl_test_search_results_changed_cb(const struct shell *sh, size_t argc,
204 					   char *argv[])
205 {
206 	mpl_test_search_results_changed_cb();
207 	return 0;
208 }
209 #endif /* CONFIG_BT_MPL_OBJECTS */
210 
cmd_mpl(const struct shell * sh,size_t argc,char ** argv)211 static int cmd_mpl(const struct shell *sh, size_t argc, char **argv)
212 {
213 	shell_error(sh, "%s unknown parameter: %s", argv[0], argv[1]);
214 
215 	return -ENOEXEC;
216 }
217 
218 SHELL_STATIC_SUBCMD_SET_CREATE(mpl_cmds,
219 #if defined(CONFIG_BT_MPL_LOG_LEVEL_DBG) && defined(CONFIG_BT_TESTING)
220 	SHELL_CMD_ARG(test_set_media_state, NULL,
221 		      "Set the media player state (test) <state>",
222 		      cmd_mpl_test_set_media_state, 2, 0),
223 #if CONFIG_BT_MPL_OBJECTS
224 	SHELL_CMD_ARG(test_unset_parent_group, NULL,
225 		      "Set current group to be its own parent (test)",
226 		      cmd_mpl_test_unset_parent_group, 1, 0),
227 #endif /* CONFIG_BT_MPL_OBJECTS */
228 #endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG && CONFIG_BT_TESTING */
229 #if defined(CONFIG_BT_MPL_LOG_LEVEL_DBG)
230 	SHELL_CMD_ARG(debug_dump_state, NULL,
231 		      "Dump media player's state as debug output (debug)",
232 		      cmd_mpl_debug_dump_state, 1, 0),
233 #endif /* CONFIG_BT_MPL_LOG_LEVEL_DBG */
234 	SHELL_CMD_ARG(init, NULL,
235 		      "Initialize media player",
236 		      cmd_media_proxy_pl_init, 1, 0),
237 	SHELL_CMD_ARG(player_name_changed_cb, NULL,
238 		      "Trigger Player Name changed callback (test)",
239 		      cmd_mpl_test_player_name_cb, 1, 0),
240 	SHELL_CMD_ARG(player_icon_url_changed_cb, NULL,
241 		      "Trigger Player icon URL changed callback (test)",
242 		      cmd_mpl_test_player_icon_url_cb, 1, 0),
243 	SHELL_CMD_ARG(track_changed_cb, NULL,
244 		      "Trigger Track Changed callback (test)",
245 		      cmd_mpl_test_track_changed_cb, 1, 0),
246 	SHELL_CMD_ARG(title_changed_cb, NULL,
247 		      "Trigger Track Title callback (test)",
248 		      cmd_mpl_test_title_changed_cb, 1, 0),
249 	SHELL_CMD_ARG(duration_changed_cb, NULL,
250 		      "Trigger Track Duration callback (test)",
251 		      cmd_mpl_test_duration_changed_cb, 1, 0),
252 	SHELL_CMD_ARG(position_changed_cb, NULL,
253 		      "Trigger Track Position callback (test)",
254 		      cmd_mpl_test_position_changed_cb, 1, 0),
255 	SHELL_CMD_ARG(playback_speed_changed_cb, NULL,
256 		      "Trigger Playback Speed callback (test)",
257 		      cmd_mpl_test_playback_speed_changed_cb, 1, 0),
258 	SHELL_CMD_ARG(seeking_speed_changed_cb, NULL,
259 		      "Trigger Seeking Speed callback (test)",
260 		      cmd_mpl_test_seeking_speed_changed_cb, 1, 0),
261 #ifdef CONFIG_BT_MPL_OBJECTS
262 	SHELL_CMD_ARG(current_track_id_changed_cb, NULL,
263 		      "Trigger Current Track callback (test)",
264 		      cmd_mpl_test_current_track_id_changed_cb, 1, 0),
265 	SHELL_CMD_ARG(next_track_id_changed_cb, NULL,
266 		      "Trigger Next Track callback (test)",
267 		      cmd_mpl_test_next_track_id_changed_cb, 1, 0),
268 	SHELL_CMD_ARG(current_group_id_changed_cb, NULL,
269 		      "Trigger Current Group callback (test)",
270 		      cmd_mpl_test_current_group_id_changed_cb, 1, 0),
271 	SHELL_CMD_ARG(parent_group_id_changed_cb, NULL,
272 		      "Trigger Parent Group callback (test)",
273 		      cmd_mpl_test_parent_group_id_changed_cb, 1, 0),
274 #endif /* CONFIG_BT_MPL_OBJECTS */
275 	SHELL_CMD_ARG(playing_order_changed_cb, NULL,
276 		      "Trigger Playing Order callback (test)",
277 		      cmd_mpl_test_playing_order_changed_cb, 1, 0),
278 	SHELL_CMD_ARG(state_changed_cb, NULL,
279 		      "Trigger Media State callback (test)",
280 		      cmd_mpl_test_state_changed_cb, 1, 0),
281 	SHELL_CMD_ARG(media_opcodes_changed_cb, NULL,
282 		      "Trigger Opcodes Supported callback (test)",
283 		      cmd_mpl_test_media_opcodes_supported_changed_cb, 1, 0),
284 #ifdef CONFIG_BT_MPL_OBJECTS
285 	SHELL_CMD_ARG(search_results_changed_cb, NULL,
286 		      "Trigger Search Results Object ID callback (test)",
287 		      cmd_mpl_test_search_results_changed_cb, 1, 0),
288 #endif /* CONFIG_BT_MPL_OBJECTS */
289 	SHELL_SUBCMD_SET_END
290 );
291 
292 /* TODO Remove this workaround macro once Scancode has been updated to
293  * not report this as a false positive MPL license
294  *
295  * See https://github.com/nexB/scancode-toolkit/issues/2304
296  * and https://github.com/nexB/scancode-toolkit/commit/6abbc4a22973f40ab74f6f8d948dd06416c97bd4
297  */
298 #define CMD_NQM cmd_mpl
299 SHELL_CMD_ARG_REGISTER(mpl, &mpl_cmds, "Media player (MPL) related commands",
300 		       CMD_NQM, 1, 1);
301 
302 #endif /* CONFIG_BT_MPL */
303