1 /**
2  * @file
3  * @brief Internal header for the media player (MPL).
4  *
5  * Copyright (c) 2019 - 2021 Nordic Semiconductor ASA
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #ifndef ZEPHYR_SUBSYS_BLUETOOTH_AUDIO_MPL_INTERNAL_
11 #define ZEPHYR_SUBSYS_BLUETOOTH_AUDIO_MPL_INTERNAL_
12 
13 #include <stdbool.h>
14 #include <stdint.h>
15 
16 #include <zephyr/autoconf.h>
17 #include <zephyr/bluetooth/audio/media_proxy.h>
18 #include <zephyr/kernel.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /* Offset into a segment/track before the "previous" command goes to start of */
25 /* current segment/track instead to previous */
26 #define PREV_MARGIN           500  /* 500 * 0.01 = 5 seconds */
27 
28 /* Increase/decrease in seeking sped factor for fast rewind/forward commands
29  * The media control specification has a requirement that the speed factor
30  * shall be [-64, -4], 0, [4, 64].  I.e., values between 0 and +/- 4 are not allowed.
31  * Set this equal to the minimum speed factor, to ensure only valid speed factors
32  * are used when changing to/from zero
33  */
34 #define MPL_SEEKING_SPEED_FACTOR_STEP  4
35 
36 
37 /* Track segments */
38 struct mpl_tseg {
39 	uint8_t            name_len;
40 	char		   name[CONFIG_BT_MPL_SEGMENT_NAME_MAX];
41 	int32_t            pos;
42 	struct mpl_tseg   *prev;
43 	struct mpl_tseg   *next;
44 };
45 
46 /* Tracks */
47 struct mpl_track {
48 #if defined(CONFIG_BT_MPL_OBJECTS) || defined(CONFIG_BT_OTS_CLIENT)
49 	uint64_t             id;
50 #endif /* CONFIG_BT_MPL_OBJECTS || CONFIG_BT_OTS_CLIENT */
51 	char                 title[CONFIG_BT_MPL_TRACK_TITLE_MAX];
52 	int32_t              duration;
53 	struct mpl_tseg     *segment;
54 #if defined(CONFIG_BT_MPL_OBJECTS) || defined(CONFIG_BT_OTS_CLIENT)
55 	uint64_t             segments_id;
56 #endif /* CONFIG_BT_MPL_OBJECTS || CONFIG_BT_OTS_CLIENT */
57 	struct mpl_track    *prev;
58 	struct mpl_track    *next;
59 };
60 
61 /* Groups */
62 struct mpl_group {
63 #if defined(CONFIG_BT_MPL_OBJECTS) || defined(CONFIG_BT_OTS_CLIENT)
64 	uint64_t             id;
65 #endif /* CONFIG_BT_MPL_OBJECTS || CONFIG_BT_OTS_CLIENT */
66 	char                 title[CONFIG_BT_MPL_GROUP_TITLE_MAX];
67 	struct mpl_track    *track;
68 	struct mpl_group    *parent;
69 	struct mpl_group    *prev;
70 	struct mpl_group    *next;
71 };
72 
73 /** @brief Media Player */
74 struct mpl_mediaplayer   {
75 	char                name[CONFIG_BT_MPL_MEDIA_PLAYER_NAME_MAX];
76 #if defined(CONFIG_BT_MPL_OBJECTS) || defined(CONFIG_BT_OTS_CLIENT)
77 	uint64_t            icon_id;
78 #endif /* CONFIG_BT_MPL_OBJECTS || CONFIG_BT_OTS_CLIENT */
79 	char                icon_url[CONFIG_BT_MPL_ICON_URL_MAX];
80 	struct mpl_group   *group;
81 	int32_t             track_pos;
82 	uint8_t             state;
83 	int8_t              playback_speed_param;
84 	int8_t              seeking_speed_factor;
85 	uint8_t             playing_order;
86 	uint16_t            playing_orders_supported;
87 	uint32_t            opcodes_supported;
88 #if defined(CONFIG_BT_MPL_OBJECTS) || defined(CONFIG_BT_OTS_CLIENT)
89 	uint64_t            search_results_id;
90 #endif /* CONFIG_BT_MPL_OBJECTS || CONFIG_BT_OTS_CLIENT */
91 	uint8_t             content_ctrl_id;
92 	struct media_proxy_pl_calls calls;
93 
94 	bool                        next_track_set; /* If next track explicitly set */
95 	struct {
96 		struct mpl_track    *track; /* The track explicitly set as next track */
97 		struct mpl_group    *group; /* The group of the set track */
98 	} next;
99 
100 	struct k_work_delayable pos_work;
101 };
102 
103 
104 /* Special calls for testing */
105 
106 /* For  IOP testing - set current group to be it's own parent */
107 void mpl_test_unset_parent_group(void);
108 
109 /* Force the media player into a given state */
110 void mpl_test_media_state_set(uint8_t state);
111 
112 /** Trigger player name changed callback */
113 void mpl_test_player_name_changed_cb(void);
114 
115 /** Trigger player name changed callback */
116 void mpl_test_player_icon_url_changed_cb(void);
117 
118 /* Trigger track changed callback */
119 void mpl_test_track_changed_cb(void);
120 
121 /* Trigger title changed callback */
122 void mpl_test_title_changed_cb(void);
123 
124 /* Trigger duration changed callback */
125 void mpl_test_duration_changed_cb(void);
126 
127 /* Trigger position changed callback */
128 void mpl_test_position_changed_cb(void);
129 
130 /* Trigger playback speed changed callback */
131 void mpl_test_playback_speed_changed_cb(void);
132 
133 /* Trigger seeking speed changed callback */
134 void mpl_test_seeking_speed_changed_cb(void);
135 
136 /* Trigger current track id changed callback */
137 void mpl_test_current_track_id_changed_cb(void);
138 
139 /* Trigger next track id changed callback */
140 void mpl_test_next_track_id_changed_cb(void);
141 
142 /* Trigger current group id changed callback */
143 void mpl_test_current_group_id_changed_cb(void);
144 
145 /* Trigger parent group id changed callback */
146 void mpl_test_parent_group_id_changed_cb(void);
147 
148 /* Trigger playing order changed callback */
149 void mpl_test_playing_order_changed_cb(void);
150 
151 /* Trigger media state changed callback */
152 void mpl_test_media_state_changed_cb(void);
153 
154 /* Trigger operations supported changed callback */
155 void mpl_test_opcodes_supported_changed_cb(void);
156 
157 /* Trigger search results changed callback */
158 void mpl_test_search_results_changed_cb(void);
159 
160 /* Output the mediaplayer's state information */
161 void mpl_debug_dump_state(void);
162 
163 #ifdef __cplusplus
164 }
165 #endif
166 
167 #endif /* ZEPHYR_SUBSYS_BLUETOOTH_AUDIO_MPL_INTERNAL_*/
168