espressif / esp-idf

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

esp_ble_gattc_write_char, The connection not created (IDFGH-11696) #12803

Closed monkey-qiu closed 10 months ago

monkey-qiu commented 10 months ago

Answers checklist.

General issue report

ESP32-C3蓝牙5.0主从一体模式,开发环境IDF 5.1 是 ESP 设备作为client连接一个server,然后ESP设备的server被app主机连接,当app和server的连接断开时,会上报ESP_GATTS_DISCONNECT_EVT 和 ESP_GATTC_DISCONNECT_EVT两个事件,然后ESP设备作为client向server发送数据时报未建立连接

 I (112345) GATTC_COEX: Gattc_Read_Time = 112346ms, client_s end_cnt = 16, client_recv_cnt = 0,client_sendlose_cnt = 0 W (116605) BT_APPL: gattc_conn_cb: if=4 st=0 id=260 rsn=0x13 W (116605) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x13 I (116605) GATTC_GATTS_COEX: ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x13 I (116615) GATTC_GATTS_COEX: ESP_GATTC_DISCONNECT_EVT, reason = 19  I (116615) GATTC_GATTS_COEX: ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT, status = 0 I (117345) GATTC_COEX: start write = 117345ms  W (117345) BT_LOG: esp_ble_gattc_write_char, The connection not created. I (117345) GATTC_COEX: Gattc_Read_Time = 117347ms, client_send_cnt = 16, client_recv_cnt = 0,client_sendlose_cnt = 1 I (122355) GATTC_COEX: start write = 122355ms  W (122355) BT_LOG: esp_ble_gattc_write_char, The connection not created. I (122355) GATTC_COEX: Gattc_Read_Time = 122357ms, client_send_cnt = 16, client_recv_cnt = 0,client_sendlose_cnt = 2

esp-zhp commented 10 months ago

@monkey-qiu ESP_GATTC_DISCONNECT_EVT 事件上来,说明 client 和 server 已经断开连接了,后面的再调用 “esp_ble_gattc_write_char” 就会提示连接还没有建立(The connection not created)。 0x13 的含义是远程设备主动断开连接。 image

请问题是每次都可以出现的吗?

monkey-qiu commented 10 months ago

@monkey-qiu ESP_GATTC_DISCONNECT_EVT 事件上来,说明 client 和 server 已经断开连接了,后面的再调用 “esp_ble_gattc_write_char” 就会提示连接还没有建立(The connection not created)。 0x13 的含义是远程设备主动断开连接。 image

请问题是每次都可以出现的吗?

我这边环境如下: 使用模式是蓝牙5.0主从一体模式,demo是乐鑫同事给的一个,官网还没有蓝牙5.0主从一体的demo 1、一个APP作为client,一个MCU带有 ESP32-C3芯片作为server,一个 ESP32-C3-DevKitC-02v1.1作为蓝牙主从一体(ble50_gattc_gattx_coex)模式 2、上面日志是ESP32-C3-DevKitC的日志 3、首先ESP32-C3-DevKitC的client连接MCU的ESP32-C3蓝牙的server并持续发送数据,server接收数据并答复 4、APP作为client连接ESP32-C3-DevKitC的server 5、当APP和ESP32-C3-DevKitC的server的连接断开时,ESP32-C3-DevKitC向ESP32-C3的server发送数据提示esp_ble_gattc_write_char, The connection not created 6、从错误看,主从一体的某个连接断开,导致其他连接也无法发送数据

esp-zhp commented 10 months ago

@monkey-qiu 也就是说两个 client 连接了一个共同的 sever,当一个 client 断开连接时,另一个未断开的 client 也不能正常工作了?

monkey-qiu commented 10 months ago

@monkey-qiu 也就是说两个 client 连接了一个共同的 sever,当一个 client 断开连接时,另一个未断开的 client 也不能正常工作了?

不是的,是主从一体的client连接esp32-C3芯片的server,然后主从一体的server被手机APP的client连接,当app和server的连接断开后,主从一体的client和esp32-C3芯片的server的连接不能正常发数据了,提示连接断开

esp-zhp commented 10 months ago

@monkey-qiu 好的,明白了。 主从一体的 BLE5.0 example 我还没有,你可以发我邮箱一下吗,或者你给我说谁给你的?我想先复现一下问题。

monkey-qiu commented 10 months ago

@monkey-qiu 好的,明白了。 主从一体的 BLE5.0 example 我还没有,你可以发我邮箱一下吗,或者你给我说谁给你的?我想先复现一下问题。

马莉给我的,我同步发你邮箱了,你这边邮箱地址能发我下么

esp-zhp commented 10 months ago

