1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef __ESP_A2DP_API_H__ 16 #define __ESP_A2DP_API_H__ 17 18 #include "esp_err.h" 19 #include "esp_bt_defs.h" 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /// Media codec types supported by A2DP 26 #define ESP_A2D_MCT_SBC (0) /*!< SBC */ 27 #define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */ 28 #define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */ 29 #define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */ 30 #define ESP_A2D_MCT_NON_A2DP (0xff) 31 32 typedef uint8_t esp_a2d_mct_t; 33 34 /** A2DP media codec capabilities union 35 */ 36 typedef struct { 37 esp_a2d_mct_t type; /*!< A2DP media codec type */ 38 #define ESP_A2D_CIE_LEN_SBC (4) 39 #define ESP_A2D_CIE_LEN_M12 (4) 40 #define ESP_A2D_CIE_LEN_M24 (6) 41 #define ESP_A2D_CIE_LEN_ATRAC (7) 42 union { 43 uint8_t sbc[ESP_A2D_CIE_LEN_SBC]; /*!< SBC codec capabilities */ 44 uint8_t m12[ESP_A2D_CIE_LEN_M12]; /*!< MPEG-1,2 audio codec capabilities */ 45 uint8_t m24[ESP_A2D_CIE_LEN_M24]; /*!< MPEG-2, 4 AAC audio codec capabilities */ 46 uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC]; /*!< ATRAC family codec capabilities */ 47 } cie; /*!< A2DP codec information element */ 48 } __attribute__((packed)) esp_a2d_mcc_t; 49 50 /// Bluetooth A2DP connection states 51 typedef enum { 52 ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released */ 53 ESP_A2D_CONNECTION_STATE_CONNECTING, /*!< connecting remote device */ 54 ESP_A2D_CONNECTION_STATE_CONNECTED, /*!< connection established */ 55 ESP_A2D_CONNECTION_STATE_DISCONNECTING /*!< disconnecting remote device */ 56 } esp_a2d_connection_state_t; 57 58 /// Bluetooth A2DP disconnection reason 59 typedef enum { 60 ESP_A2D_DISC_RSN_NORMAL = 0, /*!< Finished disconnection that is initiated by local or remote device */ 61 ESP_A2D_DISC_RSN_ABNORMAL /*!< Abnormal disconnection caused by signal loss */ 62 } esp_a2d_disc_rsn_t; 63 64 /// Bluetooth A2DP datapath states 65 typedef enum { 66 ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */ 67 ESP_A2D_AUDIO_STATE_STOPPED, /*!< audio stream datapath stopped */ 68 ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */ 69 } esp_a2d_audio_state_t; 70 71 /// A2DP media control command acknowledgement code 72 typedef enum { 73 ESP_A2D_MEDIA_CTRL_ACK_SUCCESS = 0, /*!< media control command is acknowledged with success */ 74 ESP_A2D_MEDIA_CTRL_ACK_FAILURE, /*!< media control command is acknowledged with failure */ 75 ESP_A2D_MEDIA_CTRL_ACK_BUSY, /*!< media control command is rejected, as previous command is not yet acknowledged */ 76 } esp_a2d_media_ctrl_ack_t; 77 78 /// A2DP media control commands 79 typedef enum { 80 ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< Not for application use, use inside stack only. */ 81 ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */ 82 ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */ 83 ESP_A2D_MEDIA_CTRL_STOP, /*!< command to stop media transmission */ 84 ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */ 85 } esp_a2d_media_ctrl_t; 86 87 /// Bluetooth A2DP Initiation states 88 typedef enum { 89 ESP_A2D_DEINIT_SUCCESS = 0, /*!< A2DP profile deinit successful event */ 90 ESP_A2D_INIT_SUCCESS /*!< A2DP profile deinit successful event */ 91 } esp_a2d_init_state_t; 92 93 /// A2DP callback events 94 typedef enum { 95 ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ 96 ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */ 97 ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */ 98 ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */ 99 ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */ 100 } esp_a2d_cb_event_t; 101 102 /// A2DP state callback parameters 103 typedef union { 104 /** 105 * @brief ESP_A2D_CONNECTION_STATE_EVT 106 */ 107 struct a2d_conn_stat_param { 108 esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */ 109 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 110 esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */ 111 } conn_stat; /*!< A2DP connection status */ 112 113 /** 114 * @brief ESP_A2D_AUDIO_STATE_EVT 115 */ 116 struct a2d_audio_stat_param { 117 esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */ 118 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 119 } audio_stat; /*!< audio stream playing state */ 120 121 /** 122 * @brief ESP_A2D_AUDIO_CFG_EVT 123 */ 124 struct a2d_audio_cfg_param { 125 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 126 esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */ 127 } audio_cfg; /*!< media codec configuration information */ 128 129 /** 130 * @brief ESP_A2D_MEDIA_CTRL_ACK_EVT 131 */ 132 struct media_ctrl_stat_param { 133 esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */ 134 esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */ 135 } media_ctrl_stat; /*!< status in acknowledgement to media control commands */ 136 /** 137 * @brief ESP_A2D_PROF_STATE_EVT 138 */ 139 struct a2d_prof_stat_param { 140 esp_a2d_init_state_t init_state; /*!< a2dp profile state param */ 141 } a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */ 142 } esp_a2d_cb_param_t; 143 144 /** 145 * @brief A2DP profile callback function type 146 * 147 * @param event : Event type 148 * 149 * @param param : Pointer to callback parameter 150 */ 151 typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); 152 153 /** 154 * @brief A2DP sink data callback function 155 * 156 * @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder; 157 * buf references to a static memory block and can be overwritten by upcoming data 158 * 159 * @param[in] len : size(in bytes) in buf 160 */ 161 typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len); 162 163 /** 164 * @brief A2DP source data read callback function 165 * 166 * @param[in] buf : buffer to be filled with PCM data stream from higher layer 167 * 168 * @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user 169 * that data buffer shall be flushed 170 * 171 * @return size of bytes read successfully, if the argument len is -1, this value is ignored. 172 * 173 */ 174 typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len); 175 176 /** 177 * @brief Register application callback function to A2DP module. This function should be called 178 * only after esp_bluedroid_enable() completes successfully, used by both A2DP source 179 * and sink. 180 * 181 * @param[in] callback: A2DP event callback function 182 * 183 * @return 184 * - ESP_OK: success 185 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 186 * - ESP_FAIL: if callback is a NULL function pointer 187 * 188 */ 189 esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback); 190 191 192 /** 193 * @brief Register A2DP sink data output function; For now the output is PCM data stream decoded 194 * from SBC format. This function should be called only after esp_bluedroid_enable() 195 * completes successfully, used only by A2DP sink. The callback is invoked in the context 196 * of A2DP sink task whose stack size is configurable through menuconfig. 197 * 198 * @param[in] callback: A2DP sink data callback function 199 * 200 * @return 201 * - ESP_OK: success 202 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 203 * - ESP_FAIL: if callback is a NULL function pointer 204 * 205 */ 206 esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback); 207 208 209 /** 210 * 211 * @brief Initialize the bluetooth A2DP sink module. This function should be called 212 * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT 213 * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. 214 * If you want to use AVRC together, you should initiate AVRC first. This 215 * function should be called after esp_bluedroid_enable() completes successfully. 216 * 217 * @return 218 * - ESP_OK: if the initialization request is sent successfully 219 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 220 * - ESP_FAIL: others 221 * 222 */ 223 esp_err_t esp_a2d_sink_init(void); 224 225 226 /** 227 * 228 * @brief De-initialize for A2DP sink module. This function 229 * should be called only after esp_bluedroid_enable() completes successfully, 230 * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. 231 * 232 * @return 233 * - ESP_OK: if the deinitialization request is sent successfully 234 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 235 * - ESP_FAIL: others 236 * 237 */ 238 esp_err_t esp_a2d_sink_deinit(void); 239 240 241 /** 242 * 243 * @brief Connect to remote bluetooth A2DP source device. This API must be called after 244 * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 245 * 246 * @param[in] remote_bda: remote bluetooth device address 247 * 248 * @return 249 * - ESP_OK: connect request is sent to lower layer successfully 250 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 251 * - ESP_FAIL: others 252 * 253 */ 254 esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda); 255 256 257 /** 258 * 259 * @brief Disconnect from the remote A2DP source device. This API must be called after 260 * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 261 * 262 * @param[in] remote_bda: remote bluetooth device address 263 * 264 * @return 265 * - ESP_OK: disconnect request is sent to lower layer successfully 266 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 267 * - ESP_FAIL: others 268 * 269 */ 270 esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda); 271 272 273 /** 274 * 275 * @brief Media control commands. This API can be used for both A2DP sink and source 276 * and must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 277 * 278 * @param[in] ctrl: control commands for A2DP data channel 279 * 280 * @return 281 * - ESP_OK: control command is sent to lower layer successfully 282 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 283 * - ESP_FAIL: others 284 * 285 */ 286 esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl); 287 288 289 /** 290 * 291 * @brief Initialize the bluetooth A2DP source module. A2DP can work independently. 292 * If you want to use AVRC together, you should initiate AVRC first. This function should be called 293 * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT 294 * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. 295 * If you want to use AVRC together, you should initiate AVRC first. 296 * 297 * @return 298 * - ESP_OK: if the initialization request is sent to lower layer successfully 299 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 300 * - ESP_FAIL: others 301 * 302 */ 303 esp_err_t esp_a2d_source_init(void); 304 305 306 /** 307 * 308 * @brief De-initialize for A2DP source module. This function 309 * should be called only after esp_bluedroid_enable() completes successfully, 310 * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. 311 * 312 * @return 313 * - ESP_OK: success 314 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 315 * - ESP_FAIL: others 316 * 317 */ 318 esp_err_t esp_a2d_source_deinit(void); 319 320 321 /** 322 * @brief Register A2DP source data input function. For now, the input shoule be PCM data stream. 323 * This function should be called only after esp_bluedroid_enable() completes 324 * successfully. The callback is invoked in the context of A2DP source task whose 325 * stack size is configurable through menuconfig. 326 * 327 * @param[in] callback: A2DP source data callback function 328 * 329 * @return 330 * - ESP_OK: success 331 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 332 * - ESP_FAIL: if callback is a NULL function pointer 333 * 334 */ 335 esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback); 336 337 338 /** 339 * 340 * @brief Connect to remote A2DP sink device. This API must be called 341 * after esp_a2d_source_init() and before esp_a2d_source_deinit(). 342 * 343 * @param[in] remote_bda: remote bluetooth device address 344 * 345 * @return 346 * - ESP_OK: connect request is sent to lower layer successfully 347 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 348 * - ESP_FAIL: others 349 * 350 */ 351 esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda); 352 353 354 /** 355 * 356 * @brief Disconnect from the remote A2DP sink device. This API must be called 357 * after esp_a2d_source_init() and before esp_a2d_source_deinit(). 358 * 359 * @param[in] remote_bda: remote bluetooth device address 360 * @return 361 * - ESP_OK: disconnect request is sent to lower layer 362 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 363 * - ESP_FAIL: others 364 * 365 */ 366 esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda); 367 368 #ifdef __cplusplus 369 } 370 #endif 371 372 373 #endif /* __ESP_A2DP_API_H__ */ 374