espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.89k stars 7.32k forks source link

bt_l2cap_client write time out (IDFGH-13315) #14240

Open jjj19950710 opened 4 months ago

jjj19950710 commented 4 months ago

Answers checklist.

IDF version.

v5.0.1

Espressif SoC revision.

ESP32

Operating System used.

Windows

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

CMD

Development Kit.

ESP32

Power Supply used.

USB

What is the expected behavior?

The l2cap interface is connected to the a2dp channel, and after successful connection, the query capability features are cyclically sent through the write interface, hoping to continue querying.

What is the actual behavior?

The l2cap interface is connected to the a2dp channel. After successful connection, the query capability feature is cyclically sent through the write interface. After 3700 rounds, the underlying l2cap interface cannot be called again, and the prompt "l2cap-vfsw_write exit for time out" appears。

Steps to reproduce.

1、The tested device is Bluez on Linux system 2、Modify the PSM of the connection:esp_bt_l2cap_connect(sec_mask, 0x0019, s_peer_bda); 3、Establish a2dp interaction process after channel opening 4、Register the l2cap callback function to retrieve the callback packet.Loop send getcapabilities

void l2c_data_ind_cback(UINT16 lcid, BT_HDR *p_buf){
    printf("recv ");
    for(int i=0;i<p_buf->len;i++){
        printf("%02x ",p_buf->data[i+p_buf->offset]);
    }
   osi_sem_give(&scene_sem);
   printf("\n");
}
const tL2CAP_APPL_INFO l2c_appl_callback = {
    NULL,
    NULL,
    NULL,
    l2c_config_ind_cback,
    l2c_config_cfm_cback,
    l2c_disconnect_ind_cback,
    NULL,
    NULL,
    l2c_data_ind_cback,
    NULL,
    NULL                /* tL2CA_TX_COMPLETE_CB */
};
L2CA_Register(0x0019, (tL2CAP_APPL_INFO *) &l2c_appl_callback;
static void a2dp_getcapabilities(void *arg){
    uint8_t l2cap_data1[3] = {0x10, 0x02, 0x10};//getcapabilities
    uint8_t buf[128]="\0";
    for(int i=0;i<2000;i++){
        printf("%d\n",i);
        int size = write(signal_fd, l2cap_data1, 3);
        if (size == -1) {
            printf("break %d\n",i);
            break;
        }
        osi_sem_take(&scene_sem, 5000);
    }
    vTaskDelete(NULL);
}

Debug Logs.

I (541510) BT_L2CAP: L2CA_DataWrite()  CID: 0x0041  Len: 3
esp_vhci_host_send_packet 02 81 20 07 00 03 00 40 00 10 02 10
recv 12 02 01 00 07 0d 00 ff d7 00 00 00 24 00 f2 00 00 00 00
3725
L2CA_DataWrite 0041
I (541540) BT_L2CAP: L2CA_DataWrite()  CID: 0x0041  Len: 3
esp_vhci_host_send_packet 02 81 20 07 00 03 00 40 00 10 02 10
recv 12 02 01 00 07 0d 00 ff d7 00 00 00 24 00 f2 00 00 00 00
3726
L2CA_DataWrite 0041
I (541560) BT_L2CAP: L2CA_DataWrite()  CID: 0x0041  Len: 3
esp_vhci_host_send_packet 02 81 20 07 00 03 00 40 00 10 02 10
recv 12 02 01 00 07 0d 00 ff d7 00 00 00 24 00 f2 00 00 00 00
3727
L2CA_DataWrite 0041
I (541590) BT_L2CAP: L2CA_DataWrite()  CID: 0x0041  Len: 3
esp_vhci_host_send_packet 02 81 20 07 00 03 00 40 00 10 02 10
recv 12 02 01 00 07 0d 00 ff d7 00 00 00 24 00 f2 00 00 00 00
3728
L2CA_DataWrite 0041
I (541610) BT_L2CAP: L2CA_DataWrite()  CID: 0x0041  Len: 3
esp_vhci_host_send_packet 02 81 20 07 00 03 00 40 00 10 02 10
recv 12 02 01 00 07 0d 00 ff d7 00 00 00 24 00 f2 00 00 00 00
3729
3730
W (546850) BT_HCI: hci cmd send: sniff: hdl 0x81, intv(400 800)
W (546870) BT_HCI: hcif mode change: hdl 0x81, mode 2, intv 804, status 0x0
I (546870) L2CAP_TAG: ESP_BT_GAP_MODE_CHG_EVT mode:2 bda:[e4:0d:36:34:0d:db]
avdtp_flag 3 mode 2
3731
3732
3733
3734
3735
3736
3737
3738
3739
E (631740) BT_BTC: l2cap_vfs_write exit for time out, fd:3!
break 3739

More Information.

No response

jjj19950710 commented 4 months ago

How to set a2dp encoding format to SBC for l2cap layer interface?

xiongweichao commented 4 months ago

Hi @jjj19950710 ,

  1. Could you please provide a demo that can reproduce the issue? This will be helpful in solving the issue.
  2. You can try to use the API in this folder.

Thanks

jjj19950710 commented 4 months ago

main.zip

Thank you for your reply! Replace the main.c file in the bt_l2cap_client project and modify the CMakeLists.txt file:

idf_component_register(SRCS "main.c"
                            "bt_app_core.c"
                    INCLUDE_DIRS "."
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/common/include"
                                "${IDF_PATH}/components/bt/common/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/avct/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/avdt/include")
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

Enable a2dp configuration

I already know the reason for the timeout issue and I have now resolved it.

The second question: Currently, I am only connecting to the non-a2dp aptX HD stream endpoint. I hope to register the SBC encoding format on the development board so that I can establish a connection with the stream endpoint on Bluez.How should I do it in the main.c file.

xiongweichao commented 4 months ago

Hi @jjj19950710 May I ask if you want to support both SBC and aptX encoding and decoding?

jjj19950710 commented 4 months ago

Hi @xiongweichao,It is also possible to set only the supported SBC encoding format.It would be best if you could support both.

xiongweichao commented 3 months ago

Hi @jjj19950710 ,

Please try the following modifications.

  1. Modify CMakeLists.txt file. Add the encoder header file path.
    idf_component_register(SRCS "main.c"
                            "bt_app_core.c"
                    INCLUDE_DIRS "."
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/common/include"
                                "${IDF_PATH}/components/bt/common/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/avct/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/external/sbc/decoder/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/external/sbc/encoder/include"
                                "${IDF_PATH}/components/bt/host/bluedroid/stack/avdt/include")
    target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
  2. Add the header file in main.c. For example, #include "oi_codec_sbc.h"
  3. Add the encoder/decoder API to the corresponding location according to your needs.

Not sure if it meets your requirements. Please let me know if you have any questions.

Thanks