1 /*  Media proxy */
2 
3 /*
4  * Copyright (c) 2021 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/audio/media_proxy.h>
16 #include <zephyr/bluetooth/audio/mcc.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/services/ots.h>
19 #include <zephyr/logging/log.h>
20 #include <zephyr/sys/check.h>
21 
22 #include "media_proxy_internal.h"
23 #include "mcs_internal.h"
24 
25 LOG_MODULE_REGISTER(media_proxy, CONFIG_MCTL_LOG_LEVEL);
26 
27 /* Media player */
28 struct media_player {
29 	struct media_proxy_pl_calls *calls;
30 	struct bt_conn *conn;  /* TODO: Treat local and remote player differently */
31 	bool   registered;
32 };
33 
34 /* Synchronous controller - controller using the synchronous API */
35 struct scontroller {
36 	struct media_proxy_sctrl_cbs *cbs;
37 };
38 
39 /* Asynchronous controller - controller using the asynchronous API */
40 struct controller {
41 	struct media_proxy_ctrl_cbs *cbs;
42 };
43 /* Media proxy */
44 struct mprx {
45 
46 #if defined(CONFIG_MCTL_LOCAL_PLAYER_REMOTE_CONTROL)
47 	/* Controller using the synchronous interface - e.g. remote controller via
48 	 * the media control service
49 	 */
50 	struct scontroller   sctrlr;
51 #endif /* CONFIG_MCTL_LOCAL_PLAYER_REMOTE_CONTROL */
52 
53 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
54 	/* Controller using the callback interface - i.e. upper layer */
55 	struct controller    ctrlr;
56 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
57 
58 #if defined(CONFIG_MCTL_LOCAL_PLAYER_CONTROL)
59 	/* The local media player */
60 	struct media_player  local_player;
61 #endif /* CONFIG_MCTL_LOCAL_PLAYER_CONTROL */
62 
63 	/* Control of remote players is currently only supported over Bluetooth, via MCC */
64 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL)
65 	/* Remote media player - to have a player instance for the user */
66 	struct media_player  remote_player;
67 
68 	/* MCC callbacks */
69 	struct bt_mcc_cb mcc_cbs;
70 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
71 };
72 
73 static struct mprx mprx = { 0 };
74 
75 
76 #if defined(CONFIG_MCTL_LOCAL_PLAYER_REMOTE_CONTROL)
77 /* Synchronous controller calls ***********************************************/
78 
79 /* The synchronous controller is the media control service, representing a remote controller.
80  * It only gets access to the local player, not remote players.
81  * I.e., the calls from the synchronous controller are always routed to the local_player.
82  */
83 
media_proxy_sctrl_register(struct media_proxy_sctrl_cbs * sctrl_cbs)84 int media_proxy_sctrl_register(struct media_proxy_sctrl_cbs *sctrl_cbs)
85 {
86 	mprx.sctrlr.cbs = sctrl_cbs;
87 	return 0;
88 };
89 
media_proxy_sctrl_get_player_name(void)90 const char *media_proxy_sctrl_get_player_name(void)
91 {
92 	/* TODO: Add check for whether function pointer is non-NULL everywhere */
93 	return mprx.local_player.calls->get_player_name();
94 }
95 
96 #ifdef CONFIG_BT_MPL_OBJECTS
media_proxy_sctrl_get_icon_id(void)97 uint64_t media_proxy_sctrl_get_icon_id(void)
98 {
99 	return mprx.local_player.calls->get_icon_id();
100 }
101 #endif /* CONFIG_BT_MPL_OBJECTS */
102 
media_proxy_sctrl_get_icon_url(void)103 const char *media_proxy_sctrl_get_icon_url(void)
104 {
105 	return mprx.local_player.calls->get_icon_url();
106 }
107 
media_proxy_sctrl_get_track_title(void)108 const char *media_proxy_sctrl_get_track_title(void)
109 {
110 	return mprx.local_player.calls->get_track_title();
111 }
112 
media_proxy_sctrl_get_track_duration(void)113 int32_t media_proxy_sctrl_get_track_duration(void)
114 {
115 	return mprx.local_player.calls->get_track_duration();
116 }
117 
media_proxy_sctrl_get_track_position(void)118 int32_t media_proxy_sctrl_get_track_position(void)
119 {
120 	return mprx.local_player.calls->get_track_position();
121 }
122 
media_proxy_sctrl_set_track_position(int32_t position)123 void media_proxy_sctrl_set_track_position(int32_t position)
124 {
125 	mprx.local_player.calls->set_track_position(position);
126 }
127 
media_proxy_sctrl_get_playback_speed(void)128 int8_t media_proxy_sctrl_get_playback_speed(void)
129 {
130 	return mprx.local_player.calls->get_playback_speed();
131 }
132 
media_proxy_sctrl_set_playback_speed(int8_t speed)133 void media_proxy_sctrl_set_playback_speed(int8_t speed)
134 {
135 	mprx.local_player.calls->set_playback_speed(speed);
136 }
137 
media_proxy_sctrl_get_seeking_speed(void)138 int8_t media_proxy_sctrl_get_seeking_speed(void)
139 {
140 	return mprx.local_player.calls->get_seeking_speed();
141 }
142 
143 #ifdef CONFIG_BT_MPL_OBJECTS
media_proxy_sctrl_get_track_segments_id(void)144 uint64_t media_proxy_sctrl_get_track_segments_id(void)
145 {
146 	return mprx.local_player.calls->get_track_segments_id();
147 }
148 
media_proxy_sctrl_get_current_track_id(void)149 uint64_t media_proxy_sctrl_get_current_track_id(void)
150 {
151 	return mprx.local_player.calls->get_current_track_id();
152 }
153 
media_proxy_sctrl_set_current_track_id(uint64_t id)154 void media_proxy_sctrl_set_current_track_id(uint64_t id)
155 {
156 	mprx.local_player.calls->set_current_track_id(id);
157 }
158 
media_proxy_sctrl_get_next_track_id(void)159 uint64_t media_proxy_sctrl_get_next_track_id(void)
160 {
161 	return mprx.local_player.calls->get_next_track_id();
162 }
163 
media_proxy_sctrl_set_next_track_id(uint64_t id)164 void media_proxy_sctrl_set_next_track_id(uint64_t id)
165 {
166 	mprx.local_player.calls->set_next_track_id(id);
167 }
168 
media_proxy_sctrl_get_parent_group_id(void)169 uint64_t media_proxy_sctrl_get_parent_group_id(void)
170 {
171 	return mprx.local_player.calls->get_parent_group_id();
172 }
173 
media_proxy_sctrl_get_current_group_id(void)174 uint64_t media_proxy_sctrl_get_current_group_id(void)
175 {
176 	return mprx.local_player.calls->get_current_group_id();
177 }
178 
media_proxy_sctrl_set_current_group_id(uint64_t id)179 void media_proxy_sctrl_set_current_group_id(uint64_t id)
180 {
181 	mprx.local_player.calls->set_current_group_id(id);
182 }
183 #endif /* CONFIG_BT_MPL_OBJECTS */
184 
media_proxy_sctrl_get_playing_order(void)185 uint8_t media_proxy_sctrl_get_playing_order(void)
186 {
187 	return mprx.local_player.calls->get_playing_order();
188 }
189 
media_proxy_sctrl_set_playing_order(uint8_t order)190 void media_proxy_sctrl_set_playing_order(uint8_t order)
191 {
192 	mprx.local_player.calls->set_playing_order(order);
193 }
194 
media_proxy_sctrl_get_playing_orders_supported(void)195 uint16_t media_proxy_sctrl_get_playing_orders_supported(void)
196 {
197 	return mprx.local_player.calls->get_playing_orders_supported();
198 }
199 
media_proxy_sctrl_get_media_state(void)200 uint8_t media_proxy_sctrl_get_media_state(void)
201 {
202 	return mprx.local_player.calls->get_media_state();
203 }
204 
media_proxy_sctrl_send_command(const struct mpl_cmd * cmd)205 void media_proxy_sctrl_send_command(const struct mpl_cmd *cmd)
206 {
207 	mprx.local_player.calls->send_command(cmd);
208 }
209 
media_proxy_sctrl_get_commands_supported(void)210 uint32_t media_proxy_sctrl_get_commands_supported(void)
211 {
212 	return mprx.local_player.calls->get_commands_supported();
213 }
214 
215 #ifdef CONFIG_BT_MPL_OBJECTS
media_proxy_sctrl_send_search(const struct mpl_search * search)216 void media_proxy_sctrl_send_search(const struct mpl_search *search)
217 {
218 	mprx.local_player.calls->send_search(search);
219 }
220 
media_proxy_sctrl_get_search_results_id(void)221 uint64_t media_proxy_sctrl_get_search_results_id(void)
222 {
223 	return mprx.local_player.calls->get_search_results_id();
224 }
225 void media_proxy_sctrl_search_results_id_cb(uint64_t id);
226 #endif /* CONFIG_BT_MPL_OBJECTS */
227 
media_proxy_sctrl_get_content_ctrl_id(void)228 uint8_t media_proxy_sctrl_get_content_ctrl_id(void)
229 {
230 	return mprx.local_player.calls->get_content_ctrl_id();
231 }
232 #endif /* CONFIG_MCTL_LOCAL_PLAYER_REMOTE_CONTROL */
233 
234 
235 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL)
236 /* Media control client callbacks *********************************************/
237 
mcc_discover_mcs_cb(struct bt_conn * conn,int err)238 static void mcc_discover_mcs_cb(struct bt_conn *conn, int err)
239 {
240 	if (err) {
241 		LOG_ERR("Discovery failed (%d)", err);
242 	}
243 
244 	LOG_DBG("Discovered player");
245 
246 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->discover_player) {
247 		mprx.ctrlr.cbs->discover_player(&mprx.remote_player, err);
248 	} else {
249 		LOG_DBG("No callback");
250 	}
251 }
252 
mcc_read_player_name_cb(struct bt_conn * conn,int err,const char * name)253 static void mcc_read_player_name_cb(struct bt_conn *conn, int err, const char *name)
254 {
255 	/* Debug statements for at least a couple of the callbacks, to show flow */
256 	LOG_DBG("MCC player name callback");
257 
258 	if (err) {
259 		LOG_ERR("Player name failed");
260 	}
261 
262 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->player_name_recv) {
263 		mprx.ctrlr.cbs->player_name_recv(&mprx.remote_player, err, name);
264 	} else {
265 		LOG_DBG("No callback");
266 	}
267 }
268 
269 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
mcc_read_icon_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)270 static void mcc_read_icon_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
271 {
272 	LOG_DBG("Icon Object ID callback");
273 
274 	if (err) {
275 		LOG_ERR("Icon Object ID read failed (%d)", err);
276 	}
277 
278 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->icon_id_recv) {
279 		mprx.ctrlr.cbs->icon_id_recv(&mprx.remote_player, err, id);
280 	} else {
281 		LOG_DBG("No callback");
282 	}
283 }
284 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
285 
286 #if defined(CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL)
mcc_read_icon_url_cb(struct bt_conn * conn,int err,const char * url)287 static void mcc_read_icon_url_cb(struct bt_conn *conn, int err, const char *url)
288 {
289 	if (err) {
290 		LOG_ERR("Icon URL read failed (%d)", err);
291 	}
292 
293 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->icon_url_recv) {
294 		mprx.ctrlr.cbs->icon_url_recv(&mprx.remote_player, err, url);
295 	} else {
296 		LOG_DBG("No callback");
297 	}
298 }
299 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL) */
300 
mcc_track_changed_ntf_cb(struct bt_conn * conn,int err)301 static void mcc_track_changed_ntf_cb(struct bt_conn *conn, int err)
302 {
303 	if (err) {
304 		LOG_ERR("Track change notification failed (%d)", err);
305 		return;
306 	}
307 
308 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_changed_recv) {
309 		mprx.ctrlr.cbs->track_changed_recv(&mprx.remote_player, err);
310 	} else {
311 		LOG_DBG("No callback");
312 	}
313 }
314 
315 #if defined(CONFIG_BT_MCC_READ_TRACK_TITLE)
mcc_read_track_title_cb(struct bt_conn * conn,int err,const char * title)316 static void mcc_read_track_title_cb(struct bt_conn *conn, int err, const char *title)
317 {
318 	if (err) {
319 		LOG_ERR("Track title read failed (%d)", err);
320 	}
321 
322 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_title_recv) {
323 		mprx.ctrlr.cbs->track_title_recv(&mprx.remote_player, err, title);
324 	} else {
325 		LOG_DBG("No callback");
326 	}
327 }
328 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_TITLE) */
329 
330 #if defined(CONFIG_BT_MCC_READ_TRACK_DURATION)
mcc_read_track_duration_cb(struct bt_conn * conn,int err,int32_t dur)331 static void mcc_read_track_duration_cb(struct bt_conn *conn, int err, int32_t dur)
332 {
333 	if (err) {
334 		LOG_ERR("Track duration read failed (%d)", err);
335 	}
336 
337 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_duration_recv) {
338 		mprx.ctrlr.cbs->track_duration_recv(&mprx.remote_player, err, dur);
339 	} else {
340 		LOG_DBG("No callback");
341 	}
342 }
343 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_DURATION) */
344 
345 #if defined(CONFIG_BT_MCC_READ_TRACK_POSITION)
mcc_read_track_position_cb(struct bt_conn * conn,int err,int32_t pos)346 static void mcc_read_track_position_cb(struct bt_conn *conn, int err, int32_t pos)
347 {
348 	if (err) {
349 		LOG_ERR("Track position read failed (%d)", err);
350 	}
351 
352 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_position_recv) {
353 		mprx.ctrlr.cbs->track_position_recv(&mprx.remote_player, err, pos);
354 	} else {
355 		LOG_DBG("No callback");
356 	}
357 }
358 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_POSITION) */
359 
360 #if defined(CONFIG_BT_MCC_SET_TRACK_POSITION)
mcc_set_track_position_cb(struct bt_conn * conn,int err,int32_t pos)361 static void mcc_set_track_position_cb(struct bt_conn *conn, int err, int32_t pos)
362 {
363 	if (err) {
364 		LOG_ERR("Track Position set failed (%d)", err);
365 	}
366 
367 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_position_write) {
368 		mprx.ctrlr.cbs->track_position_write(&mprx.remote_player, err, pos);
369 	} else {
370 		LOG_DBG("No callback");
371 	}
372 }
373 #endif /* defined(CONFIG_BT_MCC_SET_TRACK_POSITION) */
374 
375 #if defined(CONFIG_BT_MCC_READ_PLAYBACK_SPEED)
mcc_read_playback_speed_cb(struct bt_conn * conn,int err,int8_t speed)376 static void mcc_read_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed)
377 {
378 	if (err) {
379 		LOG_ERR("Playback speed read failed (%d)", err);
380 	}
381 
382 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playback_speed_recv) {
383 		mprx.ctrlr.cbs->playback_speed_recv(&mprx.remote_player, err, speed);
384 	} else {
385 		LOG_DBG("No callback");
386 	}
387 }
388 #endif /* defined (CONFIG_BT_MCC_READ_PLAYBACK_SPEED) */
389 
390 #if defined(CONFIG_BT_MCC_SET_PLAYBACK_SPEED)
mcc_set_playback_speed_cb(struct bt_conn * conn,int err,int8_t speed)391 static void mcc_set_playback_speed_cb(struct bt_conn *conn, int err, int8_t speed)
392 {
393 	if (err) {
394 		LOG_ERR("Playback speed set failed (%d)", err);
395 	}
396 
397 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playback_speed_write) {
398 		mprx.ctrlr.cbs->playback_speed_write(&mprx.remote_player, err, speed);
399 	} else {
400 		LOG_DBG("No callback");
401 	}
402 }
403 #endif /* defined (CONFIG_BT_MCC_SET_PLAYBACK_SPEED) */
404 
405 #if defined(CONFIG_BT_MCC_READ_SEEKING_SPEED)
mcc_read_seeking_speed_cb(struct bt_conn * conn,int err,int8_t speed)406 static void mcc_read_seeking_speed_cb(struct bt_conn *conn, int err, int8_t speed)
407 {
408 	if (err) {
409 		LOG_ERR("Seeking speed read failed (%d)", err);
410 	}
411 
412 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->seeking_speed_recv) {
413 		mprx.ctrlr.cbs->seeking_speed_recv(&mprx.remote_player, err, speed);
414 	} else {
415 		LOG_DBG("No callback");
416 	}
417 }
418 #endif /* defined (CONFIG_BT_MCC_READ_SEEKING_SPEED) */
419 
420 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
mcc_read_segments_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)421 static void mcc_read_segments_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
422 {
423 	if (err) {
424 		LOG_ERR("Track Segments Object ID read failed (%d)", err);
425 	}
426 
427 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_segments_id_recv) {
428 		mprx.ctrlr.cbs->track_segments_id_recv(&mprx.remote_player, err, id);
429 	} else {
430 		LOG_DBG("No callback");
431 	}
432 }
433 
mcc_read_current_track_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)434 static void mcc_read_current_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
435 {
436 	if (err) {
437 		LOG_ERR("Current Track Object ID read failed (%d)", err);
438 	}
439 
440 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_track_id_recv) {
441 		mprx.ctrlr.cbs->current_track_id_recv(&mprx.remote_player, err, id);
442 	} else {
443 		LOG_DBG("No callback");
444 	}
445 }
446 
447 /* TODO: current track set callback - must be added to MCC first */
448 
mcc_read_next_track_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)449 static void mcc_read_next_track_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
450 {
451 	if (err) {
452 		LOG_ERR("Next Track Object ID read failed (%d)", err);
453 	}
454 
455 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->next_track_id_recv) {
456 		mprx.ctrlr.cbs->next_track_id_recv(&mprx.remote_player, err, id);
457 	} else {
458 		LOG_DBG("No callback");
459 	}
460 }
461 
462 /* TODO: next track set callback - must be added to MCC first */
463 
mcc_read_parent_group_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)464 static void mcc_read_parent_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
465 {
466 	if (err) {
467 		LOG_ERR("Parent Group Object ID read failed (%d)", err);
468 	}
469 
470 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->parent_group_id_recv) {
471 		mprx.ctrlr.cbs->parent_group_id_recv(&mprx.remote_player, err, id);
472 	} else {
473 		LOG_DBG("No callback");
474 	}
475 }
476 
mcc_read_current_group_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)477 static void mcc_read_current_group_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
478 {
479 	if (err) {
480 		LOG_ERR("Current Group Object ID read failed (%d)", err);
481 	}
482 
483 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_group_id_recv) {
484 		mprx.ctrlr.cbs->current_group_id_recv(&mprx.remote_player, err, id);
485 	} else {
486 		LOG_DBG("No callback");
487 	}
488 }
489 
490 /* TODO: current group set callback - must be added to MCC first */
491 
492 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
493 
494 #if defined(CONFIG_BT_MCC_READ_PLAYING_ORDER)
mcc_read_playing_order_cb(struct bt_conn * conn,int err,uint8_t order)495 static void mcc_read_playing_order_cb(struct bt_conn *conn, int err, uint8_t order)
496 {
497 	if (err) {
498 		LOG_ERR("Playing order read failed (%d)", err);
499 	}
500 
501 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_order_recv) {
502 		mprx.ctrlr.cbs->playing_order_recv(&mprx.remote_player, err, order);
503 	} else {
504 		LOG_DBG("No callback");
505 	}
506 }
507 #endif /* defined(CONFIG_BT_MCC_READ_PLAYING_ORDER) */
508 
509 #if defined(CONFIG_BT_MCC_SET_PLAYING_ORDER)
mcc_set_playing_order_cb(struct bt_conn * conn,int err,uint8_t order)510 static void mcc_set_playing_order_cb(struct bt_conn *conn, int err, uint8_t order)
511 {
512 	if (err) {
513 		LOG_ERR("Playing order set failed (%d)", err);
514 	}
515 
516 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_order_write) {
517 		mprx.ctrlr.cbs->playing_order_write(&mprx.remote_player, err, order);
518 	} else {
519 		LOG_DBG("No callback");
520 	}
521 }
522 #endif /* defined(CONFIG_BT_MCC_SET_PLAYING_ORDER) */
523 
524 #if defined(CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED)
mcc_read_playing_orders_supported_cb(struct bt_conn * conn,int err,uint16_t orders)525 static void mcc_read_playing_orders_supported_cb(struct bt_conn *conn, int err, uint16_t orders)
526 {
527 	if (err) {
528 		LOG_ERR("Playing orders supported read failed (%d)", err);
529 	}
530 
531 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_orders_supported_recv) {
532 		mprx.ctrlr.cbs->playing_orders_supported_recv(&mprx.remote_player, err, orders);
533 	} else {
534 		LOG_DBG("No callback");
535 	}
536 }
537 #endif /* defined(CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED) */
538 
539 #if defined(CONFIG_BT_MCC_READ_MEDIA_STATE)
mcc_read_media_state_cb(struct bt_conn * conn,int err,uint8_t state)540 static void mcc_read_media_state_cb(struct bt_conn *conn, int err, uint8_t state)
541 {
542 	if (err) {
543 		LOG_ERR("Media State read failed (%d)", err);
544 	}
545 
546 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->media_state_recv) {
547 		mprx.ctrlr.cbs->media_state_recv(&mprx.remote_player, err, state);
548 	} else {
549 		LOG_DBG("No callback");
550 	}
551 }
552 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_STATE) */
553 
554 #if defined(CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT)
mcc_send_cmd_cb(struct bt_conn * conn,int err,const struct mpl_cmd * cmd)555 static void mcc_send_cmd_cb(struct bt_conn *conn, int err, const struct mpl_cmd *cmd)
556 {
557 	if (err) {
558 		LOG_ERR("Command send failed (%d) - opcode: %d, param: %d", err, cmd->opcode,
559 			cmd->param);
560 	}
561 
562 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->command_send) {
563 		mprx.ctrlr.cbs->command_send(&mprx.remote_player, err, cmd);
564 	} else {
565 		LOG_DBG("No callback");
566 	}
567 }
568 #endif /* defined(CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT) */
569 
mcc_cmd_ntf_cb(struct bt_conn * conn,int err,const struct mpl_cmd_ntf * ntf)570 static void mcc_cmd_ntf_cb(struct bt_conn *conn, int err,
571 			   const struct mpl_cmd_ntf *ntf)
572 {
573 	if (err) {
574 		LOG_ERR("Command notification error (%d) - command opcode: %d, result: %d", err,
575 			ntf->requested_opcode, ntf->result_code);
576 	}
577 
578 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->command_recv) {
579 		mprx.ctrlr.cbs->command_recv(&mprx.remote_player, err, ntf);
580 	} else {
581 		LOG_DBG("No callback");
582 	}
583 }
584 
585 #if defined(CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)
mcc_read_opcodes_supported_cb(struct bt_conn * conn,int err,uint32_t opcodes)586 static void mcc_read_opcodes_supported_cb(struct bt_conn *conn, int err, uint32_t opcodes)
587 {
588 	if (err) {
589 		LOG_ERR("Opcodes supported read failed (%d)", err);
590 	}
591 
592 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->commands_supported_recv) {
593 		mprx.ctrlr.cbs->commands_supported_recv(&mprx.remote_player, err, opcodes);
594 	} else {
595 		LOG_DBG("No callback");
596 	}
597 }
598 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) */
599 
600 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
mcc_send_search_cb(struct bt_conn * conn,int err,const struct mpl_search * search)601 static void mcc_send_search_cb(struct bt_conn *conn, int err, const struct mpl_search *search)
602 {
603 	if (err) {
604 		LOG_ERR("Search send failed (%d)", err);
605 	}
606 
607 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_send) {
608 		mprx.ctrlr.cbs->search_send(&mprx.remote_player, err, search);
609 	} else {
610 		LOG_DBG("No callback");
611 	}
612 }
613 
mcc_search_ntf_cb(struct bt_conn * conn,int err,uint8_t result_code)614 static void mcc_search_ntf_cb(struct bt_conn *conn, int err, uint8_t result_code)
615 {
616 	if (err) {
617 		LOG_ERR("Search notification error (%d), result code: %d", err, result_code);
618 	}
619 
620 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_recv) {
621 		mprx.ctrlr.cbs->search_recv(&mprx.remote_player, err, result_code);
622 	} else {
623 		LOG_DBG("No callback");
624 	}
625 }
626 
mcc_read_search_results_obj_id_cb(struct bt_conn * conn,int err,uint64_t id)627 static void mcc_read_search_results_obj_id_cb(struct bt_conn *conn, int err, uint64_t id)
628 {
629 	if (err) {
630 		LOG_ERR("Search Results Object ID read failed (%d)", err);
631 	}
632 
633 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_results_id_recv) {
634 		mprx.ctrlr.cbs->search_results_id_recv(&mprx.remote_player, err, id);
635 	} else {
636 		LOG_DBG("No callback");
637 	}
638 }
639 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
640 
641 #if defined(CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID)
mcc_read_content_control_id_cb(struct bt_conn * conn,int err,uint8_t ccid)642 static void mcc_read_content_control_id_cb(struct bt_conn *conn, int err, uint8_t ccid)
643 {
644 	if (err) {
645 		LOG_ERR("Content Control ID read failed (%d)", err);
646 	}
647 
648 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->content_ctrl_id_recv) {
649 		mprx.ctrlr.cbs->content_ctrl_id_recv(&mprx.remote_player, err, ccid);
650 	} else {
651 		LOG_DBG("No callback");
652 	}
653 }
654 #endif /* defined(CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID) */
655 
656 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
657 
658 
659 /* Asynchronous controller calls **********************************************/
660 
661 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
media_proxy_ctrl_register(struct media_proxy_ctrl_cbs * ctrl_cbs)662 int media_proxy_ctrl_register(struct media_proxy_ctrl_cbs *ctrl_cbs)
663 {
664 	CHECKIF(ctrl_cbs == NULL) {
665 		LOG_DBG("NULL callback pointer");
666 		return -EINVAL;
667 	}
668 
669 	mprx.ctrlr.cbs = ctrl_cbs;
670 
671 	if (mprx.local_player.registered) {
672 		if (mprx.ctrlr.cbs->local_player_instance) {
673 			mprx.ctrlr.cbs->local_player_instance(&mprx.local_player, 0);
674 		}
675 	}
676 
677 	/* TODO: Return error code if too many controllers registered */
678 	return 0;
679 };
680 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
681 
682 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL
disconnected(struct bt_conn * conn,uint8_t reason)683 static void disconnected(struct bt_conn *conn, uint8_t reason)
684 {
685 	if (mprx.remote_player.conn == conn) {
686 		bt_conn_unref(mprx.remote_player.conn);
687 		mprx.remote_player.conn = NULL;
688 	}
689 }
690 
691 BT_CONN_CB_DEFINE(conn_callbacks) = {
692 	.disconnected = disconnected,
693 };
694 
media_proxy_ctrl_discover_player(struct bt_conn * conn)695 int media_proxy_ctrl_discover_player(struct bt_conn *conn)
696 {
697 	int err;
698 
699 	CHECKIF(!conn) {
700 		LOG_DBG("NUll conn pointer");
701 		return -EINVAL;
702 	}
703 
704 	/* Initialize MCC */
705 	mprx.mcc_cbs.discover_mcs                  = mcc_discover_mcs_cb;
706 	mprx.mcc_cbs.read_player_name              = mcc_read_player_name_cb;
707 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
708 	mprx.mcc_cbs.read_icon_obj_id              = mcc_read_icon_obj_id_cb;
709 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
710 #if defined(CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL)
711 	mprx.mcc_cbs.read_icon_url                 = mcc_read_icon_url_cb;
712 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL) */
713 	mprx.mcc_cbs.track_changed_ntf             = mcc_track_changed_ntf_cb;
714 #if defined(CONFIG_BT_MCC_READ_TRACK_TITLE)
715 	mprx.mcc_cbs.read_track_title              = mcc_read_track_title_cb;
716 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_TITLE) */
717 #if defined(CONFIG_BT_MCC_READ_TRACK_DURATION)
718 	mprx.mcc_cbs.read_track_duration           = mcc_read_track_duration_cb;
719 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_DURATION) */
720 #if defined(CONFIG_BT_MCC_READ_TRACK_POSITION)
721 	mprx.mcc_cbs.read_track_position           = mcc_read_track_position_cb;
722 #endif /* defined(CONFIG_BT_MCC_READ_TRACK_POSITION) */
723 #if defined(CONFIG_BT_MCC_SET_TRACK_POSITION)
724 	mprx.mcc_cbs.set_track_position            = mcc_set_track_position_cb;
725 #endif /* defined(CONFIG_BT_MCC_SET_TRACK_POSITION) */
726 #if defined(CONFIG_BT_MCC_READ_PLAYBACK_SPEED)
727 	mprx.mcc_cbs.read_playback_speed           = mcc_read_playback_speed_cb;
728 #endif /* defined (CONFIG_BT_MCC_READ_PLAYBACK_SPEED) */
729 #if defined(CONFIG_BT_MCC_SET_PLAYBACK_SPEED)
730 	mprx.mcc_cbs.set_playback_speed            = mcc_set_playback_speed_cb;
731 #endif /* defined (CONFIG_BT_MCC_SET_PLAYBACK_SPEED) */
732 #if defined(CONFIG_BT_MCC_READ_SEEKING_SPEED)
733 	mprx.mcc_cbs.read_seeking_speed            = mcc_read_seeking_speed_cb;
734 #endif /* defined (CONFIG_BT_MCC_READ_SEEKING_SPEED) */
735 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
736 	mprx.mcc_cbs.read_segments_obj_id          = mcc_read_segments_obj_id_cb;
737 	mprx.mcc_cbs.read_current_track_obj_id     = mcc_read_current_track_obj_id_cb;
738 	mprx.mcc_cbs.read_next_track_obj_id        = mcc_read_next_track_obj_id_cb;
739 	mprx.mcc_cbs.read_parent_group_obj_id      = mcc_read_parent_group_obj_id_cb;
740 	mprx.mcc_cbs.read_current_group_obj_id     = mcc_read_current_group_obj_id_cb;
741 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
742 #if defined(CONFIG_BT_MCC_READ_PLAYING_ORDER)
743 	mprx.mcc_cbs.read_playing_order	      = mcc_read_playing_order_cb;
744 #endif /* defined(CONFIG_BT_MCC_READ_PLAYING_ORDER) */
745 #if defined(CONFIG_BT_MCC_SET_PLAYING_ORDER)
746 	mprx.mcc_cbs.set_playing_order             = mcc_set_playing_order_cb;
747 #endif /* defined(CONFIG_BT_MCC_SET_PLAYING_ORDER) */
748 #if defined(CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED)
749 	mprx.mcc_cbs.read_playing_orders_supported = mcc_read_playing_orders_supported_cb;
750 #endif /* defined(CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED) */
751 #if defined(CONFIG_BT_MCC_READ_MEDIA_STATE)
752 	mprx.mcc_cbs.read_media_state              = mcc_read_media_state_cb;
753 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_STATE) */
754 #if defined(CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT)
755 	mprx.mcc_cbs.send_cmd                      = mcc_send_cmd_cb;
756 #endif /* defined(CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT) */
757 	mprx.mcc_cbs.cmd_ntf                       = mcc_cmd_ntf_cb;
758 #if defined(CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)
759 	mprx.mcc_cbs.read_opcodes_supported        = mcc_read_opcodes_supported_cb;
760 #endif /* defined(CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED) */
761 #ifdef CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS
762 	mprx.mcc_cbs.send_search                   = mcc_send_search_cb;
763 	mprx.mcc_cbs.search_ntf                    = mcc_search_ntf_cb;
764 	mprx.mcc_cbs.read_search_results_obj_id    = mcc_read_search_results_obj_id_cb;
765 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
766 #if defined(CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID)
767 	mprx.mcc_cbs.read_content_control_id       = mcc_read_content_control_id_cb;
768 #endif /* defined(CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID) */
769 
770 	err = bt_mcc_init(&mprx.mcc_cbs);
771 	if (err) {
772 		LOG_ERR("Failed to initialize MCC");
773 		return err;
774 	}
775 
776 	/* Start discovery of remote MCS, subscribe to notifications */
777 	err = bt_mcc_discover_mcs(conn, 1);
778 	if (err) {
779 		LOG_ERR("Discovery failed");
780 		return err;
781 	}
782 
783 	if (mprx.remote_player.conn != NULL) {
784 		bt_conn_unref(mprx.remote_player.conn);
785 	}
786 	mprx.remote_player.conn = bt_conn_ref(conn);
787 	mprx.remote_player.registered = true;  /* TODO: Do MCC init and "registration" at startup */
788 
789 	return 0;
790 }
791 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL	*/
792 
793 
794 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL) || defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL)
media_proxy_ctrl_get_player_name(struct media_player * player)795 int media_proxy_ctrl_get_player_name(struct media_player *player)
796 {
797 	CHECKIF(player == NULL) {
798 		LOG_DBG("player is NULL");
799 		return -EINVAL;
800 	}
801 
802 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
803 	if (mprx.local_player.registered && player == &mprx.local_player) {
804 		LOG_DBG("Local player");
805 		if (mprx.local_player.calls->get_player_name) {
806 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->player_name_recv) {
807 				const char *name = mprx.local_player.calls->get_player_name();
808 
809 				mprx.ctrlr.cbs->player_name_recv(&mprx.local_player, 0, name);
810 			} else {
811 				LOG_DBG("No callback");
812 			}
813 
814 			return 0;
815 		}
816 
817 		LOG_DBG("No call");
818 		return -EOPNOTSUPP;
819 	}
820 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
821 
822 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL)
823 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
824 		LOG_DBG("Remote player");
825 		return bt_mcc_read_player_name(mprx.remote_player.conn);
826 	}
827 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
828 
829 	return -EINVAL;
830 }
831 
media_proxy_ctrl_get_icon_id(struct media_player * player)832 int media_proxy_ctrl_get_icon_id(struct media_player *player)
833 {
834 	CHECKIF(player == NULL) {
835 		LOG_DBG("player is NULL");
836 		return -EINVAL;
837 	}
838 
839 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
840 	if (mprx.local_player.registered && player == &mprx.local_player) {
841 		if (mprx.local_player.calls->get_icon_id) {
842 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->icon_id_recv) {
843 				const uint64_t id = mprx.local_player.calls->get_icon_id();
844 
845 				mprx.ctrlr.cbs->icon_id_recv(&mprx.local_player, 0, id);
846 			} else {
847 				LOG_DBG("No callback");
848 			}
849 
850 			return 0;
851 		}
852 
853 		LOG_DBG("No call");
854 		return -EOPNOTSUPP;
855 	}
856 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
857 
858 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
859 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
860 		return bt_mcc_read_icon_obj_id(mprx.remote_player.conn);
861 	}
862 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
863 
864 	return -EINVAL;
865 }
866 
media_proxy_ctrl_get_icon_url(struct media_player * player)867 int media_proxy_ctrl_get_icon_url(struct media_player *player)
868 {
869 	CHECKIF(player == NULL) {
870 		LOG_DBG("player is NULL");
871 		return -EINVAL;
872 	}
873 
874 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
875 	if (mprx.local_player.registered && player == &mprx.local_player) {
876 		if (mprx.local_player.calls->get_icon_url) {
877 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->icon_url_recv) {
878 				const char *url = mprx.local_player.calls->get_icon_url();
879 
880 				mprx.ctrlr.cbs->icon_url_recv(player, 0, url);
881 			} else {
882 				LOG_DBG("No callback");
883 			}
884 
885 			return 0;
886 		}
887 
888 		LOG_DBG("No call");
889 		return -EOPNOTSUPP;
890 	}
891 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
892 
893 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL)
894 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
895 		return bt_mcc_read_icon_url(mprx.remote_player.conn);
896 	}
897 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_MEDIA_PLAYER_ICON_URL */
898 
899 	return -EINVAL;
900 }
901 
media_proxy_ctrl_get_track_title(struct media_player * player)902 int media_proxy_ctrl_get_track_title(struct media_player *player)
903 {
904 	CHECKIF(player == NULL) {
905 		LOG_DBG("player is NULL");
906 		return -EINVAL;
907 	}
908 
909 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
910 	if (mprx.local_player.registered && player == &mprx.local_player) {
911 		if (mprx.local_player.calls->get_track_title) {
912 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_title_recv) {
913 
914 				const char *title = mprx.local_player.calls->get_track_title();
915 				mprx.ctrlr.cbs->track_title_recv(player, 0, title);
916 			} else {
917 				LOG_DBG("No callback");
918 			}
919 
920 			return 0;
921 		}
922 
923 		LOG_DBG("No call");
924 		return -EOPNOTSUPP;
925 	}
926 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
927 
928 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_TRACK_TITLE)
929 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
930 		return bt_mcc_read_track_title(mprx.remote_player.conn);
931 	}
932 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_TRACK_TITLE */
933 
934 	return -EINVAL;
935 }
936 
media_proxy_ctrl_get_track_duration(struct media_player * player)937 int media_proxy_ctrl_get_track_duration(struct media_player *player)
938 {
939 	CHECKIF(player == NULL) {
940 		LOG_DBG("player is NULL");
941 		return -EINVAL;
942 	}
943 
944 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
945 	if (mprx.local_player.registered && player == &mprx.local_player) {
946 		if (mprx.local_player.calls->get_track_duration) {
947 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_duration_recv) {
948 				const int32_t duration =
949 					mprx.local_player.calls->get_track_duration();
950 
951 				mprx.ctrlr.cbs->track_duration_recv(player, 0, duration);
952 			} else {
953 				LOG_DBG("No callback");
954 			}
955 
956 			return 0;
957 		}
958 
959 		LOG_DBG("No call");
960 		return -EOPNOTSUPP;
961 	}
962 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
963 
964 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_TRACK_DURATION)
965 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
966 		return bt_mcc_read_track_duration(mprx.remote_player.conn);
967 	}
968 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_TRACK_DURATION */
969 
970 	return -EINVAL;
971 }
972 
media_proxy_ctrl_get_track_position(struct media_player * player)973 int media_proxy_ctrl_get_track_position(struct media_player *player)
974 {
975 	CHECKIF(player == NULL) {
976 		LOG_DBG("player is NULL");
977 		return -EINVAL;
978 	}
979 
980 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
981 	if (mprx.local_player.registered && player == &mprx.local_player) {
982 		if (mprx.local_player.calls->get_track_position) {
983 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_position_recv) {
984 				const int32_t position =
985 					mprx.local_player.calls->get_track_position();
986 
987 				mprx.ctrlr.cbs->track_position_recv(player, 0, position);
988 			} else {
989 				LOG_DBG("No callback");
990 			}
991 
992 			return 0;
993 		}
994 
995 		LOG_DBG("No call");
996 		return -EOPNOTSUPP;
997 	}
998 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
999 
1000 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_TRACK_POSITION)
1001 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1002 		return bt_mcc_read_track_position(mprx.remote_player.conn);
1003 	}
1004 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_TRACK_POSITION */
1005 
1006 	return -EINVAL;
1007 }
1008 
media_proxy_ctrl_set_track_position(struct media_player * player,int32_t position)1009 int media_proxy_ctrl_set_track_position(struct media_player *player, int32_t position)
1010 {
1011 	CHECKIF(player == NULL) {
1012 		LOG_DBG("player is NULL");
1013 		return -EINVAL;
1014 	}
1015 
1016 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1017 	if (mprx.local_player.registered && player == &mprx.local_player) {
1018 		if (mprx.local_player.calls->set_track_position) {
1019 			mprx.local_player.calls->set_track_position(position);
1020 
1021 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_position_write) {
1022 				mprx.ctrlr.cbs->track_position_write(player, 0, position);
1023 			} else {
1024 				LOG_DBG("No callback");
1025 			}
1026 
1027 			return 0;
1028 		}
1029 
1030 		LOG_DBG("No call");
1031 		return -EOPNOTSUPP;
1032 	}
1033 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1034 
1035 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && CONFIG_BT_MCC_SET_TRACK_POSITION
1036 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1037 		return bt_mcc_set_track_position(mprx.remote_player.conn, position);
1038 	}
1039 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_SET_TRACK_POSITION */
1040 
1041 	return -EINVAL;
1042 }
1043 
media_proxy_ctrl_get_playback_speed(struct media_player * player)1044 int media_proxy_ctrl_get_playback_speed(struct media_player *player)
1045 {
1046 	CHECKIF(player == NULL) {
1047 		LOG_DBG("player is NULL");
1048 		return -EINVAL;
1049 	}
1050 
1051 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1052 	if (mprx.local_player.registered && player == &mprx.local_player) {
1053 		if (mprx.local_player.calls->get_playback_speed) {
1054 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playback_speed_recv) {
1055 				const int8_t speed = mprx.local_player.calls->get_playback_speed();
1056 
1057 				mprx.ctrlr.cbs->playback_speed_recv(player, 0, speed);
1058 			} else {
1059 				LOG_DBG("No callback");
1060 			}
1061 
1062 			return 0;
1063 		}
1064 
1065 		LOG_DBG("No call");
1066 		return -EOPNOTSUPP;
1067 	}
1068 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1069 
1070 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_PLAYBACK_SPEED)
1071 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1072 		return bt_mcc_read_playback_speed(mprx.remote_player.conn);
1073 	}
1074 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_PLAYBACK_SPEED */
1075 
1076 	return -EINVAL;
1077 }
1078 
media_proxy_ctrl_set_playback_speed(struct media_player * player,int8_t speed)1079 int media_proxy_ctrl_set_playback_speed(struct media_player *player, int8_t speed)
1080 {
1081 	CHECKIF(player == NULL) {
1082 		LOG_DBG("player is NULL");
1083 		return -EINVAL;
1084 	}
1085 
1086 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1087 	if (mprx.local_player.registered && player == &mprx.local_player) {
1088 		if (mprx.local_player.calls->set_playback_speed) {
1089 			mprx.local_player.calls->set_playback_speed(speed);
1090 
1091 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playback_speed_write) {
1092 				mprx.ctrlr.cbs->playback_speed_write(player, 0, speed);
1093 			} else {
1094 				LOG_DBG("No callback");
1095 			}
1096 
1097 			return 0;
1098 		}
1099 
1100 		LOG_DBG("No call");
1101 		return -EOPNOTSUPP;
1102 	}
1103 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1104 
1105 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_SET_PLAYBACK_SPEED)
1106 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1107 		return bt_mcc_set_playback_speed(mprx.remote_player.conn, speed);
1108 	}
1109 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_SET_PLAYBACK_SPEED */
1110 
1111 	return -EINVAL;
1112 }
1113 
media_proxy_ctrl_get_seeking_speed(struct media_player * player)1114 int media_proxy_ctrl_get_seeking_speed(struct media_player *player)
1115 {
1116 	CHECKIF(player == NULL) {
1117 		LOG_DBG("player is NULL");
1118 		return -EINVAL;
1119 	}
1120 
1121 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1122 	if (mprx.local_player.registered && player == &mprx.local_player) {
1123 		if (mprx.local_player.calls->get_seeking_speed) {
1124 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->seeking_speed_recv) {
1125 				const int8_t speed = mprx.local_player.calls->get_seeking_speed();
1126 
1127 				mprx.ctrlr.cbs->seeking_speed_recv(player, 0, speed);
1128 			} else {
1129 				LOG_DBG("No callback");
1130 			}
1131 
1132 			return 0;
1133 		}
1134 
1135 		LOG_DBG("No call");
1136 		return -EOPNOTSUPP;
1137 	}
1138 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1139 
1140 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_SEEKING_SPEED)
1141 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1142 		return bt_mcc_read_seeking_speed(mprx.remote_player.conn);
1143 	}
1144 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_SEEKING_SPEED */
1145 
1146 	return -EINVAL;
1147 }
1148 
media_proxy_ctrl_get_track_segments_id(struct media_player * player)1149 int media_proxy_ctrl_get_track_segments_id(struct media_player *player)
1150 {
1151 	CHECKIF(player == NULL) {
1152 		LOG_DBG("player is NULL");
1153 		return -EINVAL;
1154 	}
1155 
1156 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1157 	if (mprx.local_player.registered && player == &mprx.local_player) {
1158 		if (mprx.local_player.calls->get_track_segments_id) {
1159 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_segments_id_recv) {
1160 				const uint64_t id =
1161 					mprx.local_player.calls->get_track_segments_id();
1162 
1163 				mprx.ctrlr.cbs->track_segments_id_recv(player, 0, id);
1164 			} else {
1165 				LOG_DBG("No callback");
1166 			}
1167 
1168 			return 0;
1169 		}
1170 
1171 		LOG_DBG("No call");
1172 		return -EOPNOTSUPP;
1173 	}
1174 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1175 
1176 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1177 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1178 		return bt_mcc_read_segments_obj_id(mprx.remote_player.conn);
1179 	}
1180 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1181 
1182 	return -EINVAL;
1183 }
1184 
media_proxy_ctrl_get_current_track_id(struct media_player * player)1185 int media_proxy_ctrl_get_current_track_id(struct media_player *player)
1186 {
1187 	CHECKIF(player == NULL) {
1188 		LOG_DBG("player is NULL");
1189 		return -EINVAL;
1190 	}
1191 
1192 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1193 	if (mprx.local_player.registered && player == &mprx.local_player) {
1194 		if (mprx.local_player.calls->get_current_track_id) {
1195 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_track_id_recv) {
1196 				const uint64_t id = mprx.local_player.calls->get_current_track_id();
1197 
1198 				mprx.ctrlr.cbs->current_track_id_recv(player, 0, id);
1199 			} else {
1200 				LOG_DBG("No callback");
1201 			}
1202 
1203 			return 0;
1204 		}
1205 
1206 		LOG_DBG("No call");
1207 		return -EOPNOTSUPP;
1208 	}
1209 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1210 
1211 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1212 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1213 		return bt_mcc_read_current_track_obj_id(mprx.remote_player.conn);
1214 	}
1215 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1216 
1217 	return -EINVAL;
1218 }
1219 
media_proxy_ctrl_set_current_track_id(struct media_player * player,uint64_t id)1220 int media_proxy_ctrl_set_current_track_id(struct media_player *player, uint64_t id)
1221 {
1222 	CHECKIF(player == NULL) {
1223 		LOG_DBG("player is NULL");
1224 		return -EINVAL;
1225 	}
1226 
1227 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1228 	CHECKIF(!BT_MCS_VALID_OBJ_ID(id)) {
1229 		LOG_DBG("Object ID 0x%016llx invalid", id);
1230 
1231 		return -EINVAL;
1232 	}
1233 
1234 	if (mprx.local_player.registered && player == &mprx.local_player) {
1235 		if (mprx.local_player.calls->set_current_track_id) {
1236 			mprx.local_player.calls->set_current_track_id(id);
1237 
1238 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_track_id_write) {
1239 				mprx.ctrlr.cbs->current_track_id_write(player, 0, id);
1240 			} else {
1241 				LOG_DBG("No callback");
1242 			}
1243 
1244 			return 0;
1245 		}
1246 
1247 		LOG_DBG("No call");
1248 		return -EOPNOTSUPP;
1249 	}
1250 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1251 
1252 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1253 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1254 		/* TODO: Uncomment when function is implemented */
1255 		/* return bt_mcc_set_current_track_obj_id(mprx.remote_player.conn, position); */
1256 	}
1257 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1258 
1259 	return -EINVAL;
1260 }
1261 
media_proxy_ctrl_get_next_track_id(struct media_player * player)1262 int media_proxy_ctrl_get_next_track_id(struct media_player *player)
1263 {
1264 	CHECKIF(player == NULL) {
1265 		LOG_DBG("player is NULL");
1266 		return -EINVAL;
1267 	}
1268 
1269 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1270 	if (mprx.local_player.registered && player == &mprx.local_player) {
1271 		if (mprx.local_player.calls->get_next_track_id) {
1272 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->next_track_id_recv) {
1273 				const uint64_t id = mprx.local_player.calls->get_next_track_id();
1274 
1275 				mprx.ctrlr.cbs->next_track_id_recv(player, 0, id);
1276 			} else {
1277 				LOG_DBG("No callback");
1278 			}
1279 
1280 			return 0;
1281 		}
1282 
1283 		LOG_DBG("No call");
1284 		return -EOPNOTSUPP;
1285 	}
1286 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1287 
1288 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1289 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1290 		return bt_mcc_read_next_track_obj_id(mprx.remote_player.conn);
1291 	}
1292 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1293 
1294 	return -EINVAL;
1295 }
1296 
media_proxy_ctrl_set_next_track_id(struct media_player * player,uint64_t id)1297 int media_proxy_ctrl_set_next_track_id(struct media_player *player, uint64_t id)
1298 {
1299 	CHECKIF(player == NULL) {
1300 		LOG_DBG("player is NULL");
1301 		return -EINVAL;
1302 	}
1303 
1304 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1305 	CHECKIF(!BT_MCS_VALID_OBJ_ID(id)) {
1306 		LOG_DBG("Object ID 0x%016llx invalid", id);
1307 
1308 		return -EINVAL;
1309 	}
1310 
1311 	if (mprx.local_player.registered && player == &mprx.local_player) {
1312 		if (mprx.local_player.calls->set_next_track_id) {
1313 			mprx.local_player.calls->set_next_track_id(id);
1314 
1315 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->next_track_id_write) {
1316 				mprx.ctrlr.cbs->next_track_id_write(player, 0, id);
1317 			} else {
1318 				LOG_DBG("No callback");
1319 			}
1320 
1321 			return 0;
1322 		}
1323 
1324 		LOG_DBG("No call");
1325 		return -EOPNOTSUPP;
1326 	}
1327 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1328 
1329 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1330 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1331 		/* TODO: Uncomment when function is implemented */
1332 		/* return bt_mcc_set_next_track_obj_id(mprx.remote_player.conn, position); */
1333 	}
1334 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1335 
1336 	return -EINVAL;
1337 }
1338 
media_proxy_ctrl_get_parent_group_id(struct media_player * player)1339 int media_proxy_ctrl_get_parent_group_id(struct media_player *player)
1340 {
1341 	CHECKIF(player == NULL) {
1342 		LOG_DBG("player is NULL");
1343 		return -EINVAL;
1344 	}
1345 
1346 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1347 	if (mprx.local_player.registered && player == &mprx.local_player) {
1348 		if (mprx.local_player.calls->get_parent_group_id) {
1349 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->parent_group_id_recv) {
1350 				const uint64_t id = mprx.local_player.calls->get_parent_group_id();
1351 
1352 				mprx.ctrlr.cbs->parent_group_id_recv(player, 0, id);
1353 			} else {
1354 				LOG_DBG("No callback");
1355 			}
1356 
1357 			return 0;
1358 		}
1359 
1360 		LOG_DBG("No call");
1361 		return -EOPNOTSUPP;
1362 	}
1363 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1364 
1365 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1366 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1367 		return bt_mcc_read_parent_group_obj_id(mprx.remote_player.conn);
1368 	}
1369 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1370 
1371 	return -EINVAL;
1372 }
1373 
media_proxy_ctrl_get_current_group_id(struct media_player * player)1374 int media_proxy_ctrl_get_current_group_id(struct media_player *player)
1375 {
1376 	CHECKIF(player == NULL) {
1377 		LOG_DBG("player is NULL");
1378 		return -EINVAL;
1379 	}
1380 
1381 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1382 	if (mprx.local_player.registered && player == &mprx.local_player) {
1383 		if (mprx.local_player.calls->get_current_group_id) {
1384 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_group_id_recv) {
1385 				const uint64_t id = mprx.local_player.calls->get_current_group_id();
1386 
1387 				mprx.ctrlr.cbs->current_group_id_recv(player, 0, id);
1388 			} else {
1389 				LOG_DBG("No callback");
1390 			}
1391 
1392 			return 0;
1393 		}
1394 
1395 		LOG_DBG("No call");
1396 		return -EOPNOTSUPP;
1397 	}
1398 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1399 
1400 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1401 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1402 		return bt_mcc_read_current_group_obj_id(mprx.remote_player.conn);
1403 	}
1404 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1405 
1406 	return -EINVAL;
1407 }
1408 
media_proxy_ctrl_set_current_group_id(struct media_player * player,uint64_t id)1409 int media_proxy_ctrl_set_current_group_id(struct media_player *player, uint64_t id)
1410 {
1411 	CHECKIF(player == NULL) {
1412 		LOG_DBG("player is NULL");
1413 		return -EINVAL;
1414 	}
1415 
1416 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1417 	CHECKIF(!BT_MCS_VALID_OBJ_ID(id)) {
1418 		LOG_DBG("Object ID 0x%016llx invalid", id);
1419 
1420 		return -EINVAL;
1421 	}
1422 
1423 	if (mprx.local_player.registered && player == &mprx.local_player) {
1424 		if (mprx.local_player.calls->set_current_group_id) {
1425 			mprx.local_player.calls->set_current_group_id(id);
1426 
1427 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_group_id_write) {
1428 				mprx.ctrlr.cbs->current_group_id_write(player, 0, id);
1429 			} else {
1430 				LOG_DBG("No callback");
1431 			}
1432 
1433 			return 0;
1434 		}
1435 
1436 		LOG_DBG("No call");
1437 		return -EOPNOTSUPP;
1438 	}
1439 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1440 
1441 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1442 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1443 		/* TODO: Uncomment when function is implemented */
1444 		/* return bt_mcc_set_current_group_obj_id(mprx.remote_player.conn, position); */
1445 	}
1446 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1447 
1448 	return -EINVAL;
1449 }
1450 
media_proxy_ctrl_get_playing_order(struct media_player * player)1451 int media_proxy_ctrl_get_playing_order(struct media_player *player)
1452 {
1453 	CHECKIF(player == NULL) {
1454 		LOG_DBG("player is NULL");
1455 		return -EINVAL;
1456 	}
1457 
1458 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1459 	if (mprx.local_player.registered && player == &mprx.local_player) {
1460 		if (mprx.local_player.calls->get_playing_order) {
1461 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_order_recv) {
1462 				const uint8_t order = mprx.local_player.calls->get_playing_order();
1463 
1464 				mprx.ctrlr.cbs->playing_order_recv(player, 0, order);
1465 			} else {
1466 				LOG_DBG("No callback");
1467 			}
1468 
1469 			return 0;
1470 		}
1471 
1472 		LOG_DBG("No call");
1473 		return -EOPNOTSUPP;
1474 	}
1475 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1476 
1477 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_PLAYING_ORDER)
1478 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1479 		LOG_DBG("Remote player");
1480 		return bt_mcc_read_playing_order(mprx.remote_player.conn);
1481 	}
1482 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_PLAYING_ORDER */
1483 
1484 	return -EINVAL;
1485 }
1486 
media_proxy_ctrl_set_playing_order(struct media_player * player,uint8_t order)1487 int media_proxy_ctrl_set_playing_order(struct media_player *player, uint8_t order)
1488 {
1489 	CHECKIF(player == NULL) {
1490 		LOG_DBG("player is NULL");
1491 		return -EINVAL;
1492 	}
1493 
1494 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1495 	if (mprx.local_player.registered && player == &mprx.local_player) {
1496 		if (mprx.local_player.calls->set_playing_order) {
1497 			mprx.local_player.calls->set_playing_order(order);
1498 
1499 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_order_write) {
1500 				mprx.ctrlr.cbs->playing_order_write(player, 0, order);
1501 			} else {
1502 				LOG_DBG("No callback");
1503 			}
1504 
1505 			return 0;
1506 		}
1507 
1508 		LOG_DBG("No call");
1509 		return -EOPNOTSUPP;
1510 	}
1511 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1512 
1513 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_SET_PLAYING_ORDER)
1514 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1515 		return bt_mcc_set_playing_order(mprx.remote_player.conn, order);
1516 	}
1517 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_SET_PLAYING_ORDER */
1518 
1519 	return -EINVAL;
1520 }
1521 
media_proxy_ctrl_get_playing_orders_supported(struct media_player * player)1522 int media_proxy_ctrl_get_playing_orders_supported(struct media_player *player)
1523 {
1524 	CHECKIF(player == NULL) {
1525 		LOG_DBG("player is NULL");
1526 		return -EINVAL;
1527 	}
1528 
1529 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1530 	if (mprx.local_player.registered && player == &mprx.local_player) {
1531 		if (mprx.local_player.calls->get_playing_orders_supported) {
1532 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_orders_supported_recv) {
1533 				const uint16_t orders =
1534 					mprx.local_player.calls->get_playing_orders_supported();
1535 
1536 				mprx.ctrlr.cbs->playing_orders_supported_recv(player, 0, orders);
1537 			} else {
1538 				LOG_DBG("No callback");
1539 			}
1540 
1541 			return 0;
1542 		}
1543 
1544 		LOG_DBG("No call");
1545 		return -EOPNOTSUPP;
1546 	}
1547 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1548 
1549 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && \
1550 	defined(CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED)
1551 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1552 		return bt_mcc_read_playing_orders_supported(mprx.remote_player.conn);
1553 	}
1554 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_PLAYING_ORDER_SUPPORTED */
1555 
1556 	return -EINVAL;
1557 }
1558 
media_proxy_ctrl_get_media_state(struct media_player * player)1559 int media_proxy_ctrl_get_media_state(struct media_player *player)
1560 {
1561 	CHECKIF(player == NULL) {
1562 		LOG_DBG("player is NULL");
1563 		return -EINVAL;
1564 	}
1565 
1566 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1567 	if (mprx.local_player.registered && player == &mprx.local_player) {
1568 		if (mprx.local_player.calls->get_media_state) {
1569 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->media_state_recv) {
1570 				const uint8_t state = mprx.local_player.calls->get_media_state();
1571 
1572 				mprx.ctrlr.cbs->media_state_recv(player, 0, state);
1573 			} else {
1574 				LOG_DBG("No callback");
1575 			}
1576 
1577 			return 0;
1578 		}
1579 
1580 		LOG_DBG("No call");
1581 		return -EOPNOTSUPP;
1582 	}
1583 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1584 
1585 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_MEDIA_STATE)
1586 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1587 		return bt_mcc_read_media_state(mprx.remote_player.conn);
1588 	}
1589 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_MEDIA_STATE */
1590 
1591 	return -EINVAL;
1592 }
1593 
media_proxy_ctrl_send_command(struct media_player * player,const struct mpl_cmd * cmd)1594 int media_proxy_ctrl_send_command(struct media_player *player, const struct mpl_cmd *cmd)
1595 {
1596 	CHECKIF(player == NULL || cmd == NULL) {
1597 		LOG_DBG("NULL pointer");
1598 		return -EINVAL;
1599 	}
1600 
1601 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1602 	if (mprx.local_player.registered && player == &mprx.local_player) {
1603 		if (mprx.local_player.calls->send_command) {
1604 			mprx.local_player.calls->send_command(cmd);
1605 
1606 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->command_send) {
1607 				mprx.ctrlr.cbs->command_send(player, 0, cmd);
1608 			} else {
1609 				LOG_DBG("No callback");
1610 			}
1611 
1612 			return 0;
1613 		}
1614 
1615 		LOG_DBG("No call");
1616 		return -EOPNOTSUPP;
1617 	}
1618 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1619 
1620 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT)
1621 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1622 		return bt_mcc_send_cmd(mprx.remote_player.conn, cmd);
1623 	}
1624 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_SET_MEDIA_CONTROL_POINT */
1625 
1626 	return -EINVAL;
1627 }
1628 
media_proxy_ctrl_get_commands_supported(struct media_player * player)1629 int media_proxy_ctrl_get_commands_supported(struct media_player *player)
1630 {
1631 	CHECKIF(player == NULL) {
1632 		LOG_DBG("player is NULL");
1633 		return -EINVAL;
1634 	}
1635 
1636 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1637 	if (mprx.local_player.registered && player == &mprx.local_player) {
1638 		if (mprx.local_player.calls->get_commands_supported) {
1639 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->commands_supported_recv) {
1640 				const uint32_t opcodes =
1641 					mprx.local_player.calls->get_commands_supported();
1642 
1643 				mprx.ctrlr.cbs->commands_supported_recv(player, 0, opcodes);
1644 			} else {
1645 				LOG_DBG("No callback");
1646 			}
1647 
1648 			return 0;
1649 		}
1650 
1651 		LOG_DBG("No call");
1652 		return -EOPNOTSUPP;
1653 	}
1654 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1655 
1656 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && \
1657 	defined(CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)
1658 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1659 		return bt_mcc_read_opcodes_supported(mprx.remote_player.conn);
1660 	}
1661 #endif	/* CONFIG_MCTL_REMOTE_PLAYER_CONTROL &&
1662 	 * CONFIG_BT_MCC_READ_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED
1663 	 */
1664 
1665 	return -EINVAL;
1666 }
1667 
media_proxy_ctrl_send_search(struct media_player * player,const struct mpl_search * search)1668 int media_proxy_ctrl_send_search(struct media_player *player, const struct mpl_search *search)
1669 {
1670 	CHECKIF(player == NULL || search == NULL) {
1671 		LOG_DBG("NULL pointer");
1672 		return -EINVAL;
1673 	}
1674 
1675 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1676 	if (mprx.local_player.registered && player == &mprx.local_player) {
1677 		if (mprx.local_player.calls->send_search) {
1678 			mprx.local_player.calls->send_search(search);
1679 
1680 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_send) {
1681 				mprx.ctrlr.cbs->search_send(player, 0, search);
1682 			} else {
1683 				LOG_DBG("No callback");
1684 			}
1685 
1686 			return 0;
1687 		}
1688 
1689 		LOG_DBG("No call");
1690 		return -EOPNOTSUPP;
1691 	}
1692 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1693 
1694 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1695 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1696 		return bt_mcc_send_search(mprx.remote_player.conn, search);
1697 	}
1698 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1699 
1700 	return -EINVAL;
1701 }
1702 
media_proxy_ctrl_get_search_results_id(struct media_player * player)1703 int media_proxy_ctrl_get_search_results_id(struct media_player *player)
1704 {
1705 	CHECKIF(player == NULL) {
1706 		LOG_DBG("player is NULL");
1707 		return -EINVAL;
1708 	}
1709 
1710 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1711 	if (mprx.local_player.registered && player == &mprx.local_player) {
1712 		if (mprx.local_player.calls->get_search_results_id) {
1713 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_results_id_recv) {
1714 				const uint64_t id =
1715 					mprx.local_player.calls->get_search_results_id();
1716 
1717 				mprx.ctrlr.cbs->search_results_id_recv(player, 0, id);
1718 			} else {
1719 				LOG_DBG("No callback");
1720 			}
1721 
1722 			return 0;
1723 		}
1724 
1725 		LOG_DBG("No call");
1726 		return -EOPNOTSUPP;
1727 	}
1728 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1729 
1730 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS)
1731 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1732 		return bt_mcc_read_search_results_obj_id(mprx.remote_player.conn);
1733 	}
1734 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL_OBJECTS */
1735 
1736 	return -EINVAL;
1737 }
1738 
media_proxy_ctrl_get_content_ctrl_id(struct media_player * player)1739 uint8_t media_proxy_ctrl_get_content_ctrl_id(struct media_player *player)
1740 {
1741 	CHECKIF(player == NULL) {
1742 		LOG_DBG("player is NULL");
1743 		return -EINVAL;
1744 	}
1745 
1746 #if defined(CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL)
1747 	if (mprx.local_player.registered && player == &mprx.local_player) {
1748 		if (mprx.local_player.calls->get_content_ctrl_id) {
1749 			if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->content_ctrl_id_recv) {
1750 				const uint8_t ccid = mprx.local_player.calls->get_content_ctrl_id();
1751 
1752 				mprx.ctrlr.cbs->content_ctrl_id_recv(player, 0, ccid);
1753 			} else {
1754 				LOG_DBG("No callback");
1755 			}
1756 
1757 			return 0;
1758 		}
1759 
1760 		LOG_DBG("No call");
1761 		return -EOPNOTSUPP;
1762 	}
1763 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL */
1764 
1765 #if defined(CONFIG_MCTL_REMOTE_PLAYER_CONTROL) && defined(CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID)
1766 	if (mprx.remote_player.registered && player == &mprx.remote_player) {
1767 		return bt_mcc_read_content_control_id(mprx.remote_player.conn);
1768 	}
1769 #endif /* CONFIG_MCTL_REMOTE_PLAYER_CONTROL && CONFIG_BT_MCC_READ_CONTENT_CONTROL_ID */
1770 
1771 	return -EINVAL;
1772 }
1773 #endif /* CONFIG_MCTL_LOCAL_PLAYER_LOCAL_CONTROL || CONFIG_MCTL_REMOTE_PLAYER_CONTROL */
1774 
1775 
1776 
1777 #if defined(CONFIG_MCTL_LOCAL_PLAYER_CONTROL)
1778 /* Player calls *******************************************/
1779 
pl_calls_is_valid(const struct media_proxy_pl_calls * pl_calls)1780 static bool pl_calls_is_valid(const struct media_proxy_pl_calls *pl_calls)
1781 {
1782 	if (pl_calls == NULL) {
1783 		LOG_DBG("pl_calls is NULL");
1784 		return false;
1785 	}
1786 
1787 	if (pl_calls->get_player_name == NULL) {
1788 		LOG_DBG("get_player_name is NULL");
1789 		return false;
1790 	}
1791 
1792 #ifdef CONFIG_BT_MPL_OBJECTS
1793 	if (pl_calls->get_icon_id == NULL) {
1794 		LOG_DBG("get_icon_id is NULL");
1795 		return false;
1796 	}
1797 #endif /* CONFIG_BT_MPL_OBJECTS */
1798 
1799 	if (pl_calls->get_icon_url == NULL) {
1800 		LOG_DBG("get_icon_url is NULL");
1801 		return false;
1802 	}
1803 
1804 	if (pl_calls->get_track_title == NULL) {
1805 		LOG_DBG("get_track_title is NULL");
1806 		return false;
1807 	}
1808 
1809 	if (pl_calls->get_track_duration == NULL) {
1810 		LOG_DBG("get_track_duration is NULL");
1811 		return false;
1812 	}
1813 
1814 	if (pl_calls->get_track_position == NULL) {
1815 		LOG_DBG("get_track_position is NULL");
1816 		return false;
1817 	}
1818 
1819 	if (pl_calls->set_track_position == NULL) {
1820 		LOG_DBG("set_track_position is NULL");
1821 		return false;
1822 	}
1823 
1824 	if (pl_calls->get_playback_speed == NULL) {
1825 		LOG_DBG("get_playback_speed is NULL");
1826 		return false;
1827 	}
1828 
1829 	if (pl_calls->set_playback_speed == NULL) {
1830 		LOG_DBG("set_playback_speed is NULL");
1831 		return false;
1832 	}
1833 
1834 	if (pl_calls->get_seeking_speed == NULL) {
1835 		LOG_DBG("get_seeking_speed is NULL");
1836 		return false;
1837 	}
1838 
1839 #ifdef CONFIG_BT_MPL_OBJECTS
1840 	if (pl_calls->get_track_segments_id == NULL) {
1841 		LOG_DBG("get_track_segments_id is NULL");
1842 		return false;
1843 	}
1844 
1845 	if (pl_calls->get_current_track_id == NULL) {
1846 		LOG_DBG("get_current_track_id is NULL");
1847 		return false;
1848 	}
1849 
1850 	if (pl_calls->set_current_track_id == NULL) {
1851 		LOG_DBG("set_current_track_id is NULL");
1852 		return false;
1853 	}
1854 
1855 	if (pl_calls->get_next_track_id == NULL) {
1856 		LOG_DBG("get_next_track_id is NULL");
1857 		return false;
1858 	}
1859 
1860 	if (pl_calls->set_next_track_id == NULL) {
1861 		LOG_DBG("set_next_track_id is NULL");
1862 		return false;
1863 	}
1864 
1865 	if (pl_calls->get_parent_group_id == NULL) {
1866 		LOG_DBG("get_parent_group_id is NULL");
1867 		return false;
1868 	}
1869 
1870 	if (pl_calls->get_current_group_id == NULL) {
1871 		LOG_DBG("get_current_group_id is NULL");
1872 		return false;
1873 	}
1874 
1875 	if (pl_calls->set_current_group_id == NULL) {
1876 		LOG_DBG("set_current_group_id is NULL");
1877 		return false;
1878 	}
1879 
1880 #endif /* CONFIG_BT_MPL_OBJECTS */
1881 	if (pl_calls->get_playing_order == NULL) {
1882 		LOG_DBG("get_playing_order is NULL");
1883 		return false;
1884 	}
1885 
1886 	if (pl_calls->set_playing_order == NULL) {
1887 		LOG_DBG("set_playing_order is NULL");
1888 		return false;
1889 	}
1890 
1891 	if (pl_calls->get_playing_orders_supported == NULL) {
1892 		LOG_DBG("get_playing_orders_supported is NULL");
1893 		return false;
1894 	}
1895 
1896 	if (pl_calls->get_media_state == NULL) {
1897 		LOG_DBG("get_media_state is NULL");
1898 		return false;
1899 	}
1900 
1901 	if (pl_calls->send_command == NULL) {
1902 		LOG_DBG("send_command is NULL");
1903 		return false;
1904 	}
1905 
1906 	if (pl_calls->get_commands_supported == NULL) {
1907 		LOG_DBG("get_commands_supported is NULL");
1908 		return false;
1909 	}
1910 
1911 #ifdef CONFIG_BT_MPL_OBJECTS
1912 	if (pl_calls->send_search == NULL) {
1913 		LOG_DBG("send_search is NULL");
1914 		return false;
1915 	}
1916 
1917 	if (pl_calls->get_search_results_id == NULL) {
1918 		LOG_DBG("get_search_results_id is NULL");
1919 		return false;
1920 	}
1921 
1922 #endif /* CONFIG_BT_MPL_OBJECTS */
1923 	if (pl_calls->get_content_ctrl_id == NULL) {
1924 		LOG_DBG("get_content_ctrl_id is NULL");
1925 		return false;
1926 	}
1927 
1928 	return true;
1929 }
1930 
media_proxy_pl_register(struct media_proxy_pl_calls * pl_calls)1931 int media_proxy_pl_register(struct media_proxy_pl_calls *pl_calls)
1932 {
1933 	CHECKIF(!pl_calls_is_valid(pl_calls)) {
1934 		return -EINVAL;
1935 	}
1936 
1937 	if (mprx.local_player.registered) {
1938 		LOG_DBG("Player already registered");
1939 		return -EALREADY;
1940 	}
1941 
1942 	mprx.local_player.calls = pl_calls;
1943 	mprx.local_player.registered = true;
1944 
1945 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->local_player_instance) {
1946 		mprx.ctrlr.cbs->local_player_instance(&mprx.local_player, 0);
1947 	}
1948 
1949 	return 0;
1950 };
1951 
1952 /* Player callbacks ********************************/
1953 
1954 /* All callbacks here must come from the local player - mprx.local_player */
1955 
media_proxy_pl_name_cb(const char * name)1956 void media_proxy_pl_name_cb(const char *name)
1957 {
1958 	mprx.sctrlr.cbs->player_name(name);
1959 
1960 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->player_name_recv) {
1961 		mprx.ctrlr.cbs->player_name_recv(&mprx.local_player, 0, name);
1962 	} else {
1963 		LOG_DBG("No ctrlr player name callback");
1964 	}
1965 }
1966 
media_proxy_pl_icon_url_cb(const char * url)1967 void media_proxy_pl_icon_url_cb(const char *url)
1968 {
1969 	mprx.sctrlr.cbs->icon_url(url);
1970 
1971 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->player_name_recv) {
1972 		mprx.ctrlr.cbs->icon_url_recv(&mprx.local_player, 0, url);
1973 	} else {
1974 		LOG_DBG("No ctrlr player icon URL callback");
1975 	}
1976 }
1977 
media_proxy_pl_track_changed_cb(void)1978 void media_proxy_pl_track_changed_cb(void)
1979 {
1980 	mprx.sctrlr.cbs->track_changed();
1981 
1982 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_changed_recv) {
1983 		mprx.ctrlr.cbs->track_changed_recv(&mprx.local_player, 0);
1984 	} else {
1985 		LOG_DBG("No ctrlr track changed callback");
1986 	}
1987 }
1988 
media_proxy_pl_track_title_cb(char * title)1989 void media_proxy_pl_track_title_cb(char *title)
1990 {
1991 	mprx.sctrlr.cbs->track_title(title);
1992 
1993 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_title_recv) {
1994 		mprx.ctrlr.cbs->track_title_recv(&mprx.local_player, 0, title);
1995 	} else {
1996 		LOG_DBG("No ctrlr track title callback");
1997 	}
1998 }
1999 
media_proxy_pl_track_duration_cb(int32_t duration)2000 void media_proxy_pl_track_duration_cb(int32_t duration)
2001 {
2002 	mprx.sctrlr.cbs->track_duration(duration);
2003 
2004 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_duration_recv) {
2005 		mprx.ctrlr.cbs->track_duration_recv(&mprx.local_player, 0, duration);
2006 	} else {
2007 		LOG_DBG("No ctrlr track duration callback");
2008 	}
2009 }
2010 
media_proxy_pl_track_position_cb(int32_t position)2011 void media_proxy_pl_track_position_cb(int32_t position)
2012 {
2013 	mprx.sctrlr.cbs->track_position(position);
2014 
2015 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->track_position_recv) {
2016 		mprx.ctrlr.cbs->track_position_recv(&mprx.local_player, 0, position);
2017 	} else {
2018 		LOG_DBG("No ctrlr track position callback");
2019 	}
2020 }
2021 
media_proxy_pl_playback_speed_cb(int8_t speed)2022 void media_proxy_pl_playback_speed_cb(int8_t speed)
2023 {
2024 	mprx.sctrlr.cbs->playback_speed(speed);
2025 
2026 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playback_speed_recv) {
2027 		mprx.ctrlr.cbs->playback_speed_recv(&mprx.local_player, 0, speed);
2028 	} else {
2029 		LOG_DBG("No ctrlr playback speed callback");
2030 	}
2031 }
2032 
media_proxy_pl_seeking_speed_cb(int8_t speed)2033 void media_proxy_pl_seeking_speed_cb(int8_t speed)
2034 {
2035 	mprx.sctrlr.cbs->seeking_speed(speed);
2036 
2037 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->seeking_speed_recv) {
2038 		mprx.ctrlr.cbs->seeking_speed_recv(&mprx.local_player, 0, speed);
2039 	} else {
2040 		LOG_DBG("No ctrlr seeking speed callback");
2041 	}
2042 }
2043 
2044 #ifdef CONFIG_BT_MPL_OBJECTS
media_proxy_pl_current_track_id_cb(uint64_t id)2045 void media_proxy_pl_current_track_id_cb(uint64_t id)
2046 {
2047 	mprx.sctrlr.cbs->current_track_id(id);
2048 
2049 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_track_id_recv) {
2050 		mprx.ctrlr.cbs->current_track_id_recv(&mprx.local_player, 0, id);
2051 	} else {
2052 		LOG_DBG("No ctrlr current track id callback");
2053 	}
2054 }
2055 
media_proxy_pl_next_track_id_cb(uint64_t id)2056 void media_proxy_pl_next_track_id_cb(uint64_t id)
2057 {
2058 	mprx.sctrlr.cbs->next_track_id(id);
2059 
2060 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->next_track_id_recv) {
2061 		mprx.ctrlr.cbs->next_track_id_recv(&mprx.local_player, 0, id);
2062 	} else {
2063 		LOG_DBG("No ctrlr next track id callback");
2064 	}
2065 }
2066 
media_proxy_pl_parent_group_id_cb(uint64_t id)2067 void media_proxy_pl_parent_group_id_cb(uint64_t id)
2068 {
2069 	mprx.sctrlr.cbs->parent_group_id(id);
2070 
2071 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->parent_group_id_recv) {
2072 		mprx.ctrlr.cbs->parent_group_id_recv(&mprx.local_player, 0, id);
2073 	} else {
2074 		LOG_DBG("No ctrlr parent group id callback");
2075 	}
2076 }
2077 
media_proxy_pl_current_group_id_cb(uint64_t id)2078 void media_proxy_pl_current_group_id_cb(uint64_t id)
2079 {
2080 	mprx.sctrlr.cbs->current_group_id(id);
2081 
2082 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->current_group_id_recv) {
2083 		mprx.ctrlr.cbs->current_group_id_recv(&mprx.local_player, 0, id);
2084 	} else {
2085 		LOG_DBG("No ctrlr current group id callback");
2086 	}
2087 }
2088 #endif /* CONFIG_BT_MPL_OBJECTS */
2089 
media_proxy_pl_playing_order_cb(uint8_t order)2090 void media_proxy_pl_playing_order_cb(uint8_t order)
2091 {
2092 	mprx.sctrlr.cbs->playing_order(order);
2093 
2094 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->playing_order_recv) {
2095 		mprx.ctrlr.cbs->playing_order_recv(&mprx.local_player, 0, order);
2096 	} else {
2097 		LOG_DBG("No ctrlr playing order callback");
2098 	}
2099 }
2100 
media_proxy_pl_media_state_cb(uint8_t state)2101 void media_proxy_pl_media_state_cb(uint8_t state)
2102 {
2103 	mprx.sctrlr.cbs->media_state(state);
2104 
2105 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->media_state_recv) {
2106 		mprx.ctrlr.cbs->media_state_recv(&mprx.local_player, 0, state);
2107 	} else {
2108 		LOG_DBG("No ctrlr media state callback");
2109 	}
2110 }
2111 
media_proxy_pl_command_cb(const struct mpl_cmd_ntf * cmd_ntf)2112 void media_proxy_pl_command_cb(const struct mpl_cmd_ntf *cmd_ntf)
2113 {
2114 	CHECKIF(cmd_ntf == NULL) {
2115 		LOG_WRN("cmd_ntf is NULL");
2116 		return;
2117 	}
2118 
2119 	mprx.sctrlr.cbs->command(cmd_ntf);
2120 
2121 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->command_recv) {
2122 		mprx.ctrlr.cbs->command_recv(&mprx.local_player, 0, cmd_ntf);
2123 	} else {
2124 		LOG_DBG("No ctrlr command callback");
2125 	}
2126 }
2127 
media_proxy_pl_commands_supported_cb(uint32_t opcodes)2128 void media_proxy_pl_commands_supported_cb(uint32_t opcodes)
2129 {
2130 	mprx.sctrlr.cbs->commands_supported(opcodes);
2131 
2132 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->commands_supported_recv) {
2133 		mprx.ctrlr.cbs->commands_supported_recv(&mprx.local_player, 0, opcodes);
2134 	} else {
2135 		LOG_DBG("No ctrlr commands supported callback");
2136 	}
2137 }
2138 
2139 #ifdef CONFIG_BT_MPL_OBJECTS
media_proxy_pl_search_cb(uint8_t result_code)2140 void media_proxy_pl_search_cb(uint8_t result_code)
2141 {
2142 	mprx.sctrlr.cbs->search(result_code);
2143 
2144 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_recv) {
2145 		mprx.ctrlr.cbs->search_recv(&mprx.local_player, 0, result_code);
2146 	} else {
2147 		LOG_DBG("No ctrlr search callback");
2148 	}
2149 }
2150 
media_proxy_pl_search_results_id_cb(uint64_t id)2151 void media_proxy_pl_search_results_id_cb(uint64_t id)
2152 {
2153 	mprx.sctrlr.cbs->search_results_id(id);
2154 
2155 	if (mprx.ctrlr.cbs && mprx.ctrlr.cbs->search_results_id_recv) {
2156 		mprx.ctrlr.cbs->search_results_id_recv(&mprx.local_player, 0, id);
2157 	} else {
2158 		LOG_DBG("No ctrlr search results id callback");
2159 	}
2160 }
2161 #endif /* CONFIG_BT_MPL_OBJECTS */
2162 #endif /* CONFIG_MCTL_LOCAL_PLAYER_CONTROL */
2163