fix(examples): improve bluedroid BLE example error handling

Check GAP/GATT event status, fix prepare-write buffer lifecycle, and
align example code with updated Bluedroid API behavior.


(cherry picked from commit bfc47ace48)

Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
Zhi Wei Jian
2026-06-12 17:17:37 +08:00
committed by BOT
parent 109120cc50
commit da29ffba88
48 changed files with 1606 additions and 721 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -81,6 +81,15 @@ typedef struct {
static prepare_type_env_t a_prepare_write_env;
static prepare_type_env_t b_prepare_write_env;
static void prepare_write_env_free(prepare_type_env_t *env)
{
if (env->prepare_buf != NULL) {
free(env->prepare_buf);
env->prepare_buf = NULL;
}
env->prepare_len = 0;
}
//Declare the static function
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
@@ -176,10 +185,21 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
{
switch (event) {
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
//esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
/* Configure adv data only after local privacy is set up (REG_EVT requests it). */
if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(BT_BLE_COEX_TAG, "set local privacy failed, status %d", param->local_privacy_cmpl.status);
} else {
ble_init_adv_data(BLE_ADV_NAME);
}
break;
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&adv_params);
if (param->scan_rsp_data_raw_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(BT_BLE_COEX_TAG, "set raw scan rsp data failed, status %d", param->scan_rsp_data_raw_cmpl.status);
} else {
esp_ble_gap_start_advertising(&adv_params);
}
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed
@@ -265,11 +285,69 @@ void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble
} else {
ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
}
if (prepare_write_env->prepare_buf) {
free(prepare_write_env->prepare_buf);
prepare_write_env->prepare_buf = NULL;
prepare_write_env_free(prepare_write_env);
}
/* Profile A and B handle READ/WRITE identically (apart from per-profile state); these helpers
* avoid the copy-pasted bodies that existed in the previous version. */
static void gatts_coex_read_evt(esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_READ_EVT, conn_id %d, trans_id %"PRIu32", handle %d",
param->read.conn_id, param->read.trans_id, param->read.handle);
esp_gatt_rsp_t rsp;
memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
rsp.attr_value.handle = param->read.handle;
rsp.attr_value.len = 4;
rsp.attr_value.value[0] = 0xde;
rsp.attr_value.value[1] = 0xed;
rsp.attr_value.value[2] = 0xbe;
rsp.attr_value.value[3] = 0xef;
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
ESP_GATT_OK, &rsp);
}
static void gatts_coex_write_evt(esp_gatt_if_t gatts_if, int profile_idx, prepare_type_env_t *prep_env,
esp_gatt_char_prop_t char_prop, esp_ble_gatts_cb_param_t *param)
{
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d",
param->write.conn_id, param->write.trans_id, param->write.handle);
if (!param->write.is_prep) {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len);
if (gl_profile_tab[profile_idx].descr_handle == param->write.handle && param->write.len == 2) {
uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
if (descr_value == 0x0001) {
if (char_prop & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify enable");
uint8_t notify_data[15];
for (int i = 0; i < sizeof(notify_data); ++i) {
notify_data[i] = i % 0xff;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[profile_idx].char_handle,
sizeof(notify_data), notify_data, false);
}
} else if (descr_value == 0x0002) {
if (char_prop & ESP_GATT_CHAR_PROP_BIT_INDICATE) {
ESP_LOGI(BT_BLE_COEX_TAG, "indicate enable");
uint8_t indicate_data[15];
for (int i = 0; i < sizeof(indicate_data); ++i) {
indicate_data[i] = i % 0xff;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[profile_idx].char_handle,
sizeof(indicate_data), indicate_data, true);
}
} else if (descr_value == 0x0000) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify/indicate disable ");
} else {
ESP_LOGE(BT_BLE_COEX_TAG, "unknown descr value");
ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len);
}
}
}
prepare_write_env->prepare_len = 0;
example_write_event_env(gatts_if, prep_env, param);
}
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
@@ -282,68 +360,20 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00;
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_A;
//init BLE adv data and scan response data
ble_init_adv_data(BLE_ADV_NAME);
/* Adv raw data is set from gap_event_handler after ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT. */
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_A);
break;
case ESP_GATTS_READ_EVT: {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_READ_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->read.conn_id, param->read.trans_id, param->read.handle);
esp_gatt_rsp_t rsp;
memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
rsp.attr_value.handle = param->read.handle;
rsp.attr_value.len = 4;
rsp.attr_value.value[0] = 0xde;
rsp.attr_value.value[1] = 0xed;
rsp.attr_value.value[2] = 0xbe;
rsp.attr_value.value[3] = 0xef;
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
ESP_GATT_OK, &rsp);
case ESP_GATTS_READ_EVT:
gatts_coex_read_evt(gatts_if, param);
break;
}
case ESP_GATTS_WRITE_EVT: {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
if (!param->write.is_prep) {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len);
if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2) {
uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
if (descr_value == 0x0001) {
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify enable");
uint8_t notify_data[15];
for (int i = 0; i < sizeof(notify_data); ++i) {
notify_data[i] = i % 0xff;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(notify_data), notify_data, false);
}
} else if (descr_value == 0x0002) {
if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) {
ESP_LOGI(BT_BLE_COEX_TAG, "indicate enable");
uint8_t indicate_data[15];
for (int i = 0; i < sizeof(indicate_data); ++i) {
indicate_data[i] = i % 0xff;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
sizeof(indicate_data), indicate_data, true);
}
} else if (descr_value == 0x0000) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify/indicate disable ");
} else {
ESP_LOGE(BT_BLE_COEX_TAG, "unknown descr value");
ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len);
}
}
}
example_write_event_env(gatts_if, &a_prepare_write_env, param);
case ESP_GATTS_WRITE_EVT:
gatts_coex_write_evt(gatts_if, PROFILE_A_APP_ID, &a_prepare_write_env, a_property, param);
break;
}
case ESP_GATTS_EXEC_WRITE_EVT:
ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
/* Use exec_write union member, not write — these share offsets in the union but it
* was a latent bug in master to refer to param->write here. */
esp_ble_gatts_send_response(gatts_if, param->exec_write.conn_id, param->exec_write.trans_id, ESP_GATT_OK, NULL);
example_exec_write_event_env(&a_prepare_write_env, param);
break;
case ESP_GATTS_MTU_EVT:
@@ -395,13 +425,11 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
case ESP_GATTS_STOP_EVT:
break;
case ESP_GATTS_CONNECT_EVT: {
esp_ble_conn_update_params_t conn_params = {0};
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
case ESP_GATTS_CONNECT_EVT:
break;
}
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_DISCONNECT_EVT");
prepare_write_env_free(&a_prepare_write_env);
esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GATTS_CONF_EVT:
@@ -432,63 +460,15 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_B);
break;
case ESP_GATTS_READ_EVT: {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_READ_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->read.conn_id, param->read.trans_id, param->read.handle);
esp_gatt_rsp_t rsp;
memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
rsp.attr_value.handle = param->read.handle;
rsp.attr_value.len = 4;
rsp.attr_value.value[0] = 0xde;
rsp.attr_value.value[1] = 0xed;
rsp.attr_value.value[2] = 0xbe;
rsp.attr_value.value[3] = 0xef;
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
ESP_GATT_OK, &rsp);
case ESP_GATTS_READ_EVT:
gatts_coex_read_evt(gatts_if, param);
break;
}
case ESP_GATTS_WRITE_EVT: {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %"PRIu32", handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
if (!param->write.is_prep) {
ESP_LOGI(BT_BLE_COEX_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
ESP_LOG_BUFFER_HEX(BT_BLE_COEX_TAG, param->write.value, param->write.len);
if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2) {
uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
if (descr_value == 0x0001) {
if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify enable");
uint8_t notify_data[15];
for (int i = 0; i < sizeof(notify_data); ++i) {
notify_data[i] = i % 0xff;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
sizeof(notify_data), notify_data, false);
}
} else if (descr_value == 0x0002) {
if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE) {
ESP_LOGI(BT_BLE_COEX_TAG, "indicate enable");
uint8_t indicate_data[15];
for (int i = 0; i < sizeof(indicate_data); ++i) {
indicate_data[i] = i % 0xff;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
sizeof(indicate_data), indicate_data, true);
}
} else if (descr_value == 0x0000) {
ESP_LOGI(BT_BLE_COEX_TAG, "notify/indicate disable ");
} else {
ESP_LOGE(BT_BLE_COEX_TAG, "unknown value");
}
}
}
example_write_event_env(gatts_if, &b_prepare_write_env, param);
case ESP_GATTS_WRITE_EVT:
gatts_coex_write_evt(gatts_if, PROFILE_B_APP_ID, &b_prepare_write_env, b_property, param);
break;
}
case ESP_GATTS_EXEC_WRITE_EVT:
ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
esp_ble_gatts_send_response(gatts_if, param->exec_write.conn_id, param->exec_write.trans_id, ESP_GATT_OK, NULL);
example_exec_write_event_env(&b_prepare_write_env, param);
break;
case ESP_GATTS_MTU_EVT:
@@ -552,6 +532,9 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
}
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(BT_BLE_COEX_TAG, "ESP_GATTS_DISCONNECT_EVT (profile B)");
prepare_write_env_free(&b_prepare_write_env);
break;
case ESP_GATTS_OPEN_EVT:
case ESP_GATTS_CANCEL_OPEN_EVT:
case ESP_GATTS_CLOSE_EVT:
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -105,6 +105,15 @@ static esp_gatt_char_prop_t b_property = 0;
static prepare_type_env_t a_prepare_write_env;
static prepare_type_env_t b_prepare_write_env;
static uint8_t adv_config_done = 0;
static void prepare_write_env_free(prepare_type_env_t *env)
{
if (env->prepare_buf != NULL) {
free(env->prepare_buf);
env->prepare_buf = NULL;
}
env->prepare_len = 0;
}
static uint8_t char1_str[] = {0x11, 0x22, 0x33};
static bool connect = false;
static bool get_server = false;
@@ -293,11 +302,17 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
case ESP_GAP_BLE_SCAN_RESULT_EVT: {
esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param;
switch (scan_result->scan_rst.search_evt) {
case ESP_GAP_SEARCH_INQ_RES_EVT:
case ESP_GAP_SEARCH_INQ_RES_EVT: {
const uint16_t ble_adv_storage_max = ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX;
uint32_t combined_len = (uint32_t)scan_result->scan_rst.adv_data_len +
(uint32_t)scan_result->scan_rst.scan_rsp_len;
uint16_t resolve_len = (combined_len > ble_adv_storage_max)
? ble_adv_storage_max
: (uint16_t)combined_len;
adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv,
scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len,
ESP_BLE_AD_TYPE_NAME_CMPL,
&adv_name_len);
resolve_len,
ESP_BLE_AD_TYPE_NAME_CMPL,
&adv_name_len);
if (adv_name != NULL) {
if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) {
if (connect == false) {
@@ -324,6 +339,7 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
}
}
break;
}
case ESP_GAP_SEARCH_INQ_CMPL_EVT:
ESP_LOGI(COEX_TAG, "ESP_GAP_SEARCH_INQ_CMPL_EVT, scan stop");
break;
@@ -563,6 +579,7 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
// Update connect flag and get_server flag if peer device is a gatt server
connect = false;
get_server = false;
gattc_profile_tab[GATTC_PROFILE_C_APP_ID].conn_id = UINT16_MAX;
}
ESP_LOGI(COEX_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason);
break;
@@ -577,9 +594,11 @@ static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *
esp_gatt_status_t status = ESP_GATT_OK;
if (param->write.need_rsp) {
if (param->write.is_prep) {
if (param->write.offset > PREPARE_BUF_MAX_SIZE) {
size_t w_off = param->write.offset;
size_t w_len = param->write.len;
if (w_off > PREPARE_BUF_MAX_SIZE) {
status = ESP_GATT_INVALID_OFFSET;
} else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) {
} else if (w_len > ESP_GATT_MAX_ATTR_LEN || (w_off + w_len) > PREPARE_BUF_MAX_SIZE) {
status = ESP_GATT_INVALID_ATTR_LEN;
}
if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) {
@@ -591,13 +610,19 @@ static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *
}
}
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)calloc(1, sizeof(esp_gatt_rsp_t));
if (gatt_rsp) {
gatt_rsp->attr_value.len = param->write.len;
gatt_rsp->attr_value.handle = param->write.handle;
gatt_rsp->attr_value.offset = param->write.offset;
gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
if (status == ESP_GATT_OK) {
if (param->write.value == NULL) {
status = ESP_GATT_INVALID_ATTR_LEN;
} else {
gatt_rsp->attr_value.len = param->write.len;
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
}
}
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
if (response_err != ESP_OK) {
ESP_LOGE(COEX_TAG, "Send response error\n");
@@ -605,15 +630,29 @@ static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *
free(gatt_rsp);
} else {
ESP_LOGE(COEX_TAG, "%s, malloc failed", __func__);
status = ESP_GATT_NO_RESOURCES;
if (status == ESP_GATT_OK) {
status = ESP_GATT_NO_RESOURCES;
}
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id,
param->write.trans_id, status, NULL);
if (response_err != ESP_OK) {
ESP_LOGE(COEX_TAG, "Send response error\n");
}
}
if (status != ESP_GATT_OK) {
return;
}
memcpy(prepare_write_env->prepare_buf + param->write.offset,
memcpy(prepare_write_env->prepare_buf + w_off,
param->write.value,
param->write.len);
prepare_write_env->prepare_len += param->write.len;
w_len);
/* High-water end of written range (not sum of chunk lengths). */
int chunk_end = (int)(w_off + w_len);
if (chunk_end > prepare_write_env->prepare_len) {
prepare_write_env->prepare_len = chunk_end;
}
if (prepare_write_env->prepare_len > PREPARE_BUF_MAX_SIZE) {
prepare_write_env->prepare_len = PREPARE_BUF_MAX_SIZE;
}
} else {
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL);
@@ -624,15 +663,17 @@ static void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *
static void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
{
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
ESP_LOG_BUFFER_HEX(COEX_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
if (prepare_write_env->prepare_buf != NULL && prepare_write_env->prepare_len > 0) {
size_t log_len = (size_t)prepare_write_env->prepare_len;
if (log_len > PREPARE_BUF_MAX_SIZE) {
log_len = PREPARE_BUF_MAX_SIZE;
}
ESP_LOG_BUFFER_HEX(COEX_TAG, prepare_write_env->prepare_buf, log_len);
}
} else {
ESP_LOGI(COEX_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
}
if (prepare_write_env->prepare_buf) {
free(prepare_write_env->prepare_buf);
prepare_write_env->prepare_buf = NULL;
}
prepare_write_env->prepare_len = 0;
prepare_write_env_free(prepare_write_env);
}
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
@@ -793,6 +834,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
}
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(COEX_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
prepare_write_env_free(&a_prepare_write_env);
if (memcmp(peer_gatts_addr, param->disconnect.remote_bda, sizeof(esp_bd_addr_t))) {
// If the peer device is a GATT client, restart advertising
esp_ble_gap_start_advertising(&adv_params);
@@ -800,7 +842,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
case ESP_GATTS_CONF_EVT:
ESP_LOGI(COEX_TAG, "ESP_GATTS_CONF_EVT, status %d attr_handle %d", param->conf.status, param->conf.handle);
if (param->conf.status != ESP_GATT_OK) {
if (param->conf.status == ESP_GATT_OK && param->conf.value != NULL && param->conf.len > 0) {
ESP_LOG_BUFFER_HEX(COEX_TAG, param->conf.value, param->conf.len);
}
break;
@@ -941,11 +983,14 @@ static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
case ESP_GATTS_CONF_EVT:
ESP_LOGI(COEX_TAG, "ESP_GATTS_CONF_EVT status %d attr_handle %d", param->conf.status, param->conf.handle);
if (param->conf.status != ESP_GATT_OK) {
if (param->conf.status == ESP_GATT_OK && param->conf.value != NULL && param->conf.len > 0) {
ESP_LOG_BUFFER_HEX(COEX_TAG, param->conf.value, param->conf.len);
}
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(COEX_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
prepare_write_env_free(&b_prepare_write_env);
break;
case ESP_GATTS_OPEN_EVT:
default:
break;