From 36169e6beb8d777e97fbd4eb244bdddba5dedf57 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 11 Dec 2023 18:13:22 +0800 Subject: [PATCH] fix(bt/bluedroid): Fix prepare write for BLE example --- .../main/ble_compatibility_test.c | 15 +++--- .../main/example_ble_server_throughput.c | 15 +++--- .../ble/gatt_server/main/gatts_demo.c | 15 +++--- .../Gatt_Server_Example_Walkthrough.md | 48 ++++++++++--------- .../main/gatts_table_creat_demo.c | 14 +++--- .../coex/a2dp_gatts_coex/main/main.c | 16 +++---- .../gattc_gatts_coex/main/gattc_gatts_coex.c | 13 +++-- .../main/ble_helper/bluedroid_gatts.c | 48 ++++++++++++------- 8 files changed, 100 insertions(+), 84 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 dc4dc278fe..69e3dd627f 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 @@ -387,20 +387,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 260e435288..d910aade1c 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 @@ -282,20 +282,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 049def0716..35409170e8 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -241,20 +241,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 2f7ccdba80..3c230a6748 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; } @@ -828,7 +830,7 @@ 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{ 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 669b52d7d1..28ecae1a6e 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 @@ -283,20 +283,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)); 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 26065fba61..cec089a104 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -198,20 +198,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 def836866f..8da784bb9f 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 @@ -526,19 +526,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 c8fd0e5917..bc95156d60 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 @@ -105,43 +105,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); } }