From 36505e1c827e69f0df72478ae58dd2c99e01bc27 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 11 Dec 2023 18:13:22 +0800 Subject: [PATCH 1/2] 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 | 13 +++++------ .../Gatt_Server_Example_Walkthrough.md | 23 ++++++++----------- .../main/gatts_table_creat_demo.c | 14 +++++------ .../coex/a2dp_gatts_coex/main/main.c | 14 +++++------ .../gattc_gatts_coex/main/gattc_gatts_coex.c | 13 +++++------ 7 files changed, 51 insertions(+), 56 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..60b5a04789 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 321d241e61..e28bf00fbb 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 @@ -281,20 +281,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..96ff62f7e8 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -242,19 +242,18 @@ 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) { - 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..9b6527a99d 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,21 +770,19 @@ 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)); @@ -798,7 +796,6 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare if (response_err != ESP_OK){ ESP_LOGE(GATTS_TAG, "Send response error\n"); } - free(gatt_rsp); if (status != ESP_GATT_OK){ return; } @@ -850,9 +847,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..9ad5d8c00f 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 c009f93744..ac7e1eba6d 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -198,19 +198,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(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..4f48b34496 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)); From f561706053eb98daa97ed7bc407a3f6a1c000687 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 11 Dec 2023 17:41:24 +0800 Subject: [PATCH 2/2] fix(bt/bluedroid): Fix BLE prepare write --- components/bt/host/bluedroid/stack/gatt/gatt_db.c | 13 ++++++++----- components/bt/host/bluedroid/stack/gatt/gatt_sr.c | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_db.c b/components/bt/host/bluedroid/stack/gatt/gatt_db.c index 4aebc30f40..e84580bc95 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -1241,15 +1241,18 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, // btla-specific ++ else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) && (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || - p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG) ) + p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG || + p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT || + p_attr->uuid == GATT_UUID_GAP_ICON + ) ) // btla-specific -- { - if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) { /* does not allow write blob */ - status = GATT_NOT_LONG; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG,handle:0x%04x",handle); + if (op_code == GATT_REQ_PREPARE_WRITE) { /* does not allow write blob */ + status = GATT_REQ_NOT_SUPPORTED; + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,handle:0x%04x",handle); } else if (len != max_size) { /* data does not match the required format */ status = GATT_INVALID_ATTR_LEN; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU,handle:0x%04x",handle); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_ATTR_LEN,handle:0x%04x",handle); } else { status = GATT_SUCCESS; } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 1510f44871..a1c07c9d4e 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -1448,8 +1448,9 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand } if ((prepare_record->error_code_app == GATT_SUCCESS) - && ((status == GATT_INVALID_OFFSET) || (status == GATT_INVALID_ATTR_LEN))){ - prepare_record->error_code_app = status; + // update prepare write status for excute write request + && (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) { + prepare_record->error_code_app = status; } }