diff --git a/components/bt/host/bluedroid/api/esp_gattc_api.c b/components/bt/host/bluedroid/api/esp_gattc_api.c index 40f3d82d65..44d932d512 100644 --- a/components/bt/host/bluedroid/api/esp_gattc_api.c +++ b/components/bt/host/bluedroid/api/esp_gattc_api.c @@ -447,6 +447,41 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + 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__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + 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.auth_req = auth_req; + + if (read_multi->num_attr > 0) { + memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr); + } else { + LOG_ERROR("%s(), the num_attr should not be 0.", __func__); + return ESP_FAIL; + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t handle, diff --git a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h index 43a385aac0..580bc9858a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -68,6 +68,7 @@ typedef enum { ESP_GATTC_SET_ASSOC_EVT = 44, /*!< When the ble gattc set the associated address complete, the event comes */ ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< When the ble get gattc address list in cache finish, the event comes */ ESP_GATTC_DIS_SRVC_CMPL_EVT = 46, /*!< When the ble discover service complete, the event comes */ + ESP_GATTC_READ_MULTI_VAR_EVT = 47, /*!< When read multiple variable characteristic complete, the event comes */ } esp_gattc_cb_event_t; @@ -661,6 +662,23 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_gattc_multi_t *read_multi, esp_gatt_auth_req_t auth_req); +/** + * @brief This function is called to read multiple variable length characteristic or + * characteristic descriptors. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] read_multi : pointer to the read multiple parameter. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req); /** * @brief This function is called to read a characteristics descriptor. diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index d3ffd85a86..94827ff74b 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -1175,6 +1175,37 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } /******************************************************************************* ** +** Function bta_gattc_read_multi_var +** +** Description read multiple variable +** +** Returns None. +*********************************************************************************/ +void bta_gattc_read_multi_var(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) +{ + tBTA_GATT_STATUS status = BTA_GATT_OK; + tGATT_READ_PARAM read_param; + + if (bta_gattc_enqueue(p_clcb, p_data)) { + memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); + + if (status == BTA_GATT_OK) { + read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr; + read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req; + memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles, + sizeof(UINT16) * p_data->api_read_multi.num_attr); + + status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE_VAR, &read_param); + } + + /* read fail */ + if (status != BTA_GATT_OK) { + bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); + } + } +} +/******************************************************************************* +** ** Function bta_gattc_write ** ** Description Write an attribute @@ -1290,7 +1321,8 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle; } - if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) { + if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT && + p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT) { event = p_clcb->p_q_cmd->api_read.cmpl_evt; } else { event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt; @@ -1427,7 +1459,9 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) return; } if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) { - if ((p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT)&&(p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_BY_TYPE_EVT)) { + if ((p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) && + (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_BY_TYPE_EVT) && + (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT)) { mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ; if ( mapped_op > GATTC_OPTYPE_INDICATION) { mapped_op = 0; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c index f5e17a977c..3e42603aeb 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -563,6 +563,42 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, return; } +/******************************************************************************* +** +** Function BTA_GATTC_ReadMultipleVariable +** +** Description This function is called to read multiple variable length characteristic or +** characteristic descriptors. +** +** Parameters conn_id - connection ID. +** p_read_multi - pointer to the read multiple parameter. +** +** Returns None +** +*******************************************************************************/ +void BTA_GATTC_ReadMultipleVariable(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, + tBTA_GATT_AUTH_REQ auth_req) +{ + tBTA_GATTC_API_READ_MULTI *p_buf; + UINT16 len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI)); + + if ((p_buf = (tBTA_GATTC_API_READ_MULTI *) osi_malloc(len)) != NULL) { + memset(p_buf, 0, len); + + p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_VAR_EVT; + p_buf->hdr.layer_specific = conn_id; + p_buf->auth_req = auth_req; + p_buf->num_attr = p_read_multi->num_attr; + p_buf->cmpl_evt = BTA_GATTC_READ_MULTI_VAR_EVT; + if (p_buf->num_attr > 0) { + memcpy(p_buf->handles, p_read_multi->handles, sizeof(UINT16) * p_read_multi->num_attr); + } + + bta_sys_sendmsg(p_buf); + } + return; +} + /******************************************************************************* ** ** Function BTA_GATTC_Read_by_type @@ -1181,30 +1217,5 @@ uint8_t BTA_GATTC_ReadLongChar(uint8_t gatt_if, uint16_t conn_id, uint16_t handl return 0; } - -uint8_t BTA_GATTC_ReadMultiVariableChar(uint8_t gatt_if, uint16_t conn_id, uint16_t num_handles, uint16_t *handles, uint8_t auth_req) -{ - tGATT_STATUS status; - tGATT_READ_PARAM read_param; - - if (num_handles > GATT_MAX_READ_MULTI_HANDLES) { - APPL_TRACE_ERROR("%s max read multi handlse %x", __func__, num_handles); - return -1; - } - - conn_id = (UINT16)((((UINT8)conn_id) << 8) | gatt_if); - memset (&read_param, 0, sizeof(tGATT_READ_PARAM)); - read_param.read_multiple.num_handles = num_handles; - memcpy(read_param.read_multiple.handles, handles, num_handles); - read_param.read_multiple.auth_req = auth_req; - - status = GATTC_Read(conn_id, GATT_READ_MULTIPLE_VAR, &read_param); - if (status != GATT_SUCCESS) { - APPL_TRACE_ERROR("%s status %x", __func__, status); - return -1; - } - - return 0; -} /* End BLE PTS */ #endif /* defined(GATTC_INCLUDED) && (GATTC_INCLUDED == TRUE) */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c index bf5a9a9270..1b7cde80d0 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c @@ -66,6 +66,7 @@ enum { BTA_GATTC_RESTART_DISCOVER, BTA_GATTC_CFG_MTU, BTA_GATTC_READ_BY_TYPE, + BTA_GATTC_READ_MULTI_VAR, BTA_GATTC_IGNORE }; @@ -100,7 +101,8 @@ const tBTA_GATTC_ACTION bta_gattc_action[] = { bta_gattc_disc_close, bta_gattc_restart_discover, bta_gattc_cfg_mtu, - bta_gattc_read_by_type + bta_gattc_read_by_type, + bta_gattc_read_multi_var, }; @@ -137,6 +139,7 @@ static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST}, }; /* state table for wait for open state */ @@ -167,6 +170,7 @@ static const UINT8 bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST}, }; /* state table for open state */ @@ -198,6 +202,7 @@ static const UINT8 bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_READ_BY_TYPE, BTA_GATTC_CONN_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_READ_MULTI_VAR, BTA_GATTC_CONN_ST}, }; /* state table for discover state */ @@ -228,6 +233,7 @@ static const UINT8 bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST}, }; /* type for state table */ @@ -487,6 +493,8 @@ static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code) return "BTA_GATTC_API_CFG_MTU_EVT"; case BTA_GATTC_API_READ_BY_TYPE_EVT: return "BTA_GATTC_API_READ_BY_TYPE_EVT"; + case BTA_GATTC_API_READ_MULTI_VAR_EVT: + return "BTA_GATTC_API_READ_MULTI_VAR_EVT"; default: return "unknown GATTC event code"; } diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h index 011d03416e..e6bb449e93 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h @@ -61,6 +61,7 @@ enum { BTA_GATTC_INT_DISCONN_EVT, BTA_GATTC_API_READ_BY_TYPE_EVT, + BTA_GATTC_API_READ_MULTI_VAR_EVT, BTA_GATTC_INT_START_IF_EVT, BTA_GATTC_API_REG_EVT, @@ -469,6 +470,7 @@ extern void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); +extern void bta_gattc_read_multi_var(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ci_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h index 111af5a313..655458b961 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h @@ -185,6 +185,7 @@ typedef UINT8 tBTA_GATT_STATUS; #define BTA_GATTC_ASSOC_EVT 39 /* GATTC association address event */ #define BTA_GATTC_GET_ADDR_LIST_EVT 40 /* GATTC get address list in the cache event */ #define BTA_GATTC_DIS_SRVC_CMPL_EVT 41 /* GATTC discover service complete */ +#define BTA_GATTC_READ_MULTI_VAR_EVT 42 /* GATTC read multiple variable event */ typedef UINT8 tBTA_GATTC_EVT; @@ -1137,6 +1138,21 @@ extern void BTA_GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute); extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, tBTA_GATT_AUTH_REQ auth_req); +/******************************************************************************* +** +** Function BTA_GATTC_ReadMultiple +** +** Description This function is called to read multiple variable length characteristic or +** characteristic descriptors. +** +** Parameters conn_id - connection ID. +** p_read_multi - read multiple parameters. +** +** Returns None +** +*******************************************************************************/ +extern void BTA_GATTC_ReadMultipleVariable(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, + tBTA_GATT_AUTH_REQ auth_req); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index 3db904cd96..8afbae2915 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -122,7 +122,8 @@ static void btc_gattc_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src) switch (msg->act) { case BTA_GATTC_READ_DESCR_EVT: case BTA_GATTC_READ_CHAR_EVT: - case BTA_GATTC_READ_MULTIPLE_EVT: { + case BTA_GATTC_READ_MULTIPLE_EVT: + case BTA_GATTC_READ_MULTI_VAR_EVT: { if (p_src_data->read.p_value && p_src_data->read.p_value->p_value) { p_dest_data->read.p_value = (tBTA_GATT_UNFMT *)osi_malloc(sizeof(tBTA_GATT_UNFMT) + p_src_data->read.p_value->len); p_dest_data->read.p_value->p_value = (uint8_t *)(p_dest_data->read.p_value + 1); @@ -158,7 +159,8 @@ static void btc_gattc_free_req_data(btc_msg_t *msg) switch (msg->act) { case BTA_GATTC_READ_DESCR_EVT: case BTA_GATTC_READ_CHAR_EVT: - case BTA_GATTC_READ_MULTIPLE_EVT: { + case BTA_GATTC_READ_MULTIPLE_EVT: + case BTA_GATTC_READ_MULTI_VAR_EVT: { if (arg->read.p_value) { osi_free(arg->read.p_value); } @@ -604,6 +606,14 @@ static void btc_gattc_read_multiple_char(btc_ble_gattc_args_t *arg) BTA_GATTC_ReadMultiple(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); } +static void btc_gattc_read_multiple_variable_char(btc_ble_gattc_args_t *arg) +{ + tBTA_GATTC_MULTI bta_multi; + bta_multi.num_attr = arg->read_multiple.num_attr; + memcpy(bta_multi.handles, arg->read_multiple.handles, BTA_GATTC_MULTI_MAX); + BTA_GATTC_ReadMultipleVariable(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); +} + static void btc_gattc_read_char_descr(btc_ble_gattc_args_t *arg) { BTA_GATTC_ReadCharDescr(arg->read_descr.conn_id, arg->read_descr.handle, arg->read_descr.auth_req); @@ -727,6 +737,9 @@ void btc_gattc_call_handler(btc_msg_t *msg) case BTC_GATTC_ACT_READ_MULTIPLE_CHAR: btc_gattc_read_multiple_char(arg); break; + case BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR: + btc_gattc_read_multiple_variable_char(arg); + break; case BTC_GATTC_ACT_READ_CHAR_DESCR: btc_gattc_read_char_descr(arg); break; @@ -864,6 +877,11 @@ void btc_gattc_cb_handler(btc_msg_t *msg) btc_gattc_cb_to_app(ESP_GATTC_READ_MULTIPLE_EVT, gattc_if, ¶m); break; } + case BTA_GATTC_READ_MULTI_VAR_EVT: { + set_read_value(&gattc_if, ¶m, &arg->read); + btc_gattc_cb_to_app(ESP_GATTC_READ_MULTI_VAR_EVT, gattc_if, ¶m); + break; + } case BTA_GATTC_WRITE_DESCR_EVT: { tBTA_GATTC_WRITE *write = &arg->write; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h index b73d94ff79..53a31fee6f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h @@ -32,6 +32,7 @@ typedef enum { BTC_GATTC_ACT_SEARCH_SERVICE, BTC_GATTC_ACT_READ_CHAR, BTC_GATTC_ACT_READ_MULTIPLE_CHAR, + BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR, BTC_GATTC_ACT_READ_CHAR_DESCR, BTC_GATTC_ACT_READ_BY_TYPE, BTC_GATTC_ACT_WRITE_CHAR,