@monkey-qiu 好的,但是由于公司邮件过滤策略,我没有收到。我找 mali 要了一份。 我将尽快复现问题。

monkey-qiu commented 10 months ago

@monkey-qiu 好的,但是由于公司邮件过滤策略,我没有收到。我找 mali 要了一份。 我将尽快复现问题。

你好,这个有验证结果了么

esp-zhp commented 10 months ago

@monkey-qiu 我们这面复现了你说的问题,还需要做一些检查,明天会继续给你同步一下。

esp-zhp commented 10 months ago

@monkey-qiu esp_ble_gattc_write_char, The connection not created 出现该问题的原因是在调用 esp_ble_gattc_write_char 时传入的 conn_id 并不正确。 conn_id 是 记录在 gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id 而 gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id 是在 ESP_GATTC_CONNECT_EVT 中更新的。 当有连接建立时 ESP_GATTC_CONNECT_EVT 和 ESP_GATTS_CONNECT_EVT 在连接事件建立时会一起上来,也就是说 ESP32-C3(同时作为 client 和 server) 在连接其他设备和被其他设备连接时,这两个事件都会上来。 1-在主动连接别人时,记录了连接的 conn_id (假设为 0) 2-然后又被其他设备连接,重新记录了连接的 conn_id(假设为 1) 3-其他设备断开连接,此时 ESP32-C3(可同时作为 client 和 server) conn_id 为 1 的连接不存在了 4-当想给另一个没有断开的设备(server)进行写操作时,使用了 conn_id 1,所以会提示连接不存在了,实际上应该使用 conn_id 0(但是记录已经被覆盖)

为了解决上面的问题,我设置了一个变量 peer_gatts_addr ,

esp_bd_addr_t peer_gatts_addr; 

该变量保存了 对端 server 的地址

esp_ble_gattc_aux_open(gattc_profile_tab[GATTC_PROFILE_A_APP_ID].gattc_if,
param->ext_adv_report.params.addr,
param->ext_adv_report.params.addr_type, true);
memcpy(peer_gatts_addr,param->ext_adv_report.params.addr, sizeof(esp_bd_addr_t));
esp_log_buffer_hex("remote device",peer_gatts_addr,6);

