1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __ESP_A2DP_API_H__ 8 #define __ESP_A2DP_API_H__ 9 10 #include "esp_err.h" 11 #include "esp_bt_defs.h" 12 13 #ifdef __cplusplus 14 extern "C" { 15 #endif 16 17 /** 18 * @brief Media codec types supported by A2DP. 19 */ 20 #define ESP_A2D_MCT_SBC (0) /*!< SBC */ 21 #define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */ 22 #define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */ 23 #define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */ 24 #define ESP_A2D_MCT_NON_A2DP (0xff) /*!< NON-A2DP */ 25 typedef uint8_t esp_a2d_mct_t; 26 27 /** 28 * @brief Protocol service capabilities. This value is a mask. 29 */ 30 #define ESP_A2D_PSC_DELAY_RPT (1<<0) /*!< Delay Report */ 31 typedef uint16_t esp_a2d_psc_t; 32 33 /** 34 * @brief 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 /** 51 * @brief Bluetooth A2DP connection states 52 */ 53 typedef enum { 54 ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released */ 55 ESP_A2D_CONNECTION_STATE_CONNECTING, /*!< connecting remote device */ 56 ESP_A2D_CONNECTION_STATE_CONNECTED, /*!< connection established */ 57 ESP_A2D_CONNECTION_STATE_DISCONNECTING /*!< disconnecting remote device */ 58 } esp_a2d_connection_state_t; 59 60 /** 61 * @brief Bluetooth A2DP disconnection reason 62 */ 63 typedef enum { 64 ESP_A2D_DISC_RSN_NORMAL = 0, /*!< Finished disconnection that is initiated by local or remote device */ 65 ESP_A2D_DISC_RSN_ABNORMAL /*!< Abnormal disconnection caused by signal loss */ 66 } esp_a2d_disc_rsn_t; 67 68 /** 69 * @brief Bluetooth A2DP datapath states 70 */ 71 typedef enum { 72 ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */ 73 ESP_A2D_AUDIO_STATE_STOPPED, /*!< audio stream datapath stopped */ 74 ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */ 75 } esp_a2d_audio_state_t; 76 77 /** 78 * @brief A2DP media control command acknowledgement code 79 */ 80 typedef enum { 81 ESP_A2D_MEDIA_CTRL_ACK_SUCCESS = 0, /*!< media control command is acknowledged with success */ 82 ESP_A2D_MEDIA_CTRL_ACK_FAILURE, /*!< media control command is acknowledged with failure */ 83 ESP_A2D_MEDIA_CTRL_ACK_BUSY, /*!< media control command is rejected, as previous command is not yet acknowledged */ 84 } esp_a2d_media_ctrl_ack_t; 85 86 /** 87 * @brief A2DP media control commands 88 */ 89 typedef enum { 90 ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< Not for application use, use inside stack only. */ 91 ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */ 92 ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */ 93 ESP_A2D_MEDIA_CTRL_STOP, /*!< command to stop media transmission */ 94 ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */ 95 } esp_a2d_media_ctrl_t; 96 97 /** 98 * @brief Bluetooth A2DP Initiation states 99 */ 100 typedef enum { 101 ESP_A2D_DEINIT_SUCCESS = 0, /*!< A2DP profile deinit successful event */ 102 ESP_A2D_INIT_SUCCESS /*!< A2DP profile deinit successful event */ 103 } esp_a2d_init_state_t; 104 105 /** 106 * @brief Bluetooth A2DP set delay report value states 107 */ 108 typedef enum { 109 ESP_A2D_SET_SUCCESS = 0, /*!< A2DP profile set delay report value successful */ 110 ESP_A2D_SET_INVALID_PARAMS /*!< A2DP profile set delay report value is invalid parameter */ 111 } esp_a2d_set_delay_value_state_t; 112 113 /** 114 * @brief A2DP callback events 115 */ 116 typedef enum { 117 ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */ 118 ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */ 119 ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */ 120 ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */ 121 ESP_A2D_PROF_STATE_EVT, /*!< indicate a2dp init&deinit complete */ 122 ESP_A2D_SNK_PSC_CFG_EVT, /*!< protocol service capabilities configured,only used for A2DP SINK */ 123 ESP_A2D_SNK_SET_DELAY_VALUE_EVT, /*!< indicate a2dp sink set delay report value complete, only used for A2DP SINK */ 124 ESP_A2D_SNK_GET_DELAY_VALUE_EVT, /*!< indicate a2dp sink get delay report value complete, only used for A2DP SINK */ 125 ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT, /*!< report delay value, only used for A2DP SRC */ 126 } esp_a2d_cb_event_t; 127 128 /** 129 * @brief A2DP state callback parameters 130 */ 131 typedef union { 132 /** 133 * @brief ESP_A2D_CONNECTION_STATE_EVT 134 */ 135 struct a2d_conn_stat_param { 136 esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */ 137 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 138 esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */ 139 } conn_stat; /*!< A2DP connection status */ 140 141 /** 142 * @brief ESP_A2D_AUDIO_STATE_EVT 143 */ 144 struct a2d_audio_stat_param { 145 esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */ 146 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 147 } audio_stat; /*!< audio stream playing state */ 148 149 /** 150 * @brief ESP_A2D_AUDIO_CFG_EVT 151 */ 152 struct a2d_audio_cfg_param { 153 esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ 154 esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */ 155 } audio_cfg; /*!< media codec configuration information */ 156 157 /** 158 * @brief ESP_A2D_MEDIA_CTRL_ACK_EVT 159 */ 160 struct media_ctrl_stat_param { 161 esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */ 162 esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */ 163 } media_ctrl_stat; /*!< status in acknowledgement to media control commands */ 164 165 /** 166 * @brief ESP_A2D_PROF_STATE_EVT 167 */ 168 struct a2d_prof_stat_param { 169 esp_a2d_init_state_t init_state; /*!< a2dp profile state param */ 170 } a2d_prof_stat; /*!< status to indicate a2d prof init or deinit */ 171 172 /** 173 * @brief ESP_A2D_SNK_PSC_CFG_EVT 174 */ 175 struct a2d_psc_cfg_param { 176 esp_a2d_psc_t psc_mask; /*!< protocol service capabilities configured */ 177 } a2d_psc_cfg_stat; /*!< status to indicate protocol service capabilities configured */ 178 179 /** 180 * @brief ESP_A2D_SNK_SET_DELAY_VALUE_EVT 181 */ 182 struct a2d_set_stat_param { 183 esp_a2d_set_delay_value_state_t set_state; /*!< a2dp profile state param */ 184 uint16_t delay_value; /*!< delay report value */ 185 } a2d_set_delay_value_stat; /*!< A2DP sink set delay report value status */ 186 187 /** 188 * @brief ESP_A2D_SNK_GET_DELAY_VALUE_EVT 189 */ 190 struct a2d_get_stat_param { 191 uint16_t delay_value; /*!< delay report value */ 192 } a2d_get_delay_value_stat; /*!< A2DP sink get delay report value status */ 193 194 /** 195 * @brief ESP_A2D_REPORT_SNK_DELAY_VALUE_EVT 196 */ 197 struct a2d_report_delay_stat_param { 198 uint16_t delay_value; /*!< delay report value */ 199 } a2d_report_delay_value_stat; /*!< A2DP source received sink report value status */ 200 201 } esp_a2d_cb_param_t; 202 203 /** 204 * @brief A2DP profile callback function type 205 * 206 * @param event : Event type 207 * 208 * @param param : Pointer to callback parameter 209 */ 210 typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); 211 212 /** 213 * @brief A2DP sink data callback function 214 * 215 * @param[in] buf : pointer to the data received from A2DP source device and is PCM format decoded from SBC decoder; 216 * buf references to a static memory block and can be overwritten by upcoming data 217 * 218 * @param[in] len : size(in bytes) in buf 219 */ 220 typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len); 221 222 /** 223 * @brief A2DP source data read callback function 224 * 225 * @param[in] buf : buffer to be filled with PCM data stream from higher layer 226 * 227 * @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user 228 * that data buffer shall be flushed 229 * 230 * @return size of bytes read successfully, if the argument len is -1, this value is ignored. 231 * 232 */ 233 typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len); 234 235 /** 236 * @brief Register application callback function to A2DP module. This function should be called 237 * only after esp_bluedroid_enable() completes successfully, used by both A2DP source 238 * and sink. 239 * 240 * @param[in] callback: A2DP event callback function 241 * 242 * @return 243 * - ESP_OK: success 244 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 245 * - ESP_FAIL: if callback is a NULL function pointer 246 * 247 */ 248 esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback); 249 250 251 /** 252 * @brief Register A2DP sink data output function; For now the output is PCM data stream decoded 253 * from SBC format. This function should be called only after esp_bluedroid_enable() 254 * completes successfully, used only by A2DP sink. The callback is invoked in the context 255 * of A2DP sink task whose stack size is configurable through menuconfig. 256 * 257 * @param[in] callback: A2DP sink data callback function 258 * 259 * @return 260 * - ESP_OK: success 261 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 262 * - ESP_FAIL: if callback is a NULL function pointer 263 * 264 */ 265 esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback); 266 267 268 /** 269 * 270 * @brief Initialize the bluetooth A2DP sink module. This function should be called 271 * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT 272 * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. 273 * If you want to use AVRC together, you should initiate AVRC first. This 274 * function should be called after esp_bluedroid_enable() completes successfully. 275 * 276 * @return 277 * - ESP_OK: if the initialization request is sent successfully 278 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 279 * - ESP_FAIL: others 280 * 281 */ 282 esp_err_t esp_a2d_sink_init(void); 283 284 285 /** 286 * 287 * @brief De-initialize for A2DP sink module. This function 288 * should be called only after esp_bluedroid_enable() completes successfully, 289 * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. 290 * 291 * @return 292 * - ESP_OK: if the deinitialization request is sent successfully 293 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 294 * - ESP_FAIL: others 295 * 296 */ 297 esp_err_t esp_a2d_sink_deinit(void); 298 299 300 /** 301 * 302 * @brief Connect to remote bluetooth A2DP source device. This API must be called after 303 * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 304 * 305 * @param[in] remote_bda: remote bluetooth device address 306 * 307 * @return 308 * - ESP_OK: connect request is sent to lower layer successfully 309 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 310 * - ESP_FAIL: others 311 * 312 */ 313 esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda); 314 315 316 /** 317 * 318 * @brief Disconnect from the remote A2DP source device. This API must be called after 319 * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 320 * 321 * @param[in] remote_bda: remote bluetooth device address 322 * 323 * @return 324 * - ESP_OK: disconnect request is sent to lower layer successfully 325 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 326 * - ESP_FAIL: others 327 * 328 */ 329 esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda); 330 331 /** 332 * 333 * @brief Set delay reporting value. The delay value of sink is caused by buffering (including 334 * protocol stack and application layer), decoding and rendering. The default delay 335 * value is 120ms, if the set value is less than 120ms, the setting will fail. This API 336 * must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 337 * 338 * @param[in] delay_value: reporting value is in 1/10 millisecond 339 * 340 * @return 341 * - ESP_OK: delay value is sent to lower layer successfully 342 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 343 * - ESP_FAIL: others 344 * 345 */ 346 esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value); 347 348 /** 349 * 350 * @brief Get delay reporting value. This API must be called after 351 * esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 352 * 353 * @return 354 * - ESP_OK: if the request is sent successfully 355 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 356 * - ESP_FAIL: others 357 * 358 */ 359 esp_err_t esp_a2d_sink_get_delay_value(void); 360 361 362 /** 363 * 364 * @brief Media control commands. This API can be used for both A2DP sink and source 365 * and must be called after esp_a2d_sink_init() and before esp_a2d_sink_deinit(). 366 * 367 * @param[in] ctrl: control commands for A2DP data channel 368 * 369 * @return 370 * - ESP_OK: control command is sent to lower layer successfully 371 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 372 * - ESP_FAIL: others 373 * 374 */ 375 esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl); 376 377 378 /** 379 * 380 * @brief Initialize the bluetooth A2DP source module. A2DP can work independently. 381 * If you want to use AVRC together, you should initiate AVRC first. This function should be called 382 * after esp_bluedroid_enable() completes successfully, and ESP_A2D_PROF_STATE_EVT 383 * with ESP_A2D_INIT_SUCCESS will reported to the APP layer. Note: A2DP can work independently. 384 * If you want to use AVRC together, you should initiate AVRC first. 385 * 386 * @return 387 * - ESP_OK: if the initialization request is sent to lower layer successfully 388 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 389 * - ESP_FAIL: others 390 * 391 */ 392 esp_err_t esp_a2d_source_init(void); 393 394 395 /** 396 * 397 * @brief De-initialize for A2DP source module. This function 398 * should be called only after esp_bluedroid_enable() completes successfully, 399 * and ESP_A2D_PROF_STATE_EVT with ESP_A2D_DEINIT_SUCCESS will reported to APP layer. 400 * 401 * @return 402 * - ESP_OK: success 403 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 404 * - ESP_FAIL: others 405 * 406 */ 407 esp_err_t esp_a2d_source_deinit(void); 408 409 410 /** 411 * @brief Register A2DP source data input function. For now, the input shoule be PCM data stream. 412 * This function should be called only after esp_bluedroid_enable() completes 413 * successfully. The callback is invoked in the context of A2DP source task whose 414 * stack size is configurable through menuconfig. 415 * 416 * @param[in] callback: A2DP source data callback function 417 * 418 * @return 419 * - ESP_OK: success 420 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 421 * - ESP_FAIL: if callback is a NULL function pointer 422 * 423 */ 424 esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback); 425 426 427 /** 428 * 429 * @brief Connect to remote A2DP sink device. This API must be called 430 * after esp_a2d_source_init() and before esp_a2d_source_deinit(). 431 * 432 * @param[in] remote_bda: remote bluetooth device address 433 * 434 * @return 435 * - ESP_OK: connect request is sent to lower layer successfully 436 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 437 * - ESP_FAIL: others 438 * 439 */ 440 esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda); 441 442 443 /** 444 * 445 * @brief Disconnect from the remote A2DP sink device. This API must be called 446 * after esp_a2d_source_init() and before esp_a2d_source_deinit(). 447 * 448 * @param[in] remote_bda: remote bluetooth device address 449 * @return 450 * - ESP_OK: disconnect request is sent to lower layer 451 * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled 452 * - ESP_FAIL: others 453 * 454 */ 455 esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda); 456 457 #ifdef __cplusplus 458 } 459 #endif 460 461 462 #endif /* __ESP_A2DP_API_H__ */ 463