espressif / esp-idf

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

The bluetooth scanning effect of esp32s3 is very poor compared to esp32 (IDFGH-8318) #9796

Closed ericnts closed 1 year ago

ericnts commented 2 years ago

Answers checklist.

IDF version.

v4.4.2

Operating System used.

macOS

How did you build your project?

VS Code IDE

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

No response

Development Kit.

ESP32-S3-Korvo-2

Power Supply used.

Battery

What is the expected behavior?

esp32s3 and esp32 can have the same bluetooth broadcast scanning performance

What is the actual behavior?

Bluetooth broadcast scan of esp32s3 is poor

Steps to reproduce.

  1. Prepare a device that can send out Beacon broadcasts at a fixed frequency
  2. Refer to the example (esp-idf/examples/bluetooth/bluedroid/ble/gatt_client/) to write the code (the final code is in the attachment)
  3. Compile two codes and run them on ESP32 and ESP32S3 respectively
  4. Every time a Beacon broadcast data is received, it will be printed in the log.
  5. Looking at the logs, I found that the ESP32S3 lost a lot more data than the ESP32.
image

ESP32 on the left, ESP32S3 on the right

Debug Logs.

No response

More Information.

`/* This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */

/**** *

include

include

include

include

include "nvs.h"

include "nvs_flash.h"

include "esp_bt.h"

include "esp_gap_ble_api.h"

include "esp_gattc_api.h"

include "esp_gatt_defs.h"

include "esp_bt_main.h"

include "esp_gatt_common_api.h"

include "esp_log.h"

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "cJSON.h"

define GATTC_TAG "GATTC_TASK"

define REMOTE_SERVICE_UUID 0xFF00

define REMOTE_DEVID_CHAR_UUID 0xFF01

define REMOTE_DEV_STATE_CHAR_UUID 0xFF06

define REMOTE_AUTH_CHAR_UUID 0xFF0B

define PROFILE_NUM 1

define PROFILE_A_APP_ID 0

define INVALID_HANDLE 0

define SCAN_ALL_THE_TIME 0

//static const char remote_device_name[] = "gattc"; static bool connect = false; static bool get_server = false; static esp_gattc_char_elem_t char_elem_result = NULL; //static esp_gattc_descr_elem_t descr_elem_result = NULL; static esp_ble_gap_cb_param_t scan_rst; //static uint16_t alarm_conn_id = 0; //static uint16_t alarm_srv_start_handle = 0; //static uint16_t alarm_srv_end_handle = 0; //static uint16_t alarm_gattc_if = 0xff;

static const char target_adv_dat[] = {0x02, 0x01, 0x06, 0x1b, 0xff, 0xff, 0xff, 0x4e, 0x42}; / FreeRTOS event group to signal when we are connected & ready to make a request / //static EventGroupHandle_t gattc_event_group;

//const int ALARM_CONNECTED_BIT = BIT0; //const int ALARM_AUTH_BIT = BIT1; //const int ALARM_CLEAR_BIT = BIT2; //const int ALARM_CONNECTED_BIT = BIT3;

static uint32_t gatStatus = 0;

define FLAG_ALARM_CONNECTED (0x01 << 0)

define FLAG_ALARM_AUTH_REQ (0x01 << 1)

define FLAG_ALARM_AUTHED (0x01 << 2)

define FLAG_ALARM_CLEAN_REQ (0x01 << 3)

define FLAG_ALARM_CLEANED (0x01 << 4)

define FLAG_CMD_DISCONNECT_REQ (0x01 << 5)

define FLAG_CMD_CLEAN_REQ (0x01 << 6)

/ Declare static functions / static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t param); static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t param); static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);

static esp_bt_uuid_t remote_filter_service_uuid = { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = REMOTE_SERVICE_UUID,}, };

static esp_bt_uuid_t remote_filter_char_uuid = { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = REMOTE_AUTH_CHAR_UUID,}, };

//static esp_bt_uuid_t devid_filter_char_uuid = { // .len = ESP_UUID_LEN_16, // .uuid = {.uuid16 = REMOTE_DEVID_CHAR_UUID,}, //};

static esp_bt_uuid_t state_filter_char_uuid = { .len = ESP_UUID_LEN_16, .uuid = {.uuid16 = REMOTE_DEV_STATE_CHAR_UUID,}, };

//static esp_bt_uuid_t notify_descr_uuid = { // .len = ESP_UUID_LEN_16, // .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,}, //};

static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_ACTIVE, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, .scan_interval = 0x50, .scan_window = 0x30, .scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE };

struct gattc_profile_inst { esp_gattc_cb_t gattc_cb; uint16_t gattc_if; uint16_t app_id; uint16_t conn_id; uint16_t service_start_handle; uint16_t service_end_handle; uint16_t char_handle; esp_bd_addr_t remote_bda; };

/ One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT / static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = { [PROFILE_A_APP_ID] = { .gattc_cb = gattc_profile_event_handler, .gattc_if = ESP_GATT_IF_NONE, / Not get the gatt_if, so initial is ESP_GATT_IF_NONE / }, };

void clear_warning(void){

if (get_server){
    static esp_gattc_char_elem_t *char_elem   = NULL;
    uint16_t count = 0;
    esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gl_profile_tab[PROFILE_A_APP_ID].gattc_if,
                                                             gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                                             ESP_GATT_DB_CHARACTERISTIC,
                                                             gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                             gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                             INVALID_HANDLE,
                                                             &count);
    if (status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
    }

    if (count > 0){
        char_elem = (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * count);
        if (!char_elem){
            ESP_LOGE(GATTC_TAG, "gattc no mem");
        }else{
            status = esp_ble_gattc_get_char_by_uuid( gl_profile_tab[PROFILE_A_APP_ID].gattc_if,
                                                     gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                                     gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                     gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                     state_filter_char_uuid,
                                                     char_elem,
                                                     &count);
            if (status != ESP_GATT_OK){
                ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
            }

            /*  Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
            if (count > 0 && (char_elem[0].properties & ESP_GATT_CHAR_PROP_BIT_WRITE)){
                uint8_t state_char_data[1] = {0x00};
                esp_ble_gattc_write_char(gl_profile_tab[PROFILE_A_APP_ID].gattc_if,
                          gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                          char_elem[0].char_handle,
                          sizeof(state_char_data),
                          state_char_data,
                          ESP_GATT_WRITE_TYPE_RSP,
                          ESP_GATT_AUTH_REQ_NONE);

                ESP_LOGI(GATTC_TAG, "alarm clear called!");
                gatStatus |= FLAG_ALARM_CLEAN_REQ;
            }
        }
        /* free char_elem_result */
        free(char_elem);
    }else{
        ESP_LOGE(GATTC_TAG, "no char found");
    }
}

}

static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t param) { esp_ble_gattc_cb_param_t p_data = (esp_ble_gattc_cb_param_t *)param;

switch (event) {
case ESP_GATTC_REG_EVT:
    ESP_LOGI(GATTC_TAG, "REG_EVT");
    esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params);
    if (scan_ret){
        ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret);
    }
    break;
case ESP_GATTC_CONNECT_EVT:{
    ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d", p_data->connect.conn_id, gattc_if);
    gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
    memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));

    //alarm_gattc_if = gattc_if;
    //alarm_conn_id = p_data->connect.conn_id;
    gatStatus |= FLAG_ALARM_CONNECTED;

    ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
    esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[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(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
    }
    break;
}
case ESP_GATTC_OPEN_EVT:
    if (param->open.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "open failed, status %d", p_data->open.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "open success");
    break;
case ESP_GATTC_DIS_SRVC_CMPL_EVT:
    if (param->dis_srvc_cmpl.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "discover service failed, status %d", param->dis_srvc_cmpl.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "discover service complete conn_id %d", param->dis_srvc_cmpl.conn_id);
    esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
    break;
case ESP_GATTC_CFG_MTU_EVT:
    if (param->cfg_mtu.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status);
    }
    ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id);
    break;
case ESP_GATTC_SEARCH_RES_EVT: {
    ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
    ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.end_handle, p_data->search_res.srvc_id.inst_id);
    if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
        ESP_LOGI(GATTC_TAG, "service found");
        get_server = true;
        gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
        gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;
        //ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
    }
    break;
}
case ESP_GATTC_SEARCH_CMPL_EVT:
    if (p_data->search_cmpl.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
        break;
    }
    if(p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_REMOTE_DEVICE) {
        ESP_LOGI(GATTC_TAG, "Get service information from remote device");
    } else if (p_data->search_cmpl.searched_service_source == ESP_GATT_SERVICE_FROM_NVS_FLASH) {
        ESP_LOGI(GATTC_TAG, "Get service information from flash");
    } else {
        ESP_LOGI(GATTC_TAG, "unknown service source");
    }
    //ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_CMPL_EVT");
    if (get_server){
        uint16_t count = 0;
        esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
                                                                 p_data->search_cmpl.conn_id,
                                                                 ESP_GATT_DB_CHARACTERISTIC,
                                                                 gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                                 gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                                 INVALID_HANDLE,
                                                                 &count);
        if (status != ESP_GATT_OK){
            ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
        }

        if (count > 0){
            char_elem_result = (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * count);
            if (!char_elem_result){
                ESP_LOGE(GATTC_TAG, "gattc no mem");
            }else{
                status = esp_ble_gattc_get_char_by_uuid( gattc_if,
                                                         p_data->search_cmpl.conn_id,
                                                         gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                         gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                         remote_filter_char_uuid,
                                                         char_elem_result,
                                                         &count);
                if (status != ESP_GATT_OK){
                    ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
                }

                /*  Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
                if (count > 0 && (char_elem_result[0].properties & ESP_GATT_CHAR_PROP_BIT_WRITE/*ESP_GATT_CHAR_PROP_BIT_NOTIFY*/)){
                    uint8_t write_char_data[6] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30};
                    gl_profile_tab[PROFILE_A_APP_ID].char_handle = char_elem_result[0].char_handle;
                    //esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, char_elem_result[0].char_handle);
                    esp_ble_gattc_write_char( gattc_if,
                              gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                              gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                              sizeof(write_char_data),
                              write_char_data,
                              ESP_GATT_WRITE_TYPE_RSP,
                              ESP_GATT_AUTH_REQ_NONE);

                    gatStatus |= FLAG_ALARM_AUTH_REQ;

                    //ESP_LOGI(GATTC_TAG, "esp_ble_gattc_write_char called!");
                }
            }
            /* free char_elem_result */
            free(char_elem_result);
        }else{
            ESP_LOGE(GATTC_TAG, "no char found");
        }
    }
     break;
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
    ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT");
    if (p_data->reg_for_notify.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d", p_data->reg_for_notify.status);
    }else{

        ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT skiped");
    }
    break;
}
case ESP_GATTC_NOTIFY_EVT:
    if (p_data->notify.is_notify){
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:");
    }else{
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive indicate value:");
    }
    //esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
    break;
case ESP_GATTC_WRITE_DESCR_EVT:
    if (p_data->write.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "write descr success ");
    break;
case ESP_GATTC_SRVC_CHG_EVT: {
    esp_bd_addr_t bda;
    memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t));
    ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:");
    esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t));
    break;
}
case ESP_GATTC_WRITE_CHAR_EVT:
    if (p_data->write.status != ESP_GATT_OK){
        ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "write char success ");

    if(gatStatus & FLAG_ALARM_AUTH_REQ){
        gatStatus &= ~FLAG_ALARM_AUTH_REQ;
        gatStatus |= FLAG_ALARM_AUTHED;
        gatStatus |= FLAG_CMD_CLEAN_REQ;  // temp test 
        ESP_LOGI(GATTC_TAG, "AUTHED.");
    }
    if(gatStatus & FLAG_ALARM_CLEAN_REQ){
        gatStatus &= ~FLAG_ALARM_CLEAN_REQ;
        gatStatus |= FLAG_ALARM_CLEANED;
        ESP_LOGI(GATTC_TAG, "CLEANED.");
    }

    //esp_ble_gap_disconnect(gl_profile_tab[PROFILE_A_APP_ID].remote_bda);
    break;
case ESP_GATTC_DISCONNECT_EVT:
    connect = false;
    get_server = false;
    gatStatus = 0;

    esp_ble_gap_start_scanning(SCAN_ALL_THE_TIME);
    ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason);
    break;
default:
    break;
}

}

static uint32_t gattc_ticks = 0, gattc_max = 0; static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t param) { uint8_t adv_name = NULL; uint8_t adv_name_len = 0; switch (event) { case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { //the unit of the duration is second //uint32_t duration = 10; esp_ble_gap_start_scanning(SCAN_ALL_THE_TIME); break; } case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT: //scan start complete event to indicate scan start successfully or failed if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status); break; } ESP_LOGI(GATTC_TAG, "scan start success"); gattc_ticks = xTaskGetTickCount(); break; case ESP_GAP_BLE_SCAN_RESULT_EVT: { esp_ble_gap_cb_param_t scan_result = (esp_ble_gap_cb_param_t )param; uint8_t i;

    switch (scan_result->scan_rst.search_evt) {
    case ESP_GAP_SEARCH_INQ_RES_EVT:
        //esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6);
        for(i = 0; i < (sizeof(target_adv_dat)/sizeof(char)); i++){
            if(scan_result->scan_rst.ble_adv[i] != target_adv_dat[i]) return;
        }

        gattc_ticks = xTaskGetTickCount() - gattc_ticks;
        if(gattc_ticks > gattc_max) gattc_max = gattc_ticks;

        ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);

        adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv,
                                            ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
        esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len);

        if (scan_result->scan_rst.adv_data_len > 0) {
            ESP_LOGI(GATTC_TAG, "adv data:");
            esp_log_buffer_hex(GATTC_TAG, &scan_result->scan_rst.ble_adv[0], scan_result->scan_rst.adv_data_len);
        }

        // if(scan_result->scan_rst.ble_adv[29] != 0){
        //     memcpy(&(scan_rst), scan_result, sizeof(esp_ble_gap_cb_param_t));
        //     esp_ble_gap_stop_scanning();
        // }
        ESP_LOGI(GATTC_TAG, "time:%d/%d, rssi:%d, state:%d.\n", gattc_ticks, gattc_max, scan_result->scan_rst.rssi, scan_result->scan_rst.ble_adv[29]);
        gattc_ticks = xTaskGetTickCount();
        break;
    case ESP_GAP_SEARCH_INQ_CMPL_EVT:
        esp_ble_gap_start_scanning(SCAN_ALL_THE_TIME);

        ESP_LOGI(GATTC_TAG, "ESP_GAP_SEARCH_INQ_CMPL_EVT");
        break;
    default:
        break;
    }
    break;
}

case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
    if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
        ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "stop scan successfully");

    if (connect == false) {
        connect = true;
        ESP_LOGI(GATTC_TAG, "connect to the remote device.");
        esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_rst.scan_rst.bda, scan_rst.scan_rst.ble_addr_type, true);
    }
    break;

case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
    if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS){
        ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status);
        break;
    }
    ESP_LOGI(GATTC_TAG, "stop adv successfully");
    break;
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
     ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
              param->update_conn_params.status,
              param->update_conn_params.min_int,
              param->update_conn_params.max_int,
              param->update_conn_params.conn_int,
              param->update_conn_params.latency,
              param->update_conn_params.timeout);
    break;
default:
    break;
}

}

static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t param) { / If event is register event, store the gattc_if for each profile */ if (event == ESP_GATTC_REG_EVT) { if (param->reg.status == ESP_GATT_OK) { gl_profile_tab[param->reg.app_id].gattc_if = gattc_if; } else { ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d", param->reg.app_id, param->reg.status); return; } }

/* If the gattc_if equal to profile A, call profile A cb handler,
 * so here call each profile's callback */
do {
    int idx;
    for (idx = 0; idx < PROFILE_NUM; idx++) {
        if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
                gattc_if == gl_profile_tab[idx].gattc_if) {
            if (gl_profile_tab[idx].gattc_cb) {
                gl_profile_tab[idx].gattc_cb(event, gattc_if, param);
            }
        }
    }
} while (0);

}

void gattc_task(void *pvParameters) { while(1){ if((connect == true) && (gatStatus & FLAG_ALARM_AUTHED)){ if(gatStatus & FLAG_CMD_DISCONNECT_REQ){ gatStatus &= ~FLAG_CMD_DISCONNECT_REQ; esp_ble_gap_disconnect(gl_profile_tab[PROFILE_A_APP_ID].remote_bda); }

        if(gatStatus & FLAG_CMD_CLEAN_REQ){
            if(!(gatStatus & FLAG_ALARM_CLEAN_REQ)){
                gatStatus &= ~FLAG_CMD_CLEAN_REQ;
                clear_warning();
            }
        }

        if(gatStatus & FLAG_ALARM_CLEANED){
            gatStatus |= FLAG_CMD_DISCONNECT_REQ;
        }

    }else{
        //ESP_LOGI(GATTC_TAG,"disconnect\n");
    }
    vTaskDelay(200 / portTICK_PERIOD_MS);
}

vTaskDelete(NULL);

}

uint8_t gattc_app_main(void) { // Initialize NVS. esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK( ret );

ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg);
if (ret) {
    ESP_LOGE(GATTC_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
    return 0;
}

ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
if (ret) {
    ESP_LOGE(GATTC_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
    return 0;
}

ret = esp_bluedroid_init();
if (ret) {
    ESP_LOGE(GATTC_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
    return 0;
}

ret = esp_bluedroid_enable();
if (ret) {
    ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
    return 0;
}

//register the  callback function to the gap module
ret = esp_ble_gap_register_callback(esp_gap_cb);
if (ret){
    ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", __func__, ret);
    return 0;
}

//register the callback function to the gattc module
ret = esp_ble_gattc_register_callback(esp_gattc_cb);
if(ret){
    ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", __func__, ret);
    return 0;
}

ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID);
if (ret){
    ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", __func__, ret);
}
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
if (local_mtu_ret){
    ESP_LOGE(GATTC_TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
}

return 1;

}

void app_main(void){ gattc_app_main();

xTaskCreate(gattc_task, "gattcTask", 2048, NULL, 8, NULL);

}

`

Weijian-Espressif commented 2 years ago

@ericnts Please provide the esp32 and S3 sdkconfig files you used for testing and IDF commit

ericnts commented 2 years ago

@Weijian-Espressif This is all the files https://github.com/ericnts/esp-gatt

ericnts commented 2 years ago

@Weijian-Espressif IDF commit is 1b16ef6c

Weijian-Espressif commented 2 years ago

@ericnts thanks, If this issue is located, I will notify you as soon as possible

Weijian-Espressif commented 2 years ago

diff.patch.zip @ericnts Please use this patch file and retest

Weijian-Espressif commented 2 years ago

@ericnts Is there any update?

atwoz commented 1 year ago

@ericnts were you able to test the patch?

Weijian-Espressif commented 1 year ago

@atwoz We have fixed this issue in 2022, and have not waited for your reply. please test the latest IDF, if you want get more adv rsp, please disable scanbackoff in controller menuconfig.

Alvin1Zhang commented 1 year ago

To be more specific, the fix commit on release/4.4 is https://github.com/espressif/esp-idf/commit/da943339adc84e131c90a87fde823c24ad4e6a69, feel free to reopen with more updates.