当连接事件上来时,首先判断地址是不是 peer_gatts_addr,来确保是真的要更新 gattc_profile_tab 信息了。 具体做法是:

    case ESP_GATTC_CONNECT_EVT: {
        ESP_LOGI(COEX_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d\n", p_data->connect.conn_id, gattc_if);
        if (!memcmp(peer_gatts_addr, p_data->connect.remote_bda, sizeof(esp_bd_addr_t)) ) {
        // 当连接建立的时候,ESP_GATTC_CONNECT_EVT 和 ESP_GATTS_CONNECT_EVT 都会报上来, 只有对方是 server 的时候才需要更新 gattc_profile_tab 中的信息
        // 使用 peer_gatts_addr 变量记录对方 server 的地址
        gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
        memcpy(gattc_profile_tab[GATTC_PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
        ESP_LOGI(COEX_TAG, "REMOTE BDA:");
        esp_log_buffer_hex(COEX_TAG, gattc_profile_tab[GATTC_PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
        esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->connect.conn_id);
        if (mtu_ret) {
            ESP_LOGE(COEX_TAG, "config MTU error, error code = %x\n", mtu_ret);
        }
        } else {
            ESP_LOGW(COEX_TAG, "peer device is not a gatt server\n");
        }
        break;
    }

通过以上操作,gattc_profile_tab 就可以保存作为 client 时正确的 conn id 信息,

同理,如果要更新 gatts_profile_tab 的信息,需要判断对端地址 不是 peer_gatts_addr。

关于 gattc_profile_tab 的更新,我重新写了一下 example,你看一下能够解决你的问题? [Uploading ble50_gattc_gattx_coex_v2.zip…]()

monkey-qiu commented 10 months ago

@monkey-qiu esp_ble_gattc_write_char, The connection not created 出现该问题的原因是在调用 esp_ble_gattc_write_char 时传入的 conn_id 并不正确。 conn_id 是 记录在 gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id 而 gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id 是在 ESP_GATTC_CONNECT_EVT 中更新的。 当有连接建立时 ESP_GATTC_CONNECT_EVT 和 ESP_GATTS_CONNECT_EVT 在连接事件建立时会一起上来,也就是说 ESP32-C3(同时作为 client 和 server) 在连接其他设备和被其他设备连接时,这两个事件都会上来。 1-在主动连接别人时,记录了连接的 conn_id (假设为 0) 2-然后又被其他设备连接,重新记录了连接的 conn_id(假设为 1) 3-其他设备断开连接,此时 ESP32-C3(可同时作为 client 和 server) conn_id 为 1 的连接不存在了 4-当想给另一个没有断开的设备(server)进行写操作时,使用了 conn_id 1,所以会提示连接不存在了,实际上应该使用 conn_id 0(但是记录已经被覆盖)

为了解决上面的问题,我设置了一个变量 peer_gatts_addr ,

esp_bd_addr_t peer_gatts_addr; 

该变量保存了 对端 server 的地址

esp_ble_gattc_aux_open(gattc_profile_tab[GATTC_PROFILE_A_APP_ID].gattc_if,
param->ext_adv_report.params.addr,
param->ext_adv_report.params.addr_type, true);
memcpy(peer_gatts_addr,param->ext_adv_report.params.addr, sizeof(esp_bd_addr_t));
esp_log_buffer_hex("remote device",peer_gatts_addr,6);

当连接事件上来时,首先判断地址是不是 peer_gatts_addr,来确保是真的要更新 gattc_profile_tab 信息了。 具体做法是:

    case ESP_GATTC_CONNECT_EVT: {
        ESP_LOGI(COEX_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d\n", p_data->connect.conn_id, gattc_if);
        if (!memcmp(peer_gatts_addr, p_data->connect.remote_bda, sizeof(esp_bd_addr_t)) ) {
        // 当连接建立的时候,ESP_GATTC_CONNECT_EVT 和 ESP_GATTS_CONNECT_EVT 都会报上来, 只有对方是 server 的时候才需要更新 gattc_profile_tab 中的信息
        // 使用 peer_gatts_addr 变量记录对方 server 的地址
        gattc_profile_tab[GATTC_PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
        memcpy(gattc_profile_tab[GATTC_PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
        ESP_LOGI(COEX_TAG, "REMOTE BDA:");
        esp_log_buffer_hex(COEX_TAG, gattc_profile_tab[GATTC_PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
        esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->connect.conn_id);
        if (mtu_ret) {
            ESP_LOGE(COEX_TAG, "config MTU error, error code = %x\n", mtu_ret);
        }
        } else {
            ESP_LOGW(COEX_TAG, "peer device is not a gatt server\n");
        }
      break;
    }

通过以上操作,gattc_profile_tab 就可以保存作为 client 时正确的 conn id 信息,

同理,如果要更新 gatts_profile_tab 的信息,需要判断对端地址 不是 peer_gatts_addr。

关于 gattc_profile_tab 的更新,我重新写了一下 example,你看一下能够解决你的问题? Uploading ble50_gattc_gattx_coex_v2.zip…

你好,能把demo发我邮箱么,我点击上面的下载链接不跳转到下载页哈,邮箱地址:qiuzhicai@xa.com

esp-zhp commented 10 months ago

@monkey-qiu 我已经发送,请查收。

monkey-qiu commented 10 months ago

@monkey-qiu 我已经发送,请查收。

我这边已收到邮件哈,非常感谢!

esp-zhp commented 10 months ago

@monkey-qiu 该修改能够符合你的要求吗?

Alvin1Zhang commented 10 months ago

由于未及时收到反馈,将会关闭此问题。如有新的反馈,将会 Reopen,谢谢。

monkey-qiu commented 9 months ago

@monkey-qiu 我已经发送,请查收。

我现在遇到两个问题,一个是主从一体的主机连接上一个从机后,设置mtu需要将近一分钟,第二个问题是,我一个esp32-C3作为从机使用AT模式,一个esp32-C3开发板作为主从一体,主从一体的主机去连接AT模式的从机,设置mtu后持续给从机发数据,从机收到数据立马回复,现在测试看到AT模式的从机一写数据就报ERROR,写数据指令很容易失败

monkey-qiu commented 9 months ago

由于未及时收到反馈,将会关闭此问题。如有新的反馈,将会 Reopen,谢谢。

我现在遇到两个问题,一个是主从一体的主机连接上一个从机后,设置mtu需要将近一分钟,第二个问题是,我一个esp32-C3作为从机使用AT模式,一个esp32-C3开发板作为主从一体,主从一体的主机去连接AT模式的从机,设置mtu后持续给从机发数据,从机收到数据立马回复,现在测试看到AT模式的从机一写数据就报ERROR,写数据指令很容易失败

esp-zhp commented 9 months ago

@monkey-qiu 如果是新问题,请新起一个 issue 并给出 log,谢谢。

monkey-qiu commented 9 months ago

@monkey-qiu 如果是新问题,请新起一个 issue 并给出 log,谢谢。

IDFGH-11901 帮忙看下这个问题

esp-zhp commented 9 months ago

@monkey-qiu 好的,我这面看到了,并给了你一些评论,请查看一下评论~