mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user