27#ifdef ARDUINO_ARCH_ESP32
28# include "sdkconfig.h"
30#if defined(CONFIG_IDF_TARGET_ESP32)
31# define IS_VALID_PLATFORM true
33# error "Please read the ESP32-A2DP Wiki about the supported Platforms!"
34# define IS_VALID_PLATFORM false
44using namespace esp_i2s;
57#include "esp_idf_version.h"
58#include "freertos/FreeRTOS.h"
59#include "freertos/FreeRTOSConfig.h"
60#include "freertos/queue.h"
61#include "freertos/task.h"
62#include "freertos/timers.h"
63#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0)
64#include "freertos/xtensa_api.h"
66#include "xtensa_api.h"
68#include "A2DPVolumeControl.h"
69#include "esp_a2dp_api.h"
70#include "esp_avrc_api.h"
72#include "esp_bt_device.h"
73#include "esp_bt_main.h"
74#include "esp_gap_bt_api.h"
75#include "esp_spp_api.h"
76#include "esp_task_wdt.h"
81#ifdef ARDUINO_ARCH_ESP32
82#include "esp32-hal-bt.h"
83#include "esp32-hal-log.h"
88#if !defined(ESP_IDF_VERSION)
89#error Unsupported ESP32 Version: Upgrade the ESP32 version in the Board Manager
93#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 0, 0) && \
94 !defined(I2S_COMM_FORMAT_STAND_I2S)
96#define I2S_COMM_FORMAT_STAND_I2S \
97 (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB)
98#define I2S_COMM_FORMAT_STAND_MSB \
99 (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB)
100#define I2S_COMM_FORMAT_STAND_PCM_LONG \
101 (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG)
102#define I2S_COMM_FORMAT_STAND_PCM_SHORT \
103 (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT)
107#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
108#define TaskHandle_t xTaskHandle
109#define QueueHandle_t xQueueHandle
110#define TickType_t portTickType
113#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
114#define esp_bt_gap_set_device_name esp_bt_dev_set_device_name
117#define A2DP_DEPRECATED __attribute__((deprecated))
119#define BT_APP_SIG_WORK_DISPATCH (0x01)
135#define BT_AV_TAG "BT_AV"
136#define BT_RC_CT_TAG "RCCT"
137#define BT_APP_TAG "BT_API"
140#define APP_RC_CT_TL_GET_CAPS (0)
141#define APP_RC_CT_TL_GET_META_DATA (1)
142#define APP_RC_CT_TL_RN_TRACK_CHANGE (2)
143#define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3)
144#define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4)
147extern "C" void ccall_bt_app_task_handler(
void *arg);
148extern "C" void ccall_app_gap_callback(esp_bt_gap_cb_event_t event,
149 esp_bt_gap_cb_param_t *param);
150extern "C" void ccall_app_rc_ct_callback(esp_avrc_ct_cb_event_t event,
151 esp_avrc_ct_cb_param_t *param);
152extern "C" void ccall_app_a2d_callback(esp_a2d_cb_event_t event,
153 esp_a2d_cb_param_t *param);
154extern "C" void ccall_av_hdl_stack_evt(uint16_t event,
void *p_param);
156#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
157extern "C" void ccall_app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
158 esp_avrc_tg_cb_param_t *param);
159extern "C" void ccall_av_hdl_avrc_tg_evt(uint16_t event,
void *p_param);
176 friend void ccall_app_gap_callback(esp_bt_gap_cb_event_t event,
177 esp_bt_gap_cb_param_t *param);
178 friend void ccall_app_rc_ct_callback(esp_avrc_ct_cb_event_t event,
179 esp_avrc_ct_cb_param_t *param);
180 friend void ccall_app_a2d_callback(esp_a2d_cb_event_t event,
181 esp_a2d_cb_param_t *param);
182 friend void ccall_av_hdl_stack_evt(uint16_t event,
void *p_param);
184#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
187 esp_avrc_tg_cb_param_t *param);
189 friend void ccall_av_hdl_avrc_tg_evt(uint16_t event,
void *p_param);
215 virtual void end(
bool releaseMemory =
false);
224 volume_value = std::min((
int)volume, 0x7F);
225 ESP_LOGI(BT_AV_TAG,
"set_volume: %d", volume_value);
228 is_volume_used =
true;
232 virtual int get_volume() {
return is_volume_used ? volume_value : 0; }
236 volume_control_ptr = ptr;
249 void *obj =
nullptr);
255 void *obj =
nullptr);
260 void *obj =
nullptr);
264 virtual void debounce(
void (*cb)(
void),
int ms);
279 const char *
to_str(esp_bt_gap_discovery_state_t state);
281#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
302#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
322#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1)
325 bluedroid_config = cfg;
342 avrc_rn_events = events;
346 const char *bt_name = {0};
349 unsigned long reconnect_timout = 0;
350 unsigned int default_reconnect_timout = 10000;
351 bool is_autoreconnect_allowed =
false;
352 uint32_t debounce_ms = 0;
356 bool is_start_disabled =
false;
357 bool is_target_status_active =
true;
359 void *obj) =
nullptr;
361 void *obj) =
nullptr;
363 void *obj) =
nullptr;
364 void *connection_state_obj =
nullptr;
365 void *audio_state_obj =
nullptr;
366 void *audio_state_obj_post =
nullptr;
367 const char *m_a2d_conn_state_str[4] = {
"Disconnected",
"Connecting",
368 "Connected",
"Disconnecting"};
369 const char *m_a2d_audio_state_str[4] = {
"Suspended",
"Started",
"Suspended",
"Suspended"};
370 const char *m_avrc_playback_state_str[5] = {
"stopped",
"playing",
"paused",
371 "forward seek",
"reverse seek"};
372 const char *m_esp_bt_gap_discovery_state_t[2] = {
"Stopped",
"Started"};
376 UBaseType_t task_priority = configMAX_PRIORITIES - 10;
378 uint8_t volume_value = 0;
379 bool is_volume_used =
false;
380 bool is_bluedroid_initialized =
false;
381 BaseType_t task_core = 1;
383 int event_queue_size = 20;
384 int event_stack_size = 3072;
386 std::vector<esp_avrc_rn_event_ids_t> avrc_rn_events = {
387 ESP_AVRC_RN_VOLUME_CHANGE};
389 QueueHandle_t app_task_queue =
nullptr;
390 TaskHandle_t app_task_handle =
nullptr;
392#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1)
393 esp_bluedroid_config_t bluedroid_config{.ssp_en =
true};
396 virtual void init_nvs();
398 virtual const char *last_bda_nvs_name() = 0;
399 virtual void get_last_connection();
401 virtual bool has_last_connection();
402 virtual bool read_address(
const char *name,
esp_bd_addr_t &bda);
403 virtual bool write_address(
const char *name,
esp_bd_addr_t bda);
407 virtual void set_scan_mode_connectable_default() = 0;
411 return volume_control_ptr !=
nullptr ? volume_control_ptr
412 : &default_volume_control;
416 virtual esp_err_t bluedroid_init();
417 virtual esp_err_t esp_a2d_disconnect(
esp_bd_addr_t remote_bda) = 0;
418 virtual void app_task_start_up();
419 virtual void app_task_shut_down();
421 virtual void app_task_handler(
void *arg);
423 virtual bool isSource() = 0;
425 virtual void app_gap_callback(esp_bt_gap_cb_event_t event,
426 esp_bt_gap_cb_param_t *param) = 0;
429 esp_avrc_ct_cb_param_t *param) = 0;
432 esp_a2d_cb_param_t *param) = 0;
434 virtual void av_hdl_stack_evt(uint16_t event,
void *p_param) = 0;
436#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
438 virtual void app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
439 esp_avrc_tg_cb_param_t *param) = 0;
440 virtual void av_hdl_avrc_tg_evt(uint16_t event,
void *p_param) = 0;
void(* app_callback_t)(uint16_t event, void *param)
handler for the dispatched work
Definition BluetoothA2DPCommon.h:124
Default implementation for handling of the volume of the audio data.
Definition A2DPVolumeControl.h:151
Abstract class for handling of the volume of the audio data.
Definition A2DPVolumeControl.h:54
virtual void set_volume(uint8_t volume)=0
Sets the volume level (pure virtual function)
void set_enabled(bool enabled)
Enables or disables volume control.
Definition A2DPVolumeControl.h:112
Common Bluetooth A2DP functions.
Definition BluetoothA2DPCommon.h:173
void set_event_stack_size(int size)
Defines the stack size of the event task (in bytes)
Definition BluetoothA2DPCommon.h:297
virtual void set_connected(bool active)
Calls disconnect or reconnect.
Definition BluetoothA2DPCommon.cpp:110
virtual void set_volume(uint8_t volume)
Sets the volume (range 0 - 127)
Definition BluetoothA2DPCommon.h:223
virtual int get_volume()
Determines the actual volume.
Definition BluetoothA2DPCommon.h:232
void set_bluedroid_config_t(esp_bluedroid_config_t cfg)
Defines the esp_bluedroid_config_t: Available from IDF 5.2.1.
Definition BluetoothA2DPCommon.h:324
virtual void set_on_audio_state_changed_post(void(*callBack)(esp_a2d_audio_state_t state, void *), void *obj=nullptr)
Definition BluetoothA2DPCommon.cpp:351
virtual void set_avrc_rn_events(std::vector< esp_avrc_rn_event_ids_t > events)
Definition BluetoothA2DPCommon.h:341
void delay_ms(uint32_t millis)
calls vTaskDelay to pause for the indicated number of milliseconds
Definition BluetoothA2DPCommon.cpp:586
const char * to_str(esp_a2d_connection_state_t state)
converts esp_a2d_connection_state_t to a string
Definition BluetoothA2DPCommon.cpp:373
virtual void set_default_bt_mode(esp_bt_mode_t mode)
Definition BluetoothA2DPCommon.h:320
virtual const char * get_name()
Provides the actual SSID name.
Definition BluetoothA2DPCommon.h:313
virtual ~BluetoothA2DPCommon()=default
Destructor.
virtual esp_a2d_connection_state_t get_connection_state()
Determine the connection state.
Definition BluetoothA2DPCommon.cpp:76
void set_auto_reconnect(bool active)
Definition BluetoothA2DPCommon.cpp:82
virtual bool is_connected()
Checks if A2DP is connected.
Definition BluetoothA2DPCommon.h:218
virtual void set_on_audio_state_changed(void(*callBack)(esp_a2d_audio_state_t state, void *), void *obj=nullptr)
Set the callback that is called when the audio state is changed.
Definition BluetoothA2DPCommon.cpp:343
unsigned long get_millis()
Provides the time in milliseconds since the last system boot.
Definition BluetoothA2DPCommon.cpp:595
void set_task_priority(UBaseType_t priority)
defines the task priority (the default value is configMAX_PRIORITIES - 10)
Definition BluetoothA2DPCommon.h:287
void set_task_core(BaseType_t core)
Definition BluetoothA2DPCommon.h:291
virtual void app_a2d_callback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)=0
callback function for A2DP source
friend void ccall_bt_app_task_handler(void *arg)
task handler
Definition BluetoothA2DPCommon.cpp:23
virtual esp_a2d_audio_state_t get_audio_state()
Determine the actual audio state.
Definition BluetoothA2DPCommon.cpp:72
virtual void end(bool releaseMemory=false)
Closes the connection and stops A2DP.
Definition BluetoothA2DPCommon.cpp:132
virtual void set_volume_control(A2DPVolumeControl *ptr)
you can define a custom VolumeControl implementation
Definition BluetoothA2DPCommon.h:235
virtual bool connect_to(esp_bd_addr_t peer)
Connnects to the indicated address.
Definition BluetoothA2DPCommon.cpp:99
void log_free_heap()
Logs the free heap.
Definition BluetoothA2DPCommon.cpp:368
BluetoothA2DPCommon()
Default constructor.
Definition BluetoothA2DPCommon.cpp:68
virtual void set_connectable(bool connectable)
Bluetooth connectable.
Definition BluetoothA2DPCommon.h:308
virtual bool bt_start()
Startup logic as implemented by Arduino.
Definition BluetoothA2DPCommon.cpp:401
virtual void set_discoverability(esp_bt_discovery_mode_t d)
Bluetooth discoverability.
Definition BluetoothA2DPCommon.cpp:543
virtual A2DPVolumeControl * volume_control()
provides access to the VolumeControl object
Definition BluetoothA2DPCommon.h:410
virtual void clean_last_connection()
clean last connection (delete)
Definition BluetoothA2DPCommon.cpp:284
virtual void debounce(void(*cb)(void), int ms)
Definition BluetoothA2DPCommon.cpp:359
virtual void set_on_connection_state_changed(void(*callBack)(esp_a2d_connection_state_t state, void *), void *obj=nullptr)
Set the callback that is called when the connection state is changed.
Definition BluetoothA2DPCommon.cpp:335
virtual void disconnect()
Closes the connection.
Definition BluetoothA2DPCommon.cpp:119
virtual void app_rc_ct_callback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)=0
callback function for AVRCP controller
virtual bool reconnect()
Reconnects to the last device.
Definition BluetoothA2DPCommon.cpp:87
friend void ccall_app_rc_tg_callback(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param)
handle esp_avrc_tg_cb_event_t
Definition BluetoothA2DPCommon.cpp:54
virtual esp_bd_addr_t * get_last_peer_address()
Provides the address of the last device.
Definition BluetoothA2DPCommon.h:300
void set_event_queue_size(int size)
Defines the queue size of the event task.
Definition BluetoothA2DPCommon.h:294
virtual void set_scan_mode_connectable(bool connectable)
Defines if the bluetooth is connectable.
Definition BluetoothA2DPCommon.cpp:552
ReconnectStatus
Buetooth A2DP Reconnect Status.
Definition BluetoothA2DPCommon.h:166
esp_a2d_audio_state_t
Buetooth A2DP datapath states.
Definition external_lists.h:5
esp_a2d_connection_state_t
Buetooth A2DP connection states.
Definition external_lists.h:16
esp_bt_discovery_mode_t
AVRCP discovery mode.
Definition external_lists.h:85
esp_avrc_playback_stat_t
AVRCP current status of playback.
Definition external_lists.h:72
esp_bt_mode_t
Bluetooth Controller mode.
Definition external_lists.h:96
uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]
Bluetooth address.
Definition external_lists.h:107
@ ESP_A2D_AUDIO_STATE_STOPPED
Definition external_lists.h:8
@ ESP_A2D_CONNECTION_STATE_CONNECTED
Definition external_lists.h:19
@ ESP_A2D_CONNECTION_STATE_DISCONNECTED
Definition external_lists.h:17
@ ESP_BT_GENERAL_DISCOVERABLE
Definition external_lists.h:88
@ ESP_BT_MODE_CLASSIC_BT
Definition external_lists.h:99
Internal message to be sent for BluetoothA2DPSink and BluetoothA2DPSource.
Definition BluetoothA2DPCommon.h:128
uint16_t sig
Definition BluetoothA2DPCommon.h:129
app_callback_t cb
Definition BluetoothA2DPCommon.h:131
uint16_t event
Definition BluetoothA2DPCommon.h:130
void * param
Definition BluetoothA2DPCommon.h:132