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