pschatzmann / ESP32-A2DP

A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF
Apache License 2.0
1.86k stars 297 forks source link

bt music sender frequently scan BT devices after calling set_connected(false) #650

Closed flywhc closed 4 days ago

flywhc commented 1 week ago

Problem Description

Then we can see two issues after the device starts:

Issue 1: It shows massive logs repeatly reporting 'Target device not found' because it cannot find the BT device - I feel the device is less responsive. Should it have a delay() after 'Result: Target device not found'?

Issue 2: after calling a2dp_source.set_connected(false), the BT stack should be quiet but it still keep scanning. This is more serious issue because WIFI won't work even I tried disconnecting BT.

ps. I did some study on co-existing of BT and WiFi. The result is it is possible to make BT and WiFi work together in a rotatory way. Neither BT nor WiFi may have a heavy data load in the co-existing mode, so WiFi is unlikely to work while A2DP is in operation. So my idea is to completely shut BT down and allow my phone to connect to WiFi AP, manually change settings then back to BT A2DP mode. In this way, I don't have to install a screen on my mini BT transmitter.

Device Description

ESP32 WROOM 32E with programmer

Sketch

#include "BluetoothA2DPSource.h"
#define c3_frequency  130.81

BluetoothA2DPSource a2dp_source;
bool state = true;

// 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) {
    static double m_time = 0.0;
    double m_amplitude = 10000.0;  // -32,768 to 32,767
    double m_deltaTime = 1.0 / 44100.0;
    double m_phase = 0.0;
    double double_Pi = PI * 2.0;
    // fill the channel data
    for (int sample = 0; sample < channel_len; ++sample) {
        double angle = double_Pi * c3_frequency * m_time + m_phase;
        frame[sample].channel1 = m_amplitude * sin(angle);
        frame[sample].channel2 = frame[sample].channel1;
        m_time += m_deltaTime;
    }

    return channel_len;
}

void setup() {
  Serial.begin(115200);
  //a2dp_source.set_auto_reconnect(false);
  a2dp_source.start("LEXON MINO L", get_data_channels);  
  a2dp_source.set_volume(20);
}

void loop() {
  delay(10000); // change state every minute
  state = !state;
  Serial.print("Connected: ");
  Serial.println(state);
  a2dp_source.set_connected(state);
}

Other Steps to Reproduce

No response

Provide your Version of the EP32 Arduino Core (or the IDF Version)

3.0.7

I have checked existing issues, discussions and online documentation

flywhc commented 1 week ago

there are massive lines of logs. I only paste some logs before and after 'Connected: 0'

