From d216f52dbca1b470df851c9bf60afd430532330c Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Sat, 18 Jan 2025 12:16:51 +0100 Subject: [PATCH 1/4] set_avrc_passthru_command_callback --- src/BluetoothA2DPCommon.cpp | 4 ++-- src/BluetoothA2DPSource.cpp | 47 +++++++++++++++++++++++-------------- src/BluetoothA2DPSource.h | 8 +++++++ 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/BluetoothA2DPCommon.cpp b/src/BluetoothA2DPCommon.cpp index 058d828..72df0a7 100644 --- a/src/BluetoothA2DPCommon.cpp +++ b/src/BluetoothA2DPCommon.cpp @@ -418,13 +418,13 @@ unsigned long BluetoothA2DPCommon::get_millis() { void ccall_app_rc_tg_callback(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) { - ESP_LOGI(BT_AV_TAG, "%s", __func__); + ESP_LOGD(BT_AV_TAG, "%s", __func__); if (actual_bluetooth_a2dp_common) actual_bluetooth_a2dp_common->app_rc_tg_callback(event, param); } void ccall_av_hdl_avrc_tg_evt(uint16_t event, void *param) { - ESP_LOGI(BT_AV_TAG, "%s", __func__); + ESP_LOGD(BT_AV_TAG, "%s", __func__); if (actual_bluetooth_a2dp_common) actual_bluetooth_a2dp_common->av_hdl_avrc_tg_evt(event, param); } diff --git a/src/BluetoothA2DPSource.cpp b/src/BluetoothA2DPSource.cpp index 88b7964..0cb1ca5 100644 --- a/src/BluetoothA2DPSource.cpp +++ b/src/BluetoothA2DPSource.cpp @@ -590,22 +590,22 @@ void BluetoothA2DPSource::bt_av_hdl_stack_evt(uint16_t event, void *p_param) { esp_avrc_ct_init(); esp_avrc_ct_register_callback(ccall_bt_app_rc_ct_cb); -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) /* initialize AVRCP target */ - if (esp_avrc_tg_init() == ESP_OK) { + if (is_passthru_active){ + esp_avrc_tg_init(); esp_avrc_tg_register_callback(ccall_app_rc_tg_callback); - // add request to ESP_AVRC_RN_VOLUME_CHANGE - esp_avrc_rn_evt_cap_mask_t evt_set = {0}; - for (auto event : avrc_rn_events) { - esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, - &evt_set, - event); - if (esp_avrc_tg_set_rn_evt_cap(&evt_set) != ESP_OK) { - ESP_LOGE(BT_AV_TAG, "esp_avrc_tg_set_rn_evt_cap failed: %d", event); - } - } - } else { - ESP_LOGE(BT_AV_TAG, "esp_avrc_tg_init failed"); + } + + // add request to ESP_AVRC_RN_VOLUME_CHANGE + esp_avrc_rn_evt_cap_mask_t evt_set = {0}; + for (auto event : avrc_rn_events) { + esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, + &evt_set, + event); + } + if (esp_avrc_tg_set_rn_evt_cap(&evt_set) != ESP_OK) { + ESP_LOGE(BT_AV_TAG, "esp_avrc_tg_set_rn_evt_cap failed"); } #endif @@ -979,6 +979,8 @@ void BluetoothA2DPSource::bt_av_volume_changed(void) { ESP_AVRC_RN_VOLUME_CHANGE)) { esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, ESP_AVRC_RN_VOLUME_CHANGE, 0); + }else { + ESP_LOGW(BT_RC_CT_TAG, "Unhandled event"); } } @@ -1146,7 +1148,7 @@ void BluetoothA2DPSource::set_reset_ble(bool doInit) { reset_ble = doInit; } void BluetoothA2DPSource::app_rc_tg_callback(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) { - ESP_LOGI(BT_AV_TAG, "%s", __func__); + ESP_LOGD(BT_AV_TAG, "%s", __func__); switch (event) { case ESP_AVRC_TG_CONNECTION_STATE_EVT: case ESP_AVRC_TG_REMOTE_FEATURES_EVT: @@ -1154,12 +1156,12 @@ void BluetoothA2DPSource::app_rc_tg_callback(esp_avrc_tg_cb_event_t event, case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT: { - bt_app_work_dispatch(ccall_bt_app_av_sm_hdlr, event, param, + bt_app_work_dispatch(ccall_av_hdl_avrc_tg_evt, event, param, sizeof(esp_a2d_cb_param_t), NULL); break; } default: - ESP_LOGE(BT_AV_TAG, "Unsupported AVRC event: %d", event); + ESP_LOGE(BT_AV_TAG, "Unsupported AVRC TG event: %d", event); break; } } @@ -1172,12 +1174,20 @@ void BluetoothA2DPSource::av_hdl_avrc_tg_evt(uint16_t event, void *p_param) { case ESP_AVRC_TG_CONNECTION_STATE_EVT: { ESP_LOGI(BT_AV_TAG, "AVRC conn_state evt: state %d, [%s]", rc->conn_stat.connected, to_str(rc->conn_stat.remote_bda)); + if (rc->conn_stat.connected){ + esp_avrc_psth_bit_mask_t psth_set = {0}; + esp_avrc_tg_get_psth_cmd_filter(ESP_AVRC_PSTH_FILTER_ALLOWED_CMD, &psth_set); + if (!esp_avrc_tg_set_psth_cmd_filter(ESP_AVRC_PSTH_FILTER_SUPPORTED_CMD, &psth_set)!=ESP_OK){ + ESP_LOGE(BT_AV_TAG,"esp_avrc_tg_set_psth_cmd_filter"); + } + ESP_LOGI(BT_AV_TAG, "Set passthru capabilities: 0x%0x", psth_set); + } break; } - case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { ESP_LOGI(BT_AV_TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); + if (passthru_command_callback) passthru_command_callback(rc->psth_cmd.key_code, rc->psth_cmd.key_state); break; } @@ -1191,6 +1201,7 @@ void BluetoothA2DPSource::av_hdl_avrc_tg_evt(uint16_t event, void *p_param) { ESP_LOGI(BT_AV_TAG, "AVRC register event notification: %d, param: 0x%x", rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { + ESP_LOGW(BT_AV_TAG, "ESP_AVRC_RN_VOLUME_CHANGE"); //s_volume_notify = true; // esp_avrc_rn_param_t rn_param; // rn_param.volume = s_volume; diff --git a/src/BluetoothA2DPSource.h b/src/BluetoothA2DPSource.h index b61ac04..db1d42a 100644 --- a/src/BluetoothA2DPSource.h +++ b/src/BluetoothA2DPSource.h @@ -203,6 +203,12 @@ class BluetoothA2DPSource : public BluetoothA2DPCommon { this->valid_cod_services = filter; } + /// Define the handler fur button presses on the remote bluetooth speaker + virtual void set_avrc_passthru_command_callback(void (*cb)(uint8_t key, bool isReleased)){ + passthru_command_callback = cb; + is_passthru_active = (cb != nullptr); + } + protected: music_data_channels_cb_t data_stream_channels_callback; const char *dev_name = "ESP32_A2DP_SRC"; @@ -238,6 +244,8 @@ class BluetoothA2DPSource : public BluetoothA2DPCommon { bool(*ssid_callback)(const char*ssid, esp_bd_addr_t address, int rrsi) = nullptr; void(*discovery_mode_callback)(esp_bt_gap_discovery_state_t discoveryMode) = nullptr; + void(*passthru_command_callback)(uint8_t, bool) = nullptr; + bool is_passthru_active = false; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; From 8cc5d624adb0b25a1dff78e59b5773a6cd0cae3c Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Sat, 18 Jan 2025 12:20:53 +0100 Subject: [PATCH 2/4] example semder_avrc --- .../bt_music_sender_avrc.ino | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 examples/bt_music_sender_avrc/bt_music_sender_avrc.ino diff --git a/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino b/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino new file mode 100644 index 0000000..090b846 --- /dev/null +++ b/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino @@ -0,0 +1,54 @@ +/* + Streaming of sound data with Bluetooth to other Bluetooth device. + We generate 2 tones which will be sent to the 2 channels. + + Copyright (C) 2020 Phil Schatzmann + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +// Example that demonstrates how to handle button presses on a bluetooth speaker + +#include "BluetoothA2DPSource.h" + +BluetoothA2DPSource a2dp_source; + +// The supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded +// from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data +int32_t get_data_channels(Frame *frame, int32_t channel_len) { + // fill the channel silence data + for (int sample = 0; sample < channel_len; ++sample) { + frame[sample].channel1 = 0; + frame[sample].channel2 = 0; + } + return channel_len; +} + +// gets called when button on bluetooth speaker is pressed +void button_handler(uint8_t id, bool isReleased){ + if (isReleased) { + Serial.print("button id "); + Serial.print(id); + Serial.println(" released"); + } +} + +void setup() { + Serial.begin(115200); + + a2dp_source.set_avrc_passthru_command_callback(button_handler); + a2dp_source.start("My vision", get_data_channels); +} + + +void loop() { + delay(1000); +} \ No newline at end of file From e149e4d4f96f46572d1dea369e6c3a1f37f4d675 Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Sat, 18 Jan 2025 12:26:15 +0100 Subject: [PATCH 3/4] exampole sender_avrc --- examples/bt_music_sender_avrc/bt_music_sender_avrc.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino b/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino index 090b846..3fcd5a8 100644 --- a/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino +++ b/examples/bt_music_sender_avrc/bt_music_sender_avrc.ino @@ -1,6 +1,5 @@ /* - Streaming of sound data with Bluetooth to other Bluetooth device. - We generate 2 tones which will be sent to the 2 channels. + Example that demonstrates how to handle button presses on a bluetooth speaker. Copyright (C) 2020 Phil Schatzmann This program is free software: you can redistribute it and/or modify @@ -15,8 +14,6 @@ along with this program. If not, see . */ -// Example that demonstrates how to handle button presses on a bluetooth speaker - #include "BluetoothA2DPSource.h" BluetoothA2DPSource a2dp_source; From d0d23c492bb9fe5cd2f85535e5e880f80e7c480d Mon Sep 17 00:00:00 2001 From: pschatzmann Date: Sat, 18 Jan 2025 12:27:17 +0100 Subject: [PATCH 4/4] doxygen --- docs/html/_bluetooth_a2_d_p_common_8h.html | 20 +- .../_bluetooth_a2_d_p_common_8h_source.html | 555 ++++++----- .../_bluetooth_a2_d_p_sink_8h_source.html | 917 +++++++++--------- ...luetooth_a2_d_p_sink_queued_8h_source.html | 2 +- .../_bluetooth_a2_d_p_source_8h_source.html | 261 ++--- ...class_bluetooth_a2_d_p_common-members.html | 110 ++- docs/html/class_bluetooth_a2_d_p_common.html | 24 + .../class_bluetooth_a2_d_p_sink-members.html | 369 ++++--- docs/html/class_bluetooth_a2_d_p_sink.html | 29 +- ..._bluetooth_a2_d_p_sink_queued-members.html | 395 ++++---- .../class_bluetooth_a2_d_p_sink_queued.html | 22 +- ...class_bluetooth_a2_d_p_source-members.html | 315 +++--- docs/html/class_bluetooth_a2_d_p_source.html | 23 + docs/html/functions.html | 8 +- docs/html/functions_func.html | 10 +- docs/html/functions_rela.html | 2 +- docs/html/index.html | 8 +- docs/html/search/all_10.js | 2 +- docs/html/search/all_11.js | 6 +- docs/html/search/all_12.js | 4 +- docs/html/search/all_13.js | 6 +- docs/html/search/all_2.js | 2 +- docs/html/search/all_e.js | 102 +- docs/html/search/all_f.js | 6 +- docs/html/search/classes_0.js | 10 +- docs/html/search/classes_1.js | 20 +- docs/html/search/classes_2.js | 4 +- docs/html/search/classes_3.js | 2 +- docs/html/search/classes_4.js | 2 +- docs/html/search/enums_0.js | 2 +- docs/html/search/enums_1.js | 2 +- docs/html/search/enums_2.js | 12 +- docs/html/search/enums_3.js | 2 +- docs/html/search/enumvalues_0.js | 2 +- docs/html/search/enumvalues_1.js | 42 +- docs/html/search/enumvalues_2.js | 2 +- docs/html/search/enumvalues_3.js | 2 +- docs/html/search/files_0.js | 4 +- docs/html/search/functions_0.js | 4 +- docs/html/search/functions_1.js | 20 +- docs/html/search/functions_10.js | 2 +- docs/html/search/functions_11.js | 6 +- docs/html/search/functions_12.js | 4 +- docs/html/search/functions_13.js | 6 +- docs/html/search/functions_2.js | 6 +- docs/html/search/functions_3.js | 8 +- docs/html/search/functions_4.js | 2 +- docs/html/search/functions_5.js | 2 +- docs/html/search/functions_6.js | 28 +- docs/html/search/functions_7.js | 2 +- docs/html/search/functions_8.js | 18 +- docs/html/search/functions_9.js | 2 +- docs/html/search/functions_a.js | 2 +- docs/html/search/functions_b.js | 4 +- docs/html/search/functions_c.js | 8 +- docs/html/search/functions_d.js | 6 +- docs/html/search/functions_e.js | 110 +-- docs/html/search/functions_f.js | 6 +- docs/html/search/groups_0.js | 2 +- docs/html/search/pages_0.js | 2 +- docs/html/search/related_0.js | 20 +- docs/html/search/typedefs_0.js | 2 +- docs/html/search/typedefs_1.js | 2 +- docs/html/search/variables_0.js | 2 +- docs/html/search/variables_1.js | 4 +- docs/html/search/variables_2.js | 2 +- docs/html/search/variables_3.js | 2 +- 67 files changed, 1853 insertions(+), 1737 deletions(-) diff --git a/docs/html/_bluetooth_a2_d_p_common_8h.html b/docs/html/_bluetooth_a2_d_p_common_8h.html index 4ac0f78..300cbf7 100644 --- a/docs/html/_bluetooth_a2_d_p_common_8h.html +++ b/docs/html/_bluetooth_a2_d_p_common_8h.html @@ -69,7 +69,9 @@ Classes | Macros | Typedefs | -Enumerations +Enumerations | +Functions | +Variables
BluetoothA2DPCommon.h File Reference
@@ -83,6 +85,7 @@ #include <stdbool.h>
#include <string.h>
#include <math.h>
+#include <vector>
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "freertos/FreeRTOSConfig.h"
@@ -160,6 +163,21 @@ }  Buetooth A2DP Reconnect Status.
  + + + + + + +

+Functions

+void ccall_app_rc_tg_callback (esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param)
 
+void ccall_av_hdl_avrc_tg_evt (uint16_t event, void *p_param)
 
+ + +

+Variables

+BluetoothA2DPCommonactual_bluetooth_a2dp_common
 

Detailed Description

Author
Phil Schatzmann
diff --git a/docs/html/_bluetooth_a2_d_p_common_8h_source.html b/docs/html/_bluetooth_a2_d_p_common_8h_source.html index dfa938e..26b2313 100644 --- a/docs/html/_bluetooth_a2_d_p_common_8h_source.html +++ b/docs/html/_bluetooth_a2_d_p_common_8h_source.html @@ -103,276 +103,301 @@
40 #include <stdbool.h>
41 #include <string.h>
42 #include <math.h>
-
43 #include "freertos/FreeRTOS.h" // needed for ESP Arduino < 2.0
-
44 #include "freertos/timers.h"
-
45 #include "freertos/FreeRTOSConfig.h"
-
46 #include "freertos/queue.h"
-
47 #include "freertos/task.h"
-
48 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2 , 0)
-
49 # include "freertos/xtensa_api.h"
-
50 #else
-
51 # include "xtensa_api.h"
-
52 #endif
-
53 #include "esp_bt.h"
-
54 #include "esp_bt_main.h"
-
55 #include "esp_bt_device.h"
-
56 #include "esp_gap_bt_api.h"
-
57 #include "esp_a2dp_api.h"
-
58 #include "esp_avrc_api.h"
-
59 #include "esp_spp_api.h"
-
60 #include "nvs.h"
-
61 #include "nvs_flash.h"
-
62 #include "SoundData.h"
-
63 #include "A2DPVolumeControl.h"
-
64 #include "esp_task_wdt.h"
-
65 #include "esp_timer.h"
-
66 
-
67 #ifdef ARDUINO_ARCH_ESP32
-
68 #include "esp32-hal-log.h"
-
69 #include "esp32-hal-bt.h"
-
70 #else
-
71 #include "esp_log.h"
-
72 
-
73 #endif
-
74 
-
75 #if !defined(ESP_IDF_VERSION)
-
76 # error Unsupported ESP32 Version: Upgrade the ESP32 version in the Board Manager
-
77 #endif
-
78 
-
79 // Support for old and new IDF version
-
80 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 0 , 0) && !defined(I2S_COMM_FORMAT_STAND_I2S)
-
81 // support for old idf releases
-
82 # define I2S_COMM_FORMAT_STAND_I2S (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB)
-
83 # define I2S_COMM_FORMAT_STAND_MSB (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB)
-
84 # define I2S_COMM_FORMAT_STAND_PCM_LONG (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG)
-
85 # define I2S_COMM_FORMAT_STAND_PCM_SHORT (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT)
-
86 #endif
-
87 
-
88 // Prior IDF 5 support
-
89 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0 , 0)
-
90 # define TaskHandle_t xTaskHandle
-
91 # define QueueHandle_t xQueueHandle
-
92 # define TickType_t portTickType
-
93 #endif
-
94 
-
95 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
-
96 # define esp_bt_gap_set_device_name esp_bt_dev_set_device_name
-
97 #endif
-
98 
-
99 #define A2DP_DEPRECATED __attribute__((deprecated))
-
100 
-
104 typedef void (* app_callback_t) (uint16_t event, void *param);
-
105 
-
107 typedef struct {
-
108  uint16_t sig;
-
109  uint16_t event;
- -
111  void *param;
-
112 } bt_app_msg_t;
-
113 
+
43 #include <vector>
+
44 #include "freertos/FreeRTOS.h" // needed for ESP Arduino < 2.0
+
45 #include "freertos/timers.h"
+
46 #include "freertos/FreeRTOSConfig.h"
+
47 #include "freertos/queue.h"
+
48 #include "freertos/task.h"
+
49 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2 , 0)
+
50 # include "freertos/xtensa_api.h"
+
51 #else
+
52 # include "xtensa_api.h"
+
53 #endif
+
54 #include "esp_bt.h"
+
55 #include "esp_bt_main.h"
+
56 #include "esp_bt_device.h"
+
57 #include "esp_gap_bt_api.h"
+
58 #include "esp_a2dp_api.h"
+
59 #include "esp_avrc_api.h"
+
60 #include "esp_spp_api.h"
+
61 #include "nvs.h"
+
62 #include "nvs_flash.h"
+
63 #include "SoundData.h"
+
64 #include "A2DPVolumeControl.h"
+
65 #include "esp_task_wdt.h"
+
66 #include "esp_timer.h"
+
67 
+
68 #ifdef ARDUINO_ARCH_ESP32
+
69 #include "esp32-hal-log.h"
+
70 #include "esp32-hal-bt.h"
+
71 #else
+
72 #include "esp_log.h"
+
73 
+
74 #endif
+
75 
+
76 #if !defined(ESP_IDF_VERSION)
+
77 # error Unsupported ESP32 Version: Upgrade the ESP32 version in the Board Manager
+
78 #endif
+
79 
+
80 // Support for old and new IDF version
+
81 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 0 , 0) && !defined(I2S_COMM_FORMAT_STAND_I2S)
+
82 // support for old idf releases
+
83 # define I2S_COMM_FORMAT_STAND_I2S (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB)
+
84 # define I2S_COMM_FORMAT_STAND_MSB (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB)
+
85 # define I2S_COMM_FORMAT_STAND_PCM_LONG (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG)
+
86 # define I2S_COMM_FORMAT_STAND_PCM_SHORT (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT)
+
87 #endif
+
88 
+
89 // Prior IDF 5 support
+
90 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0 , 0)
+
91 # define TaskHandle_t xTaskHandle
+
92 # define QueueHandle_t xQueueHandle
+
93 # define TickType_t portTickType
+
94 #endif
+
95 
+
96 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
+
97 # define esp_bt_gap_set_device_name esp_bt_dev_set_device_name
+
98 #endif
+
99 
+
100 #define A2DP_DEPRECATED __attribute__((deprecated))
+
101 
+
105 typedef void (* app_callback_t) (uint16_t event, void *param);
+
106 
+
108 typedef struct {
+
109  uint16_t sig;
+
110  uint16_t event;
+ +
112  void *param;
+
113 } bt_app_msg_t;
114 
-
115 #define BT_AV_TAG "BT_AV"
-
116 #define BT_RC_CT_TAG "RCCT"
-
117 #define BT_APP_TAG "BT_API"
-
118 
-
119 /* AVRCP used transaction labels */
-
120 #define APP_RC_CT_TL_GET_CAPS (0)
-
121 #define APP_RC_CT_TL_GET_META_DATA (1)
-
122 #define APP_RC_CT_TL_RN_TRACK_CHANGE (2)
-
123 #define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3)
-
124 #define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4)
-
125 
-
130 enum ReconnectStatus { NoReconnect, AutoReconnect, IsReconnecting};
-
131 
- -
138  public:
-
140  virtual ~BluetoothA2DPCommon() = default;
-
141 
-
143  void set_auto_reconnect(bool active);
-
144 
-
146  virtual void disconnect();
+
115 
+
116 #define BT_AV_TAG "BT_AV"
+
117 #define BT_RC_CT_TAG "RCCT"
+
118 #define BT_APP_TAG "BT_API"
+
119 
+
120 /* AVRCP used transaction labels */
+
121 #define APP_RC_CT_TL_GET_CAPS (0)
+
122 #define APP_RC_CT_TL_GET_META_DATA (1)
+
123 #define APP_RC_CT_TL_RN_TRACK_CHANGE (2)
+
124 #define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3)
+
125 #define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4)
+
126 
+
127 
+
128 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
+
129 extern "C" void ccall_app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
+
130  esp_avrc_tg_cb_param_t *param);
+
131 extern "C" void ccall_av_hdl_avrc_tg_evt(uint16_t event, void *p_param);
+
132 #endif
+
133 
+
138 enum ReconnectStatus { NoReconnect, AutoReconnect, IsReconnecting};
+
139 
+ +
146 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
147 
-
149  virtual bool reconnect();
-
150 
-
152  virtual bool connect_to(esp_bd_addr_t peer);
+
149  friend void ccall_app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
+
150  esp_avrc_tg_cb_param_t *param);
+
151  /* avrc TG event handler */
+
152  friend void ccall_av_hdl_avrc_tg_evt(uint16_t event, void *p_param);
153 
-
155  virtual void set_connected(bool active);
-
156 
-
158  virtual void end(bool releaseMemory=false);
-
159 
-
161  virtual bool is_connected() { return connection_state == ESP_A2D_CONNECTION_STATE_CONNECTED;}
+
154 #endif
+
155 
+
156  public:
+
158  virtual ~BluetoothA2DPCommon() = default;
+
159 
+
161  void set_auto_reconnect(bool active);
162 
-
164  virtual void set_volume(uint8_t volume){
-
165  volume_value = std::min((int)volume, 0x7F);
-
166  ESP_LOGI(BT_AV_TAG, "set_volume: %d", volume_value);
-
167  volume_control()->set_volume(volume_value);
-
168  volume_control()->set_enabled(true);
-
169  is_volume_used = true;
-
170  }
-
171 
-
173  virtual int get_volume(){
-
174  return is_volume_used ? volume_value : 0;
-
175  }
-
176 
- -
179  volume_control_ptr = ptr;
-
180  }
-
181 
-
183  virtual esp_a2d_audio_state_t get_audio_state();
-
184 
-
186  virtual esp_a2d_connection_state_t get_connection_state();
-
187 
-
190  virtual void set_on_connection_state_changed(void (*callBack)(esp_a2d_connection_state_t state, void *), void *obj=nullptr);
-
191 
-
194  virtual void set_on_audio_state_changed_post(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
-
195 
-
197  virtual void set_on_audio_state_changed(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
-
198 
-
200  virtual void debounce(void(*cb)(void),int ms);
-
201 
-
203  void log_free_heap();
-
204 
-
206  const char* to_str(esp_a2d_connection_state_t state);
-
207 
-
209  const char* to_str(esp_a2d_audio_state_t state);
-
210 
-
212  const char* to_str(esp_bd_addr_t bda);
+
164  virtual void disconnect();
+
165 
+
167  virtual bool reconnect();
+
168 
+
170  virtual bool connect_to(esp_bd_addr_t peer);
+
171 
+
173  virtual void set_connected(bool active);
+
174 
+
176  virtual void end(bool releaseMemory=false);
+
177 
+
179  virtual bool is_connected() { return connection_state == ESP_A2D_CONNECTION_STATE_CONNECTED;}
+
180 
+
182  virtual void set_volume(uint8_t volume){
+
183  volume_value = std::min((int)volume, 0x7F);
+
184  ESP_LOGI(BT_AV_TAG, "set_volume: %d", volume_value);
+
185  volume_control()->set_volume(volume_value);
+
186  volume_control()->set_enabled(true);
+
187  is_volume_used = true;
+
188  }
+
189 
+
191  virtual int get_volume(){
+
192  return is_volume_used ? volume_value : 0;
+
193  }
+
194 
+ +
197  volume_control_ptr = ptr;
+
198  }
+
199 
+
201  virtual esp_a2d_audio_state_t get_audio_state();
+
202 
+
204  virtual esp_a2d_connection_state_t get_connection_state();
+
205 
+
208  virtual void set_on_connection_state_changed(void (*callBack)(esp_a2d_connection_state_t state, void *), void *obj=nullptr);
+
209 
+
212  virtual void set_on_audio_state_changed_post(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
213 
-
214 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
-
216  const char* to_str(esp_avrc_playback_stat_t state);
-
217 #endif
-
218 
-
220  void set_task_priority(UBaseType_t priority){
-
221  task_priority = priority;
-
222  }
-
223 
-
224 
-
226  void set_task_core(BaseType_t core){
-
227  task_core = core;
-
228  }
-
229 
-
231  void set_event_queue_size(int size){
-
232  event_queue_size = size;
-
233  }
-
234 
-
236  void set_event_stack_size(int size){
-
237  event_stack_size = size;
-
238  }
-
239 
- -
242  return &last_connection;
-
243  }
-
244 
-
245 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
-
247  virtual void set_discoverability(esp_bt_discovery_mode_t d);
-
248 #endif
-
249 
-
251  virtual void set_connectable(bool connectable) {
-
252  set_scan_mode_connectable(connectable);
-
253  }
-
254 
-
256  virtual const char* get_name() {
-
257  return bt_name;
-
258  }
-
259 
-
261  virtual void clean_last_connection();
+
215  virtual void set_on_audio_state_changed(void (*callBack)(esp_a2d_audio_state_t state, void*), void* obj=nullptr);
+
216 
+
218  virtual void debounce(void(*cb)(void),int ms);
+
219 
+
221  void log_free_heap();
+
222 
+
224  const char* to_str(esp_a2d_connection_state_t state);
+
225 
+
227  const char* to_str(esp_a2d_audio_state_t state);
+
228 
+
230  const char* to_str(esp_bd_addr_t bda);
+
231 
+
232 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
+
234  const char* to_str(esp_avrc_playback_stat_t state);
+
235 #endif
+
236 
+
238  void set_task_priority(UBaseType_t priority){
+
239  task_priority = priority;
+
240  }
+
241 
+
242 
+
244  void set_task_core(BaseType_t core){
+
245  task_core = core;
+
246  }
+
247 
+
249  void set_event_queue_size(int size){
+
250  event_queue_size = size;
+
251  }
+
252 
+
254  void set_event_stack_size(int size){
+
255  event_stack_size = size;
+
256  }
+
257 
+ +
260  return &last_connection;
+
261  }
262 
-
264  virtual void set_default_bt_mode(esp_bt_mode_t mode){
-
265  bt_mode = mode;
-
266  }
+
263 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
+
265  virtual void set_discoverability(esp_bt_discovery_mode_t d);
+
266 #endif
267 
-
268 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2 , 1)
-
270  void set_bluedroid_config_t(esp_bluedroid_config_t cfg){
-
271  bluedroid_config = cfg;
-
272  }
-
273 #endif
-
275  void delay_ms(uint32_t millis);
-
277  unsigned long get_millis();
-
278 
-
279  protected:
-
280  const char* bt_name = {0};
-
281  esp_bd_addr_t peer_bd_addr;
-
282  ReconnectStatus reconnect_status = NoReconnect;
-
283  unsigned long reconnect_timout=0;
-
284  unsigned int default_reconnect_timout=10000;
-
285  bool is_autoreconnect_allowed = false;
-
286  uint32_t debounce_ms = 0;
-
287  A2DPDefaultVolumeControl default_volume_control;
-
288  A2DPVolumeControl *volume_control_ptr = nullptr;
-
289  esp_bd_addr_t last_connection = {0,0,0,0,0,0};
-
290  bool is_start_disabled = false;
-
291  bool is_target_status_active = true;
-
292  void (*connection_state_callback)(esp_a2d_connection_state_t state, void* obj) = nullptr;
-
293  void (*audio_state_callback)(esp_a2d_audio_state_t state, void* obj) = nullptr;
-
294  void (*audio_state_callback_post)(esp_a2d_audio_state_t state, void* obj) = nullptr;
-
295  void *connection_state_obj = nullptr;
-
296  void *audio_state_obj = nullptr;
-
297  void *audio_state_obj_post = nullptr;
-
298  const char *m_a2d_conn_state_str[4] = {"Disconnected", "Connecting", "Connected", "Disconnecting"};
-
299  const char *m_a2d_audio_state_str[3] = {"Suspended", "Stopped", "Started"};
-
300  const char *m_avrc_playback_state_str[5] = {"stopped", "playing", "paused", "forward seek", "reverse seek"};
- - -
303  UBaseType_t task_priority = configMAX_PRIORITIES - 10;
-
304  // volume
-
305  uint8_t volume_value = 0;
-
306  bool is_volume_used = false;
-
307  BaseType_t task_core = 1;
-
308 
-
309  int event_queue_size = 20;
-
310  int event_stack_size = 3072;
- -
312 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
- -
314 #endif
-
315 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1)
-
316  esp_bluedroid_config_t bluedroid_config {
-
317  .ssp_en = true
-
318  };
-
319 #endif
-
320 
-
321  virtual esp_err_t esp_a2d_connect(esp_bd_addr_t peer) = 0;
-
322  virtual const char* last_bda_nvs_name() = 0;
-
323  virtual void get_last_connection();
-
324  virtual void set_last_connection(esp_bd_addr_t bda);
-
325  virtual bool has_last_connection();
-
326  virtual bool read_address(const char* name, esp_bd_addr_t& bda);
-
327  virtual bool write_address(const char* name, esp_bd_addr_t bda);
-
328 
-
329  // change the scan mode
-
330  virtual void set_scan_mode_connectable(bool connectable);
-
331  virtual void set_scan_mode_connectable_default() = 0;
-
332 
- -
335  return volume_control_ptr !=nullptr ? volume_control_ptr : &default_volume_control;
-
336  }
-
337 
-
338  virtual bool bt_start();
-
339  virtual esp_err_t bluedroid_init();
-
340  virtual esp_err_t esp_a2d_disconnect(esp_bd_addr_t remote_bda) = 0;
-
341 
-
342 };
-
343 
-
void(* app_callback_t)(uint16_t event, void *param)
handler for the dispatched work
Definition: BluetoothA2DPCommon.h:104
+
269  virtual void set_connectable(bool connectable) {
+
270  set_scan_mode_connectable(connectable);
+
271  }
+
272 
+
274  virtual const char* get_name() {
+
275  return bt_name;
+
276  }
+
277 
+
279  virtual void clean_last_connection();
+
280 
+
282  virtual void set_default_bt_mode(esp_bt_mode_t mode){
+
283  bt_mode = mode;
+
284  }
+
285 
+
286 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2 , 1)
+
288  void set_bluedroid_config_t(esp_bluedroid_config_t cfg){
+
289  bluedroid_config = cfg;
+
290  }
+
291 #endif
+
293  void delay_ms(uint32_t millis);
+
295  unsigned long get_millis();
+
296 
+
298  virtual void set_avrc_rn_events(std::vector<esp_avrc_rn_event_ids_t> events) {avrc_rn_events = events;}
+
299 
+
300  protected:
+
301  const char* bt_name = {0};
+
302  esp_bd_addr_t peer_bd_addr;
+
303  ReconnectStatus reconnect_status = NoReconnect;
+
304  unsigned long reconnect_timout=0;
+
305  unsigned int default_reconnect_timout=10000;
+
306  bool is_autoreconnect_allowed = false;
+
307  uint32_t debounce_ms = 0;
+
308  A2DPDefaultVolumeControl default_volume_control;
+
309  A2DPVolumeControl *volume_control_ptr = nullptr;
+
310  esp_bd_addr_t last_connection = {0,0,0,0,0,0};
+
311  bool is_start_disabled = false;
+
312  bool is_target_status_active = true;
+
313  void (*connection_state_callback)(esp_a2d_connection_state_t state, void* obj) = nullptr;
+
314  void (*audio_state_callback)(esp_a2d_audio_state_t state, void* obj) = nullptr;
+
315  void (*audio_state_callback_post)(esp_a2d_audio_state_t state, void* obj) = nullptr;
+
316  void *connection_state_obj = nullptr;
+
317  void *audio_state_obj = nullptr;
+
318  void *audio_state_obj_post = nullptr;
+
319  const char *m_a2d_conn_state_str[4] = {"Disconnected", "Connecting", "Connected", "Disconnecting"};
+
320  const char *m_a2d_audio_state_str[3] = {"Suspended", "Stopped", "Started"};
+
321  const char *m_avrc_playback_state_str[5] = {"stopped", "playing", "paused", "forward seek", "reverse seek"};
+ + +
324  UBaseType_t task_priority = configMAX_PRIORITIES - 10;
+
325  // volume
+
326  uint8_t volume_value = 0;
+
327  bool is_volume_used = false;
+
328  BaseType_t task_core = 1;
+
329 
+
330  int event_queue_size = 20;
+
331  int event_stack_size = 3072;
+ +
333  std::vector<esp_avrc_rn_event_ids_t> avrc_rn_events = {ESP_AVRC_RN_VOLUME_CHANGE };
+
334 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
+ +
336  virtual void app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
+
337  esp_avrc_tg_cb_param_t *param) = 0;
+
338  virtual void av_hdl_avrc_tg_evt(uint16_t event, void *p_param) = 0;
+
339 #endif
+
340 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 1)
+
341  esp_bluedroid_config_t bluedroid_config {
+
342  .ssp_en = true
+
343  };
+
344 #endif
+
345 
+
346  virtual esp_err_t esp_a2d_connect(esp_bd_addr_t peer) = 0;
+
347  virtual const char* last_bda_nvs_name() = 0;
+
348  virtual void get_last_connection();
+
349  virtual void set_last_connection(esp_bd_addr_t bda);
+
350  virtual bool has_last_connection();
+
351  virtual bool read_address(const char* name, esp_bd_addr_t& bda);
+
352  virtual bool write_address(const char* name, esp_bd_addr_t bda);
+
353 
+
354  // change the scan mode
+
355  virtual void set_scan_mode_connectable(bool connectable);
+
356  virtual void set_scan_mode_connectable_default() = 0;
+
357 
+ +
360  return volume_control_ptr !=nullptr ? volume_control_ptr : &default_volume_control;
+
361  }
+
362 
+
363  virtual bool bt_start();
+
364  virtual esp_err_t bluedroid_init();
+
365  virtual esp_err_t esp_a2d_disconnect(esp_bd_addr_t remote_bda) = 0;
+
366 
+
367 };
+
368 
+
369 extern BluetoothA2DPCommon* actual_bluetooth_a2dp_common;
+
void(* app_callback_t)(uint16_t event, void *param)
handler for the dispatched work
Definition: BluetoothA2DPCommon.h:105
Default implementation for handling of the volume of the audio data.
Definition: A2DPVolumeControl.h:88
Abstract class for handling of the volume of the audio data.
Definition: A2DPVolumeControl.h:28
-
Common Bluetooth A2DP functions.
Definition: BluetoothA2DPCommon.h:137
-
void set_event_stack_size(int size)
Defines the stack size of the event task (in bytes)
Definition: BluetoothA2DPCommon.h:236
-
virtual void set_volume(uint8_t volume)
Sets the volume (range 0 - 127)
Definition: BluetoothA2DPCommon.h:164
-
virtual int get_volume()
Determines the actual volume.
Definition: BluetoothA2DPCommon.h:173
-
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:270
-
virtual void set_default_bt_mode(esp_bt_mode_t mode)
Defines the default bt mode. The default is ESP_BT_MODE_CLASSIC_BT: use this e.g. to set to ESP_BT_MO...
Definition: BluetoothA2DPCommon.h:264
+
Common Bluetooth A2DP functions.
Definition: BluetoothA2DPCommon.h:145
+
void set_event_stack_size(int size)
Defines the stack size of the event task (in bytes)
Definition: BluetoothA2DPCommon.h:254
+
virtual void set_volume(uint8_t volume)
Sets the volume (range 0 - 127)
Definition: BluetoothA2DPCommon.h:182
+
virtual int get_volume()
Determines the actual volume.
Definition: BluetoothA2DPCommon.h:191
+
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:288
+
virtual void set_avrc_rn_events(std::vector< esp_avrc_rn_event_ids_t > events)
Define the vector of esp_avrc_rn_event_ids_t with e.g. ESP_AVRC_RN_PLAY_STATUS_CHANGE | ESP_AVRC_RN_T...
Definition: BluetoothA2DPCommon.h:298
+
virtual void set_default_bt_mode(esp_bt_mode_t mode)
Defines the default bt mode. The default is ESP_BT_MODE_CLASSIC_BT: use this e.g. to set to ESP_BT_MO...
Definition: BluetoothA2DPCommon.h:282
virtual ~BluetoothA2DPCommon()=default
Destructor.
-
virtual bool is_connected()
Checks if A2DP is connected.
Definition: BluetoothA2DPCommon.h:161
-
void set_task_priority(UBaseType_t priority)
defines the task priority (the default value is configMAX_PRIORITIES - 10)
Definition: BluetoothA2DPCommon.h:220
-
void set_task_core(BaseType_t core)
Defines the core which is used to start the tasks (to process the events and audio queue)
Definition: BluetoothA2DPCommon.h:226
-
virtual A2DPVolumeControl * volume_control()
provides access to the VolumeControl object
Definition: BluetoothA2DPCommon.h:334
-
virtual const char * get_name()
Provides the actual SSID name.
Definition: BluetoothA2DPCommon.h:256
-
virtual void set_volume_control(A2DPVolumeControl *ptr)
you can define a custom VolumeControl implementation
Definition: BluetoothA2DPCommon.h:178
-
virtual void set_connectable(bool connectable)
Bluetooth connectable.
Definition: BluetoothA2DPCommon.h:251
-
virtual esp_bd_addr_t * get_last_peer_address()
Provides the address of the last device.
Definition: BluetoothA2DPCommon.h:241
-
void set_event_queue_size(int size)
Defines the queue size of the event task.
Definition: BluetoothA2DPCommon.h:231
-
ReconnectStatus
Buetooth A2DP Reconnect Status.
Definition: BluetoothA2DPCommon.h:130
+
virtual bool is_connected()
Checks if A2DP is connected.
Definition: BluetoothA2DPCommon.h:179
+
void set_task_priority(UBaseType_t priority)
defines the task priority (the default value is configMAX_PRIORITIES - 10)
Definition: BluetoothA2DPCommon.h:238
+
void set_task_core(BaseType_t core)
Defines the core which is used to start the tasks (to process the events and audio queue)
Definition: BluetoothA2DPCommon.h:244
+
virtual A2DPVolumeControl * volume_control()
provides access to the VolumeControl object
Definition: BluetoothA2DPCommon.h:359
+
virtual const char * get_name()
Provides the actual SSID name.
Definition: BluetoothA2DPCommon.h:274
+
virtual void set_volume_control(A2DPVolumeControl *ptr)
you can define a custom VolumeControl implementation
Definition: BluetoothA2DPCommon.h:196
+
virtual void set_connectable(bool connectable)
Bluetooth connectable.
Definition: BluetoothA2DPCommon.h:269
+
virtual esp_bd_addr_t * get_last_peer_address()
Provides the address of the last device.
Definition: BluetoothA2DPCommon.h:259
+
void set_event_queue_size(int size)
Defines the queue size of the event task.
Definition: BluetoothA2DPCommon.h:249
+
ReconnectStatus
Buetooth A2DP Reconnect Status.
Definition: BluetoothA2DPCommon.h:138
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
@@ -384,11 +409,11 @@
@ 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:107
-
uint16_t sig
Definition: BluetoothA2DPCommon.h:108
-
app_callback_t cb
Definition: BluetoothA2DPCommon.h:110
-
uint16_t event
Definition: BluetoothA2DPCommon.h:109
-
void * param
Definition: BluetoothA2DPCommon.h:111
+
Internal message to be sent for BluetoothA2DPSink and BluetoothA2DPSource.
Definition: BluetoothA2DPCommon.h:108
+
uint16_t sig
Definition: BluetoothA2DPCommon.h:109
+
app_callback_t cb
Definition: BluetoothA2DPCommon.h:111
+
uint16_t event
Definition: BluetoothA2DPCommon.h:110
+
void * param
Definition: BluetoothA2DPCommon.h:112