Arduino A2DP
Loading...
Searching...
No Matches
BluetoothA2DPSource.h
1// C++ Class Implementation for a A2DP Source to be used as Arduino Library
2// The original ESP32 implementation can be found at
3// https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/bluedroid/classic_bt/a2dp_source
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16//
17// Copyright 2020 Phil Schatzmann
18// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
19
20#pragma once
21
22#include <vector>
23
24#include "BluetoothA2DPCommon.h"
25
26#if IS_VALID_PLATFORM
27
28#ifdef ARDUINO
29#include "Stream.h"
30#endif
31
32#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
33#define TIMER_ARG_TYPE void *
34#else
35#define TIMER_ARG_TYPE tmrTimerControl *
36#endif
37
38typedef int32_t (*music_data_cb_t)(uint8_t *data, int32_t len);
39typedef int32_t (*music_data_frames_cb_t)(Frame *data, int32_t len);
40typedef void (*bt_app_copy_cb_t)(bt_app_msg_t *msg, void *p_dest, void *p_src);
41typedef void (*bt_app_cb_t)(uint16_t event, void *param);
42
43extern "C" void ccall_a2d_app_heart_beat(TIMER_ARG_TYPE arg);
44extern "C" void ccall_bt_app_av_sm_hdlr(uint16_t event, void *param);
45extern "C" void ccall_bt_av_hdl_avrc_ct_evt(uint16_t event, void *param);
46extern "C" int32_t ccall_bt_app_a2d_data_cb(uint8_t *data, int32_t len);
47
53 APP_AV_STATE_IDLE,
54 APP_AV_STATE_DISCOVERING,
55 APP_AV_STATE_DISCOVERED,
56 APP_AV_STATE_UNCONNECTED,
57 APP_AV_STATE_CONNECTING,
58 APP_AV_STATE_CONNECTED,
59 APP_AV_STATE_DISCONNECTING,
60};
61
62static const char *APP_AV_STATE_STR[] = {
63 "IDLE", "DISCOVERING", "DISCOVERED", "UNCONNECTED",
64 "CONNECTING", "CONNECTED", "DISCONNECTING"};
65
74 friend void ccall_a2d_app_heart_beat(TIMER_ARG_TYPE arg);
75 friend void ccall_bt_app_av_sm_hdlr(uint16_t event, void *param);
76 friend void ccall_bt_av_hdl_avrc_ct_evt(uint16_t event, void *param);
77 friend int32_t ccall_bt_app_a2d_data_cb(uint8_t *data, int32_t len);
78
79 public:
82
85
87 virtual void set_ssp_enabled(bool active) { this->ssp_enabled = active; }
88
91 virtual void set_auto_reconnect(bool active) {
92 this->reconnect_status = active ? AutoReconnect : NoReconnect;
93 }
94
96 virtual void set_auto_reconnect(esp_bd_addr_t addr) {
98 memcpy(last_connection, addr, ESP_BD_ADDR_LEN);
99 }
100
102 virtual void set_local_name(const char *name) { dev_name = name; }
103
105 virtual void set_data_callback(int32_t(cb)(uint8_t *data, int32_t len)) {
106 get_data_cb = cb;
107 }
108
110 virtual void set_data_callback_in_frames(int32_t(cb)(Frame *data,
111 int32_t len)) {
112 get_data_in_frames_cb = cb;
113 }
114
115#ifdef ARDUINO
116
118 virtual void set_data_source(Stream &data) { p_stream = &data; }
120 virtual void set_data_source_callback(Stream &(*next_stream)()) {
121 get_next_stream_cb = next_stream;
122 }
123#endif
124
127 virtual void start() {
128 std::vector<const char *> names; // empty vector
129 start(names);
130 }
131
133 virtual void start(const char *name) {
134 std::vector<const char *> names = {name}; // empty vector
135 start(names);
136 }
137
139 virtual void start(std::vector<const char *> names);
140
142 virtual void start(const char *name, music_data_frames_cb_t callback) {
144 std::vector<const char *> names = {name};
145 start(names);
146 }
147
149 virtual void start(music_data_frames_cb_t callback) {
151 start();
152 }
153
155 virtual void start(std::vector<const char *> names,
156 music_data_frames_cb_t callback) {
158 start(names);
159 }
160
162 virtual void start_raw(const char *name, music_data_cb_t callback = nullptr) {
163 set_data_callback(callback);
164 start(name);
165 }
166
168 virtual void start_raw(std::vector<const char *> names,
169 music_data_cb_t callback = nullptr) {
170 set_data_callback(callback);
171 start(names);
172 }
173
175 virtual void start_raw(music_data_cb_t callback = nullptr) {
176 set_data_callback(callback);
177 start();
178 }
179
181 void set_pin_code(const char *pin_code, esp_bt_pin_type_t pin_type);
182
184 virtual void set_reset_ble(bool doInit);
185
187 virtual void set_ssid_callback(bool (*callback)(const char *ssid,
188 esp_bd_addr_t address,
189 int rrsi)) {
190 ssid_callback = callback;
191 }
192
195 void (*callback)(esp_bt_gap_discovery_state_t discoveryMode)) {
196 discovery_mode_callback = callback;
197 }
198
201 virtual bool is_discovery_active() { return discovery_active; }
202
206 virtual void set_valid_cod_service(uint16_t filter) {
207 this->valid_cod_services = filter;
208 }
209
211 virtual void set_avrc_passthru_command_callback(void (*cb)(uint8_t key,
212 bool isReleased)) {
213 passthru_command_callback = cb;
214 is_passthru_active = (cb != nullptr);
215 }
216
218 void end(bool releaseMemory=false) override;
219
220 protected:
222 int32_t (*get_data_cb)(uint8_t *data, int32_t len) = nullptr;
223 int32_t (*get_data_in_frames_cb)(Frame *data, int32_t len) = nullptr;
224#ifdef ARDUINO
225 Stream *p_stream = nullptr;
226 Stream &(*get_next_stream_cb)() = nullptr;
227#endif
228 const char *dev_name = "ESP32_A2DP_SRC";
229 bool ssp_enabled = false;
230 std::vector<const char *> bt_names;
231 esp_bt_pin_type_t pin_type;
232 esp_bt_pin_code_t pin_code;
233 uint32_t pin_code_len;
234 uint8_t s_peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
235 APP_AV_STATE s_a2d_state = APP_AV_STATE_IDLE; // Next Target Connection State
236 APP_AV_STATE s_a2d_last_state =
237 APP_AV_STATE_IDLE; // Next Target Connection State
238 int s_media_state = 0;
239 int s_intv_cnt = 0;
240 int s_connecting_heatbeat_count;
241 uint32_t s_pkt_cnt;
242 TimerHandle_t s_tmr;
243
244 // initialization
245 bool reset_ble = false;
246 bool discovery_active = false;
247 uint16_t valid_cod_services = ESP_BT_COD_SRVC_RENDERING |
248 ESP_BT_COD_SRVC_AUDIO |
249 ESP_BT_COD_SRVC_TELEPHONY;
250
251 bool (*ssid_callback)(const char *ssid, esp_bd_addr_t address,
252 int rrsi) = nullptr;
253 void (*discovery_mode_callback)(esp_bt_gap_discovery_state_t discoveryMode) =
254 nullptr;
255 void (*passthru_command_callback)(uint8_t, bool) = nullptr;
256 bool is_passthru_active = false;
257 bool is_end = false;
258
259#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
260 esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap;
261#endif
262
263 void app_gap_callback(esp_bt_gap_cb_event_t event,
264 esp_bt_gap_cb_param_t *param) override;
265 void app_rc_ct_callback(esp_avrc_ct_cb_event_t event,
266 esp_avrc_ct_cb_param_t *param) override;
267 void app_a2d_callback(esp_a2d_cb_event_t event,
268 esp_a2d_cb_param_t *param) override;
269 void av_hdl_stack_evt(uint16_t event, void *p_param) override;
270
272 virtual int32_t get_audio_data(uint8_t *data, int32_t len);
274 virtual int32_t get_audio_data_volume(uint8_t *data, int32_t len);
275
276
277 virtual void process_user_state_callbacks(uint16_t event, void *param);
278
279 virtual bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event,
280 void *p_params, int param_len,
281 bt_app_copy_cb_t p_copy_cback);
282 virtual void bt_app_av_media_proc(uint16_t event, void *param);
283
285 virtual void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param);
286 virtual void bt_app_av_state_connecting_hdlr(uint16_t event, void *param);
287 virtual void bt_app_av_state_connected_hdlr(uint16_t event, void *param);
288 virtual void bt_app_av_state_disconnecting_hdlr(uint16_t event, void *param);
289
290 virtual bool get_name_from_eir(uint8_t *eir, uint8_t *bdname,
291 uint8_t *bdname_len);
292 virtual void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param);
293
294 virtual const char *last_bda_nvs_name() { return "src_bda"; }
295
296 virtual void a2d_app_heart_beat(void *arg);
298 virtual void bt_app_av_sm_hdlr(uint16_t event, void *param);
300 virtual void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param);
302 virtual void reset_last_connection();
305 virtual bool is_valid_cod_service(uint32_t cod);
306
307 esp_err_t esp_a2d_connect(esp_bd_addr_t peer) override {
308 ESP_LOGI(BT_AV_TAG, "==> a2dp connecting to: %s", to_str(peer));
309 s_media_state = 0;
310 s_a2d_state = APP_AV_STATE_CONNECTING;
311 return esp_a2d_source_connect(peer);
312 }
313
314 esp_err_t esp_a2d_disconnect(esp_bd_addr_t peer) override {
315 ESP_LOGI(BT_AV_TAG, "==> a2dp esp_a2d_source_disconnect from: %s",
316 to_str(peer));
317 esp_a2d_media_ctrl(ESP_A2D_MEDIA_CTRL_STOP);
318 return esp_a2d_source_disconnect(peer);
319 }
320
322 const char *to_state_str(int state) { return APP_AV_STATE_STR[state]; }
323
324 void set_scan_mode_connectable_default() override {
326 }
327
328#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
329 virtual void bt_av_notify_evt_handler(uint8_t event, esp_avrc_rn_param_t *param);
330 virtual void bt_av_volume_changed(void);
331 virtual void app_rc_tg_callback(esp_avrc_tg_cb_event_t event,
332 esp_avrc_tg_cb_param_t *param) override;
333 virtual void av_hdl_avrc_tg_evt(uint16_t event, void *p_param) override;
334 virtual bool isSource() { return true;}
335
336#endif
337};
338
339
340#endif // platform
Common Bluetooth A2DP functions.
Definition BluetoothA2DPCommon.h:173
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_scan_mode_connectable(bool connectable)
Defines if the bluetooth is connectable.
Definition BluetoothA2DPCommon.cpp:552
A2DP Bluetooth Source.
Definition BluetoothA2DPSource.h:73
virtual void bt_app_av_state_unconnected_hdlr(uint16_t event, void *param)
A2DP application state machine handler for each state.
Definition BluetoothA2DPSource.cpp:617
virtual int32_t get_audio_data_volume(uint8_t *data, int32_t len)
provides the audio after applying the volume
Definition BluetoothA2DPSource.cpp:161
virtual void start_raw(std::vector< const char * > names, music_data_cb_t callback=nullptr)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:168
void set_pin_code(const char *pin_code, esp_bt_pin_type_t pin_type)
Defines the pin code. If nothing is defined we use "1234".
Definition BluetoothA2DPSource.cpp:82
virtual void reset_last_connection()
resets the last connectioin so that we can reconnect
Definition BluetoothA2DPSource.cpp:193
virtual void start(std::vector< const char * > names, music_data_frames_cb_t callback)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:155
void app_rc_ct_callback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) override
callback function for AVRCP controller
Definition BluetoothA2DPSource.cpp:856
virtual void set_valid_cod_service(uint16_t filter)
Definition BluetoothA2DPSource.h:206
virtual int32_t get_audio_data(uint8_t *data, int32_t len)
provides the audio data to be sent
Definition BluetoothA2DPSource.cpp:168
virtual void start_raw(music_data_cb_t callback=nullptr)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:175
~BluetoothA2DPSource()
Destructor.
Definition BluetoothA2DPSource.cpp:80
const char * to_state_str(int state)
converts a APP_AV_STATE_ENUM to a string
Definition BluetoothA2DPSource.h:322
virtual bool is_valid_cod_service(uint32_t cod)
Definition BluetoothA2DPSource.cpp:269
BluetoothA2DPSource()
Constructor.
Definition BluetoothA2DPSource.cpp:61
virtual void set_reset_ble(bool doInit)
Defines if the BLE should be reset on start.
Definition BluetoothA2DPSource.cpp:1016
virtual void set_auto_reconnect(bool active)
Definition BluetoothA2DPSource.h:91
virtual void start(const char *name, music_data_frames_cb_t callback)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:142
virtual void set_ssid_callback(bool(*callback)(const char *ssid, esp_bd_addr_t address, int rrsi))
Define callback to be notified about the found ssids.
Definition BluetoothA2DPSource.h:187
virtual void set_avrc_passthru_command_callback(void(*cb)(uint8_t key, bool isReleased))
Define the handler fur button presses on the remote bluetooth speaker.
Definition BluetoothA2DPSource.h:211
virtual void set_discovery_mode_callback(void(*callback)(esp_bt_gap_discovery_state_t discoveryMode))
Define callback to be notified about bt discovery mode state changes.
Definition BluetoothA2DPSource.h:194
virtual void set_data_source(Stream &data)
Defines a single Arduino Stream (e.g. File) as audio source.
Definition BluetoothA2DPSource.h:118
virtual void set_data_source_callback(Stream &(*next_stream)())
Provide a callback which provides streams.
Definition BluetoothA2DPSource.h:120
virtual void set_ssp_enabled(bool active)
activate Secure Simple Pairing
Definition BluetoothA2DPSource.h:87
virtual void start()
Definition BluetoothA2DPSource.h:127
virtual void set_data_callback(int32_t(cb)(uint8_t *data, int32_t len))
Defines the data callback.
Definition BluetoothA2DPSource.h:105
void app_a2d_callback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) override
callback function for A2DP source
Definition BluetoothA2DPSource.cpp:544
virtual void set_auto_reconnect(esp_bd_addr_t addr)
automatically tries to reconnect to the indicated address
Definition BluetoothA2DPSource.h:96
virtual void bt_app_av_state_connecting_hdlr(uint16_t event, void *param)
Definition BluetoothA2DPSource.cpp:657
int32_t(* get_data_cb)(uint8_t *data, int32_t len)
callback for data
Definition BluetoothA2DPSource.h:222
virtual void set_local_name(const char *name)
Defines the local name.
Definition BluetoothA2DPSource.h:102
virtual void start(music_data_frames_cb_t callback)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:149
virtual void bt_app_av_sm_hdlr(uint16_t event, void *param)
A2DP application state machine.
Definition BluetoothA2DPSource.cpp:589
virtual void set_data_callback_in_frames(int32_t(cb)(Frame *data, int32_t len))
Defines the data callback.
Definition BluetoothA2DPSource.h:110
virtual void start_raw(const char *name, music_data_cb_t callback=nullptr)
Obsolete: use the start w/o callback and set the callback separately.
Definition BluetoothA2DPSource.h:162
virtual void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param)
avrc CT event handler
Definition BluetoothA2DPSource.cpp:913
void end(bool releaseMemory=false) override
Ends the processing and releases the resources.
Definition BluetoothA2DPSource.cpp:147
virtual bool is_discovery_active()
Definition BluetoothA2DPSource.h:201
virtual void start(const char *name)
Starts the A2DP source.
Definition BluetoothA2DPSource.h:133
APP_AV_STATE
Buetooth A2DP global state.
Definition BluetoothA2DPSource.h:52
uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]
Bluetooth address.
Definition external_lists.h:107
Internal message to be sent for BluetoothA2DPSink and BluetoothA2DPSource.
Definition BluetoothA2DPCommon.h:128