From 73da8018c5afdb49bda4182cfff97ae2bd26446a Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Thu, 21 Dec 2023 10:51:31 +0800 Subject: [PATCH] fix(bt/bluedroid): Fix prepare write for BLE example --- .../main/ble_compatibility_test.c | 17 +++--- .../main/example_ble_server_throughput.c | 17 +++--- .../ble/gatt_server/main/gatts_demo.c | 15 +++--- .../Gatt_Server_Example_Walkthrough.md | 52 ++++++++++--------- .../main/gatts_table_creat_demo.c | 16 +++--- .../coex/a2dp_gatts_coex/main/main.c | 18 +++---- .../gattc_gatts_coex/main/gattc_gatts_coex.c | 15 +++--- .../main/ble_helper/bluedroid_gatts.c | 50 ++++++++++++------ 8 files changed, 108 insertions(+), 92 deletions(-) diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c index 82fb7aad1cd..8050dbc7750 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -385,20 +385,21 @@ void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t { EXAMPLE_DEBUG(EXAMPLE_TAG, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len); esp_gatt_status_t status = ESP_GATT_OK; - if (prepare_write_env->prepare_buf == NULL) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(EXAMPLE_TAG, "%s, Gatt_server prep no mem", __func__); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } + /*send response when param->write.need_rsp is true */ if (param->write.need_rsp){ esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c index fa981ab51a4..58176e3101a 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -280,20 +280,19 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare esp_gatt_status_t status = ESP_GATT_OK; if (param->write.need_rsp) { if (param->write.is_prep) { - if (prepare_write_env->prepare_buf == NULL) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE || - prepare_write_env->prepare_len > param->write.offset) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c index 19d7eb56b79..eb2a48120c2 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -242,20 +242,19 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ esp_gatt_status_t status = ESP_GATT_OK; if (param->write.need_rsp){ - if (param->write.is_prep){ - if (prepare_write_env->prepare_buf == NULL) { + if (param->write.is_prep) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md index 584fa1f7787..cede36fccd6 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md +++ b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md @@ -770,35 +770,37 @@ The `example_write_event_env()` function contains the logic for the write long c void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ esp_gatt_status_t status = ESP_GATT_OK; if (param->write.need_rsp){ - if (param->write.is_prep){ - if (prepare_write_env->prepare_buf == NULL){ + if (param->write.is_prep) { + if(param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } - else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); - 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); - 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(GATTS_TAG, "Send response error\n"); + 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); + 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(GATTS_TAG, "Send response error\n"); + } + free(gatt_rsp); + } else { + ESP_LOGE(GATTS_TAG, "malloc failed, no resource to send response error\n"); + status = ESP_GATT_NO_RESOURCES; } - free(gatt_rsp); if (status != ESP_GATT_OK){ return; } @@ -807,7 +809,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare param->write.len); prepare_write_env->prepare_len += param->write.len; - }else{ + } else { esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL); } } @@ -828,9 +830,9 @@ The function then checks if the Prepare Write Request parameter represented by t ```c … -if (param->write.is_prep){ +if (param->write.is_prep) { … -}else{ +} else { esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL); } … @@ -850,9 +852,9 @@ static prepare_type_env_t b_prepare_write_env; In order to use the prepare buffer, some memory space is allocated for it. In case the allocation fails due to a lack of memory, an error is printed: ```c -if (prepare_write_env->prepare_buf == NULL) { - prepare_write_env->prepare_buf = - (uint8_t*)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); +if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { + prepare_write_env->prepare_buf = + (uint8_t*)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n"); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c index ae0025692b4..52978dcabf6 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -281,20 +281,20 @@ void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t { ESP_LOGI(GATTS_TABLE_TAG, "prepare write, handle = %d, value len = %d", param->write.handle, param->write.len); esp_gatt_status_t status = ESP_GATT_OK; - if (prepare_write_env->prepare_buf == NULL) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(GATTS_TABLE_TAG, "%s, Gatt_server prep no mem", __func__); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } + /*send response when param->write.need_rsp is true */ if (param->write.need_rsp){ esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); @@ -305,7 +305,7 @@ void example_prepare_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE; 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){ + if (response_err != ESP_OK) { ESP_LOGE(GATTS_TABLE_TAG, "Send response error"); } free(gatt_rsp); diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 8de8f9315fe..e510329c974 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -197,20 +197,20 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param){ esp_gatt_status_t status = ESP_GATT_OK; if (param->write.need_rsp){ - if (param->write.is_prep){ - if (prepare_write_env->prepare_buf == NULL) { + if (param->write.is_prep) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(BT_BLE_COEX_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c index 7dc7731362e..2db3b205594 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -525,19 +525,18 @@ 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 (prepare_write_env->prepare_buf == NULL) { + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE*sizeof(uint8_t)); prepare_write_env->prepare_len = 0; if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(COEX_TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if(param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c index 60843e796bf..1cc9706b4a2 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -99,43 +99,59 @@ void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param) { esp_gatt_status_t status = ESP_GATT_OK; + + // Check if a response is needed if (param->write.need_rsp) { + // Check if the write operation is a prepared write if (param->write.is_prep) { - if (prepare_write_env->prepare_buf == NULL) { + // Check for invalid offset or attribute length + if (param->write.offset > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_OFFSET; + } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { + status = ESP_GATT_INVALID_ATTR_LEN; + } + // Allocate memory for the prepare buffer if not already allocated + if (status == ESP_GATT_OK && prepare_write_env->prepare_buf == NULL) { prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t)); prepare_write_env->prepare_len = 0; + + // Check for allocation failure if (prepare_write_env->prepare_buf == NULL) { ESP_LOGE(TAG, "Gatt_server prep no mem\n"); status = ESP_GATT_NO_RESOURCES; } - } else { - if (param->write.offset > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_OFFSET; - } else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE) { - status = ESP_GATT_INVALID_ATTR_LEN; - } } + // Allocate and configure the GATT response esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t)); - 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); - 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(TAG, "Send response error\n"); + if (gatt_rsp != NULL) { + 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); + 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(TAG, "Send response error"); + } + free(gatt_rsp); + } else { + ESP_LOGE(TAG, "%s, malloc failed, and no resource to send response", __func__); + status = ESP_GATT_NO_RESOURCES; } - free(gatt_rsp); + if (status != ESP_GATT_OK) { return; } + + // Update the prepare buffer with the received data memcpy(prepare_write_env->prepare_buf + param->write.offset, param->write.value, param->write.len); prepare_write_env->prepare_len += param->write.len; } else { + // Send a response for non-prepared write esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL); } }