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