fix(ble/bluedroid): fix GATT client API parameter validation

(cherry picked from commit 653477c3e9)

Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
Zhi Wei Jian
2026-06-10 19:53:36 +08:00
parent 99a9a87fa3
commit b9eaab2dce
2 changed files with 126 additions and 46 deletions

View File

@@ -397,7 +397,9 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
@@ -415,14 +417,16 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
esp_gattc_char_elem_t *result,
uint16_t *count, uint16_t offset)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
if ((start_handle == 0) && (end_handle == 0)) {
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -437,7 +441,9 @@ esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
esp_gattc_descr_elem_t *result,
uint16_t *count, uint16_t offset)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (char_handle == 0) {
return ESP_GATT_INVALID_HANDLE;
@@ -459,13 +465,15 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
esp_gattc_char_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
if (start_handle == 0 && end_handle == 0) {
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -484,12 +492,19 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
uint16_t conn_hdl = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
return btc_ble_gattc_get_descr_by_uuid(conn_hdl, start_handle, end_handle, char_uuid, descr_uuid, result, count);
}
@@ -501,7 +516,9 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
esp_gattc_descr_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
@@ -524,13 +541,15 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
esp_gattc_incl_svc_elem_t *result,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (result == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
if (start_handle == 0 && end_handle == 0) {
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -547,13 +566,17 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t char_handle,
uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (count == NULL) {
return ESP_GATT_INVALID_PDU;
}
if ((start_handle == 0 && end_handle == 0) && (type != ESP_GATT_DB_DESCRIPTOR)) {
/* start_handle/end_handle are ignored for ESP_GATT_DB_DESCRIPTOR (see esp_gattc_api.h). */
if (type != ESP_GATT_DB_DESCRIPTOR &&
((start_handle == 0 && end_handle == 0) || start_handle > end_handle)) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -565,14 +588,16 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
esp_gattc_db_elem_t *db, uint16_t *count)
{
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_GATT_WRONG_STATE;
}
if (db == NULL || count == NULL || *count == 0) {
return ESP_GATT_INVALID_PDU;
}
if (start_handle == 0 && end_handle == 0) {
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
*count = 0;
return ESP_GATT_INVALID_HANDLE;
}
@@ -644,10 +669,14 @@ esp_err_t esp_ble_gattc_read_by_type (esp_gatt_if_t gattc_if,
return ESP_FAIL;
}
if (start_handle == 0 || end_handle == 0) {
if ((start_handle == 0 && end_handle == 0) || start_handle > end_handle) {
return ESP_GATT_INVALID_HANDLE;
}
if (start_handle == 0) {
start_handle = 1;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_BY_TYPE;
@@ -670,7 +699,12 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((read_multi == NULL) || (read_multi->num_attr == 0) || (read_multi->num_attr > ESP_GATT_MAX_READ_MULTI_HANDLES)) {
if (read_multi == NULL) {
return ESP_ERR_INVALID_ARG;
}
uint8_t num_attr = read_multi->num_attr;
if ((num_attr == 0) || (num_attr > ESP_GATT_MAX_READ_MULTI_HANDLES)) {
return ESP_ERR_INVALID_ARG;
}
@@ -689,10 +723,10 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_MULTIPLE_CHAR;
arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
arg.read_multiple.num_attr = read_multi->num_attr;
arg.read_multiple.num_attr = num_attr;
arg.read_multiple.auth_req = auth_req;
memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr);
memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t) * num_attr);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
@@ -707,7 +741,12 @@ esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((read_multi == NULL) || (read_multi->num_attr == 0) || (read_multi->num_attr > ESP_GATT_MAX_READ_MULTI_HANDLES)) {
if (read_multi == NULL) {
return ESP_ERR_INVALID_ARG;
}
uint8_t num_attr = read_multi->num_attr;
if ((num_attr == 0) || (num_attr > ESP_GATT_MAX_READ_MULTI_HANDLES)) {
return ESP_ERR_INVALID_ARG;
}
@@ -726,9 +765,9 @@ esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if,
msg.pid = BTC_PID_GATTC;
msg.act = BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR;
arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
arg.read_multiple.num_attr = read_multi->num_attr;
arg.read_multiple.num_attr = num_attr;
arg.read_multiple.auth_req = auth_req;
memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr);
memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t) * num_attr);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
@@ -829,6 +868,10 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((value_len > 0) && (value == NULL)) {
return ESP_ERR_INVALID_ARG;
}
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
LOG_WARN("%s, The connection not created.", __func__);
@@ -873,6 +916,10 @@ esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((value_len > 0) && (value == NULL)) {
return ESP_ERR_INVALID_ARG;
}
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
LOG_WARN("%s, The connection not created.", __func__);
@@ -915,6 +962,10 @@ esp_err_t esp_ble_gattc_prepare_write_char_descr(esp_gatt_if_t gattc_if,
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
if ((value_len > 0) && (value == NULL)) {
return ESP_ERR_INVALID_ARG;
}
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
LOG_WARN("%s, The connection not created.", __func__);

View File

@@ -519,8 +519,12 @@ esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id,
* 2. `esp_ble_gattc_cache_refresh` can be used to discover services again.
*
* @return
* - ESP_OK: Success
* - ESP_FAIL: Failure
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_GATT_NOT_FOUND: No matching service was found in the local cache
* - ESP_GATT_INVALID_OFFSET: `offset` is out of range of the matched services
* - ESP_GATT_NO_RESOURCES: Failed to allocate memory for the UUID lookup
*/
esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *svc_uuid,
esp_gattc_service_elem_t *result, uint16_t *count, uint16_t offset);
@@ -538,13 +542,17 @@ esp_gatt_status_t esp_ble_gattc_get_service(esp_gatt_if_t gattc_if, uint16_t con
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 2. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and matches
* cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No characteristic found in the given handle range
* - ESP_GATT_INVALID_OFFSET: `offset` is out of range of the matched characteristics
*/
esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -568,10 +576,12 @@ esp_gatt_status_t esp_ble_gattc_get_all_char(esp_gatt_if_t gattc_if,
* 2. `char_handle` must be greater than 0.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `char_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No descriptor found under the given characteristic
* - ESP_GATT_INVALID_OFFSET: `offset` is out of range of the matched descriptors
*/
esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -592,13 +602,16 @@ esp_gatt_status_t esp_ble_gattc_get_all_descr(esp_gatt_if_t gattc_if,
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 2. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and matches
* cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No characteristic matching `char_uuid` found in the handle range
*/
esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -622,12 +635,16 @@ esp_gatt_status_t esp_ble_gattc_get_char_by_uuid(esp_gatt_if_t gattc_if,
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 2. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and matches
* cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No descriptor matching the given UUIDs found in the handle range
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -653,10 +670,11 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_uuid(esp_gatt_if_t gattc_if,
* 2. `char_handle` must be greater than 0.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `char_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No descriptor matching `descr_uuid` found under `char_handle`
*/
esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -678,12 +696,16 @@ esp_gatt_status_t esp_ble_gattc_get_descr_by_char_handle(esp_gatt_if_t gattc_if,
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 2. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and matches
* cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle` or `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `result` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No included service matching `incl_uuid` found in the handle range
*/
esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -707,13 +729,15 @@ esp_gatt_status_t esp_ble_gattc_get_include_service(esp_gatt_if_t gattc_if,
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle` if the `type` is not `ESP_GATT_DB_DESCRIPTOR`.
* 2. If the `type` is not `ESP_GATT_DB_DESCRIPTOR`, `start_handle` must not be greater than
* `end_handle`, and `start_handle` and `end_handle` must not both be 0. 0 is allowed for
* `start_handle` alone and matches cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle`, `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `count`
* - ESP_FAIL: Failure due to other reasons
*/
esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
uint16_t conn_id,
@@ -735,13 +759,16 @@ esp_gatt_status_t esp_ble_gattc_get_attr_count(esp_gatt_if_t gattc_if,
*
* @note
* 1. This API does not trigger any event.
* 2. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 2. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and matches
* cached attributes from the beginning of the handle range.
*
* @return
* - ESP_OK: Success
* - ESP_GATT_OK: Success
* - ESP_GATT_WRONG_STATE: Bluedroid stack is not enabled
* - ESP_GATT_INVALID_HANDLE: Invalid GATT `start_handle`, `end_handle`
* - ESP_GATT_INVALID_PDU: NULL pointer to `db` or NULL pointer to `count` or the count value is 0
* - ESP_FAIL: Failure due to other reasons
* - ESP_GATT_NOT_FOUND: No GATT database element found in the given handle range
*
*/
esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
@@ -784,7 +811,9 @@ esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
* @note
* 1. This function triggers `ESP_GATTC_READ_CHAR_EVT`.
* 2. This function should be called only after the connection has been established.
* 3. `start_handle` must be greater than 0, and smaller than `end_handle`.
* 3. `start_handle` must not be greater than `end_handle`, and `start_handle` and
* `end_handle` must not both be 0. 0 is allowed for `start_handle` alone and is
* treated as 1 on air.
*
* @return
* - ESP_OK: Success