7:41:22.823 -> [ 11018][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:22.823 -> [ 11028][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:22.823 -> [ 11036][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:22.857 -> [ 11046][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:22.857 -> [ 11056][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -51 17:41:22.857 -> [ 11064][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:22.889 -> [ 11073][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:22.889 -> [ 11083][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:22.889 -> [ 11092][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:22.926 -> [ 11111][D][BluetoothA2DPSource.cpp:256] bt_app_work_dispatch(): [BT_API] bt_app_work_dispatch event 0xff00, param len 0 17:41:22.926 -> [ 11122][D][BluetoothA2DPSource.cpp:306] bt_app_task_handler(): [BT_API] bt_app_task_handler, signal: 0x1, event: 0xff00 17:41:22.926 -> [ 11133][I][BluetoothA2DPSource.cpp:674] bt_app_av_sm_hdlr(): [BT_AV] bt_app_av_sm_hdlr state APP_AV_STATE_DISCOVERING, evt 0xff00 17:41:22.958 -> [ 11144][D][BluetoothA2DPSource.cpp:641] process_user_state_callbacks(): [BT_AV] process_user_state_callbacks 17:41:22.991 -> [ 11193][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:22.991 -> [ 11202][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.024 -> [ 11212][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:23.024 -> [ 11221][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -51 17:41:23.024 -> [ 11229][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.065 -> [ 11238][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:23.065 -> [ 11248][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.065 -> [ 11258][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.097 -> [ 11283][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.097 -> [ 11292][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.097 -> [ 11302][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:23.131 -> [ 11311][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -55 17:41:23.131 -> [ 11319][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.131 -> [ 11328][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:23.131 -> [ 11338][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.166 -> [ 11348][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.166 -> [ 11363][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.166 -> Connected: 0 17:41:23.166 -> [ 11364][I][BluetoothA2DPCommon.cpp:68] disconnect(): [BT_AV] disconect a2d: 00:00:00:00:00:00 17:41:23.200 -> [ 11381][I[ 11381][I][BluetoothA2DP]S[oBulruceet.oho:t3h0A02]D PeSsopu_rac2ed._cdpips:c3o9n4n]e cfti(l)t:e r[_BiTnqAuVi]r y==s>can_p espta2d: [Br_e_diSconnedt devmc 8 844:4f:54:54:e0 17:41:23.200 -> 0 17:41:23.200 -> [ 11398][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:23.200 -> [ 11407][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -51 17:41:23.232 -> [ 11415][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.232 -> [ 11424][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:23.232 -> [ 11434][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.266 -> [ 11444][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.266 -> [ 11454][D][BluetoothA2DPSource.cpp:256] bt_app_work_dispatch(): [BT_API] bt_app_work_dispatch event 0x3, param len 16 17:41:23.266 -> [ 11464][D][BluetoothA2DPSource.cpp:306] bt_app_task_handler(): [BT_API] bt_app_task_handler, signal: 0x1, event: 0x3 17:41:23.266 -> [ 11464][D][BluetoothA2DPSource.cpp:256] bt_app_work_dispatch(): [BT_API] bt_app_work_dispatch event 0x0, param len 16 17:41:23.300 -> [ 11485][I][BluetoothA2DPSource.cpp:674] bt_app_av_sm_hdlr(): [BT_AV] bt_app_av_sm_hdlr state APP_AV_STATE_DISCOVERING, evt 0x3 17:41:23.300 -> [ 11485][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.300 -> [ 11505][D][BluetoothA2DPSource.cpp:641] process_user_state_callbacks(): [BT_AV] process_user_s[t a1t1e5_0c5a]l[lIb]a[cBklsue 17:41:23.333 -> toothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.333 -> [ 11524][I][BluetoothA2DPSource.cpp:[4 0101]5 2f4i]l[tDe]r[_Bilnuqeutioroyt_hsAc2aDnPSroeusruclet.(c)p:p :[3B0T6]A Vb]t _-a-pCp_task of Dlvr():: 0x_AP04 4 17:41:23.333 -> _app_task_handler, signal: 0x1, event: 0x0 17:41:23.333 -> [ 11[5 4121]5[4I2]][[BIl]u[eBtlouoetthoAo2tDhPAS2oDuPrScoeu.rccpep.:c4p0p4:]6 7f4i]l tbetr__aipnpq_uaivr_ys_ms_chadnl_rr(e)s:u l[B():V [bTApp-v_RSSI:l 5t0 17:41:23.366 -> APP_AV_STATE_DISCOVERING, evt 0x0 17:41:23.366 -> [ 11558][D][BluetoothA2DPSource.cpp:641] process_user_state_callbacks(): [BT_AV] process_user_state_callb[a c1k1s5 17:41:23.366 -> 58][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.366 -> [ 11577][I][BluetoothA2DPSource.cpp:426] filter_inquiry_sca[n _1r1e5s7u7l]t[(D)]:[ B[lBuTe_tAoVo]t h-A-2NDaPmSeo:u rTcmea.lclp pGe64e]BprOM(sAuEe) 17:41:23.400 -> tate_callbacks(): [BT_AV] process_user_state_callbacks ESP_A2D_CONNECTION_STATE_EVT: Disconnected 17:41:23.400 -> [ 11599][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.400 -> [ 11608][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.433 -> [ 11618][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.433 -> [ 11627][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.433 -> [ 11637][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:23.433 -> [ 11646][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -50 17:41:23.466 -> [ 11654][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.466 -> [ 11664][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:23.466 -> [ 11673][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.500 -> [ 11683][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.500 -> [ 11693][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.500 -> [ 11702][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.500 -> [ 11712][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404 17:41:23.533 -> [ 11721][I][BluetoothA2DPSource.cpp:404] filter_inquiry_scan_result(): [BT_AV] --RSSI: -50 17:41:23.533 -> [ 11729][I][BluetoothA2DPSource.cpp:424] filter_inquiry_scan_result(): [BT_AV] --Compatiblity: Compatible 17:41:23.533 -> [ 11738][I][BluetoothA2DPSource.cpp:426] filter_inquiry_scan_result(): [BT_AV] --Name: Tmall Genie BOOM(EA:E0) 17:41:23.567 -> [ 11748][D][BluetoothA2DPSource.cpp:438] filter_inquiry_scan_result(): [BT_AV] --Checking match: LEXON MINO L 17:41:23.567 -> [ 11758][I][BluetoothA2DPSource.cpp:454] filter_inquiry_scan_result(): [BT_AV] --Result: Target device not found 17:41:23.605 -> [ 11813][D][BluetoothA2DPSource.cpp:461] bt_app_gap_callback(): [BT_AV] bt_app_gap_callback evt 0 17:41:23.639 -> [ 11822][I][BluetoothA2DPSource.cpp:394] filter_inquiry_scan_result(): [BT_AV] Scanned device: 84:44:af:54:ea:e0 17:41:23.639 -> [ 11832][I][BluetoothA2DPSource.cpp:400] filter_inquiry_scan_result(): [BT_AV] --Class of Device: 0x240404

pschatzmann commented 1 week ago

ad 1: feel free to implement your own logic

ad 2) I can't reproduce your issue: after beeing disconnected the task handler is just looping in disconnected state: so this works as designed. I you want to end all processing call end() as documented

[ 91118][I][BluetoothA2DPSource.cpp:674] bt_app_av_sm_hdlr(): [BT_AV] bt_app_av_sm_hdlr state APP_AV_STATE_UNCONNECTED, evt 0xff00
[ 91130][D][BluetoothA2DPSource.cpp:641] process_user_state_callbacks(): [BT_AV] process_user_state_callbacks
[ 91139][D][BluetoothA2DPSource.cpp:702] bt_app_av_state_unconnected_hdlr(): [BT_AV] bt_app_av_state_unconnected_hdlr evt 65280
[101097][D][BluetoothA2DPSource.cpp:256] bt_app_work_dispatch(): [BT_API] bt_app_work_dispatch event 0xff00, param len 0
[101108][D][BluetoothA2DPSource.cpp:306] bt_app_task_handler(): [BT_API] bt_app_task_handler, signal: 0x1, event: 0xff00
flywhc commented 5 days ago

@pschatzmann end() doesn't stop the bluetooth related code running. I guess I found the way to fix this issue. Would you please confirm:

s_tmr is created but it is not stopped/deleted so that the code is called every 10 seconds even after calling end(true) - this causes my problem. esp_avrc_ct_init() is called but esp_avrc_ct_deinit() is not called in end() - this doesn't cause my problem but it is potential leak.

So my fix is adding a overrided end() in BluetoothA2DPSource.cpp:

BluetoothA2DPSource::BluetoothA2DPSource() {
...
  s_tmr = NULL;
}

void BluetoothA2DPSource::end(bool release_memory) {
  esp_avrc_ct_deinit();
  if(s_tmr != NULL) {
    xTimerDelete(s_tmr, portMAX_DELAY);
    s_tmr = NULL;
  }
  BluetoothA2DPCommon::end(release_memory);
}

and add a line in the BluetoothA2DPSource.h:

virtual void end(bool releaseMemory=false);

pschatzmann commented 5 days ago

I see: maybe it is best to move the logic which is currently implemented in the A2DPSink to Common: in both cases the task needs to be stopped with app_task_shut_down() as well!

end() is working fine now both in the Source and Sink.

pschatzmann commented 4 days ago

I moved the functionality that is available both in the source and sink to common to address this issue: this includes the task management.

end() is now working fine both in the A2DPSink and A2DPSource.