From 4145099bdc0fb3628fddd21a7cf81d288dee78fa Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 12:15:25 +0800 Subject: [PATCH 01/12] bluedroid: support oob pairing for smp secure connection --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 34 +++++++++- .../api/include/api/esp_gap_ble_api.h | 33 +++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 45 +++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 51 +++++++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_co.c | 4 -- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 2 + .../bluedroid/bta/dm/include/bta_dm_int.h | 20 ++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 36 +++++++++- .../bt/host/bluedroid/btc/core/btc_dm.c | 15 ++++- .../btc/profile/std/gap/btc_gap_ble.c | 40 ++++++++++- .../btc/profile/std/include/btc_gap_ble.h | 9 ++- .../bt/host/bluedroid/stack/btm/btm_ble.c | 66 ++++++++++++++++++- .../bluedroid/stack/include/stack/btm_api.h | 1 + .../stack/include/stack/btm_ble_api.h | 23 +++++++ .../bluedroid/stack/include/stack/smp_api.h | 6 +- .../bluedroid/stack/smp/include/smp_int.h | 3 + .../bt/host/bluedroid/stack/smp/smp_act.c | 11 +++- .../bt/host/bluedroid/stack/smp/smp_api.c | 28 ++------ .../bt/host/bluedroid/stack/smp/smp_keys.c | 59 +++++++++++++++-- .../bt/host/bluedroid/stack/smp/smp_utils.c | 2 + 20 files changed, 440 insertions(+), 48 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 535f8c2e59..5d48642325 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -729,6 +729,38 @@ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len) btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]) +{ + if (!p_c || !p_r) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT; + memcpy(arg.sc_oob_req_reply.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + arg.sc_oob_req_reply.p_c = p_c; + arg.sc_oob_req_reply.p_r = p_r; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, + btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_create_sc_oob_data(void) +{ + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SC_CR_OOB_DATA_EVT; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} #endif /* #if (SMP_INCLUDED == TRUE) */ esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index cf70cc62b8..bf7ef3b33f 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -586,6 +586,13 @@ typedef struct { esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */ } esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/ +/** +* @brief structure type of the ble local oob data value +*/ +typedef struct { + esp_bt_octet16_t oob_c; /*!< the 128 bits of confirmation value */ + esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */ +} esp_ble_local_oob_data_t; /** * @brief Structure associated with ESP_AUTH_CMPL_EVT @@ -612,6 +619,7 @@ typedef union esp_ble_sec_req_t ble_req; /*!< BLE SMP related request */ esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */ esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */ + esp_ble_local_oob_data_t oob_data; /*!< BLE SMP secure connection OOB data */ esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */ } esp_ble_sec_t; /*!< BLE security type */ #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -1790,6 +1798,29 @@ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_lis */ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len); +/** +* @brief This function is called to provide the OOB data for +* SMP in response to ESP_GAP_BLE_SC_OOB_REQ_EVT +* +* @param[in] bd_addr: BD address of the peer device. +* @param[in] p_c: Confirmation value, it shall be a 128-bit random number +* @param[in] p_r: Randomizer value, it should be a 128-bit random number +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16]); + +/** +* @brief This function is called to create the OOB data for +* SMP when secure connection +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_create_sc_oob_data(void); #endif /* #if (SMP_INCLUDED == TRUE) */ /** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 9e007eb12c..a8c4e7f396 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -1443,6 +1443,40 @@ void bta_dm_oob_reply(tBTA_DM_MSG *p_data) #endif } +/******************************************************************************* +** +** Function bta_dm_sc_oob_reply +** +** Description This function is called to provide the OOB data for +** SMP in response to BLE secure connection OOB request. +** +** Returns void +** +*******************************************************************************/ +void bta_dm_sc_oob_reply(tBTA_DM_MSG *p_data) +{ +#if (BLE_INCLUDED) + BTM_BleSecureConnectionOobDataReply(p_data->sc_oob_reply.bd_addr, p_data->sc_oob_reply.c, p_data->sc_oob_reply.r); +#endif +} + +/******************************************************************************* +** +** Function bta_dm_sc_create_oob_data +** +** Description This function is called to create the OOB data for +** SMP when secure connection. +** +** Returns void +** +*******************************************************************************/ +void bta_dm_sc_create_oob_data(tBTA_DM_MSG *p_data) +{ +#if (BLE_INCLUDED) + BTM_BleSecureConnectionCreateOobData(); +#endif +} + /******************************************************************************* ** ** Function bta_dm_ci_io_req_act @@ -4729,6 +4763,17 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event); break; + case BTM_LE_SC_OOB_REQ_EVT: + bdcpy(sec_event.ble_req.bd_addr, bda); + bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event); + break; + + case BTM_LE_SC_LOC_OOB_EVT: + memcpy(sec_event.local_oob_data.local_oob_c, p_data->local_oob_data.commitment, BT_OCTET16_LEN); + memcpy(sec_event.local_oob_data.local_oob_r, p_data->local_oob_data.randomizer, BT_OCTET16_LEN); + bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_CR_LOC_OOB_EVT, &sec_event); + break; + case BTM_LE_NC_REQ_EVT: bdcpy(sec_event.key_notif.bd_addr, bda); BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,bta_dm_get_remname(), BD_NAME_LEN); diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 6c33dacf82..0786cc22f8 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -672,7 +672,7 @@ void BTA_DmLocalOob(void) ** Function BTA_DmOobReply ** ** This function is called to provide the OOB data for -** SMP in response to BTM_LE_OOB_REQ_EVT +** SMP in response to BTA_LE_OOB_REQ_EVT ** ** Parameters: bd_addr - Address of the peer device ** len - length of simple pairing Randomizer C @@ -697,6 +697,55 @@ void BTA_DmOobReply(BD_ADDR bd_addr, UINT8 len, UINT8 *p_value) bta_sys_sendmsg(p_msg); } } + +/******************************************************************************* +** +** Function BTA_DmSecureConnectionOobReply +** +** This function is called to provide the OOB data for +** SMP in response to BTA_LE_OOB_REQ_EVT +** +** Parameters: bd_addr - Address of the peer device +** p_c - Pointer to Confirmation +** p_r - Pointer to Randomizer +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSecureConnectionOobReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r) +{ + tBTA_DM_API_SC_OOB_REPLY *p_msg; + + if ((p_msg = (tBTA_DM_API_SC_OOB_REPLY *) osi_malloc(sizeof(tBTA_DM_API_OOB_REPLY))) != NULL) { + p_msg->hdr.event = BTA_DM_API_SC_OOB_REPLY_EVT; + if((p_c == NULL) || (p_r == NULL)) { + return; + } + memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN); + memcpy(p_msg->c, p_c, BT_OCTET16_LEN); + memcpy(p_msg->r, p_r, BT_OCTET16_LEN); + bta_sys_sendmsg(p_msg); + } +} +/******************************************************************************* +** +** Function BTA_DmSecureConnectionCreateOobData +** +** This function is called to create the OOB data for +** SMP when secure connection +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSecureConnectionCreateOobData(void) +{ + tBTA_DM_API_SC_CR_OOB_DATA *p_msg; + + if ((p_msg = (tBTA_DM_API_SC_CR_OOB_DATA *) osi_malloc(sizeof(tBTA_DM_API_SC_CR_OOB_DATA))) != NULL) { + p_msg->hdr.event = BTA_DM_API_SC_CR_OOB_DATA_EVT; + bta_sys_sendmsg(p_msg); + } +} #endif /* BTM_OOB_INCLUDED */ /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index fdb979bd5a..69e729ef44 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -349,10 +349,6 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, *p_auth_req = bte_appl_cfg.ble_auth_req | (bte_appl_cfg.ble_auth_req & BTA_LE_AUTH_REQ_MITM) | ((*p_auth_req) & BTA_LE_AUTH_REQ_MITM); - if (*p_oob_data == BTM_BLE_OOB_ENABLE) { - *p_auth_req = (*p_auth_req)&(~BTA_LE_AUTH_REQ_SC_ONLY); - } - if (bte_appl_cfg.ble_io_cap <= 4) { *p_io_cap = bte_appl_cfg.ble_io_cap; } diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 78b0a920dd..0deb1e821e 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -97,6 +97,8 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) bta_dm_loc_oob, /* BTA_DM_API_LOC_OOB_EVT */ bta_dm_oob_reply, /* BTA_DM_API_OOB_REPLY_EVT */ + bta_dm_sc_oob_reply, /* BTA_DM_API_SC_OOB_REPLY_EVT */ + bta_dm_sc_create_oob_data, /* BTA_DM_API_SC_CR_OOB_DATA_EVT */ bta_dm_ci_io_req_act, /* BTA_DM_CI_IO_REQ_EVT */ bta_dm_ci_rmt_oob_act, /* BTA_DM_CI_RMT_OOB_EVT */ #endif /* BTM_OOB_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index de7719c02e..4a1a7d2396 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -93,6 +93,8 @@ enum { #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE) BTA_DM_API_LOC_OOB_EVT, BTA_DM_API_OOB_REPLY_EVT, + BTA_DM_API_SC_OOB_REPLY_EVT, + BTA_DM_API_SC_CR_OOB_DATA_EVT, BTA_DM_CI_IO_REQ_EVT, BTA_DM_CI_RMT_OOB_EVT, #endif /* BTM_OOB_INCLUDED */ @@ -401,8 +403,23 @@ typedef struct { BD_ADDR bd_addr; UINT8 len; UINT8 value[BT_OCTET16_LEN]; + UINT8 c[BT_OCTET16_LEN]; + UINT8 r[BT_OCTET16_LEN]; } tBTA_DM_API_OOB_REPLY; +/* data type for BTA_DM_API_SC_OOB_REPLY_EVT */ +typedef struct { + BT_HDR hdr; + BD_ADDR bd_addr; + UINT8 c[BT_OCTET16_LEN]; + UINT8 r[BT_OCTET16_LEN]; +} tBTA_DM_API_SC_OOB_REPLY; + +/* data type for BTA_DM_API_SC_CR_OOB_DATA_EVT */ +typedef struct { + BT_HDR hdr; +} tBTA_DM_API_SC_CR_OOB_DATA; + /* data type for BTA_DM_API_CONFIRM_EVT */ typedef struct { BT_HDR hdr; @@ -1055,6 +1072,7 @@ typedef union { tBTA_DM_API_LOC_OOB loc_oob; tBTA_DM_API_OOB_REPLY oob_reply; + tBTA_DM_API_SC_OOB_REPLY sc_oob_reply; tBTA_DM_API_CONFIRM confirm; tBTA_DM_API_KEY_REQ key_req; tBTA_DM_CI_IO_REQ ci_io_req; @@ -1614,6 +1632,8 @@ extern BOOLEAN bta_dm_check_if_only_hd_connected(BD_ADDR peer_addr); #if (BTM_OOB_INCLUDED == TRUE) extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data); extern void bta_dm_oob_reply(tBTA_DM_MSG *p_data); +extern void bta_dm_sc_oob_reply(tBTA_DM_MSG *p_data); +extern void bta_dm_sc_create_oob_data(tBTA_DM_MSG *p_data); extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data); extern void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data); #endif /* BTM_OOB_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 2ed5c24236..bf6fabb224 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -660,6 +660,8 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK; #define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */ #define BTA_DM_PM_MODE_CHG_EVT 31 /* Mode changed event */ #define BTA_DM_ACL_LINK_STAT_EVT 32 /* ACL connection status report event */ +#define BTA_DM_BLE_SC_OOB_REQ_EVT 33 /* BLE SMP SC OOB request event */ +#define BTA_DM_BLE_SC_CR_LOC_OOB_EVT 34 /* BLE SMP SC Create Local OOB request event */ typedef UINT8 tBTA_DM_SEC_EVT; @@ -979,6 +981,10 @@ typedef struct { tBTA_PM_MODE mode; /* the new connection role */ } tBTA_DM_MODE_CHG; +typedef struct { + BT_OCTET16 local_oob_c; /* Local OOB Data Confirmation/Commitment */ + BT_OCTET16 local_oob_r; /* Local OOB Data Randomizer */ +} tBTA_DM_LOC_OOB_DATA; /* Union of all security callback structures */ typedef union { @@ -1004,6 +1010,7 @@ typedef union { #if BTA_DM_PM_INCLUDED tBTA_DM_MODE_CHG mode_chg; /* mode change event */ #endif ///BTA_DM_PM_INCLUDED + tBTA_DM_LOC_OOB_DATA local_oob_data; /* Local OOB data generated by us */ } tBTA_DM_SEC; /* Security callback */ @@ -1934,7 +1941,7 @@ extern void BTA_DmLocalOob(void); ** Function BTA_DmOobReply ** ** This function is called to provide the OOB data for -** SMP in response to BTM_LE_OOB_REQ_EVT +** SMP in response to BTA_LE_OOB_REQ_EVT ** ** Parameters: bd_addr - Address of the peer device ** len - length of simple pairing Randomizer C @@ -1944,6 +1951,33 @@ extern void BTA_DmLocalOob(void); ** *******************************************************************************/ extern void BTA_DmOobReply(BD_ADDR bd_addr, UINT8 len, UINT8 *p_value); + +/******************************************************************************* +** +** Function BTA_DmSecureConnectionOobReply +** +** This function is called to provide the OOB data for +** SMP in response to BTA_LE_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - Pointer to Confirmation +** p_r - Pointer to Randomizer +** +** Returns void +** +*******************************************************************************/ +extern void BTA_DmSecureConnectionOobReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r); +/******************************************************************************* +** +** Function BTA_DmSecureConnectionCreateOobData +** +** This function is called to create the OOB data for +** SMP when secure connection +** +** Returns void +** +*******************************************************************************/ +extern void BTA_DmSecureConnectionCreateOobData(void); #endif /* BTM_OOB_INCLUDED */ /******************************************************************************* diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index 70b41efe7b..4c1cd9f0a8 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -944,6 +944,19 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) memcpy(param.ble_security.ble_req.bd_addr, p_data->ble_req.bd_addr, BD_ADDR_LEN); break; } + case BTA_DM_BLE_SC_OOB_REQ_EVT: { + rsp_app = true; + ble_msg->act = ESP_GAP_BLE_SC_OOB_REQ_EVT; + memcpy(param.ble_security.ble_req.bd_addr, p_data->ble_req.bd_addr, BD_ADDR_LEN); + break; + } + case BTA_DM_BLE_SC_CR_LOC_OOB_EVT: { + rsp_app = true; + ble_msg->act = ESP_GAP_BLE_SC_CR_LOC_OOB_EVT; + memcpy(param.ble_security.oob_data.oob_c, p_data->local_oob_data.local_oob_c, BT_OCTET16_LEN); + memcpy(param.ble_security.oob_data.oob_r, p_data->local_oob_data.local_oob_r, BT_OCTET16_LEN); + break; + } case BTA_DM_BLE_LOCAL_IR_EVT: { rsp_app = true; ble_msg->act = ESP_GAP_BLE_LOCAL_IR_EVT; diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 90fa326d28..cfbae97953 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1335,6 +1335,27 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } break; } + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: { + btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src; + btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *)p_dest; + if (src->sc_oob_req_reply.p_c) { + dst->sc_oob_req_reply.p_c = osi_malloc(BT_OCTET16_LEN); + if (dst->sc_oob_req_reply.p_c) { + memcpy(dst->sc_oob_req_reply.p_c, src->sc_oob_req_reply.p_c, BT_OCTET16_LEN); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + if (src->sc_oob_req_reply.p_r) { + dst->sc_oob_req_reply.p_r = osi_malloc(BT_OCTET16_LEN); + if (dst->sc_oob_req_reply.p_r) { + memcpy(dst->sc_oob_req_reply.p_r, src->sc_oob_req_reply.p_r, BT_OCTET16_LEN); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + } #if (BLE_50_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW: case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: { @@ -1460,6 +1481,17 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) } break; } + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: { + uint8_t *value = ((btc_ble_gap_args_t *)msg->arg)->sc_oob_req_reply.p_c; + if (value) { + osi_free(value); + } + value = ((btc_ble_gap_args_t *)msg->arg)->sc_oob_req_reply.p_r; + if (value) { + osi_free(value); + } + break; + } #if (BLE_50_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_CFG_EXT_ADV_DATA_RAW: case BTC_GAP_BLE_CFG_EXT_SCAN_RSP_DATA_RAW: { @@ -1722,6 +1754,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_OOB_REQ_REPLY_EVT: BTA_DmOobReply(arg->oob_req_reply.bd_addr, arg->oob_req_reply.len, arg->oob_req_reply.p_value); break; + case BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT: + BTA_DmSecureConnectionOobReply(arg->sc_oob_req_reply.bd_addr, arg->sc_oob_req_reply.p_c, arg->sc_oob_req_reply.p_r); + break; + case BTC_GAP_BLE_SC_CR_OOB_DATA_EVT: + BTA_DmSecureConnectionCreateOobData(); + break; #endif ///SMP_INCLUDED == TRUE case BTC_GAP_BLE_DISCONNECT_EVT: btc_ble_disconnect(arg->disconnect.remote_device); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 265f224e56..11811e1366 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,6 +54,8 @@ typedef enum { BTC_GAP_BLE_DISCONNECT_EVT, BTC_GAP_BLE_REMOVE_BOND_DEV_EVT, BTC_GAP_BLE_OOB_REQ_REPLY_EVT, + BTC_GAP_BLE_SC_OOB_REQ_REPLY_EVT, + BTC_GAP_BLE_SC_CR_OOB_DATA_EVT, BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST, BTC_GAP_BLE_SET_AFH_CHANNELS, #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -201,6 +203,11 @@ typedef union { uint8_t len; uint8_t *p_value; } oob_req_reply; + struct sc_oob_req_reply_args { + esp_bd_addr_t bd_addr; + uint8_t *p_c; + uint8_t *p_r; + } sc_oob_req_reply; //BTC_GAP_BLE_DISCONNECT_EVT struct disconnect_args { esp_bd_addr_t remote_device; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index ae41206795..69e5404a2e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -497,6 +497,62 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data) #endif } +/******************************************************************************* +** +** Function BTM_BleSecureConnectionOobDataReply +** +** Description This function is called to provide the OOB data for +** SMP in response to BTM_LE_SC_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - pointer to Confirmation +** p_r - pointer to Randomizer +** +*******************************************************************************/ +void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r) +{ +#if SMP_INCLUDED == TRUE + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr); + + BTM_TRACE_DEBUG ("%s", __func__); + + if (p_dev_rec == NULL) { + BTM_TRACE_ERROR("%s Unknown device", __func__); + return; + } + + p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + + tSMP_SC_OOB_DATA oob; + memset(&oob, 0, sizeof(tSMP_SC_OOB_DATA)); + + oob.peer_oob_data.present = true; + memcpy(&oob.peer_oob_data.commitment, p_c, BT_OCTET16_LEN); + memcpy(&oob.peer_oob_data.randomizer, p_r, BT_OCTET16_LEN); + oob.peer_oob_data.addr_rcvd_from.type = p_dev_rec->ble.ble_addr_type; + memcpy(oob.peer_oob_data.addr_rcvd_from.bda, bd_addr, BD_ADDR_LEN); + + SMP_SecureConnectionOobDataReply((UINT8 *)&oob); +#endif +} + +/******************************************************************************* +** +** Function BTM_BleSecureConnectionCreateOobData +** +** Description This function is called to create the OOB data for +** SMP when secure connection +** +*******************************************************************************/ +void BTM_BleSecureConnectionCreateOobData(void) +{ +#if SMP_INCLUDED == TRUE + BTM_TRACE_DEBUG ("%s", __func__); + + SMP_CreateLocalSecureConnectionsOobData(); +#endif +} + /****************************************************************************** ** ** Function BTM_BleSetConnScanParams @@ -2224,7 +2280,15 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) } } else { - BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { + tBTM_LE_EVT_DATA evt_data; + memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + if (btm_cb.api.p_le_callback) { + (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); + } + } else { + BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + } } return 0; } diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 75d7d83b28..ff4fc233f8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -1766,6 +1766,7 @@ typedef union { #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE tBTM_LE_COMPLT complt; /* BTM_LE_COMPLT_EVT */ tSMP_OOB_DATA_TYPE req_oob_type; + tSMP_LOC_OOB_DATA local_oob_data; #endif tBTM_LE_KEY key; } tBTM_LE_EVT_DATA; diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index e84e2e6dea..bd1d7438da 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1809,6 +1809,29 @@ void BTM_BleConfirmReply (BD_ADDR bd_addr, UINT8 res); //extern void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data); +/******************************************************************************* +** +** Function BTM_BleSecureConnectionOobDataReply +** +** Description This function is called to provide the OOB data for +** SMP in response to BTM_LE_SC_OOB_REQ_EVT when secure connection +** +** Parameters: bd_addr - Address of the peer device +** p_c - pointer to Confirmation +** p_r - pointer to Randomizer +** +*******************************************************************************/ +void BTM_BleSecureConnectionOobDataReply(BD_ADDR bd_addr, UINT8 *p_c, UINT8 *p_r); + +/******************************************************************************* +** +** Function BTM_BleSecureConnectionCreateOobData +** +** Description This function is called to create the OOB data for +** SMP when secure connection +** +*******************************************************************************/ +void BTM_BleSecureConnectionCreateOobData(void); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/include/stack/smp_api.h b/components/bt/host/bluedroid/stack/include/stack/smp_api.h index 1064237c8d..11d432e716 100644 --- a/components/bt/host/bluedroid/stack/include/stack/smp_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/smp_api.h @@ -498,13 +498,9 @@ extern void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value); ** Description This function is called to start creation of local SC OOB ** data set (tSMP_LOC_OOB_DATA). ** -** Parameters: bd_addr - Address of the device to send OOB data block -** to. -** ** Returns Boolean - TRUE: creation of local SC OOB data set started. *******************************************************************************/ -extern BOOLEAN SMP_CreateLocalSecureConnectionsOobData ( - tBLE_BD_ADDR *addr_to_send_to); +extern BOOLEAN SMP_CreateLocalSecureConnectionsOobData (void); #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/smp/include/smp_int.h b/components/bt/host/bluedroid/stack/smp/include/smp_int.h index d8fb55c381..f3ab7ad445 100644 --- a/components/bt/host/bluedroid/stack/smp/include/smp_int.h +++ b/components/bt/host/bluedroid/stack/smp/include/smp_int.h @@ -527,6 +527,9 @@ extern BOOLEAN smp_calculate_f5_key(UINT8 *w, UINT8 *t); extern BOOLEAN smp_calculate_f6(UINT8 *w, UINT8 *n1, UINT8 *n2, UINT8 *r, UINT8 *iocap, UINT8 *a1, UINT8 *a2, UINT8 *f3); extern BOOLEAN smp_calculate_h6(UINT8 *w, UINT8 *keyid, UINT8 *h2); +extern void smp_save_local_oob_data(tSMP_CB *p_cb); +extern void smp_clear_local_oob_data(void); +extern tSMP_LOC_OOB_DATA *smp_get_local_oob_data(void); #if SMP_DEBUG == TRUE extern void smp_debug_print_nbyte_little_endian (UINT8 *p, const UINT8 *key_name, UINT8 len); diff --git a/components/bt/host/bluedroid/stack/smp/smp_act.c b/components/bt/host/bluedroid/stack/smp/smp_act.c index 353ee9c9b6..0e7dcd5b3f 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_act.c +++ b/components/bt/host/bluedroid/stack/smp/smp_act.c @@ -622,7 +622,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -661,7 +661,8 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + /* Only if peer oob data present, then should request peer oob data */ + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -1459,7 +1460,7 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } } - if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB && p_cb->loc_oob_flag == SMP_OOB_PRESENT) { if (smp_request_oob_data(p_cb)) { return; } @@ -1947,6 +1948,7 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->sc_oob_data.loc_oob_data.randomizer, 0, p_cb->sc_oob_data.loc_oob_data.commitment); + p_cb->sc_oob_data.loc_oob_data.present = true; #if SMP_DEBUG == TRUE UINT8 *p_print = NULL; SMP_TRACE_DEBUG("local SC OOB data set:\n"); @@ -1975,6 +1977,9 @@ void smp_set_local_oob_random_commitment(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) p_cb->cb_evt = SMP_SC_LOC_OOB_DATA_UP_EVT; smp_send_app_cback(p_cb, NULL); + // Store the data for later use when we are paired with + smp_save_local_oob_data(p_cb); + smp_cb_cleanup(p_cb); } diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index 69d4520c29..df8f4cea21 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -471,6 +471,9 @@ void SMP_SecureConnectionOobDataReply(UINT8 *p_data) return; } + /* Set local oob data when req_oob_type = SMP_OOB_BOTH */ + memcpy(&p_oob->loc_oob_data, smp_get_local_oob_data(), sizeof(tSMP_LOC_OOB_DATA)); + SMP_TRACE_EVENT ("%s req_oob_type: %d, loc_oob_data.present: %d, " "peer_oob_data.present: %d", __FUNCTION__, p_cb->req_oob_type, p_oob->loc_oob_data.present, @@ -504,6 +507,7 @@ void SMP_SecureConnectionOobDataReply(UINT8 *p_data) } if (data_missing) { + SMP_TRACE_ERROR("%s data missing", __func__); smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &failure); return; } @@ -589,32 +593,13 @@ void SMP_KeypressNotification (BD_ADDR bd_addr, UINT8 value) ** Description This function is called to start creation of local SC OOB ** data set (tSMP_LOC_OOB_DATA). ** -** Parameters: bd_addr - Address of the device to send OOB data block to -** ** Returns Boolean - TRUE: creation of local SC OOB data set started. *******************************************************************************/ -BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to) +BOOLEAN SMP_CreateLocalSecureConnectionsOobData (void) { tSMP_CB *p_cb = &smp_cb; -#if (!CONFIG_BT_STACK_NO_LOG) - UINT8 *bd_addr; -#endif - if (addr_to_send_to == NULL) { - SMP_TRACE_ERROR ("%s addr_to_send_to is not provided", __FUNCTION__); - return FALSE; - } - -#if (!CONFIG_BT_STACK_NO_LOG) - bd_addr = addr_to_send_to->bda; -#endif - - SMP_TRACE_EVENT ("%s addr type: %u, BDA: %08x%04x, state: %u, br_state: %u", - __FUNCTION__, addr_to_send_to->type, - (bd_addr[0] << 24) + (bd_addr[1] << 16) + (bd_addr[2] << 8) + bd_addr[3], - (bd_addr[4] << 8) + bd_addr[5], - p_cb->state, - p_cb->br_state); + SMP_TRACE_EVENT ("%s state: %u, br_state: %u", __FUNCTION__, p_cb->state, p_cb->br_state); if ((p_cb->state != SMP_STATE_IDLE) || (p_cb->smp_over_br)) { SMP_TRACE_WARNING ("%s creation of local OOB data set "\ @@ -622,7 +607,6 @@ BOOLEAN SMP_CreateLocalSecureConnectionsOobData (tBLE_BD_ADDR *addr_to_send_to) return FALSE; } - p_cb->sc_oob_data.loc_oob_data.addr_sent_to = *addr_to_send_to; smp_sm_event(p_cb, SMP_CR_LOC_SC_OOB_DATA_EVT, NULL); return TRUE; diff --git a/components/bt/host/bluedroid/stack/smp/smp_keys.c b/components/bt/host/bluedroid/stack/smp/smp_keys.c index e8337b1007..aec6f709c5 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_keys.c +++ b/components/bt/host/bluedroid/stack/smp/smp_keys.c @@ -71,6 +71,32 @@ static const tSMP_ACT smp_encrypt_action[] = { smp_generate_rand_cont /* SMP_GEN_SRAND_MRAND_CONT */ }; +/* If there is data saved here, then use its info instead + * This needs to be cleared on a successful pairing using the oob data + */ +static tSMP_LOC_OOB_DATA saved_local_oob_data = {}; + +void smp_save_local_oob_data(tSMP_CB *p_cb) +{ + memcpy(&saved_local_oob_data, &p_cb->sc_oob_data.loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); +} + +void smp_clear_local_oob_data(void) +{ + memset(&saved_local_oob_data, 0, sizeof(tSMP_LOC_OOB_DATA)); +} + +static BOOLEAN oob_data_is_empty(tSMP_LOC_OOB_DATA *data) +{ + tSMP_LOC_OOB_DATA empty_data = {0}; + return (memcmp(data, &empty_data, sizeof(tSMP_LOC_OOB_DATA)) == 0); +} + +tSMP_LOC_OOB_DATA *smp_get_local_oob_data(void) +{ + return &saved_local_oob_data; +} + void smp_debug_print_nbyte_little_endian(UINT8 *p, const UINT8 *key_name, UINT8 len) { #if SMP_DEBUG == TRUE @@ -973,7 +999,19 @@ BOOLEAN smp_calculate_legacy_short_term_key(tSMP_CB *p_cb, tSMP_ENC *output) *******************************************************************************/ void smp_create_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) { - SMP_TRACE_DEBUG ("%s", __FUNCTION__); + SMP_TRACE_DEBUG("%s", __func__); + + if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_OOB) { + SMP_TRACE_EVENT("OOB Association Model"); + if (!oob_data_is_empty(&saved_local_oob_data)) { + SMP_TRACE_EVENT("Found OOB data, loading keys"); + memcpy(&p_cb->sc_oob_data.loc_oob_data, &saved_local_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + smp_process_private_key(p_cb); + return; + } + SMP_TRACE_EVENT("OOB Association Model with no saved data"); + } + p_cb->rand_enc_proc_state = SMP_GENERATE_PRIVATE_KEY_0_7; if (!btsnd_hcic_ble_rand((void *)smp_rand_back)) { smp_rand_back(NULL); @@ -1005,7 +1043,7 @@ void smp_use_oob_private_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) case SMP_OOB_BOTH: case SMP_OOB_LOCAL: SMP_TRACE_DEBUG("%s restore secret key\n", __func__); - memcpy(p_cb->private_key, p_cb->sc_oob_data.loc_oob_data.private_key_used, BT_OCTET32_LEN); + // copy private key in smp_process_private_key smp_process_private_key(p_cb); break; default: @@ -1082,13 +1120,22 @@ void smp_process_private_key(tSMP_CB *p_cb) { Point public_key; BT_OCTET32 private_key; + tSMP_LOC_OOB_DATA *p_loc_oob = &p_cb->sc_oob_data.loc_oob_data; SMP_TRACE_DEBUG ("%s", __FUNCTION__); - memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); - ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); - memcpy(p_cb->loc_publ_key.x, public_key.x, BT_OCTET32_LEN); - memcpy(p_cb->loc_publ_key.y, public_key.y, BT_OCTET32_LEN); + /* if local oob data present, then restore oob private and public key */ + if (p_loc_oob->present) { + memcpy(p_cb->private_key, p_loc_oob->private_key_used, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.x, p_loc_oob->publ_key_used.x, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.y, p_loc_oob->publ_key_used.y, BT_OCTET32_LEN); + memcpy(p_cb->local_random, p_loc_oob->randomizer, BT_OCTET16_LEN); + } else { + memcpy(private_key, p_cb->private_key, BT_OCTET32_LEN); + ECC_PointMult(&public_key, &(curve_p256.G), (DWORD *) private_key, KEY_LENGTH_DWORDS_P256); + memcpy(p_cb->loc_publ_key.x, public_key.x, BT_OCTET32_LEN); + memcpy(p_cb->loc_publ_key.y, public_key.y, BT_OCTET32_LEN); + } smp_debug_print_nbyte_little_endian (p_cb->private_key, (const UINT8 *)"private", BT_OCTET32_LEN); diff --git a/components/bt/host/bluedroid/stack/smp/smp_utils.c b/components/bt/host/bluedroid/stack/smp/smp_utils.c index a9b4bf1a12..2e9fac77c9 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_utils.c +++ b/components/bt/host/bluedroid/stack/smp/smp_utils.c @@ -1031,6 +1031,8 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb) #endif ///BLE_INCLUDED == TRUE smp_reset_control_value(p_cb); + // TODO: clear local oob data when start advertising + smp_clear_local_oob_data(); if (p_callback) { (*p_callback) (SMP_COMPLT_EVT, pairing_bda, &evt_data); From 52e3e684e04e93a7bf3c7c39e99620e64d165006 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 14:23:50 +0800 Subject: [PATCH 02/12] bluedroid: support LE L2CAP credit based connection --- .../bluedroid/stack/include/stack/l2cdefs.h | 12 ++++ .../bt/host/bluedroid/stack/l2cap/l2c_ble.c | 63 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/components/bt/host/bluedroid/stack/include/stack/l2cdefs.h b/components/bt/host/bluedroid/stack/include/stack/l2cdefs.h index 61a68f102e..1572a37d6d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/l2cdefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/l2cdefs.h @@ -321,4 +321,16 @@ #define L2CAP_FCR_INIT_CRC 0 /* Initial state of the CRC register */ #define L2CAP_FCR_SEQ_MODULO 0x3F /* Mask for sequence numbers (range 0 - 63) */ +#define L2CAP_LE_RESULT_CONN_OK 0 +#define L2CAP_LE_RESULT_NO_PSM 2 +#define L2CAP_LE_RESULT_NO_RESOURCES 4 +#define L2CAP_LE_RESULT_INSUFFICIENT_AUTHENTICATION 5 +#define L2CAP_LE_RESULT_INSUFFICIENT_AUTHORIZATION 6 +#define L2CAP_LE_RESULT_INSUFFICIENT_ENCRY_KEY_SIZE 7 +#define L2CAP_LE_RESULT_INSUFFICIENT_ENCRY 8 +#define L2CAP_LE_RESULT_INVALID_SOURCE_CID 9 +#define L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED 0x0A +#define L2CAP_LE_RESULT_UNACCEPTABLE_PARAMETERS 0x0B +#define L2CAP_LE_RESULT_INVALID_PARAMETERS 0x0C + #endif diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index e485f70e49..8d9f510f55 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -793,6 +793,69 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) } break; } + case L2CAP_CMD_BLE_CREDIT_BASED_CONN_REQ: { + tL2C_CCB *p_ccb = NULL; + tL2C_RCB *p_rcb = NULL; + UINT16 spsm; + UINT16 scid; + UINT16 mtu; + UINT16 mps; + UINT16 credits; + STREAM_TO_UINT16(spsm, p); + STREAM_TO_UINT16(scid, p); + STREAM_TO_UINT16(mtu, p); + STREAM_TO_UINT16(mps, p); + STREAM_TO_UINT16(credits, p); + L2CAP_TRACE_DEBUG("%s spsm %x, scid %x", __func__, spsm, scid); + + p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, scid); + if (p_ccb) { + l2cu_reject_ble_connection(p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED); + break; + } + + #if 0 + p_rcb = l2cu_find_ble_rcb_by_psm(spsm); + if (p_rcb == NULL) { + break; + } + #endif + + p_ccb = l2cu_allocate_ccb(p_lcb, 0); + if (p_ccb == NULL) { + l2cu_reject_ble_connection(p_lcb, id, L2CAP_LE_RESULT_NO_RESOURCES); + break; + } + + p_ccb->remote_id = id; + p_ccb->p_rcb = p_rcb; + p_ccb->remote_cid = scid; + p_ccb->local_conn_cfg.mtu = mtu; + p_ccb->local_conn_cfg.mps = controller_get_interface()->get_acl_data_size_ble(); + p_ccb->local_conn_cfg.credits = credits; + p_ccb->peer_conn_cfg.mtu = mtu; + p_ccb->peer_conn_cfg.mps = mps; + p_ccb->peer_conn_cfg.credits = credits; + + l2cu_send_peer_ble_credit_based_conn_res(p_ccb, L2CAP_LE_RESULT_CONN_OK); + break; + } + case L2CAP_CMD_DISC_REQ: { + tL2C_CCB *p_ccb = NULL; + UINT16 lcid; + UINT16 rcid; + STREAM_TO_UINT16(lcid, p); + STREAM_TO_UINT16(rcid, p); + + p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); + if (p_ccb) { + p_ccb->remote_id = id; + // TODO + } + + l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid); + break; + } default: L2CAP_TRACE_WARNING ("L2CAP - LE - unknown cmd code: %d", cmd_code); l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); From ed34a2b5003d6468e7b94f4e40cdcadfecb6f630 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 14:31:43 +0800 Subject: [PATCH 03/12] bluedroid: support periodic advertising sync transfer cmd --- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 12 +++ .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 27 +++++++ .../bt/host/bluedroid/stack/btu/btu_hcif.c | 23 +++++- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 81 +++++++++++++++++++ .../stack/include/stack/btm_ble_api.h | 16 ++++ .../bluedroid/stack/include/stack/hcidefs.h | 5 ++ .../bluedroid/stack/include/stack/hcimsgs.h | 8 ++ 7 files changed, 171 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 0786cc22f8..968c1a3350 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3159,6 +3159,18 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add } +uint8_t BTA_DmBlePeriodicAdvSetInfoTrans(uint8_t addr[6], uint16_t service_data, uint8_t adv_handle) +{ + BTM_BlePeriodicAdvSetInfoTrans(addr, service_data, adv_handle); + return 0; +} + +uint8_t BTA_DmBleSetPeriodicAdvSyncTransParams(uint8_t addr[6], uint8_t mode, uint16_t skip, uint16_t sync_timeout) +{ + BTM_BleSetPeriodicAdvSyncTransParams(addr, mode, skip, sync_timeout, 0); + return 0; +} + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 09969ef97f..54cbcca951 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1032,6 +1032,33 @@ void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *p return; } +void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + return; + } + + if (!btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle)) { + BTM_TRACE_ERROR("%s, hci cmd error", __func__); + } +} + +void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + return; + } + + if (!btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type)) { + BTM_TRACE_ERROR("%s, hci cmd error", __func__); + } +} void btm_ble_extended_init(void) { diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 451df2255c..a6e1f5d5b8 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -145,7 +145,7 @@ static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p); static void btu_ble_scan_timeout_evt(UINT8 *p); static void btu_ble_adv_set_terminate_evt(UINT8 *p); static void btu_ble_scan_req_received_evt(UINT8 *p); - +static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) extern osi_sem_t adv_enable_sem; @@ -412,6 +412,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) break; case HCI_BLE_CHANNEL_SELECT_ALG: break; + case HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT: + btu_ble_periodic_adv_sync_trans_recv(p); + break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) } break; @@ -2305,6 +2308,24 @@ static void btu_ble_scan_req_received_evt(UINT8 *p) btm_ble_scan_req_received_evt(&req_received); } + +static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) +{ + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV recv = {0}; + + STREAM_TO_UINT8(recv.status, p); + STREAM_TO_UINT16(recv.conn_handle, p); + STREAM_TO_UINT16(recv.service_data, p); + STREAM_TO_UINT16(recv.sync_handle, p); + STREAM_TO_UINT8(recv.adv_sid, p); + STREAM_TO_UINT8(recv.adv_addr_type, p); + STREAM_TO_BDADDR(recv.adv_addr, p); + STREAM_TO_UINT8(recv.adv_phy, p); + STREAM_TO_UINT16(recv.period_adv_interval, p); + STREAM_TO_UINT8(recv.adv_clk_accuracy, p); + + HCI_TRACE_DEBUG("%s status %x, conn handle %x, sync handle %x", recv.status, recv.conn_handle, recv.sync_handle); +} #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) /********************************************** ** End of BLE Events Handler diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 2b82203032..07c31df64d 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1775,5 +1775,86 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } + +UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED(p, pp, 3); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE); + UINT8_TO_STREAM(pp, 3); + + UINT16_TO_STREAM(pp, sync_handle); + UINT8_TO_STREAM(pp, enable); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCIC_BLE_CMD_CREATED(p, pp, 6); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SYNC_TRANS); + UINT8_TO_STREAM(pp, 6); + + UINT16_TO_STREAM(pp, conn_handle); + UINT16_TO_STREAM(pp, service_data); + UINT16_TO_STREAM(pp, sync_handle); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s conn handle %x, adv handle %x", __func__, conn_handle, adv_handle); + + HCIC_BLE_CMD_CREATED(p, pp, 5); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SET_INFO_TRANS); + UINT8_TO_STREAM(pp, 5); + + UINT16_TO_STREAM(pp, conn_handle); + UINT16_TO_STREAM(pp, service_data); + UINT8_TO_STREAM(pp, adv_handle); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s conn handle %x, mode %x, sync timeout %x", __func__, conn_handle, mode, sync_timeout); + + HCIC_BLE_CMD_CREATED(p, pp, 8); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS); + UINT8_TO_STREAM(pp, 8); + + UINT16_TO_STREAM(pp, conn_handle); + UINT8_TO_STREAM(pp, mode); + UINT16_TO_STREAM(pp, skip); + UINT16_TO_STREAM(pp, sync_timeout); + UINT8_TO_STREAM(pp, cte_type); + + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); +} #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index bd1d7438da..88adb506ce 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1230,6 +1230,19 @@ typedef struct { UINT8 adv_clk_accuracy; } tBTM_BLE_PERIOD_ADV_SYNC_ESTAB; +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT16 service_data; + UINT16 sync_handle; + UINT8 adv_sid; + UINT8 adv_addr_type; + BD_ADDR adv_addr; + UINT8 adv_phy; + UINT16 period_adv_interval; + UINT8 adv_clk_accuracy; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; + typedef struct { UINT16 scan_interval; UINT16 scan_window; @@ -2638,6 +2651,9 @@ tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period); void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params); +void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle); + +void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 00920638e4..1f04192c45 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -384,6 +384,10 @@ #define HCI_BLE_RD_RF_PATH_COMPENSATION (0x004C | HCI_GRP_BLE_CMDS) #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) +#define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) +#define HCI_BLE_PERIOD_ADV_SET_INFO_TRANS (0x005B | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS (0x005C | HCI_GRP_BLE_CMDS) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -801,6 +805,7 @@ #define HCI_BLE_ADV_SET_TERMINATED_EVT 0x12 #define HCI_BLE_SCAN_REQ_RECEIVED_EVT 0x13 #define HCI_BLE_CHANNEL_SELECT_ALG 0x14 +#define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) /* Definitions for LE Channel Map */ diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index ba5e66e7d9..676e626eb2 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1031,6 +1031,14 @@ UINT8 btsnd_hcic_ble_read_trans_power(void); UINT8 btsnd_hcic_ble_read_rf_path_compensation(void); UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_path); + +UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); + +UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); + +UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); + +UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 From 1ce00f01ca178d88d5dfe31e4fea18b562ae9e4e Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 14:34:41 +0800 Subject: [PATCH 04/12] bluedroid: support GATT services database hash calculate --- components/bt/CMakeLists.txt | 1 + .../host/bluedroid/stack/gatt/gatt_sr_hash.c | 171 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 0a83faaf96..ea2e72a718 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -321,6 +321,7 @@ if(CONFIG_BT_ENABLED) "host/bluedroid/stack/gatt/gatt_db.c" "host/bluedroid/stack/gatt/gatt_main.c" "host/bluedroid/stack/gatt/gatt_sr.c" + "host/bluedroid/stack/gatt/gatt_sr_hash.c" "host/bluedroid/stack/gatt/gatt_utils.c" "host/bluedroid/stack/hcic/hciblecmds.c" "host/bluedroid/stack/hcic/hcicmds.c" diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c new file mode 100644 index 0000000000..f302e2b13f --- /dev/null +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c @@ -0,0 +1,171 @@ +#include "common/bt_target.h" +#include "osi/allocator.h" + +#include +#include "gatt_int.h" +#include "stack/l2c_api.h" +#include "l2c_int.h" +#include "smp_int.h" + +#if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) +static void attr_uuid_to_bt_uuid(void *p_attr, tBT_UUID *p_uuid) +{ + tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr; + + if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) { + p_uuid->len = LEN_UUID_16; + p_uuid->uu.uuid16 = p_attr16->uuid; + } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) { + tGATT_ATTR32 *p_attr32 = (tGATT_ATTR32 *)p_attr; + p_uuid->len = LEN_UUID_32; + p_uuid->uu.uuid32 = p_attr32->uuid; + } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_128) { + tGATT_ATTR128 *p_attr128 = (tGATT_ATTR128 *)p_attr; + p_uuid->len = LEN_UUID_128; + memcpy(p_uuid->uu.uuid128, p_attr128->uuid, LEN_UUID_128); + } +} + +static size_t calculate_database_info_size(void) +{ + UINT8 i; + tGATT_SVC_DB *p_db; + tGATT_ATTR16 *p_attr; + size_t len = 0; + + for (i = 0; i < GATT_MAX_SR_PROFILES; i++) { + p_db = gatt_cb.sr_reg[i].p_db; + if (p_db && p_db->p_attr_list) { + p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; + while (p_attr) { + if (p_attr->uuid == GATT_UUID_PRI_SERVICE || + p_attr->uuid == GATT_UUID_SEC_SERVICE) { + // Service declaration + len += 4 + p_attr->p_value->uuid.len; + } else if (p_attr->uuid == GATT_UUID_INCLUDE_SERVICE) { + // Included service declaration + len += 8 + p_attr->p_value->incl_handle.service_type.len; + } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) { + tBT_UUID char_uuid; + // Characteristic declaration + p_attr = (tGATT_ATTR16 *)p_attr->p_next; + attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid); + // Increment 1 to fetch characteristic uuid from value declaration attribute + len += 7 + char_uuid.len; + } else if (p_attr->uuid == GATT_UUID_CHAR_DESCRIPTION || + p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || + p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG || + p_attr->uuid == GATT_UUID_CHAR_PRESENT_FORMAT || + p_attr->uuid == GATT_UUID_CHAR_AGG_FORMAT) { + // Descriptor + len += 4; + } else if (p_attr->uuid == GATT_UUID_CHAR_EXT_PROP) { + // Descriptor + len += 6; + } + p_attr = (tGATT_ATTR16 *) p_attr->p_next; + } + } + } + + return len; +} + +static void fill_database_info(UINT8 *p_data) +{ + UINT8 i; + tGATT_SVC_DB *p_db; + tGATT_ATTR16 *p_attr; + + for (i = 0; i < GATT_MAX_SR_PROFILES; i++) { + p_db = gatt_cb.sr_reg[i].p_db; + if (p_db && p_db->p_attr_list) { + p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; + while (p_attr) { + if (p_attr->uuid == GATT_UUID_PRI_SERVICE || + p_attr->uuid == GATT_UUID_SEC_SERVICE) { + // Service declaration + UINT16_TO_STREAM(p_data, p_attr->handle); + UINT16_TO_STREAM(p_data, p_attr->uuid); + gatt_build_uuid_to_stream(&p_data, p_attr->p_value->uuid); + } else if (p_attr->uuid == GATT_UUID_INCLUDE_SERVICE) { + // Included service declaration + UINT16_TO_STREAM(p_data, p_attr->handle); + UINT16_TO_STREAM(p_data, GATT_UUID_INCLUDE_SERVICE); + UINT16_TO_STREAM(p_data, p_attr->p_value->incl_handle.s_handle); + UINT16_TO_STREAM(p_data, p_attr->p_value->incl_handle.e_handle); + gatt_build_uuid_to_stream(&p_data, p_attr->p_value->incl_handle.service_type); + } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) { + tBT_UUID char_uuid; + // Characteristic declaration + UINT16_TO_STREAM(p_data, p_attr->handle); + UINT16_TO_STREAM(p_data, GATT_UUID_CHAR_DECLARE); + UINT8_TO_STREAM(p_data, p_attr->p_value->char_decl.property); + UINT16_TO_STREAM(p_data, p_attr->p_value->char_decl.char_val_handle); + p_attr = (tGATT_ATTR16 *)p_attr->p_next; + attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid); + // Increment 1 to fetch characteristic uuid from value declaration attribute + gatt_build_uuid_to_stream(&p_data, char_uuid); + } else if (p_attr->uuid == GATT_UUID_CHAR_DESCRIPTION || + p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || + p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG || + p_attr->uuid == GATT_UUID_CHAR_PRESENT_FORMAT || + p_attr->uuid == GATT_UUID_CHAR_AGG_FORMAT) { + // Descriptor + UINT16_TO_STREAM(p_data, p_attr->handle); + UINT16_TO_STREAM(p_data, p_attr->uuid); + } else if (p_attr->uuid == GATT_UUID_CHAR_EXT_PROP) { + // Descriptor + UINT16_TO_STREAM(p_data, p_attr->handle); + UINT16_TO_STREAM(p_data, p_attr->uuid); + // TODO: process extended properties descriptor + if (p_attr->p_value->attr_val.attr_len == 2) { + memcpy(p_data, p_attr->p_value->attr_val.attr_val, 2); + } else { + UINT16_TO_STREAM(p_data, 0x0000); + } + } + p_attr = (tGATT_ATTR16 *) p_attr->p_next; + } + } + } +} + +tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash) +{ + UINT8 tmp; + UINT16 i; + UINT16 j; + size_t len; + UINT8 *data_buf = NULL; + + len = calculate_database_info_size(); + + data_buf = (UINT8 *)osi_malloc(len); + if (data_buf == NULL) { + GATT_TRACE_ERROR ("%s failed to allocate buffer (%u)\n", __func__, len); + return GATT_NO_RESOURCES; + } + + fill_database_info(data_buf); + + // reverse database info + for (i = 0, j = len-1; i < j; i++, j--) { + tmp = data_buf[i]; + data_buf[i] = data_buf[j]; + data_buf[j] = tmp; + } + +#if SMP_INCLUDED == TRUE + BT_OCTET16 key = {0}; + aes_cipher_msg_auth_code(key, data_buf, len, 16, hash); + //ESP_LOG_BUFFER_HEX("db hash", hash, BT_OCTET16_LEN); +#else + // TODO + GATT_TRACE_ERROR("%s SMP disabled", __func__); +#endif + + osi_free(data_buf); + return GATT_SUCCESS; +} +#endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ From 42a1d94830554c4950c25c104f3482be3a16351c Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 15:06:27 +0800 Subject: [PATCH 05/12] bluedroid: support GATT robust caching feature --- .../bt/host/bluedroid/bta/gatt/bta_gatts_co.c | 86 +++++++ .../bluedroid/bta/include/bta/bta_gatts_co.h | 7 + .../host/bluedroid/btc/core/btc_ble_storage.c | 80 +++++- .../bt/host/bluedroid/btc/core/btc_dm.c | 4 + .../btc/include/btc/btc_ble_storage.h | 16 +- .../bt/host/bluedroid/stack/gatt/gatt_api.c | 16 ++ .../bt/host/bluedroid/stack/gatt/gatt_attr.c | 239 ++++++++++++++++-- .../bt/host/bluedroid/stack/gatt/gatt_sr.c | 87 +++++++ .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 1 + .../bluedroid/stack/gatt/include/gatt_int.h | 18 ++ .../bluedroid/stack/include/stack/gatt_api.h | 2 + .../bluedroid/stack/include/stack/gattdefs.h | 4 + 12 files changed, 542 insertions(+), 18 deletions(-) diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c index 2130005a11..0fdf789bb2 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c @@ -24,6 +24,8 @@ #include #include #include "bta/bta_gatts_co.h" +#include "btc/btc_storage.h" +#include "btc/btc_ble_storage.h" // #include "btif_util.h" #if (defined(BTIF_INCLUDED) && BTIF_INCLUDED == TRUE) @@ -159,5 +161,89 @@ BOOLEAN bta_gatts_co_load_handle_range(UINT8 index, return FALSE; } + +/******************************************************************************* +** +** Function bta_gatts_co_cl_feat_save +** +** Description This callout function is executed by GATTS when GATT server +** client support feature is requested to write to NV. +** +** Parameter remote_addr - remote device address +** feature - pointer of client support feature +** +** Returns void. +** +*******************************************************************************/ +void bta_gatts_co_cl_feat_save(BD_ADDR remote_addr, UINT8 *feature) +{ + bt_bdaddr_t bd_addr; + + memcpy(bd_addr.address, remote_addr, BD_ADDR_LEN); + btc_storage_set_gatt_cl_supp_feat(&bd_addr, feature, 1); +} + +/******************************************************************************* +** +** Function bta_gatts_co_db_hash_save +** +** Description This callout function is executed by GATTS when GATT server +** client status is requested to write to NV. +** +** Parameter remote_addr - remote device address +** db_hash - pointer of GATT service datebase hash +** +** Returns void. +** +*******************************************************************************/ +void bta_gatts_co_db_hash_save(BD_ADDR remote_addr, BT_OCTET16 db_hash) +{ + bt_bdaddr_t bd_addr; + + memcpy(bd_addr.address, remote_addr, BD_ADDR_LEN); + btc_storage_set_gatt_db_hash(&bd_addr, db_hash, BT_OCTET16_LEN); +} + +/******************************************************************************* +** +** Function bta_gatts_co_cl_feat_load +** +** Description This callout function is executed by GATTS when GATT server +** client status is requested to load from NV. +** +** Parameter remote_addr - remote device address +** feature - pointer of GATT service datebase hash +** +** Returns void. +** +*******************************************************************************/ +void bta_gatts_co_cl_feat_load(BD_ADDR remote_addr, UINT8 *feature) +{ + bt_bdaddr_t bd_addr; + + memcpy(bd_addr.address, remote_addr, BD_ADDR_LEN); + btc_storage_get_gatt_cl_supp_feat(&bd_addr, feature, 1); +} + +/******************************************************************************* +** +** Function bta_gatts_co_db_hash_load +** +** Description This callout function is executed by GATTS when GATT server +** client status is requested to load from NV. +** +** Parameter remote_addr - remote device address +** db_hash - pointer of GATT service datebase hash +** +** Returns void. +** +*******************************************************************************/ +void bta_gatts_co_db_hash_load(BD_ADDR remote_addr, BT_OCTET16 db_hash) +{ + bt_bdaddr_t bd_addr; + + memcpy(bd_addr.address, remote_addr, BD_ADDR_LEN); + btc_storage_get_gatt_db_hash(&bd_addr, db_hash, BT_OCTET16_LEN); +} #endif #endif diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatts_co.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatts_co.h index 9d81d6461d..66178c76fc 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatts_co.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatts_co.h @@ -77,5 +77,12 @@ extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd, extern BOOLEAN bta_gatts_co_load_handle_range(UINT8 index, tBTA_GATTS_HNDL_RANGE *p_handle); +extern void bta_gatts_co_cl_feat_save(BD_ADDR remote_addr, UINT8 *feature); + +extern void bta_gatts_co_db_hash_save(BD_ADDR remote_addr, BT_OCTET16 db_hash); + +extern void bta_gatts_co_cl_feat_load(BD_ADDR remote_addr, UINT8 *feature); + +extern void bta_gatts_co_db_hash_load(BD_ADDR remote_addr, BT_OCTET16 db_hash); #endif /* BTA_GATTS_CO_H */ diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index cd30ac9d80..17333f35ef 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -39,7 +39,9 @@ static void _btc_storage_save(void) !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PID_STR) && !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR) && !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LENC_STR) && - !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_GATT_DB_HASH_STR)) { iter = btc_config_section_next(iter); btc_config_remove_section(section); continue; @@ -924,3 +926,79 @@ int btc_storage_get_num_ble_bond_devices(void) } #endif ///BLE_INCLUDED == TRUE #endif ///SMP_INCLUDED == TRUE + +#if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) +bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t *)&len); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) +{ + int ret; + bdstr_t bdstr; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); + ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t)len); + if (ret == false) { + return BT_STATUS_FAIL; + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_get_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t *)&len); + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} + +bt_status_t btc_storage_set_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) +{ + int ret; + bdstr_t bdstr; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); + ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t)len); + if (ret == false) { + return BT_STATUS_FAIL; + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_remove_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr) +{ + bool ret = true; + bdstr_t bdstr; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR); + if (ret == false) { + return BT_STATUS_FAIL; + } + + return BT_STATUS_SUCCESS; +} + +bt_status_t btc_storage_remove_gatt_db_hash(bt_bdaddr_t *remote_bd_addr) +{ + bool ret = true; + bdstr_t bdstr; + + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR); + if (ret == false) { + return BT_STATUS_FAIL; + } + + return BT_STATUS_SUCCESS; +} +#endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index 4c1cd9f0a8..373c3f13f6 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -173,6 +173,8 @@ static void btc_dm_remove_ble_bonding_keys(void) bdcpy(bd_addr.address, btc_dm_cb.pairing_cb.bd_addr); + btc_storage_remove_gatt_cl_supp_feat(&bd_addr); + btc_storage_remove_gatt_db_hash(&bd_addr); btc_storage_remove_remote_addr_type(&bd_addr, false); btc_storage_remove_ble_dev_auth_mode(&bd_addr, false); btc_storage_remove_ble_dev_type(&bd_addr, false); @@ -809,6 +811,8 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) if (p_data->link_down.status == HCI_SUCCESS) { //remove the bonded key in the config and nvs flash. + btc_storage_remove_gatt_cl_supp_feat(&bd_addr); + btc_storage_remove_gatt_db_hash(&bd_addr); btc_storage_remove_ble_dev_type(&bd_addr, false); btc_storage_remove_remote_addr_type(&bd_addr, false); btc_storage_remove_ble_dev_auth_mode(&bd_addr, false); diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h b/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h index 0b8751f895..490e97fd5f 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h @@ -88,6 +88,20 @@ bt_status_t btc_storage_load_bonded_ble_devices(void); bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num); int btc_storage_get_num_ble_bond_devices(void); - #endif ///SMP_INCLUDED == TRUE + +#define BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR "GATT_CL_SUPP_FEAT" +#define BTC_BLE_STORAGE_GATT_DB_HASH_STR "GATT_DB_HASH" + +bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len); + +bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len); + +bt_status_t btc_storage_remove_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr); + +bt_status_t btc_storage_get_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len); + +bt_status_t btc_storage_set_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len); + +bt_status_t btc_storage_remove_gatt_db_hash(bt_bdaddr_t *remote_bd_addr); #endif ///__BTC_BLE_STORAGE_H__ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 1d60319033..6f1e5537d4 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -122,6 +122,20 @@ BOOLEAN GATTS_NVRegister (const tGATT_APPL_INFO *p_cb_info) return status; } +static void gatt_update_for_database_change(void) +{ + UINT8 i; + + gatts_calculate_datebase_hash(gatt_cb.database_hash); + + for (i = 0; i < GATT_MAX_PHY_CHANNEL; i++) { + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(i); + if (p_tcb && p_tcb->in_use) { + gatt_sr_update_cl_status(p_tcb, false); + } + } +} + /******************************************************************************* ** ** Function GATTS_CreateService @@ -398,6 +412,7 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_ GATT_TRACE_DEBUG ("Delete a new service changed item - the service has not yet started"); osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf)); } else { + gatt_update_for_database_change(); if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } @@ -510,6 +525,7 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, if ( (p_buf = gatt_sr_is_new_srv_chg(&p_list->asgn_range.app_uuid128, &p_list->asgn_range.svc_uuid, p_list->asgn_range.svc_inst)) != NULL) { + gatt_update_for_database_change(); if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c index 1360fbaaca..7205558023 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c @@ -29,11 +29,18 @@ #include "stack/gatt_api.h" #include "gatt_int.h" #include "stack/sdpdefs.h" +#include "bta/bta_gatts_co.h" #if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) +#define BLE_GATT_SR_SUPP_FEAT_EATT_BITMASK 0x01 +#define BLE_GATT_CL_SUPP_FEAT_ROBUST_CACHING_BITMASK 0x01 +#define BLE_GATT_CL_SUPP_FEAT_EATT_BITMASK 0x02 +#define BLE_GATT_CL_SUPP_FEAT_MULTI_NOTIF_BITMASK 0x04 +#define BLE_GATT_CL_SUPP_FEAT_BITMASK 0x07 + #define GATTP_MAX_NUM_INC_SVR 0 -#define GATTP_MAX_CHAR_NUM 2 +#define GATTP_MAX_CHAR_NUM 4 #define GATTP_MAX_ATTR_NUM (GATTP_MAX_CHAR_NUM * 2 + GATTP_MAX_NUM_INC_SVR + 1) #define GATTP_MAX_CHAR_VALUE_SIZE 50 @@ -180,30 +187,104 @@ void gatt_profile_clcb_dealloc (tGATT_PROFILE_CLCB *p_clcb) ** Returns GATT_SUCCESS if successfully sent; otherwise error code. ** *******************************************************************************/ -tGATT_STATUS gatt_proc_read (tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS_RSP *p_rsp) +tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS_RSP *p_rsp) { tGATT_STATUS status = GATT_NO_RESOURCES; + UINT16 len = 0; + UINT8 *value; UNUSED(type); + GATT_TRACE_DEBUG("%s handle %x", __func__, p_data->handle); + + UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); + tGATT_TCB *tcb = gatt_get_tcb_by_idx(tcb_idx); + if (p_data->is_long) { p_rsp->attr_value.offset = p_data->offset; } p_rsp->attr_value.handle = p_data->handle; - UINT16 len = 0; - uint8_t *value; - status = GATTS_GetAttributeValue(p_data->handle, &len, &value); - if(status == GATT_SUCCESS && len > 0 && value) { - if(len > GATT_MAX_ATTR_LEN) { - len = GATT_MAX_ATTR_LEN; + + /* handle request for reading service changed */ + if (p_data->handle == gatt_cb.handle_of_h_r) { + status = GATTS_GetAttributeValue(p_data->handle, &len, &value); + if(status == GATT_SUCCESS && len > 0 && value) { + if(len > GATT_MAX_ATTR_LEN) { + len = GATT_MAX_ATTR_LEN; + } + p_rsp->attr_value.len = len; + memcpy(p_rsp->attr_value.value, value, len); } - p_rsp->attr_value.len = len; - memcpy(p_rsp->attr_value.value, value, len); + } + + /* handle request for reading client supported features */ + if (p_data->handle == gatt_cb.handle_of_cl_supported_feat) { + p_rsp->attr_value.len = 1; + memcpy(p_rsp->attr_value.value, &tcb->cl_supp_feat, 1); + status = GATT_SUCCESS; + } + + /* handle request for reading database hash */ + if (p_data->handle == gatt_cb.handle_of_database_hash) { + p_rsp->attr_value.len = BT_OCTET16_LEN; + memcpy(p_rsp->attr_value.value, gatt_cb.database_hash, BT_OCTET16_LEN); + gatt_sr_update_cl_status(tcb, true); + status = GATT_SUCCESS; + } + + /* handle request for reading server supported features */ + if (p_data->handle == gatt_cb.handle_of_sr_supported_feat) { + p_rsp->attr_value.len = 1; + memcpy(p_rsp->attr_value.value, &gatt_cb.gatt_sr_supported_feat_mask, 1); + status = GATT_SUCCESS; } return status; } +static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ *p_data) +{ + UINT8 val_new; + UINT8 val_old; + UINT8 val_xor; + UINT8 val_and; + UINT8 *p = p_data->value; + UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx); + + GATT_TRACE_DEBUG("%s len %u, feat %x", __func__, p_data->len, *p); + + if (p_tcb == NULL) { + GATT_TRACE_ERROR("%s no conn", __func__); + return GATT_NOT_FOUND; + } + + if (p_data->len != 1) { + GATT_TRACE_ERROR("%s len %u", __func__, p_data->len); + return GATT_INVALID_PDU; + } + + STREAM_TO_UINT8(val_new, p); + val_new = (val_new & BLE_GATT_CL_SUPP_FEAT_BITMASK); + + if (val_new == 0) { + GATT_TRACE_ERROR("%s bit cannot be all zero", __func__); + return GATT_VALUE_NOT_ALLOWED; + } + + val_old = p_tcb->cl_supp_feat; + val_xor = val_old ^ val_new; + val_and = val_xor & val_new; + if (val_and != val_xor) { + GATT_TRACE_ERROR("%s bit cannot be reset", __func__); + return GATT_VALUE_NOT_ALLOWED; + } + + p_tcb->cl_supp_feat = val_new; + bta_gatts_co_cl_feat_save(p_tcb->peer_bda, &p_tcb->cl_supp_feat); + return GATT_SUCCESS; +} + /****************************************************************************** ** ** Function gatt_proc_write_req @@ -213,12 +294,29 @@ tGATT_STATUS gatt_proc_read (tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATT ** Returns GATT_SUCCESS if successfully sent; otherwise error code. ** *******************************************************************************/ -tGATT_STATUS gatt_proc_write_req( tGATTS_REQ_TYPE type, tGATT_WRITE_REQ *p_data) +tGATT_STATUS gatt_proc_write_req(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_WRITE_REQ *p_data) { if(p_data->len > GATT_MAX_ATTR_LEN) { p_data->len = GATT_MAX_ATTR_LEN; } - return GATTS_SetAttributeValue(p_data->handle, + + if (p_data->handle == gatt_cb.handle_of_h_r) { + return GATT_WRITE_NOT_PERMIT; + } + + if (p_data->handle == gatt_cb.handle_of_cl_supported_feat) { + return gatt_sr_write_cl_supp_feat(conn_id, p_data); + } + + if (p_data->handle == gatt_cb.handle_of_database_hash) { + return GATT_WRITE_NOT_PERMIT; + } + + if (p_data->handle == gatt_cb.handle_of_sr_supported_feat) { + return GATT_WRITE_NOT_PERMIT; + } + + return GATTS_SetAttributeValue(p_data->handle, p_data->len, p_data->value); @@ -244,14 +342,14 @@ static void gatt_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE switch (type) { case GATTS_REQ_TYPE_READ: - status = gatt_proc_read(type, &p_data->read_req, &rsp_msg); + status = gatt_proc_read(conn_id, type, &p_data->read_req, &rsp_msg); break; case GATTS_REQ_TYPE_WRITE: if (!p_data->write_req.need_rsp) { ignore = TRUE; } - status = gatt_proc_write_req(type, &p_data->write_req); + status = gatt_proc_write_req(conn_id, type, &p_data->write_req); break; case GATTS_REQ_TYPE_WRITE_EXEC: @@ -370,8 +468,21 @@ void gatt_profile_db_init (void) }; GATTS_AddCharDescriptor (service_handle, GATT_PERM_READ | GATT_PERM_WRITE , &descr_uuid, &attr_val, NULL); - /* start service - */ + + /* add Client Supported Features characteristic */ + uuid.uu.uuid16 = GATT_UUID_CLIENT_SUP_FEAT; + gatt_cb.handle_of_cl_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ | GATT_PERM_WRITE, + GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE, NULL, NULL); + + /* add Database Hash characteristic */ + uuid.uu.uuid16 = GATT_UUID_GATT_DATABASE_HASH; + gatt_cb.handle_of_database_hash = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, NULL, NULL); + + /* add Server Supported Features characteristic */ + uuid.uu.uuid16 = GATT_UUID_SERVER_SUP_FEAT; + gatt_cb.handle_of_sr_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, NULL, NULL); + + /* start service */ status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED ); #if (CONFIG_BT_STACK_NO_LOG) @@ -576,4 +687,100 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP gatt_cl_start_config_ccc(p_clcb); } +/******************************************************************************* +** +** Function gatt_sr_is_cl_robust_caching_supported +** +** Description Check if Robust Caching is supported for the connection +** +** Returns true if enabled by client side, otherwise false +** +*******************************************************************************/ +static BOOLEAN gatt_sr_is_cl_robust_caching_supported(tGATT_TCB *p_tcb) +{ + // Server robust caching not enabled + if (!GATTS_ROBUST_CACHING_ENABLED) { + return FALSE; + } + + return (p_tcb->cl_supp_feat & BLE_GATT_CL_SUPP_FEAT_ROBUST_CACHING_BITMASK); +} + +/******************************************************************************* +** +** Function gatt_sr_is_cl_change_aware +** +** Description Check if the connection is change-aware +** +** Returns true if change aware, otherwise false +** +*******************************************************************************/ +BOOLEAN gatt_sr_is_cl_change_aware(tGATT_TCB *p_tcb) +{ + // If robust caching is not supported, should always return true by default + if (!gatt_sr_is_cl_robust_caching_supported(p_tcb)) { + return true; + } + + return p_tcb->is_robust_cache_change_aware; +} + +/******************************************************************************* +** +** Function gatt_sr_init_cl_status +** +** Description Restore status for trusted device +** +** Returns none +** +*******************************************************************************/ +void gatt_sr_init_cl_status(tGATT_TCB *p_tcb) +{ + bta_gatts_co_cl_feat_load(p_tcb->peer_bda, &p_tcb->cl_supp_feat); + + // This is used to reset bit when robust caching is disabled + if (!GATTS_ROBUST_CACHING_ENABLED) { + p_tcb->cl_supp_feat &= ~BLE_GATT_CL_SUPP_FEAT_ROBUST_CACHING_BITMASK; + } + + if (gatt_sr_is_cl_robust_caching_supported(p_tcb)) { + BT_OCTET16 stored_hash = {0}; + bta_gatts_co_db_hash_load(p_tcb->peer_bda, stored_hash); + p_tcb->is_robust_cache_change_aware = (memcmp(stored_hash, gatt_cb.database_hash, BT_OCTET16_LEN) == 0); + } else { + p_tcb->is_robust_cache_change_aware = true; + } + + GATT_TRACE_DEBUG("%s feat %x aware %d", __func__, p_tcb->cl_supp_feat, p_tcb->is_robust_cache_change_aware); +} + +/******************************************************************************* +** +** Function gatt_sr_update_cl_status +** +** Description Update change-aware status for the remote device +** +** Returns none +** +*******************************************************************************/ +void gatt_sr_update_cl_status(tGATT_TCB *p_tcb, BOOLEAN chg_aware) +{ + if (p_tcb == NULL) { + return; + } + + // if robust caching is not supported, do nothing + if (!gatt_sr_is_cl_robust_caching_supported(p_tcb)) { + return; + } + + // only when client status is changed from unaware to aware, we should store database hash + if (!p_tcb->is_robust_cache_change_aware && chg_aware) { + bta_gatts_co_db_hash_save(p_tcb->peer_bda, gatt_cb.database_hash); + } + + p_tcb->is_robust_cache_change_aware = chg_aware; + + GATT_TRACE_DEBUG("%s status %d", __func__, chg_aware); +} #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 837e7d7157..907b5c9aa4 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -1563,6 +1563,9 @@ static BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) gatts_proc_srv_chg_ind_ack(p_tcb); /* there is no need to inform the application since srv chg is handled internally by GATT */ continue_processing = FALSE; + + /* after receiving ack of svc_chg_ind, reset client status */ + gatt_sr_update_cl_status(p_tcb, true); } gatts_chk_pending_ind(p_tcb); @@ -1609,6 +1612,85 @@ void gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code) } } +static BOOLEAN gatts_handle_db_out_of_sync(tGATT_TCB *p_tcb, UINT8 op_code, + UINT16 len, UINT8 *p_data) +{ + if (gatt_sr_is_cl_change_aware(p_tcb)) { + return false; + } + + bool should_ignore = true; + bool should_rsp = true; + + switch (op_code) { + case GATT_REQ_READ_BY_TYPE: + { + tBT_UUID uuid; + UINT16 s_hdl = 0; + UINT16 e_hdl = 0; + UINT16 db_hash_handle = gatt_cb.handle_of_database_hash; + tGATT_STATUS reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl); + if (reason == GATT_SUCCESS && + (s_hdl <= db_hash_handle && db_hash_handle <= e_hdl) && + (uuid.uu.uuid16 == GATT_UUID_GATT_DATABASE_HASH)) { + should_ignore = false; + } + break; + } + case GATT_REQ_READ: + // for pts don't process read request + #if 0 + { + UINT16 handle = 0; + UINT8 *p = p_data; + tGATT_STATUS status = GATT_SUCCESS; + + if (len < 2) { + status = GATT_INVALID_PDU; + } else { + STREAM_TO_UINT16(handle, p); + len -= 2; + } + + if (status == GATT_SUCCESS && handle == gatt_cb.handle_of_database_hash) { + should_ignore = false; + } + break; + } + #endif + case GATT_REQ_READ_BY_GRP_TYPE: + case GATT_REQ_FIND_TYPE_VALUE: + case GATT_REQ_FIND_INFO: + case GATT_REQ_READ_BLOB: + case GATT_REQ_READ_MULTI: + case GATT_REQ_READ_MULTI_VAR: + case GATT_REQ_WRITE: + case GATT_REQ_PREPARE_WRITE: + break; + case GATT_CMD_WRITE: + case GATT_SIGN_CMD_WRITE: + should_rsp = false; + break; + case GATT_REQ_MTU: + case GATT_REQ_EXEC_WRITE: + case GATT_HANDLE_VALUE_CONF: + default: + should_ignore = false; + break; + } + + if (should_ignore) { + if (should_rsp) { + gatt_send_error_rsp(p_tcb, GATT_DATABASE_OUT_OF_SYNC, op_code, 0x0000, false); + } + + GATT_TRACE_ERROR("database out of sync op_code %x, should_rsp %d", op_code, should_rsp); + gatt_sr_update_cl_status(p_tcb, should_rsp); + } + + return should_ignore; +} + /******************************************************************************* ** ** Function gatt_server_handle_client_req @@ -1640,6 +1722,11 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, } /* otherwise, ignore the pkt */ } else { + // handle database out of sync + if (gatts_handle_db_out_of_sync(p_tcb, op_code, len, p_data)) { + return; + } + switch (op_code) { case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */ case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index a7b823cd8b..ab11d96b4d 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1090,6 +1090,7 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); + gatt_sr_init_cl_status(p_tcb); } return p_tcb; } diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 05174ee638..4583eda447 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -405,6 +405,13 @@ typedef struct { UINT8 pending_cl_req; UINT8 next_slot_inq; /* index of next available slot in queue */ + /* client supported feature */ + UINT8 cl_supp_feat; + /* server supported feature */ + UINT8 sr_supp_feat; + /* if false, should handle database out of sync */ + BOOLEAN is_robust_cache_change_aware; + BOOLEAN in_use; UINT8 tcb_idx; tGATT_PREPARE_WRITE_RECORD prepare_write_record; /* prepare write packets record */ @@ -532,6 +539,12 @@ typedef struct { tGATT_PROFILE_CLCB profile_clcb[GATT_MAX_APPS]; #endif ///GATTS_INCLUDED == TRUE UINT16 handle_of_h_r; /* Handle of the handles reused characteristic value */ + UINT16 handle_of_database_hash; + UINT16 handle_of_cl_supported_feat; + UINT16 handle_of_sr_supported_feat; + BT_OCTET16 database_hash; + UINT8 gatt_sr_supported_feat_mask; + UINT8 gatt_cl_supported_feat_mask; tGATT_APPL_INFO cb_info; @@ -759,4 +772,9 @@ extern BOOLEAN gatt_check_connection_state_by_tcb(tGATT_TCB *p_tcb); extern void gatt_reset_bgdev_list(void); extern uint16_t gatt_get_local_mtu(void); extern void gatt_set_local_mtu(uint16_t mtu); + +extern tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash); +extern BOOLEAN gatt_sr_is_cl_change_aware(tGATT_TCB *p_tcb); +extern void gatt_sr_init_cl_status(tGATT_TCB *p_tcb); +extern void gatt_sr_update_cl_status(tGATT_TCB *tcb, BOOLEAN chg_aware); #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index 7bf1c03694..f8a3143c76 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -44,6 +44,8 @@ #define GATT_INSUF_ENCRYPTION 0x0f #define GATT_UNSUPPORT_GRP_TYPE 0x10 #define GATT_INSUF_RESOURCE 0x11 +#define GATT_DATABASE_OUT_OF_SYNC 0x12 +#define GATT_VALUE_NOT_ALLOWED 0x13 #define GATT_NO_RESOURCES 0x80 diff --git a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h index 9380e2e9c6..d8e4cb591e 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gattdefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/gattdefs.h @@ -121,4 +121,8 @@ #define GATT_UUID_SCAN_INT_WINDOW 0x2A4F #define GATT_UUID_SCAN_REFRESH 0x2A31 +#define GATT_UUID_CLIENT_SUP_FEAT 0x2B29 +#define GATT_UUID_GATT_DATABASE_HASH 0x2B2A +#define GATT_UUID_SERVER_SUP_FEAT 0x2B3A + #endif From 69b8b587c9e909842a41fae8885fa8b6628d43fd Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 7 Dec 2022 15:18:10 +0800 Subject: [PATCH 06/12] bluedroid: add config for robust caching and RPA timeout --- components/bt/host/bluedroid/Kconfig.in | 16 ++++++++++++++++ .../include/common/bluedroid_user_config.h | 12 ++++++++++++ .../bluedroid/common/include/common/bt_target.h | 8 ++++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 2 -- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index d87000e139..85175654ef 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -215,6 +215,13 @@ config BT_GATTS_SEND_SERVICE_CHANGE_MODE default 1 if BT_GATTS_SEND_SERVICE_CHANGE_MANUAL default 0 +config BT_GATTS_ROBUST_CACHING_ENABLED + bool "Enable Robust Caching on Server Side" + depends on BT_GATTS_ENABLE + default n + help + This option enable gatt robust caching feature on server + config BT_GATTC_ENABLE bool "Include GATT client module(GATTC)" depends on BT_BLE_ENABLED @@ -1100,6 +1107,15 @@ config BT_BLE_RPA_SUPPORTED For other BLE chips, devices support network privacy mode and device privacy mode, users can switch the two modes according to their own needs. So this option is enabled by default. +config BT_BLE_RPA_TIMEOUT + int "timeout of resolvable private address" + depends on BT_BLUEDROID_ENABLED + range 1 3600 + default 900 + help + This set RPA timeout of Controller and Host. + Default is 900 s (15 minutes). Range is 1 s to 1 hour (3600 s). + config BT_BLE_50_FEATURES_SUPPORTED bool "Enable BLE 5.0 features" depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 05cb6fab27..3fde16f61a 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -288,12 +288,24 @@ #define UC_BT_GATTS_SEND_SERVICE_CHANGE_MODE 0 #endif +#ifdef CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED +#define UC_BT_GATTS_ROBUST_CACHING_ENABLED CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED +#else +#define UC_BT_GATTS_ROBUST_CACHING_ENABLED 0 +#endif + #ifdef CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN #else #define UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN FALSE #endif +#ifdef CONFIG_BT_BLE_RPA_TIMEOUT +#define UC_BT_BLE_RPA_TIMEOUT CONFIG_BT_BLE_RPA_TIMEOUT +#else +#define UC_BT_BLE_RPA_TIMEOUT 900 +#endif + //SCO VOICE OVER HCI #ifdef CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI #define UC_BT_HFP_AUDIO_DATA_PATH_HCI CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 68d7902145..5329e1b887 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -493,6 +493,10 @@ #define GATTS_SEND_SERVICE_CHANGE_MODE UC_BT_GATTS_SEND_SERVICE_CHANGE_MODE #endif +#ifdef UC_BT_GATTS_ROBUST_CACHING_ENABLED +#define GATTS_ROBUST_CACHING_ENABLED UC_BT_GATTS_ROBUST_CACHING_ENABLED +#endif + #ifdef UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN #endif @@ -503,6 +507,10 @@ #define BT_CLASSIC_BQB_INCLUDED FALSE #endif +#ifdef UC_BT_BLE_RPA_TIMEOUT +#define BTM_BLE_PRIVATE_ADDR_INT UC_BT_BLE_RPA_TIMEOUT +#endif + /* This feature is used to eanble interleaved scan*/ #ifndef BTA_HOST_INTERLEAVE_SEARCH #define BTA_HOST_INTERLEAVE_SEARCH FALSE diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 8d52c65fe9..113af0dfb4 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -143,8 +143,6 @@ typedef struct { #define BTM_BLE_ISVALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == BTM_BLE_CONN_PARAM_UNDEF)) -#define BTM_BLE_PRIVATE_ADDR_INT 900 /* 15 minutes minimum for random address refreshing */ - typedef struct { UINT16 discoverable_mode; UINT16 connectable_mode; From 0b76c3615e64b88ff65eaba272335e428e94dbd5 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Thu, 8 Dec 2022 19:49:35 +0800 Subject: [PATCH 07/12] bluedroid: add internal GATT API for PTS --- .../host/bluedroid/bta/gatt/bta_gattc_act.c | 9 +- .../host/bluedroid/bta/gatt/bta_gattc_api.c | 104 ++++++++++++++ .../host/bluedroid/bta/gatt/bta_gattc_cache.c | 8 ++ .../host/bluedroid/bta/gatt/bta_gatts_api.c | 27 ++++ .../bta/gatt/include/bta_gattc_int.h | 1 + .../host/bluedroid/stack/gatt/att_protocol.c | 11 +- .../bt/host/bluedroid/stack/gatt/gatt_api.c | 82 ++++++++++- .../bt/host/bluedroid/stack/gatt/gatt_cl.c | 133 +++++++++++++++--- .../bt/host/bluedroid/stack/gatt/gatt_db.c | 69 ++++++++- .../bt/host/bluedroid/stack/gatt/gatt_main.c | 3 + .../bt/host/bluedroid/stack/gatt/gatt_sr.c | 132 ++++++++++++++++- .../bluedroid/stack/gatt/include/gatt_int.h | 3 + .../bluedroid/stack/include/stack/gatt_api.h | 53 ++++++- 13 files changed, 600 insertions(+), 35 deletions(-) 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 78ac48d652..361955262b 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -126,6 +126,7 @@ static void bta_gattc_enable(tBTA_GATTC_CB *p_cb) if (p_cb->state == BTA_GATTC_STATE_DISABLED) { /* initialize control block */ memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB)); + bta_gattc_cb.auto_disc = true; p_cb->state = BTA_GATTC_STATE_ENABLED; } else { APPL_TRACE_DEBUG("GATTC is already enabled"); @@ -692,9 +693,11 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } else #endif { /* cache is building */ - p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; - /* cache load failure, start discovery */ - bta_gattc_start_discover(p_clcb, NULL); + if (bta_gattc_cb.auto_disc) { + p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC; + /* cache load failure, start discovery */ + bta_gattc_start_discover(p_clcb, NULL); + } } } else { /* cache is building */ p_clcb->state = BTA_GATTC_DISCOVER_ST; 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 f586db4c49..f5e17a977c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -1103,4 +1103,108 @@ void BTA_GATTC_Broadcast(tBTA_GATTC_IF client_if, BOOLEAN start) return; } +/* Add For BLE PTS */ +uint8_t BTA_GATTC_AutoDiscoverEnable(uint8_t enable) +{ + APPL_TRACE_DEBUG("%s enable %d", __func__, enable); + + bta_gattc_cb.auto_disc = ((enable > 0) ? true : false); + GATTC_AutoDiscoverEnable(enable); + + return 0; +} + +typedef struct { + UINT16 len; + union { + UINT16 uuid16; + UINT32 uuid32; + UINT8 uuid128[LEN_UUID_128]; + } uuid; +} __attribute__((packed)) tAPP_UUID; + +uint8_t BTA_GATTC_Discover(uint8_t gatt_if, uint16_t conn_id, void *uuid, uint8_t disc_type, uint16_t s_handle, uint16_t e_handle) +{ + tGATT_STATUS status; + tGATT_DISC_PARAM param; + tAPP_UUID *app_uuid = (tAPP_UUID *)uuid; + + conn_id = (UINT16)((((UINT8)conn_id) << 8) | gatt_if); + memset(¶m, 0, sizeof(tGATT_DISC_PARAM)); + + if (disc_type == GATT_DISC_SRVC_ALL || disc_type == GATT_DISC_SRVC_BY_UUID) { + param.s_handle = 1; + param.e_handle = 0xFFFF; + } else { + param.s_handle = s_handle; + param.e_handle = e_handle; + } + + if (app_uuid) { + param.service.len = app_uuid->len; + if (app_uuid->len == LEN_UUID_16) { + param.service.uu.uuid16 = app_uuid->uuid.uuid16; + } else if (app_uuid->len == LEN_UUID_32) { + param.service.uu.uuid32 = app_uuid->uuid.uuid32; + } else if (app_uuid->len == LEN_UUID_128) { + memcpy(param.service.uu.uuid128, app_uuid->uuid.uuid128, LEN_UUID_128); + } else { + APPL_TRACE_ERROR("%s invalid uuid len %u", __func__, app_uuid->len); + } + } + + status = GATTC_Discover (conn_id, disc_type, ¶m); + if (status != GATT_SUCCESS) { + APPL_TRACE_ERROR("%s status %x", __func__, status); + return -1; + } + + return 0; +} + +uint8_t BTA_GATTC_ReadLongChar(uint8_t gatt_if, uint16_t conn_id, uint16_t handle, uint16_t offset, uint8_t auth_req) +{ + tGATT_STATUS status; + tGATT_READ_PARAM read_param; + + conn_id = (UINT16)((((UINT8)conn_id) << 8) | gatt_if); + memset (&read_param, 0, sizeof(tGATT_READ_PARAM)); + read_param.partial.handle = handle; + read_param.partial.offset = offset; + read_param.partial.auth_req = auth_req; + + status = GATTC_Read(conn_id, GATT_READ_PARTIAL, &read_param); + if (status != GATT_SUCCESS) { + APPL_TRACE_ERROR("%s status %x", __func__, status); + return -1; + } + + 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_cache.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_cache.c index fb48cb9cfa..7af5e6beee 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_cache.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_cache.c @@ -969,6 +969,10 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_ BOOLEAN pri_srvc; tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); + if (bta_gattc_cb.auto_disc == FALSE) { + return; + } + p_srvc_cb = bta_gattc_find_scb_by_cid(conn_id); if (p_srvc_cb != NULL && p_clcb != NULL && p_clcb->state == BTA_GATTC_DISCOVER_ST) { @@ -1042,6 +1046,10 @@ void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT tBTA_GATTC_SERV *p_srvc_cb; tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); + if (bta_gattc_cb.auto_disc == FALSE) { + return; + } + if ( p_clcb && (status != GATT_SUCCESS || p_clcb->status != GATT_SUCCESS) ) { if (status == GATT_SUCCESS) { p_clcb->status = status; diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c index cff4688cd4..03e584f12b 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c @@ -640,4 +640,31 @@ void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target return; } +uint8_t BTA_GATTS_SetServiceChangeMode(uint8_t mode) +{ + tGATT_STATUS status; + APPL_TRACE_DEBUG("%s mode %u", __func__, mode); + + status = GATTS_SetServiceChangeMode(mode); + if (status != GATT_SUCCESS) { + APPL_TRACE_ERROR("%s status %x", __func__, status); + return -1; + } + + return 0; +} + +uint8_t BTA_GATTS_SendMultiNotification(uint8_t gatt_if, uint16_t conn_id, void *tuples, uint16_t num_tuples) +{ + tGATT_STATUS status; + conn_id = (UINT16)((((UINT8)conn_id) << 8) | gatt_if); + + status = GATTS_HandleMultiValueNotification(conn_id, (tGATT_HLV *)tuples, num_tuples); + if (status != GATT_SUCCESS) { + APPL_TRACE_ERROR("%s status %x", __func__, status); + return -1; + } + + return 0; +} #endif /* BTA_GATT_INCLUDED */ 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 874315028c..45caacf67b 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 @@ -394,6 +394,7 @@ enum { typedef struct { UINT8 state; + BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */ tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX]; tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX]; tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX]; diff --git a/components/bt/host/bluedroid/stack/gatt/att_protocol.c b/components/bt/host/bluedroid/stack/gatt/att_protocol.c index c6bb441105..310a9756ef 100644 --- a/components/bt/host/bluedroid/stack/gatt/att_protocol.c +++ b/components/bt/host/bluedroid/stack/gatt/att_protocol.c @@ -197,7 +197,7 @@ BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_ ** Returns None. ** *******************************************************************************/ -BT_HDR *attp_build_read_multi_cmd(UINT16 payload_size, UINT16 num_handle, UINT16 *p_handle) +BT_HDR *attp_build_read_multi_cmd(UINT8 op_code, UINT16 payload_size, UINT16 num_handle, UINT16 *p_handle) { BT_HDR *p_buf = NULL; UINT8 *p, i = 0; @@ -208,7 +208,7 @@ BT_HDR *attp_build_read_multi_cmd(UINT16 payload_size, UINT16 num_handle, UINT16 p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = 1; - UINT8_TO_STREAM (p, GATT_REQ_READ_MULTI); + UINT8_TO_STREAM (p, op_code); for (i = 0; i < num_handle && p_buf->len + 2 <= payload_size; i ++) { UINT16_TO_STREAM (p, *(p_handle + i)); @@ -304,7 +304,7 @@ BT_HDR *attp_build_value_cmd (UINT16 payload_size, UINT8 op_code, UINT16 handle, UINT8_TO_STREAM (p, pair_len); p_buf->len += 1; } - if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) { + if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ && op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) { UINT16_TO_STREAM (p, handle); p_buf->len += 2; } @@ -391,6 +391,7 @@ BT_HDR *attp_build_sr_msg(tGATT_TCB *p_tcb, UINT8 op_code, tGATT_SR_MSG *p_msg) case GATT_RSP_READ: case GATT_HANDLE_VALUE_NOTIF: case GATT_HANDLE_VALUE_IND: + case GATT_HANDLE_MULTI_VALUE_NOTIF: case GATT_RSP_ERROR: case GATT_RSP_MTU: /* Need to check the validation of parameter p_msg*/ @@ -417,6 +418,7 @@ BT_HDR *attp_build_sr_msg(tGATT_TCB *p_tcb, UINT8 op_code, tGATT_SR_MSG *p_msg) case GATT_RSP_READ: case GATT_HANDLE_VALUE_NOTIF: case GATT_HANDLE_VALUE_IND: + case GATT_HANDLE_MULTI_VALUE_NOTIF: p_cmd = attp_build_value_cmd(p_tcb->payload_size, op_code, p_msg->attr_value.handle, @@ -613,7 +615,8 @@ tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, break; case GATT_REQ_READ_MULTI: - p_cmd = attp_build_read_multi_cmd(p_tcb->payload_size, + case GATT_REQ_READ_MULTI_VAR: + p_cmd = attp_build_read_multi_cmd(op_code, p_tcb->payload_size, p_msg->read_multi.num_handles, p_msg->read_multi.handles); break; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 6f1e5537d4..4c2917edd6 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -413,7 +413,7 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_ osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf)); } else { gatt_update_for_database_change(); - if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) { + if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } } @@ -526,7 +526,7 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, &p_list->asgn_range.svc_uuid, p_list->asgn_range.svc_inst)) != NULL) { gatt_update_for_database_change(); - if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) { + if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } /* remove the new service element after the srv changed processing is completed*/ @@ -996,6 +996,7 @@ tGATT_STATUS GATTC_Read (UINT16 conn_id, tGATT_READ_TYPE type, tGATT_READ_PARAM memcpy(&p_clcb->uuid, &p_read->service.uuid, sizeof(tBT_UUID)); break; case GATT_READ_MULTIPLE: + case GATT_READ_MULTIPLE_VAR: p_clcb->s_handle = 0; /* copy multiple handles in CB */ p_read_multi = (tGATT_READ_MULTI *)osi_malloc(sizeof(tGATT_READ_MULTI)); @@ -1187,6 +1188,12 @@ tGATT_STATUS GATTC_SendHandleValueConfirm (UINT16 conn_id, UINT16 handle) return ret; } +tGATT_STATUS GATTC_AutoDiscoverEnable(UINT8 enable) +{ + gatt_cb.auto_disc = (enable > 0) ? TRUE : FALSE; + return GATT_SUCCESS; +} + #endif ///GATTC_INCLUDED == TRUE /*******************************************************************************/ @@ -1559,7 +1566,8 @@ tGATT_STATUS GATT_SendServiceChangeIndication (BD_ADDR bd_addr) tGATT_TCB *p_tcb; tBT_TRANSPORT transport; tGATT_STATUS status = GATT_NOT_FOUND; - if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) { + + if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { status = GATT_WRONG_STATE; GATT_TRACE_ERROR ("%s can't send service change indication manually, please configure the option through menuconfig", __func__); return status; @@ -1691,4 +1699,72 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr) return gatt_update_listen_mode(); } +tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode) +{ + if (mode > GATTS_SEND_SERVICE_CHANGE_MANUAL) { + GATT_TRACE_ERROR("%s invalid service change mode %u", __func__, mode); + return GATT_VALUE_NOT_ALLOWED; + } + + gatt_cb.srv_chg_mode = mode; + return GATT_SUCCESS; +} + +tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tuples, UINT16 num_tuples) +{ + tGATT_STATUS cmd_sent = GATT_ILLEGAL_PARAMETER; + BT_HDR *p_buf; + tGATT_VALUE notif; + tGATT_IF gatt_if = GATT_GET_GATT_IF(conn_id); + UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); + tGATT_REG *p_reg = gatt_get_regcb(gatt_if); + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(tcb_idx); + UINT8 *p = notif.value; + tGATT_HLV *p_hlv = tuples; + + GATT_TRACE_API ("GATTS_HandleMultiValueNotification"); + + if ( (p_reg == NULL) || (p_tcb == NULL)) { + GATT_TRACE_ERROR ("GATTS_HandleMultiValueNotification Unknown conn_id: %u \n", conn_id); + return (tGATT_STATUS) GATT_INVALID_CONN_ID; + } + + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + GATT_TRACE_ERROR("connection not established\n"); + return GATT_WRONG_STATE; + } + + if (tuples == NULL) { + return GATT_ILLEGAL_PARAMETER; + } + + notif.len = 0; + + while (num_tuples) { + if (!GATT_HANDLE_IS_VALID (p_hlv->handle)) { + return GATT_ILLEGAL_PARAMETER; + } + + UINT16_TO_STREAM(p, p_hlv->handle); //handle + UINT16_TO_STREAM(p, p_hlv->length); //length + memcpy (p, p_hlv->value, p_hlv->length); //value + GATT_TRACE_DEBUG("%s handle %x, length %u", __func__, p_hlv->handle, p_hlv->length); + p += p_hlv->length; + notif.len += 4 + p_hlv->length; + num_tuples--; + p_hlv++; + } + + notif.auth_req = GATT_AUTH_REQ_NONE; + + p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_MULTI_VALUE_NOTIF, (tGATT_SR_MSG *)¬if); + if (p_buf != NULL) { + cmd_sent = attp_send_sr_msg (p_tcb, p_buf); + } else { + cmd_sent = GATT_NO_RESOURCES; + } + + return cmd_sent; +} + #endif diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c index ec046eadad..9fd0adf89a 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c @@ -53,6 +53,7 @@ static const UINT8 disc_type_to_att_opcode[GATT_DISC_MAX] = { GATT_REQ_FIND_TYPE_VALUE, /* GATT_DISC_SRVC_BY_UUID, */ GATT_REQ_READ_BY_TYPE, /* GATT_DISC_INC_SRVC, */ GATT_REQ_READ_BY_TYPE, /* GATT_DISC_CHAR, */ + GATT_REQ_READ_BY_TYPE, /* GATT_DISC_CHAR_BY_UUID, */ GATT_REQ_FIND_INFO /* GATT_DISC_CHAR_DSCPT, */ }; @@ -65,6 +66,41 @@ static const UINT16 disc_type_to_uuid[GATT_DISC_MAX] = { 0 /* no type filtering for DISC_CHAR_DSCPT */ }; +// Use for GATTC discover infomation print +#define GATT_DISC_INFO(fmt, args...) {if (gatt_cb.auto_disc == FALSE) BT_PRINT_I("BT_GATT", fmt, ## args);} + +char *gatt_uuid_to_str(const tBT_UUID *uuid) +{ + static char dst[48] = {0}; + const uint8_t *u8p; + + memset(dst, 0, sizeof(dst)); + + switch (uuid->len) { + case LEN_UUID_16: + sprintf(dst, "0x%04x", uuid->uu.uuid16); + break; + case LEN_UUID_32: + sprintf(dst, "0x%08x", uuid->uu.uuid32); + break; + case LEN_UUID_128: + u8p = uuid->uu.uuid128; + + sprintf(dst, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + u8p[15], u8p[14], u8p[13], u8p[12], + u8p[11], u8p[10], u8p[9], u8p[8], + u8p[7], u8p[6], u8p[5], u8p[4], + u8p[3], u8p[2], u8p[1], u8p[0]); + break; + default: + dst[0] = '\0'; + break; + } + + return dst; +} + /******************************************************************************* ** @@ -107,6 +143,10 @@ void gatt_act_discovery(tGATT_CLCB *p_clcb) } } + if (p_clcb->op_subtype == GATT_DISC_CHAR_BY_UUID) { + memcpy(&cl_req.browse.uuid, &p_clcb->uuid, sizeof(tBT_UUID)); + } + st = attp_send_cl_msg(p_clcb->p_tcb, p_clcb->clcb_idx, op_code, &cl_req); if (st != GATT_SUCCESS && st != GATT_CMD_STARTED) { @@ -181,6 +221,11 @@ void gatt_act_read (tGATT_CLCB *p_clcb, UINT16 offset) memcpy (&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI)); break; + case GATT_READ_MULTIPLE_VAR: + op_code = GATT_REQ_READ_MULTI_VAR; + memcpy (&msg.read_multi, p_clcb->p_attr_buf, sizeof(tGATT_READ_MULTI)); + break; + case GATT_READ_INC_SRV_UUID128: op_code = GATT_REQ_READ; msg.handle = p_clcb->s_handle; @@ -408,6 +453,7 @@ void gatt_process_find_type_value_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UIN while (len >= 4) { STREAM_TO_UINT16 (result.handle, p); STREAM_TO_UINT16 (result.value.group_value.e_handle, p); + GATT_DISC_INFO("%s handle %x, end handle %x", __func__, result.handle, result.value.group_value.e_handle); memcpy (&result.value.group_value.service_type, &p_clcb->uuid, sizeof(tBT_UUID)); len -= 4; @@ -474,6 +520,8 @@ void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_c len -= (uuid_len + 2); + GATT_DISC_INFO("%s handle %x, uuid %s", __func__, result.handle, gatt_uuid_to_str(&result.type)); + if (p_clcb->p_reg->app_cb.p_disc_res_cb) { (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id, p_clcb->op_subtype, &result); } @@ -510,7 +558,7 @@ void gatt_proc_disc_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 opcode case GATT_REQ_FIND_INFO: if (reason == GATT_NOT_FOUND) { status = GATT_SUCCESS; - GATT_TRACE_DEBUG("Discovery completed"); + GATT_DISC_INFO("Discovery completed"); } break; default: @@ -541,7 +589,7 @@ void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, UNUSED(op_code); UNUSED(len); - GATT_TRACE_DEBUG("gatt_process_error_rsp "); + GATT_TRACE_DEBUG("%s", __func__); STREAM_TO_UINT8(opcode, p); STREAM_TO_UINT16(handle, p); STREAM_TO_UINT8(reason, p); @@ -634,7 +682,7 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 conn_id; tGATT_STATUS encrypt_status; UINT8 *p = p_data, i, - event = (op_code == GATT_HANDLE_VALUE_NOTIF) ? GATTC_OPTYPE_NOTIFICATION : GATTC_OPTYPE_INDICATION; + event = (op_code == GATT_HANDLE_VALUE_IND) ? GATTC_OPTYPE_INDICATION: GATTC_OPTYPE_NOTIFICATION; GATT_TRACE_DEBUG("gatt_process_notification "); @@ -644,8 +692,6 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code, } STREAM_TO_UINT16 (value.handle, p); - value.len = len - 2; - memcpy (value.value, p, value.len); if (!GATT_HANDLE_IS_VALID(value.handle)) { /* illegal handle, send ack now */ @@ -655,6 +701,28 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code, return; } + if (op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { + if (len < GATT_NOTIFICATION_MIN_LEN + 2) { + GATT_TRACE_ERROR("illegal notification PDU length, discard"); + return; + } + + STREAM_TO_UINT16(value.len, p); + if (value.len > len - 4) { + return; + } + } else { + value.len = len - 2; + } + + if (value.len > GATT_MAX_ATTR_LEN) { + GATT_TRACE_ERROR("value length larger than GATT_MAX_ATTR_LEN, discard"); + return; + } + + memcpy(value.value, p, value.len); + p += value.len; + if (event == GATTC_OPTYPE_INDICATION) { if (p_tcb->ind_count) { /* this is an error case that receiving an indication but we @@ -665,19 +733,16 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code, GATT_TRACE_ERROR("gatt_process_notification rcv Ind. but ind_count=%d (will reset ind_count)", p_tcb->ind_count); } p_tcb->ind_count = 0; - } - /* should notify all registered client with the handle value notificaion/indication - Note: need to do the indication count and start timer first then do callback - */ - - for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) { - if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb && (event == GATTC_OPTYPE_INDICATION)) { - p_tcb->ind_count++; + /* should notify all registered client with the handle value notificaion/indication + Note: need to do the indication count and start timer first then do callback + */ + for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) { + if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb && (event == GATTC_OPTYPE_INDICATION)) { + p_tcb->ind_count++; + } } - } - if (event == GATTC_OPTYPE_INDICATION) { /* start a timer for app confirmation */ if (p_tcb->ind_count > 0) { gatt_start_ind_ack_timer(p_tcb); @@ -694,6 +759,33 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code, } } + if (op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) { + return; + } + + if (len < (4 + value.len)) { + GATT_TRACE_ERROR("no remain data for multi notification"); + return; + } + + len -= (4 + value.len); + + while (len > 4) { + STREAM_TO_UINT16(value.handle, p); + STREAM_TO_UINT16(value.len, p); + len -= 4; + value.len = MIN(len, value.len); + memcpy(value.value, p, value.len); + p += value.len; + len -= value.len; + + for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) { + if (p_reg->in_use && p_reg->app_cb.p_cmpl_cb) { + conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if); + (*p_reg->app_cb.p_cmpl_cb) (conn_id, event, encrypt_status, (tGATT_CL_COMPLETE *)&value); + } + } + } } /******************************************************************************* @@ -746,6 +838,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 while (len >= (handle_len + value_len)) { STREAM_TO_UINT16(handle, p); + GATT_DISC_INFO("%s op %x, handle %x", __func__, op_code, handle); if (!GATT_HANDLE_IS_VALID(handle)) { gatt_end_operation(p_clcb, GATT_INVALID_HANDLE, NULL); @@ -775,6 +868,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 break; } } + GATT_DISC_INFO("DISC ALL SVC end handle %x, uuid %s", record_value.group_value.e_handle, gatt_uuid_to_str(&record_value.group_value.service_type)); } /* discover included service */ else if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY && p_clcb->op_subtype == GATT_DISC_INC_SRVC) { @@ -790,6 +884,8 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 if (value_len == 6) { STREAM_TO_UINT16(record_value.incl_service.service_type.uu.uuid16, p); record_value.incl_service.service_type.len = LEN_UUID_16; + GATT_DISC_INFO("DISC INC SVC start handle %x, end handle %x, uuid %s", + record_value.incl_service.s_handle, record_value.incl_service.e_handle, gatt_uuid_to_str(&record_value.incl_service.service_type)); } else if (value_len == 4) { p_clcb->s_handle = record_value.incl_service.s_handle; p_clcb->read_uuid128.wait_for_read_rsp = TRUE; @@ -797,7 +893,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 memcpy(&p_clcb->read_uuid128.result, &result, sizeof(result)); memcpy(&p_clcb->read_uuid128.result.value, &record_value, sizeof (result.value)); p_clcb->op_subtype |= 0x90; - gatt_act_read(p_clcb, 0); + gatt_act_read(p_clcb, 0); // read 128-bit uuid of include service return; } else { GATT_TRACE_ERROR("gatt_process_read_by_type_rsp INCL_SRVC failed with invalid data value_len=%d", value_len); @@ -937,6 +1033,9 @@ void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code, memcpy(p_clcb->read_uuid128.result.value.incl_service.service_type.uu.uuid128, p, len); p_clcb->read_uuid128.result.value.incl_service.service_type.len = LEN_UUID_128; + tGATT_INCL_SRVC *inc_srvc = &p_clcb->read_uuid128.result.value.incl_service; + GATT_DISC_INFO("DISC INC SRVC start handle %x, end handle %x, uuid %s", + inc_srvc->s_handle, inc_srvc->e_handle, gatt_uuid_to_str(&inc_srvc->service_type)); if ( p_clcb->p_reg->app_cb.p_disc_res_cb) { (*p_clcb->p_reg->app_cb.p_disc_res_cb)(p_clcb->conn_id, p_clcb->op_subtype, &p_clcb->read_uuid128.result); } @@ -1133,6 +1232,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, case GATT_RSP_READ: case GATT_RSP_READ_BLOB: case GATT_RSP_READ_MULTI: + case GATT_RSP_READ_MULTI_VAR: gatt_process_read_rsp(p_tcb, p_clcb, op_code, len, p_data); break; @@ -1154,6 +1254,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, case GATT_HANDLE_VALUE_NOTIF: case GATT_HANDLE_VALUE_IND: + case GATT_HANDLE_MULTI_VALUE_NOTIF: gatt_process_notification(p_tcb, op_code, len, p_data); break; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_db.c b/components/bt/host/bluedroid/stack/gatt/gatt_db.c index d18a0ccf3d..ed03d0453b 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -35,6 +35,9 @@ #include "stack/l2c_api.h" #include "btm_int.h" +extern tGATT_STATUS gap_proc_read(tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS_RSP *p_rsp); +extern tGATT_STATUS gatt_proc_read(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS_RSP *p_rsp); + /******************************************************************************** ** L O C A L F U N C T I O N P R O T O T Y P E S * *********************************************************************************/ @@ -764,6 +767,66 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, return GATT_SUCCESS; } +/******************************************************************************* +** +** Function gatts_get_attr_value_internal +** +** Description This function get the attribute value in gap service and gatt service +** +** Parameter attr_handle: the attribute handle +** length: the attribute value length +** value: the pointer to the data to be get to the attribute value in the database +** +** Returns Status of the operation. +** +*******************************************************************************/ +static tGATT_STATUS gatts_get_attr_value_internal(UINT16 attr_handle, UINT16 *length, UINT8 **value) +{ + UINT8 i; + tGATT_READ_REQ read_req; + tGATT_STATUS status = GATT_NOT_FOUND; + tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; + UINT8 service_uuid[LEN_UUID_128] = {0}; + + // find the service by handle + for (i = 0; i < GATT_MAX_SR_PROFILES; i++, p_rcb++) { + if (p_rcb->in_use && p_rcb->s_hdl <= attr_handle && p_rcb->e_hdl >= attr_handle) { + break; + } + } + + // service cb not found + if (i == GATT_MAX_SR_PROFILES) { + return status; + } + + if (p_rcb->app_uuid.len != LEN_UUID_128) { + return status; + } + + memset(&read_req, 0, sizeof(tGATT_READ_REQ)); + read_req.handle = attr_handle; + + // read gatt service attribute value + memset(service_uuid, 0x81, LEN_UUID_128); + if (!memcmp(p_rcb->app_uuid.uu.uuid128, service_uuid, LEN_UUID_128)) { + status = gatt_proc_read(0, GATTS_REQ_TYPE_READ, &read_req, &gatt_cb.rsp); + } + + // read gap service attribute value + memset(service_uuid, 0x82, LEN_UUID_128); + if (!memcmp(p_rcb->app_uuid.uu.uuid128, service_uuid, LEN_UUID_128)) { + status = gap_proc_read(GATTS_REQ_TYPE_READ, &read_req, &gatt_cb.rsp); + } + + if (status == GATT_SUCCESS) { + *length = gatt_cb.rsp.attr_value.len; + *value = gatt_cb.rsp.attr_value.value; + } + + return status; +} + /******************************************************************************* ** ** Function gatts_get_attribute_value @@ -805,7 +868,11 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, return GATT_INVALID_PDU; } - p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; + if (gatts_get_attr_value_internal(attr_handle, length, value) == GATT_SUCCESS) { + return GATT_SUCCESS; + } + + p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; while (p_cur != NULL) { if (p_cur->handle == attr_handle) { diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index 1a91639e2a..9f437f94c8 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -103,6 +103,7 @@ void gatt_init (void) memset (&gatt_cb, 0, sizeof(tGATT_CB)); memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG)); + gatt_cb.auto_disc = TRUE; gatt_cb.p_clcb_list = list_new(osi_free_func); gatt_cb.p_tcb_list = list_new(osi_free_func); #if defined(GATT_INITIAL_TRACE_LEVEL) @@ -114,6 +115,8 @@ void gatt_init (void) gatt_cb.sign_op_queue = fixed_queue_new(QUEUE_SIZE_MAX); gatt_cb.srv_chg_clt_q = fixed_queue_new(QUEUE_SIZE_MAX); gatt_cb.pending_new_srv_start_q = fixed_queue_new(QUEUE_SIZE_MAX); + gatt_cb.srv_chg_mode = GATTS_SEND_SERVICE_CHANGE_MODE; + /* First, register fixed L2CAP channel for ATT over BLE */ fixed_reg.fixed_chnl_opts.mode = L2CAP_FCR_BASIC_MODE; fixed_reg.fixed_chnl_opts.max_transmit = 0xFF; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 907b5c9aa4..1510f44871 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -277,6 +277,117 @@ static BOOLEAN process_read_multi_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status, return (FALSE); } +static BOOLEAN process_read_multi_var_rsp (tGATT_SR_CMD *p_cmd, tGATT_STATUS status, + tGATTS_RSP *p_msg, UINT16 mtu) +{ + UINT16 ii; + UINT16 total_len; + UINT16 len; + UINT8 *p; + + GATT_TRACE_DEBUG ("process_read_multi_var rsp status=%d mtu=%d", status, mtu); + + if (p_cmd->multi_rsp_q == NULL) { + p_cmd->multi_rsp_q = fixed_queue_new(QUEUE_SIZE_MAX); + } + + /* Enqueue the response */ + BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(tGATTS_RSP)); + if (p_buf == NULL) { + p_cmd->status = GATT_INSUF_RESOURCE; + return FALSE; + } + memcpy((void *)p_buf, (const void *)p_msg, sizeof(tGATTS_RSP)); + + fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf, FIXED_QUEUE_MAX_TIMEOUT); + + p_cmd->status = status; + if (status == GATT_SUCCESS) { + GATT_TRACE_DEBUG ("Multi var read count=%d num_hdls=%d", + fixed_queue_length(p_cmd->multi_rsp_q), + p_cmd->multi_req.num_handles); + /* Wait till we get all the responses */ + if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { + len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; + if ((p_buf = (BT_HDR *)osi_calloc(len)) == NULL) { + p_cmd->status = GATT_INSUF_RESOURCE; + return (TRUE); + } + + p_buf->offset = L2CAP_MIN_OFFSET; + p = (UINT8 *)(p_buf + 1) + p_buf->offset; + + /* First byte in the response is the opcode */ + *p++ = GATT_RSP_READ_MULTI_VAR; + p_buf->len = 1; + + /* Now walk through the buffers puting the data into the response in order */ + list_t *list = NULL; + const list_node_t *node = NULL; + if (! fixed_queue_is_empty(p_cmd->multi_rsp_q)) { + list = fixed_queue_get_list(p_cmd->multi_rsp_q); + } + for (ii = 0; ii < p_cmd->multi_req.num_handles; ii++) { + tGATTS_RSP *p_rsp = NULL; + if (list != NULL) { + if (ii == 0) { + node = list_begin(list); + } else { + node = list_next(node); + } + if (node != list_end(list)) { + p_rsp = (tGATTS_RSP *)list_node(node); + } + } + + if (p_rsp != NULL) { + + total_len = (p_buf->len + 2); // value length + + if (total_len > mtu) { + GATT_TRACE_DEBUG ("multi read variable overflow available len=%d val_len=%d", len, p_rsp->attr_value.len ); + break; + } + len = MIN(p_rsp->attr_value.len, (mtu - total_len)); // attribute value length + + if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) { + GATT_TRACE_DEBUG("%s handle %x len %u", __func__, p_rsp->attr_value.handle, p_rsp->attr_value.len); + UINT16_TO_STREAM(p, p_rsp->attr_value.len); + memcpy (p, p_rsp->attr_value.value, len); + p += len; + p_buf->len += (2+len); + } else { + p_cmd->status = GATT_NOT_FOUND; + break; + } + } else { + p_cmd->status = GATT_NOT_FOUND; + break; + } + + } /* loop through all handles*/ + + /* Sanity check on the buffer length */ + if (p_buf->len == 0) { + GATT_TRACE_ERROR("%s - nothing found!!", __func__); + p_cmd->status = GATT_NOT_FOUND; + osi_free (p_buf); + } else if (p_cmd->p_rsp_msg != NULL) { + osi_free (p_buf); + } else { + p_cmd->p_rsp_msg = p_buf; + } + + return (TRUE); + } + } else { /* any handle read exception occurs, return error */ + return (TRUE); + } + + /* If here, still waiting */ + return (FALSE); +} + /******************************************************************************* ** ** Function gatt_sr_process_app_rsp @@ -303,6 +414,10 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if, if (!process_read_multi_rsp (&p_tcb->sr_cmd, status, p_msg, p_tcb->payload_size)) { return (GATT_SUCCESS); } + } else if (op_code == GATT_REQ_READ_MULTI_VAR) { + if (!process_read_multi_var_rsp(&p_tcb->sr_cmd, status, p_msg, p_tcb->payload_size)) { + return (GATT_SUCCESS); + } } else { if (op_code == GATT_REQ_PREPARE_WRITE && status == GATT_SUCCESS) { gatt_sr_update_prep_cnt(p_tcb, gatt_if, TRUE, FALSE); @@ -514,7 +629,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U sec_flag, key_size)) != GATT_SUCCESS) { - GATT_TRACE_DEBUG("read permission denied : 0x%02x", err); + GATT_TRACE_ERROR("read permission denied : 0x%02x", err); break; } } else { @@ -525,13 +640,15 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U ll -= 2; } - if (ll != 0) { - GATT_TRACE_ERROR("max attribute handle reached in ReadMultiple Request."); - err = GATT_INVALID_HANDLE; - } + if (err == GATT_SUCCESS) { + if (ll != 0) { + GATT_TRACE_ERROR("max attribute handle reached in ReadMultiple Request."); + err = GATT_INVALID_HANDLE; + } - if (p_tcb->sr_cmd.multi_req.num_handles == 0) { - err = GATT_INVALID_HANDLE; + if (p_tcb->sr_cmd.multi_req.num_handles == 0) { + err = GATT_INVALID_HANDLE; + } } if (err == GATT_SUCCESS) { @@ -1765,6 +1882,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, break; case GATT_REQ_READ_MULTI: + case GATT_REQ_READ_MULTI_VAR: gatt_process_read_multi_req (p_tcb, op_code, len, p_data); break; diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 4583eda447..e31bbd0c5e 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -553,6 +553,9 @@ typedef struct { tGATT_HDL_CFG hdl_cfg; tGATT_BG_CONN_DEV bgconn_dev[GATT_MAX_BG_CONN_DEV]; + BOOLEAN auto_disc; /* internal use: true for auto discovering after connected */ + UINT8 srv_chg_mode; /* internal use: service change mode */ + tGATTS_RSP rsp; /* use to read internal service attribute */ } tGATT_CB; typedef struct{ diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index f8a3143c76..441bb12250 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -110,8 +110,11 @@ typedef UINT8 tGATT_STATUS; #define GATT_HANDLE_VALUE_NOTIF 0x1B #define GATT_HANDLE_VALUE_IND 0x1D #define GATT_HANDLE_VALUE_CONF 0x1E +#define GATT_REQ_READ_MULTI_VAR 0x20 +#define GATT_RSP_READ_MULTI_VAR 0x21 +#define GATT_HANDLE_MULTI_VALUE_NOTIF 0x23 #define GATT_SIGN_CMD_WRITE 0xD2 /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ -#define GATT_OP_CODE_MAX GATT_HANDLE_VALUE_CONF + 1 /* 0x1E = 30 + 1 = 31*/ +#define GATT_OP_CODE_MAX GATT_HANDLE_MULTI_VALUE_NOTIF + 1 /* 0x1E = 30 + 1 = 31*/ #define GATT_COMMAND_FLAG 0x40 /* Command Flag: set to one means command */ @@ -415,6 +418,7 @@ enum { GATT_DISC_SRVC_BY_UUID, /* discover service of a special type */ GATT_DISC_INC_SRVC, /* discover the included service within a service */ GATT_DISC_CHAR, /* discover characteristics of a service with/without type requirement */ + GATT_DISC_CHAR_BY_UUID, /* discover characteristic with type requirement */ GATT_DISC_CHAR_DSCPT, /* discover characteristic descriptors of a character */ GATT_DISC_MAX /* maximnun discover type */ }; @@ -434,6 +438,7 @@ enum { GATT_READ_BY_TYPE = 1, GATT_READ_BY_HANDLE, GATT_READ_MULTIPLE, + GATT_READ_MULTIPLE_VAR, GATT_READ_CHAR_VALUE, GATT_READ_PARTIAL, GATT_READ_MAX @@ -657,6 +662,12 @@ typedef struct { tGATTS_NV_SRV_CHG_CBACK *p_srv_chg_callback; } tGATT_APPL_INFO; +typedef struct { + UINT16 handle; + UINT16 length; + UINT8 *value; +} tGATT_HLV; + /* *********************** End Handle Management Definitions **********************/ @@ -1034,6 +1045,18 @@ extern tGATT_STATUS GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute); *******************************************************************************/ extern tGATT_STATUS GATTC_SendHandleValueConfirm (UINT16 conn_id, UINT16 handle); +/******************************************************************************* +** +** Function GATTC_AutoDiscoverEnable +** +** Description This function is called to enable/disable auto discover. +** +** Parameters enable: 0 for disable, otherwise enable. +** +** Returns GATT_SUCCESS if command started successfully. +** +*******************************************************************************/ +extern tGATT_STATUS GATTC_AutoDiscoverEnable(UINT8 enable); /******************************************************************************* ** @@ -1228,6 +1251,34 @@ extern BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr extern void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSPORT transport); +/******************************************************************************* +** +** Function GATTS_SetServiceChangeMode +** +** Description Configure service change indication mode +** +** Parameters mode: service change mode +** +** Returns Status. +** +*******************************************************************************/ +extern tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode); + +/******************************************************************************* +** +** Function GATTS_HandleMultiValueNotification +** +** Description This function sends multiple handle value notification to a client. +** +** Parameter conn_id: connection identifier. +** tuples: Pointer to handle-length-value tuple list. +** num_tuples: Number of tuples. +** +** Returns GATT_SUCCESS if successfully sent; otherwise error code. +** +*******************************************************************************/ +extern tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tuples, UINT16 num_tuples); + #ifdef __cplusplus } From 285e86ad0477b29203731bb931aae3a4ecf8e3ba Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Thu, 8 Dec 2022 19:52:28 +0800 Subject: [PATCH 08/12] bluedroid: add config for GAP service and periodic adv sync transfer --- components/bt/host/bluedroid/Kconfig.in | 16 ++++- .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 6 +- .../include/common/bluedroid_user_config.h | 14 ++++- .../common/include/common/bt_target.h | 21 ++++++- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 58 ++++++++++--------- .../bt/host/bluedroid/stack/btu/btu_hcif.c | 13 ++++- .../bt/host/bluedroid/stack/gap/gap_ble.c | 47 ++++++++++++--- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 4 +- .../stack/include/stack/btm_ble_api.h | 32 +++++----- .../bluedroid/stack/include/stack/hcidefs.h | 8 ++- .../bluedroid/stack/include/stack/hcimsgs.h | 4 +- 11 files changed, 160 insertions(+), 63 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 85175654ef..c15013719a 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -222,6 +222,20 @@ config BT_GATTS_ROBUST_CACHING_ENABLED help This option enable gatt robust caching feature on server +config BT_GATTS_DEVICE_NAME_WRITABLE + bool "Allow to write device name by GATT clients" + depends on BT_GATTS_ENABLE + default n + help + Enabling this option allows remote GATT clients to write device name + +config BT_GATTS_APPEARANCE_WRITABLE + bool "Allow to write appearance by GATT clients" + depends on BT_GATTS_ENABLE + default n + help + Enabling this option allows remote GATT clients to write appearance + config BT_GATTC_ENABLE bool "Include GATT client module(GATTC)" depends on BT_BLE_ENABLED @@ -1108,7 +1122,7 @@ config BT_BLE_RPA_SUPPORTED users can switch the two modes according to their own needs. So this option is enabled by default. config BT_BLE_RPA_TIMEOUT - int "timeout of resolvable private address" + int "Timeout of resolvable private address" depends on BT_BLUEDROID_ENABLED range 1 3600 default 900 diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index 968c1a3350..dc9e1ff14f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3159,6 +3159,9 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add } +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) uint8_t BTA_DmBlePeriodicAdvSetInfoTrans(uint8_t addr[6], uint16_t service_data, uint8_t adv_handle) { BTM_BlePeriodicAdvSetInfoTrans(addr, service_data, adv_handle); @@ -3170,7 +3173,6 @@ uint8_t BTA_DmBleSetPeriodicAdvSyncTransParams(uint8_t addr[6], uint8_t mode, ui BTM_BleSetPeriodicAdvSyncTransParams(addr, mode, skip, sync_timeout, 0); return 0; } - -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 3fde16f61a..244e3e8596 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -291,7 +291,19 @@ #ifdef CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED #define UC_BT_GATTS_ROBUST_CACHING_ENABLED CONFIG_BT_GATTS_ROBUST_CACHING_ENABLED #else -#define UC_BT_GATTS_ROBUST_CACHING_ENABLED 0 +#define UC_BT_GATTS_ROBUST_CACHING_ENABLED FALSE +#endif + +#ifdef CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE +#define UC_BT_GATTS_DEVICE_NAME_WRITABLE CONFIG_BT_GATTS_DEVICE_NAME_WRITABLE +#else +#define UC_BT_GATTS_DEVICE_NAME_WRITABLE FALSE +#endif + +#ifdef CONFIG_BT_GATTS_APPEARANCE_WRITABLE +#define UC_BT_GATTS_APPEARANCE_WRITABLE CONFIG_BT_GATTS_APPEARANCE_WRITABLE +#else +#define UC_BT_GATTS_APPEARANCE_WRITABLE FALSE #endif #ifdef CONFIG_BT_BLE_ACT_SCAN_REP_ADV_SCAN diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 5329e1b887..e84558f206 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -493,8 +493,22 @@ #define GATTS_SEND_SERVICE_CHANGE_MODE UC_BT_GATTS_SEND_SERVICE_CHANGE_MODE #endif -#ifdef UC_BT_GATTS_ROBUST_CACHING_ENABLED -#define GATTS_ROBUST_CACHING_ENABLED UC_BT_GATTS_ROBUST_CACHING_ENABLED +#if (UC_BT_GATTS_ROBUST_CACHING_ENABLED == TRUE) +#define GATTS_ROBUST_CACHING_ENABLED TRUE +#else +#define GATTS_ROBUST_CACHING_ENABLED FALSE +#endif + +#if (UC_BT_GATTS_DEVICE_NAME_WRITABLE == TRUE) +#define GATTS_DEVICE_NAME_WRITABLE TRUE +#else +#define GATTS_DEVICE_NAME_WRITABLE FALSE +#endif + +#if (UC_BT_GATTS_APPEARANCE_WRITABLE == TRUE) +#define GATTS_APPEARANCE_WRITABLE TRUE +#else +#define GATTS_APPEARANCE_WRITABLE FALSE #endif #ifdef UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN @@ -2301,6 +2315,9 @@ The maximum number of payload octets that the local device can receive in a sing #define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE #endif +// TODO: add menuconfig and api for periodic adv sync transfer +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE + #include "common/bt_trace.h" #endif /* BT_TARGET_H */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 54cbcca951..babf3a3acf 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1032,34 +1032,6 @@ void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *p return; } -void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle) -{ - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); - - if (!p_lcb) { - BTM_TRACE_ERROR("%s, invalid parameters", __func__); - return; - } - - if (!btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); - } -} - -void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) -{ - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); - - if (!p_lcb) { - BTM_TRACE_ERROR("%s, invalid parameters", __func__); - return; - } - - if (!btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); - } -} - void btm_ble_extended_init(void) { @@ -1310,3 +1282,33 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + return; + } + + if (!btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle)) { + BTM_TRACE_ERROR("%s, hci cmd error", __func__); + } +} + +void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +{ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + return; + } + + if (!btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type)) { + BTM_TRACE_ERROR("%s, hci cmd error", __func__); + } +} +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index a6e1f5d5b8..c20343c082 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -145,8 +145,10 @@ static void btu_ble_periodic_adv_sync_lost_evt(UINT8 *p); static void btu_ble_scan_timeout_evt(UINT8 *p); static void btu_ble_adv_set_terminate_evt(UINT8 *p); static void btu_ble_scan_req_received_evt(UINT8 *p); -static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) extern osi_sem_t adv_enable_sem; extern osi_sem_t adv_data_sem; @@ -412,10 +414,12 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) break; case HCI_BLE_CHANNEL_SELECT_ALG: break; +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) case HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT: btu_ble_periodic_adv_sync_trans_recv(p); break; -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) } break; #endif /* BLE_INCLUDED */ @@ -2308,7 +2312,9 @@ static void btu_ble_scan_req_received_evt(UINT8 *p) btm_ble_scan_req_received_evt(&req_received); } +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) { tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV recv = {0}; @@ -2326,7 +2332,8 @@ static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) HCI_TRACE_DEBUG("%s status %x, conn handle %x, sync handle %x", recv.status, recv.conn_handle, recv.sync_handle); } -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /********************************************** ** End of BLE Events Handler ***********************************************/ diff --git a/components/bt/host/bluedroid/stack/gap/gap_ble.c b/components/bt/host/bluedroid/stack/gap/gap_ble.c index 45b776b4c2..5bac86f0c2 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_ble.c +++ b/components/bt/host/bluedroid/stack/gap/gap_ble.c @@ -298,12 +298,34 @@ UINT8 gap_proc_write_req( tGATTS_REQ_TYPE type, tGATT_WRITE_REQ *p_data) UNUSED(type); for (i = 0; i < GAP_MAX_CHAR_NUM; i ++, p_db_attr ++) { - if (p_data-> handle == p_db_attr->handle) { + if (p_data->handle == p_db_attr->handle) { + switch (p_db_attr->uuid) { + #if (GATTS_DEVICE_NAME_WRITABLE == TRUE) + case GATT_UUID_GAP_DEVICE_NAME: { + UINT8 *p_val = p_data->value; + p_val[p_data->len] = '\0'; + BTM_SetLocalDeviceName((char *)p_val); + return GATT_SUCCESS; + } + #endif + #if (GATTS_APPEARANCE_WRITABLE == TRUE) + case GATT_UUID_GAP_ICON: { + UINT8 *p_val = p_data->value; + if (p_data->len != sizeof(UINT16)) { + return GATT_INVALID_ATTR_LEN; + } + STREAM_TO_UINT16(p_db_attr->attr_value.icon, p_val); + return GATT_SUCCESS; + } + #endif + default: + break; + } return GATT_WRITE_NOT_PERMIT; } } - return GATT_NOT_FOUND; + return GATT_NOT_FOUND; } /****************************************************************************** @@ -393,17 +415,26 @@ void gap_attr_db_init(void) */ uuid.len = LEN_UUID_16; uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_DEVICE_NAME; - p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, - NULL, NULL); + p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, + #if (GATTS_DEVICE_NAME_WRITABLE == TRUE) + GATT_PERM_READ | GATT_PERM_WRITE, + GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR, + #else + GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, + #endif + NULL, NULL); p_db_attr ++; /* add Icon characteristic */ uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_ICON; - p_db_attr->handle = GATTS_AddCharacteristic(service_handle, - &uuid, - GATT_PERM_READ, - GATT_CHAR_PROP_BIT_READ, + p_db_attr->handle = GATTS_AddCharacteristic(service_handle, &uuid, + #if (GATTS_APPEARANCE_WRITABLE == TRUE) + GATT_PERM_READ | GATT_PERM_WRITE, + GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR, + #else + GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, + #endif NULL, NULL); p_db_attr ++; diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 07c31df64d..dfaf7d5d3e 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1775,7 +1775,9 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_ return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable) { BT_HDR *p; @@ -1856,5 +1858,5 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 88adb506ce..16230bc7b5 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1230,19 +1230,6 @@ typedef struct { UINT8 adv_clk_accuracy; } tBTM_BLE_PERIOD_ADV_SYNC_ESTAB; -typedef struct { - UINT8 status; - UINT16 conn_handle; - UINT16 service_data; - UINT16 sync_handle; - UINT8 adv_sid; - UINT8 adv_addr_type; - BD_ADDR adv_addr; - UINT8 adv_phy; - UINT16 period_adv_interval; - UINT8 adv_clk_accuracy; -} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; - typedef struct { UINT16 scan_interval; UINT16 scan_window; @@ -1301,6 +1288,21 @@ typedef void (*tBTM_BLE_5_HCI_CBACK)(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_5_GAP_ #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + UINT8 status; + UINT16 conn_handle; + UINT16 service_data; + UINT16 sync_handle; + UINT8 adv_sid; + UINT8 adv_addr_type; + BD_ADDR adv_addr; + UINT8 adv_phy; + UINT16 period_adv_interval; + UINT8 adv_clk_accuracy; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /***************************************************************************** ** EXTERNAL FUNCTION DECLARATIONS *****************************************************************************/ @@ -2650,10 +2652,12 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params); tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period); void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle); void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 1f04192c45..aee16e8d78 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -384,11 +384,13 @@ #define HCI_BLE_RD_RF_PATH_COMPENSATION (0x004C | HCI_GRP_BLE_CMDS) #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SET_INFO_TRANS (0x005B | HCI_GRP_BLE_CMDS) #define HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS (0x005C | HCI_GRP_BLE_CMDS) -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -805,8 +807,10 @@ #define HCI_BLE_ADV_SET_TERMINATED_EVT 0x12 #define HCI_BLE_SCAN_REQ_RECEIVED_EVT 0x13 #define HCI_BLE_CHANNEL_SELECT_ALG 0x14 -#define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18 #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define HCI_BLE_PERIOD_ADV_SYNC_TRANS_RECV_EVT 0x18 +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) /* Definitions for LE Channel Map */ #define HCI_BLE_CHNL_MAP_SIZE 5 diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 676e626eb2..e50b6510b5 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1032,6 +1032,8 @@ UINT8 btsnd_hcic_ble_read_rf_path_compensation(void); UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_path); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); @@ -1039,7 +1041,7 @@ UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_ UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); -#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 From 3100841f64a0a141654ba5674781e1ed15f72470 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Fri, 6 Jan 2023 14:28:56 +0800 Subject: [PATCH 09/12] bluedroid: fixed GATT multi notify and robust caching --- .../bt/host/bluedroid/bta/gatt/bta_gatts_co.c | 6 ++- .../host/bluedroid/btc/core/btc_ble_storage.c | 6 +-- .../common/include/common/bt_target.h | 4 ++ .../bt/host/bluedroid/stack/gatt/gatt_api.c | 2 + .../bt/host/bluedroid/stack/gatt/gatt_attr.c | 11 +++++ .../bt/host/bluedroid/stack/gatt/gatt_cl.c | 45 +++---------------- .../host/bluedroid/stack/gatt/gatt_sr_hash.c | 3 -- .../bt/host/bluedroid/stack/gatt/gatt_utils.c | 34 ++++++++++++++ .../bluedroid/stack/gatt/include/gatt_int.h | 1 + 9 files changed, 64 insertions(+), 48 deletions(-) diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c index 0fdf789bb2..a5a73b521e 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_co.c @@ -162,6 +162,7 @@ BOOLEAN bta_gatts_co_load_handle_range(UINT8 index, return FALSE; } +#if (SMP_INCLUDED == TRUE) /******************************************************************************* ** ** Function bta_gatts_co_cl_feat_save @@ -245,5 +246,6 @@ void bta_gatts_co_db_hash_load(BD_ADDR remote_addr, BT_OCTET16 db_hash) memcpy(bd_addr.address, remote_addr, BD_ADDR_LEN); btc_storage_get_gatt_db_hash(&bd_addr, db_hash, BT_OCTET16_LEN); } -#endif -#endif +#endif // #if (SMP_INCLUDED == TRUE) +#endif // #if (GATTS_INCLUDED == TRUE) +#endif // #if (BLE_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index 17333f35ef..0dab8e1305 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -924,10 +924,7 @@ int btc_storage_get_num_ble_bond_devices(void) return num_dev; } -#endif ///BLE_INCLUDED == TRUE -#endif ///SMP_INCLUDED == TRUE -#if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) { bdstr_t bdstr; @@ -1001,4 +998,5 @@ bt_status_t btc_storage_remove_gatt_db_hash(bt_bdaddr_t *remote_bd_addr) return BT_STATUS_SUCCESS; } -#endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ +#endif ///BLE_INCLUDED == TRUE +#endif ///SMP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index e84558f206..f1bc1d5613 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -2316,7 +2316,11 @@ The maximum number of payload octets that the local device can receive in a sing #endif // TODO: add menuconfig and api for periodic adv sync transfer +#if (BLE_50_FEATURE_SUPPORT) +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE +#else #define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE +#endif #include "common/bt_trace.h" diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 4c2917edd6..62707bbd2f 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -181,8 +181,10 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, } else { if ( (p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GATT_SERVER)) { s_hdl = gatt_cb.hdl_cfg.gatt_start_hdl; + save_hdl = TRUE; } else if ((p_svc_uuid->len == LEN_UUID_16) && (p_svc_uuid->uu.uuid16 == UUID_SERVCLASS_GAP_SERVER)) { s_hdl = gatt_cb.hdl_cfg.gap_start_hdl; + save_hdl = TRUE; } else { p_list = p_list_info->p_first; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c index 7205558023..441d0398e8 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c @@ -219,6 +219,9 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE /* handle request for reading client supported features */ if (p_data->handle == gatt_cb.handle_of_cl_supported_feat) { + if (tcb == NULL) { + return GATT_INSUF_RESOURCE; + } p_rsp->attr_value.len = 1; memcpy(p_rsp->attr_value.value, &tcb->cl_supp_feat, 1); status = GATT_SUCCESS; @@ -281,7 +284,9 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ * } p_tcb->cl_supp_feat = val_new; +#if (SMP_INCLUDED == TRUE) bta_gatts_co_cl_feat_save(p_tcb->peer_bda, &p_tcb->cl_supp_feat); +#endif return GATT_SUCCESS; } @@ -736,7 +741,9 @@ BOOLEAN gatt_sr_is_cl_change_aware(tGATT_TCB *p_tcb) *******************************************************************************/ void gatt_sr_init_cl_status(tGATT_TCB *p_tcb) { +#if (SMP_INCLUDED == TRUE) bta_gatts_co_cl_feat_load(p_tcb->peer_bda, &p_tcb->cl_supp_feat); +#endif // This is used to reset bit when robust caching is disabled if (!GATTS_ROBUST_CACHING_ENABLED) { @@ -745,7 +752,9 @@ void gatt_sr_init_cl_status(tGATT_TCB *p_tcb) if (gatt_sr_is_cl_robust_caching_supported(p_tcb)) { BT_OCTET16 stored_hash = {0}; +#if (SMP_INCLUDED == TRUE) bta_gatts_co_db_hash_load(p_tcb->peer_bda, stored_hash); +#endif p_tcb->is_robust_cache_change_aware = (memcmp(stored_hash, gatt_cb.database_hash, BT_OCTET16_LEN) == 0); } else { p_tcb->is_robust_cache_change_aware = true; @@ -776,7 +785,9 @@ void gatt_sr_update_cl_status(tGATT_TCB *p_tcb, BOOLEAN chg_aware) // only when client status is changed from unaware to aware, we should store database hash if (!p_tcb->is_robust_cache_change_aware && chg_aware) { +#if (SMP_INCLUDED == TRUE) bta_gatts_co_db_hash_save(p_tcb->peer_bda, gatt_cb.database_hash); +#endif } p_tcb->is_robust_cache_change_aware = chg_aware; diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c index 9fd0adf89a..12168dc00d 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_cl.c @@ -69,39 +69,6 @@ static const UINT16 disc_type_to_uuid[GATT_DISC_MAX] = { // Use for GATTC discover infomation print #define GATT_DISC_INFO(fmt, args...) {if (gatt_cb.auto_disc == FALSE) BT_PRINT_I("BT_GATT", fmt, ## args);} -char *gatt_uuid_to_str(const tBT_UUID *uuid) -{ - static char dst[48] = {0}; - const uint8_t *u8p; - - memset(dst, 0, sizeof(dst)); - - switch (uuid->len) { - case LEN_UUID_16: - sprintf(dst, "0x%04x", uuid->uu.uuid16); - break; - case LEN_UUID_32: - sprintf(dst, "0x%08x", uuid->uu.uuid32); - break; - case LEN_UUID_128: - u8p = uuid->uu.uuid128; - - sprintf(dst, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x", - u8p[15], u8p[14], u8p[13], u8p[12], - u8p[11], u8p[10], u8p[9], u8p[8], - u8p[7], u8p[6], u8p[5], u8p[4], - u8p[3], u8p[2], u8p[1], u8p[0]); - break; - default: - dst[0] = '\0'; - break; - } - - return dst; -} - - /******************************************************************************* ** ** Function gatt_act_discovery @@ -1187,7 +1154,8 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, tGATT_CLCB *p_clcb = NULL; UINT8 rsp_code; - if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) { + if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF && + op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) { p_clcb = gatt_cmd_dequeue(p_tcb, &rsp_code); rsp_code = gatt_cmd_to_rsp_code(rsp_code); @@ -1206,8 +1174,8 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, /* The message has to be smaller than the agreed MTU, len does not count op_code */ if (len >= p_tcb->payload_size) { GATT_TRACE_ERROR("invalid response/indicate pkt size: %d, PDU size: %d", len + 1, p_tcb->payload_size); - if (op_code != GATT_HANDLE_VALUE_NOTIF && - op_code != GATT_HANDLE_VALUE_IND) { + if (op_code != GATT_HANDLE_VALUE_NOTIF && op_code != GATT_HANDLE_VALUE_IND && + op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) { gatt_end_operation(p_clcb, GATT_ERROR, NULL); } } else { @@ -1264,11 +1232,10 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code, } } - if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF) { + if (op_code != GATT_HANDLE_VALUE_IND && op_code != GATT_HANDLE_VALUE_NOTIF && + op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) { gatt_cl_send_next_cmd_inq(p_tcb); } - - return; } #endif /* BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c index f302e2b13f..f332292179 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c @@ -160,9 +160,6 @@ tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash) BT_OCTET16 key = {0}; aes_cipher_msg_auth_code(key, data_buf, len, 16, hash); //ESP_LOG_BUFFER_HEX("db hash", hash, BT_OCTET16_LEN); -#else - // TODO - GATT_TRACE_ERROR("%s SMP disabled", __func__); #endif osi_free(data_buf); diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index ab11d96b4d..2dbbcd8d8a 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1090,7 +1090,9 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); +#if (GATTS_INCLUDED == TRUE) gatt_sr_init_cl_status(p_tcb); +#endif ///GATTS_INCLUDED == TRUE } return p_tcb; } @@ -2911,4 +2913,36 @@ BOOLEAN gatt_update_listen_mode(void) return rt; } + +char *gatt_uuid_to_str(const tBT_UUID *uuid) +{ + static char dst[48] = {0}; + const UINT8 *u8p; + + memset(dst, 0, sizeof(dst)); + + switch (uuid->len) { + case LEN_UUID_16: + sprintf(dst, "0x%04x", uuid->uu.uuid16); + break; + case LEN_UUID_32: + sprintf(dst, "0x%08x", uuid->uu.uuid32); + break; + case LEN_UUID_128: + u8p = uuid->uu.uuid128; + + sprintf(dst, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + u8p[15], u8p[14], u8p[13], u8p[12], + u8p[11], u8p[10], u8p[9], u8p[8], + u8p[7], u8p[6], u8p[5], u8p[4], + u8p[3], u8p[2], u8p[1], u8p[0]); + break; + default: + dst[0] = '\0'; + break; + } + + return dst; +} #endif diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index e31bbd0c5e..a34e5d1eb4 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -625,6 +625,7 @@ extern BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid, UINT16 len, UINT8 **p_ extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid); extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar); extern void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32); +extern char *gatt_uuid_to_str(const tBT_UUID *uuid); extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size); extern void gatt_start_rsp_timer(UINT16 clcb_idx); extern void gatt_start_conf_timer(tGATT_TCB *p_tcb); From 630154ed2d130522217d652da4462e12d87102d0 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Sun, 23 Apr 2023 17:13:04 +0800 Subject: [PATCH 10/12] bluedroid: support gatts show local database --- .../bt/host/bluedroid/api/esp_gatts_api.c | 13 +++ .../bluedroid/api/include/api/esp_gatts_api.h | 10 +++ .../host/bluedroid/bta/gatt/bta_gatts_act.c | 16 ++++ .../host/bluedroid/bta/gatt/bta_gatts_api.c | 10 +++ .../host/bluedroid/bta/gatt/bta_gatts_main.c | 3 + .../bta/gatt/include/bta_gatts_int.h | 4 +- .../bluedroid/bta/include/bta/bta_gatt_api.h | 10 +++ .../btc/profile/std/gatt/btc_gatts.c | 8 ++ .../btc/profile/std/include/btc_gatts.h | 2 + .../bt/host/bluedroid/stack/gatt/gatt_api.c | 6 ++ .../host/bluedroid/stack/gatt/gatt_sr_hash.c | 88 +++++++++++++++++++ .../bluedroid/stack/gatt/include/gatt_int.h | 2 + .../bluedroid/stack/include/stack/gatt_api.h | 11 +++ 13 files changed, 182 insertions(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/api/esp_gatts_api.c b/components/bt/host/bluedroid/api/esp_gatts_api.c index 7fb6b58ea9..17b8cac7bd 100644 --- a/components/bt/host/bluedroid/api/esp_gatts_api.c +++ b/components/bt/host/bluedroid/api/esp_gatts_api.c @@ -421,4 +421,17 @@ static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_ return ESP_OK; } +esp_err_t esp_ble_gatts_show_local_database(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SHOW_LOCAL_DATABASE; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #endif ///GATTS_INCLUDED diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h index 1fb3a08141..67195369ac 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h @@ -572,6 +572,16 @@ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id); */ esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda); +/** + * @brief Print local database (GATT service table) + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_show_local_database(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index 5320f66711..cc3134d9da 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -906,6 +906,22 @@ void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) } } +/******************************************************************************* +** +** Function bta_gatts_show_local_database +** +** Description print loacl service database +** +** Returns none. +** +*******************************************************************************/ +void bta_gatts_show_local_database (void) +{ + if (GATTS_ShowLocalDatabase()) { + APPL_TRACE_ERROR("%s failed", __func__); + } +} + /******************************************************************************* ** ** Function bta_gatts_request_cback diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c index 03e584f12b..ffe3abec6a 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c @@ -667,4 +667,14 @@ uint8_t BTA_GATTS_SendMultiNotification(uint8_t gatt_if, uint16_t conn_id, void return 0; } + +void BTA_GATTS_ShowLocalDatabase(void) +{ + BT_HDR *p_buf; + + if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) { + p_buf->event = BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT; + bta_sys_sendmsg(p_buf); + } +} #endif /* BTA_GATT_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c index 993b384d7d..299851491c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c @@ -133,6 +133,9 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg) case BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT: bta_gatts_send_service_change_indication((tBTA_GATTS_DATA *) p_msg); break; + case BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT: + bta_gatts_show_local_database(); + break; default: break; } diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h index 30f14ac4d5..51d6fd4ed6 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h @@ -53,7 +53,8 @@ enum { BTA_GATTS_API_CLOSE_EVT, BTA_GATTS_API_LISTEN_EVT, BTA_GATTS_API_DISABLE_EVT, - BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT + BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT, + BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT }; typedef UINT16 tBTA_GATTS_INT_EVT; @@ -251,6 +252,7 @@ extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg); +extern void bta_gatts_show_local_database (void); extern BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src); extern tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if); 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 f9f73ad1fe..89059c3c4d 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 @@ -1542,6 +1542,16 @@ void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remo extern void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda); +/******************************************************************************* +** +** Function BTA_GATTS_ShowLocalDatabase +** +** Description print local service database. +** +** Returns void +** +*******************************************************************************/ +extern void BTA_GATTS_ShowLocalDatabase(void); extern void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id); diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c index 5badf5f45b..c29da65f01 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -498,6 +498,11 @@ esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *lengt return BTA_GetAttributeValue(attr_handle, length, value); } +esp_gatt_status_t btc_gatts_show_local_database(void) +{ + BTA_GATTS_ShowLocalDatabase(); + return ESP_GATT_OK; +} static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src) { @@ -741,6 +746,9 @@ void btc_gatts_call_handler(btc_msg_t *msg) BTA_GATTS_SendServiceChangeIndication(arg->send_service_change.gatts_if, remote_bda); break; } + case BTC_GATTS_ACT_SHOW_LOCAL_DATABASE: + BTA_GATTS_ShowLocalDatabase(); + break; default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h index a8de3539a4..82ae435339 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h @@ -30,6 +30,7 @@ typedef enum { BTC_GATTS_ACT_OPEN, BTC_GATTS_ACT_CLOSE, BTC_GATTS_ACT_SEND_SERVICE_CHANGE, + BTC_GATTS_ACT_SHOW_LOCAL_DATABASE, } btc_gatts_act_t; /* btc_ble_gatts_args_t */ @@ -164,6 +165,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg); void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_gatts_arg_deep_free(btc_msg_t *msg); esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value); +esp_gatt_status_t btc_gatts_show_local_database(void); #endif /* __BTC_GATTS_H__ */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 62707bbd2f..9a5e28da36 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -1769,4 +1769,10 @@ tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tupl return cmd_sent; } +tGATT_STATUS GATTS_ShowLocalDatabase(void) +{ + gatts_show_local_database(); + return GATT_SUCCESS; +} + #endif diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c index f332292179..13a2fada21 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c @@ -8,6 +8,36 @@ #include "smp_int.h" #if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) + +const char *const gatt_attr_name[] = { + "primary service", + "secondary service", + "included service", + "characteristic", +}; + +const char *const gatt_char_desc_name[] = { + "characteristic extended properties", + "characteristic user description", + "client characteristic configuration", + "server characteristic configuration", + "characteristic presentation format", + "characteristic aggregate format", +}; + +static const char *gatt_get_attr_name(UINT16 uuid) +{ + if (uuid >= GATT_UUID_PRI_SERVICE && uuid <= GATT_UUID_CHAR_DECLARE) { + return gatt_attr_name[uuid - GATT_UUID_PRI_SERVICE]; + } + + if (uuid >= GATT_UUID_CHAR_EXT_PROP && uuid <= GATT_UUID_CHAR_AGG_FORMAT) { + return gatt_char_desc_name[uuid - GATT_UUID_CHAR_EXT_PROP]; + } + + return "Unknown Attribute"; +} + static void attr_uuid_to_bt_uuid(void *p_attr, tBT_UUID *p_uuid) { tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr; @@ -165,4 +195,62 @@ tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash) osi_free(data_buf); return GATT_SUCCESS; } + +void gatts_show_local_database(void) +{ + UINT8 i; + tGATT_SVC_DB *p_db; + tGATT_ATTR16 *p_attr; + + printf("\n================= GATTS DATABASE DUMP START =================\n"); + for (i = 0; i < GATT_MAX_SR_PROFILES; i++) { + p_db = gatt_cb.sr_reg[i].p_db; + if (p_db && p_db->p_attr_list) { + p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; + while (p_attr) { + switch (p_attr->uuid) { + case GATT_UUID_PRI_SERVICE: + case GATT_UUID_SEC_SERVICE: + // Service declaration + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\n", gatt_uuid_to_str(&p_attr->p_value->uuid)); + printf("\thandle %d\n", p_attr->handle); + printf("\tend_handle %d\n",p_db->end_handle-1); + break; + case GATT_UUID_INCLUDE_SERVICE: + // Included service declaration + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\t", gatt_uuid_to_str(&p_attr->p_value->incl_handle.service_type)); + printf("\thandle %d\n", p_attr->p_value->incl_handle.s_handle); + printf("\tend_handle %d\n", p_attr->p_value->incl_handle.e_handle); + break; + case GATT_UUID_CHAR_DECLARE: { + tBT_UUID char_uuid; + tGATT_ATTR16 *p_char_val; + p_char_val = (tGATT_ATTR16 *)p_attr->p_next; + attr_uuid_to_bt_uuid((void *)p_char_val, &char_uuid); + + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\n", gatt_uuid_to_str(&char_uuid)); + printf("\tdef_handle %d\n", p_attr->handle); + printf("\tval_handle %d\n", p_attr->p_value->char_decl.char_val_handle); + printf("\tperm 0x%04x, prop 0x%02x\n", p_char_val->permission, p_attr->p_value->char_decl.property); + break; + } + case GATT_UUID_CHAR_EXT_PROP: + case GATT_UUID_CHAR_DESCRIPTION: + case GATT_UUID_CHAR_CLIENT_CONFIG: + case GATT_UUID_CHAR_SRVR_CONFIG: + case GATT_UUID_CHAR_PRESENT_FORMAT: + case GATT_UUID_CHAR_AGG_FORMAT: + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\thandle %d\n", p_attr->handle); + break; + } + p_attr = (tGATT_ATTR16 *) p_attr->p_next; + } + } + } + printf("================= GATTS DATABASE DUMP END =================\n"); +} #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index a34e5d1eb4..d688b29df7 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -778,6 +778,8 @@ extern uint16_t gatt_get_local_mtu(void); extern void gatt_set_local_mtu(uint16_t mtu); extern tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash); +extern void gatts_show_local_database(void); + extern BOOLEAN gatt_sr_is_cl_change_aware(tGATT_TCB *p_tcb); extern void gatt_sr_init_cl_status(tGATT_TCB *p_tcb); extern void gatt_sr_update_cl_status(tGATT_TCB *tcb, BOOLEAN chg_aware); diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index 441bb12250..f972fdcbcb 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -1279,6 +1279,17 @@ extern tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode); *******************************************************************************/ extern tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tuples, UINT16 num_tuples); +/******************************************************************************* +** +** Function GATTS_ShowLocalDatabase +** +** Description This function print local service database. +** +** Returns GATT_SUCCESS if successfully sent; otherwise error code. +** +*******************************************************************************/ +extern tGATT_STATUS GATTS_ShowLocalDatabase(void); + #ifdef __cplusplus } From 0315b24514e341f18c8f94e51bb6b2ae8036edda Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 18 Jan 2023 16:50:27 +0800 Subject: [PATCH 11/12] bluedroid: add periodic adv sync transfer API and EVT --- components/bt/host/bluedroid/Kconfig.in | 7 + .../bt/host/bluedroid/api/esp_gap_ble_api.c | 92 +++++++++++++ .../api/include/api/esp_gap_ble_api.h | 124 +++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 31 +++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 66 ++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 7 + .../bluedroid/bta/dm/include/bta_dm_int.h | 51 +++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 28 +++- .../btc/profile/std/gap/btc_gap_ble.c | 58 ++++++++ .../btc/profile/std/include/btc_gap_ble.h | 30 +++++ .../include/common/bluedroid_user_config.h | 6 + .../common/include/common/bt_target.h | 13 +- .../bt/host/bluedroid/device/controller.c | 2 +- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 127 ++++++++++++++++-- .../bluedroid/stack/btm/include/btm_ble_int.h | 4 + .../bluedroid/stack/btm/include/btm_int.h | 3 + .../bt/host/bluedroid/stack/btu/btu_hcif.c | 51 +++++-- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 53 ++++++-- .../stack/include/stack/btm_ble_api.h | 68 +++++++--- .../bluedroid/stack/include/stack/hcidefs.h | 3 +- .../bluedroid/stack/include/stack/hcimsgs.h | 28 ++-- 21 files changed, 778 insertions(+), 74 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index c15013719a..9d28c585df 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1143,3 +1143,10 @@ config BT_BLE_42_FEATURES_SUPPORTED default n help This enables BLE 4.2 features. + +config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER + bool "Enable BLE periodic advertising sync transfer feature" + depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + default n + help + This enables BLE periodic advertising sync transfer feature diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 5d48642325..76bdc6aadd 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1370,3 +1370,95 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, } #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE; + + arg.periodic_adv_recv_en.sync_handle = sync_handle; + arg.periodic_adv_recv_en.enable = enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, uint16_t service_data, uint16_t sync_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS; + + memcpy(arg.periodic_adv_sync_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_sync_trans.service_data = service_data; + arg.periodic_adv_sync_trans.sync_handle = sync_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, uint16_t service_data, uint8_t adv_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS; + + memcpy(arg.periodic_adv_set_info_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_set_info_trans.service_data = service_data; + arg.periodic_adv_set_info_trans.adv_handle = adv_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, const esp_ble_gap_past_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS; + + if (addr) { + memcpy(arg.set_periodic_adv_sync_trans_params.addr, addr, sizeof(esp_bd_addr_t)); + } else { + memset(arg.set_periodic_adv_sync_trans_params.addr, 0, sizeof(esp_bd_addr_t)); + } + memcpy(&arg.set_periodic_adv_sync_trans_params.params, params, sizeof(esp_ble_gap_past_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index bf7ef3b33f..0fc0e395e1 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -202,6 +202,12 @@ typedef enum { ESP_GAP_BLE_SC_OOB_REQ_EVT, /*!< Secure Connection OOB request event */ ESP_GAP_BLE_SC_CR_LOC_OOB_EVT, /*!< Secure Connection create OOB data complete event */ ESP_GAP_BLE_GET_DEV_NAME_COMPLETE_EVT, /*!< When getting BT device name complete, the event comes */ + //BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER + ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, /*!< when set periodic advertising receive enable complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, /*!< when periodic advertising sync transfer complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, /*!< when periodic advertising set info transfer complete, the event comes */ + ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT, /*!< when set periodic advertising sync transfer params complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, /*!< when periodic advertising sync transfer received, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -910,6 +916,25 @@ typedef struct { #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/// Periodic advertising sync trans mode +#define ESP_BLE_GAP_PAST_MODE_NO_SYNC_EVT (0x00) /*!< No attempt is made to sync and no periodic adv sync transfer received event */ +#define ESP_BLE_GAP_PAST_MODE_NO_REPORT_EVT (0x01) /*!< An periodic adv sync transfer received event and no periodic adv report events */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_DISABLED (0x02) /*!< Periodic adv report events will be enabled with duplicate filtering disabled */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_ENABLED (0x03) /*!< Periodic adv report events will be enabled with duplicate filtering enabled */ +typedef uint8_t esp_ble_gap_past_mode_t; + +/** +* @brief periodic adv sync transfer parameters +*/ +typedef struct { + esp_ble_gap_past_mode_t mode; /*!< periodic advertising sync transfer mode */ + uint16_t skip; /*!< the number of periodic advertising packets that can be skipped */ + uint16_t sync_timeout; /*!< synchronization timeout for the periodic advertising train */ + uint8_t cte_type; /*!< periodic advertising sync transfer CET type */ +} esp_ble_gap_past_params_t; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** * @brief Gap callback parameters union */ @@ -1308,6 +1333,50 @@ typedef union { esp_ble_gap_periodic_adv_report_t params; /*!< periodic advertising report parameters */ } period_adv_report; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT + */ + struct ble_periodic_adv_recv_enable_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising receive enable status */ + } period_adv_recv_enable; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_sync_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_sync_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_set_info_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising set info transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_set_info_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT + */ + struct ble_set_past_params_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising sync transfer params status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } set_past_params; /*!< Event parameter of ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT + */ + struct ble_periodic_adv_sync_trans_recv_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer received status */ + esp_bd_addr_t bda; /*!< The remote device address */ + uint16_t service_data; /*!< The value provided by the peer device */ + uint16_t sync_handle; /*!< Periodic advertising sync handle */ + uint8_t adv_sid; /*!< Periodic advertising set id */ + uint8_t adv_addr_type; /*!< Periodic advertiser address type */ + esp_bd_addr_t adv_addr; /*!< Periodic advertiser address */ + esp_ble_gap_phy_t adv_phy; /*!< Periodic advertising PHY */ + uint16_t adv_interval; /*!< Periodic advertising interval */ + uint8_t adv_clk_accuracy; /*!< Periodic advertising clock accuracy */ + } past_received; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT */ +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) } esp_ble_gap_cb_param_t; /** @@ -2197,6 +2266,61 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/** +* @brief This function is used to set periodic advertising receive enable +* +* @param[in] sync_handle : Handle of periodic advertising sync +* @param[in] enable : Determines whether reporting and duplicate filtering are enabled or disabled +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable); + +/** +* @brief This function is used to transfer periodic advertising sync +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] sync_handle : Handle of periodic advertising sync +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, + uint16_t service_data, uint16_t sync_handle); + +/** +* @brief This function is used to transfer periodic advertising set info +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] adv_handle : Handle of advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, + uint16_t service_data, uint8_t adv_handle); + +/** +* @brief This function is used to set periodic advertising sync transfer params +* +* @param[in] addr : Peer device address +* @param[in] params : Params of periodic advertising sync transfer +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, + const esp_ble_gap_past_params_t *params); +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index a8c4e7f396..21bb638aff 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5820,6 +5820,37 @@ void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data) } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void bta_dm_ble_gap_periodic_adv_recv_enable(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvRecvEnable(p_data->ble_periodic_adv_recv_enable.sync_handle, + p_data->ble_periodic_adv_recv_enable.enable); +} + +void bta_dm_ble_gap_periodic_adv_sync_trans(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvSyncTrans(p_data->ble_periodic_adv_sync_trans.addr, + p_data->ble_periodic_adv_sync_trans.service_data, + p_data->ble_periodic_adv_sync_trans.sync_handle); +} + +void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvSetInfoTrans(p_data->ble_periodic_adv_set_info_trans.addr, + p_data->ble_periodic_adv_set_info_trans.service_data, + p_data->ble_periodic_adv_set_info_trans.adv_hanlde); +} + +void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data) +{ + BTM_BleSetPeriodicAdvSyncTransParams(p_data->ble_set_past_params.addr, + p_data->ble_set_past_params.params.mode, + p_data->ble_set_past_params.params.skip, + p_data->ble_set_past_params.params.sync_timeout, + p_data->ble_set_past_params.params.cte_type); +} +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) /******************************************************************************* ** ** Function bta_dm_ble_setup_storage diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index dc9e1ff14f..ea5d4f6593 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -3162,16 +3162,70 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -uint8_t BTA_DmBlePeriodicAdvSetInfoTrans(uint8_t addr[6], uint16_t service_data, uint8_t adv_handle) +void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) { - BTM_BlePeriodicAdvSetInfoTrans(addr, service_data, adv_handle); - return 0; + tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT; + p_msg->sync_handle = sync_handle; + p_msg->enable = enable; + //start sent the msg to the bta system control moudle + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } } -uint8_t BTA_DmBleSetPeriodicAdvSyncTransParams(uint8_t addr[6], uint8_t mode, uint16_t skip, uint16_t sync_timeout) +void BTA_DmBleGapPeriodicAdvSyncTrans(BD_ADDR peer_addr, UINT16 service_data, UINT16 sync_handle) { - BTM_BleSetPeriodicAdvSyncTransParams(addr, mode, skip, sync_timeout, 0); - return 0; + tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + p_msg->service_data = service_data; + p_msg->sync_handle = sync_handle; + //start sent the msg to the bta system control moudle + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 service_data, UINT8 adv_handle) +{ + tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + p_msg->service_data = service_data; + p_msg->adv_hanlde = adv_handle; + //start sent the msg to the bta system control moudle + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params) +{ + tBTA_DM_API_SET_PAST_PARAMS *p_msg; + p_msg = (tBTA_DM_API_SET_PAST_PARAMS *) osi_malloc(sizeof(tBTA_DM_API_SET_PAST_PARAMS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_SET_PAST_PARAMS)); + p_msg->hdr.event = BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_PAST_PARAMS)); + //start sent the msg to the bta system control moudle + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 0deb1e821e..7f71052da9 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -202,7 +202,14 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_ext_scan_params, /* BTA_DM_API_SET_EXT_SCAN_PARAMS_EVT */ bta_dm_ble_gap_ext_scan, /* BTA_DM_API_START_EXT_SCAN_EVT */ bta_dm_ble_gap_set_prefer_ext_conn_params, /* BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT */ + NULL, /* BTA_DM_API_EXT_CONN_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + bta_dm_ble_gap_periodic_adv_recv_enable, /* BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT */ + bta_dm_ble_gap_periodic_adv_sync_trans, /* BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT */ + bta_dm_ble_gap_periodic_adv_set_info_trans, /* BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT */ + bta_dm_ble_gap_set_periodic_adv_sync_trans_params, /* BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT */ +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 4a1a7d2396..862d5cff25 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -200,6 +200,12 @@ enum { BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT, BTA_DM_API_EXT_CONN_EVT, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT, + BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT, + BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT, + BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT, +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) BTA_DM_MAX_EVT }; @@ -1031,6 +1037,35 @@ typedef struct { BD_ADDR peer_addr; } tBTA_DM_API_EXT_CONN; #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 sync_handle; + UINT8 enable; +} tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + UINT16 service_data; + UINT16 sync_handle; +} tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + UINT16 service_data; + UINT8 adv_hanlde; +} tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + tBTA_DM_BLE_PAST_PARAMS params; +} tBTA_DM_API_SET_PAST_PARAMS; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /* union of all data types */ typedef union { /* event buffer header */ @@ -1171,6 +1206,12 @@ typedef union { tBTA_DM_API_EXT_SCAN ble_ext_scan; tBTA_DM_API_SET_PER_EXT_CONN_PARAMS ble_set_per_ext_conn_params; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE ble_periodic_adv_recv_enable; + tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS ble_periodic_adv_sync_trans; + tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS ble_periodic_adv_set_info_trans; + tBTA_DM_API_SET_PAST_PARAMS ble_set_past_params; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif tBTA_DM_API_REMOVE_ACL remove_acl; @@ -1727,4 +1768,14 @@ extern void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +extern void bta_dm_ble_gap_periodic_adv_recv_enable(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_periodic_adv_sync_trans(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif /* BTA_DM_INT_H */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index bf6fabb224..f49708073d 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1597,7 +1597,14 @@ typedef struct { #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT -#define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT +#define BTA_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT; typedef tBTM_BLE_5_GAP_CB_PARAMS tBTA_DM_BLE_5_GAP_CB_PARAMS; @@ -1607,6 +1614,15 @@ extern tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + UINT8 mode; + UINT16 skip; + UINT16 sync_timeout; + UINT8 cte_type; +} tBTA_DM_BLE_PAST_PARAMS; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /***************************************************************************** ** External Function Declarations *****************************************************************************/ @@ -3015,6 +3031,16 @@ extern void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr, extern void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_addr); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +extern void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable); + +extern void BTA_DmBleGapPeriodicAdvSyncTrans(BD_ADDR peer_addr, UINT16 service_data, UINT16 sync_handle); + +extern void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 service_data, UINT8 adv_handle); + +extern void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif enum { diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index cfbae97953..9de6681881 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -1099,6 +1099,40 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.periodic_adv_sync_estab.adv_clk_accuracy = params->sync_estab.adv_clk_accuracy; break; } +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT; + param.period_adv_recv_enable.status = btc_btm_status_to_esp_status(params->per_adv_recv_enable.status); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT; + param.period_adv_sync_trans.status = btc_btm_status_to_esp_status(params->per_adv_sync_trans.status); + memcpy(param.period_adv_sync_trans.bda, params->per_adv_sync_trans.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT; + param.period_adv_set_info_trans.status = btc_btm_status_to_esp_status(params->per_adv_set_info_trans.status); + memcpy(param.period_adv_set_info_trans.bda, params->per_adv_set_info_trans.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT; + param.set_past_params.status = btc_btm_status_to_esp_status(params->set_past_params.status); + memcpy(param.set_past_params.bda, params->set_past_params.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT; + param.past_received.status = btc_btm_status_to_esp_status(params->past_recv.status); + memcpy(param.past_received.bda, params->past_recv.addr, sizeof(BD_ADDR)); + param.past_received.service_data = params->past_recv.service_data; + param.past_received.sync_handle = params->past_recv.sync_handle; + param.past_received.adv_sid = params->past_recv.adv_sid; + param.past_received.adv_addr_type = params->past_recv.adv_addr_type; + memcpy(param.past_received.adv_addr, params->past_recv.adv_addr, sizeof(BD_ADDR)); + param.past_received.adv_phy = params->past_recv.adv_phy; + param.past_received.adv_interval = params->past_recv.adv_interval; + param.past_received.adv_clk_accuracy = params->past_recv.adv_clk_accuracy; + break; +#endif default: break; } @@ -1960,6 +1994,30 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) (const tBTA_DM_BLE_CONN_PARAMS *)&arg_5->set_ext_conn_params.phy_coded_conn_params); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE"); + BTA_DmBleGapPeriodicAdvRecvEnable(arg_5->periodic_adv_recv_en.sync_handle, + arg_5->periodic_adv_recv_en.enable); + break; + case BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS"); + BTA_DmBleGapPeriodicAdvSyncTrans(arg_5->periodic_adv_sync_trans.addr, + arg_5->periodic_adv_sync_trans.service_data, + arg_5->periodic_adv_sync_trans.sync_handle); + break; + case BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS"); + BTA_DmBleGapPeriodicAdvSetInfoTrans(arg_5->periodic_adv_set_info_trans.addr, + arg_5->periodic_adv_set_info_trans.service_data, + arg_5->periodic_adv_set_info_trans.adv_handle); + break; + case BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS"); + BTA_DmBleGapSetPeriodicAdvSyncTransParams(arg_5->set_periodic_adv_sync_trans_params.addr, + (tBTA_DM_BLE_PAST_PARAMS *)&arg_5->set_periodic_adv_sync_trans_params.params); + break; +#endif default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 11811e1366..c10f211cad 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -86,6 +86,12 @@ typedef enum { BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_ACT_GET_DEV_NAME, +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE, + BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS, + BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS, + BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS, +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -342,6 +348,30 @@ typedef union { esp_bd_addr_t peer_addr; } ext_conn; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + struct periodic_adv_recv_en_args { + uint16_t sync_handle; + uint8_t enable; + } periodic_adv_recv_en; + + struct periodic_adv_sync_trans_args { + esp_bd_addr_t addr; + uint16_t service_data; + uint16_t sync_handle; + } periodic_adv_sync_trans; + + struct periodic_adv_set_info_trans_args { + esp_bd_addr_t addr; + uint16_t service_data; + uint16_t adv_handle; + } periodic_adv_set_info_trans; + + struct set_periodic_adv_sync_trans_params_args { + esp_bd_addr_t addr; + esp_ble_gap_past_params_t params; + } set_periodic_adv_sync_trans_params; +#endif + } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 244e3e8596..12308a3b97 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -131,6 +131,12 @@ #define UC_BT_BLE_42_FEATURES_SUPPORTED FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER +#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER +#else +#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE +#endif + //GATTS #ifdef CONFIG_BT_GATTS_ENABLE #define UC_BT_GATTS_ENABLE CONFIG_BT_GATTS_ENABLE diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index f1bc1d5613..55fc776ba4 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -192,6 +192,12 @@ #define BLE_42_FEATURE_SUPPORT FALSE #endif +#if (UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE +#else +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE +#endif + #if (UC_BT_BLE_RPA_SUPPORTED == TRUE) #define CONTROLLER_RPA_LIST_ENABLE TRUE #else @@ -2315,13 +2321,6 @@ The maximum number of payload octets that the local device can receive in a sing #define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE #endif -// TODO: add menuconfig and api for periodic adv sync transfer -#if (BLE_50_FEATURE_SUPPORT) -#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE -#else -#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE -#endif - #include "common/bt_trace.h" #endif /* BT_TARGET_H */ diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index 3a813d9a87..8d2349b4cd 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -30,7 +30,7 @@ #include "device/version.h" #include "osi/future.h" #if (BLE_50_FEATURE_SUPPORT == TRUE) -const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x0f\xff\xff" }; +const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\xff\xff\xff" }; #else const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" }; #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index babf3a3acf..331657af2d 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1284,31 +1284,142 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + UINT8 evt = BTM_BLE_5_GAP_UNKNOWN_EVT; + tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(conn_handle); + + switch (op_code) { + case HCI_BLE_PERIOD_ADV_SYNC_TRANS: + evt = BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT; + break; + case HCI_BLE_PERIOD_ADV_SET_INFO_TRANS: + evt = BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT; + break; + case HCI_BLE_SET_PAST_PARAMS: + evt = BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT; + break; + default: + return; + } + + cb_params.per_adv_sync_trans.status = BTM_SUCCESS; + if(hci_status != HCI_SUCCESS) { + cb_params.per_adv_sync_trans.status = BTM_ILLEGAL_VALUE; + BTM_TRACE_ERROR("%s error status %d", __func__, hci_status); + } + + if(p_lcb) { + memcpy(cb_params.per_adv_sync_trans.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); + } + + BTM_ExtBleCallbackTrigger(evt, &cb_params); +} + +void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_ILLEGAL_VALUE; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, &cb_params); +} + +void BTM_BlePeriodicAdvSyncTrans(BD_ADDR bd_addr, UINT16 service_data, UINT16 sync_handle) +{ + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + status = BTM_ILLEGAL_VALUE; + } + + if (status != BTM_SUCCESS) { + cb_params.per_adv_sync_trans.status = status; + memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, &cb_params); + return; + } + + btsnd_hcic_ble_periodic_adv_sync_trans(p_lcb->handle, service_data, sync_handle); +} + void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle) { + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (!p_lcb) { BTM_TRACE_ERROR("%s, invalid parameters", __func__); + status = BTM_ILLEGAL_VALUE; + } + + if (status != BTM_SUCCESS) { + cb_params.per_adv_sync_trans.status = status; + memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, &cb_params); return; } - if (!btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); - } + btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle); } void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) { - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; - if (!p_lcb) { - BTM_TRACE_ERROR("%s, invalid parameters", __func__); + // Set default past params + if (bdaddr_is_empty((bt_bdaddr_t *)bd_addr)) { + tHCI_STATUS err = HCI_SUCCESS; + if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_ILLEGAL_VALUE; + } + + cb_params.set_past_params.status = status; + memset(cb_params.set_past_params.addr, 0, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params); return; } - if (!btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + status = BTM_ILLEGAL_VALUE; } + + if (status != BTM_SUCCESS) { + cb_params.set_past_params.status = status; + memcpy(cb_params.set_past_params.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params); + return; + } + + btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type); +} + +void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + memcpy(&cb_params.past_recv, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV)); + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, &cb_params); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 113af0dfb4..fe297bec9e 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -533,6 +533,10 @@ void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params); void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *params); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 781999e6b5..2715c51c13 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1085,6 +1085,9 @@ void btm_create_sync_callback(UINT8 status); void btm_set_phy_callback(UINT8 status); void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy); #endif +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle); +#endif /* Internal functions provided by btm_sco.c ******************************************** */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index c20343c082..1bfa1a81e0 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1117,6 +1117,21 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_test_command_complete(p); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE: + case HCI_BLE_SET_DEFAULT_PAST_PARAMS: + break; + case HCI_BLE_PERIOD_ADV_SYNC_TRANS: + case HCI_BLE_PERIOD_ADV_SET_INFO_TRANS: + case HCI_BLE_SET_PAST_PARAMS: { + UINT8 status; + UINT16 conn_handle; + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT16(conn_handle, p); + btm_ble_periodic_adv_sync_trans_complete(opcode, status, conn_handle); + break; + } +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif #endif /* (BLE_INCLUDED == TRUE) */ @@ -2317,20 +2332,32 @@ static void btu_ble_scan_req_received_evt(UINT8 *p) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) { - tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV recv = {0}; + UINT16 conn_handle; + tL2C_LCB *p_lcb = NULL; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv = {0}; - STREAM_TO_UINT8(recv.status, p); - STREAM_TO_UINT16(recv.conn_handle, p); - STREAM_TO_UINT16(recv.service_data, p); - STREAM_TO_UINT16(recv.sync_handle, p); - STREAM_TO_UINT8(recv.adv_sid, p); - STREAM_TO_UINT8(recv.adv_addr_type, p); - STREAM_TO_BDADDR(recv.adv_addr, p); - STREAM_TO_UINT8(recv.adv_phy, p); - STREAM_TO_UINT16(recv.period_adv_interval, p); - STREAM_TO_UINT8(recv.adv_clk_accuracy, p); + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } - HCI_TRACE_DEBUG("%s status %x, conn handle %x, sync handle %x", recv.status, recv.conn_handle, recv.sync_handle); + STREAM_TO_UINT8(past_recv.status, p); + STREAM_TO_UINT16(conn_handle, p); + STREAM_TO_UINT16(past_recv.service_data, p); + STREAM_TO_UINT16(past_recv.sync_handle, p); + STREAM_TO_UINT8(past_recv.adv_sid, p); + STREAM_TO_UINT8(past_recv.adv_addr_type, p); + STREAM_TO_BDADDR(past_recv.adv_addr, p); + STREAM_TO_UINT8(past_recv.adv_phy, p); + STREAM_TO_UINT16(past_recv.adv_interval, p); + STREAM_TO_UINT8(past_recv.adv_clk_accuracy, p); + + p_lcb = l2cu_find_lcb_by_handle(conn_handle); + if(p_lcb) { + memcpy(past_recv.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); + } + + btm_ble_periodic_adv_sync_trans_recv_evt(&past_recv); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index dfaf7d5d3e..729134686e 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1783,12 +1783,12 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enab BT_HDR *p; UINT8 *pp; - HCIC_BLE_CMD_CREATED(p, pp, 3); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE); - UINT8_TO_STREAM(pp, 3); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE); UINT16_TO_STREAM(pp, sync_handle); UINT8_TO_STREAM(pp, enable); @@ -1796,59 +1796,61 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enab return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } -UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle) +BOOLEAN btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle) { BT_HDR *p; UINT8 *pp; - HCIC_BLE_CMD_CREATED(p, pp, 6); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SYNC_TRANS); - UINT8_TO_STREAM(pp, 6); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS); UINT16_TO_STREAM(pp, conn_handle); UINT16_TO_STREAM(pp, service_data); UINT16_TO_STREAM(pp, sync_handle); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; } -UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle) +BOOLEAN btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle) { BT_HDR *p; UINT8 *pp; HCI_TRACE_DEBUG("%s conn handle %x, adv handle %x", __func__, conn_handle, adv_handle); - HCIC_BLE_CMD_CREATED(p, pp, 5); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SET_INFO_TRANS); - UINT8_TO_STREAM(pp, 5); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS); UINT16_TO_STREAM(pp, conn_handle); UINT16_TO_STREAM(pp, service_data); UINT8_TO_STREAM(pp, adv_handle); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; } -UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) { BT_HDR *p; UINT8 *pp; HCI_TRACE_DEBUG("%s conn handle %x, mode %x, sync timeout %x", __func__, conn_handle, mode, sync_timeout); - HCIC_BLE_CMD_CREATED(p, pp, 8); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PAST_PARAMS); pp = (UINT8 *)(p + 1); - UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS); - UINT8_TO_STREAM(pp, 8); + UINT16_TO_STREAM(pp, HCI_BLE_SET_PAST_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PAST_PARAMS); UINT16_TO_STREAM(pp, conn_handle); UINT8_TO_STREAM(pp, mode); @@ -1856,6 +1858,29 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT UINT16_TO_STREAM(pp, sync_timeout); UINT8_TO_STREAM(pp, cte_type); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s mode %x, skip %x, sync timeout %x", __func__, mode, skip, sync_timeout); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_DEFAULT_PAST_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS); + + UINT8_TO_STREAM(pp, mode); + UINT16_TO_STREAM(pp, skip); + UINT16_TO_STREAM(pp, sync_timeout); + UINT8_TO_STREAM(pp, cte_type); + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 16230bc7b5..1e93242cd8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -1031,7 +1031,14 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT 32 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT 33 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT 34 -#define BTM_BLE_5_GAP_UNKNOWN_EVT 35 +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT 35 +#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT 36 +#define BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT 37 +#define BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT 38 +#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT 39 +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTM_BLE_5_GAP_UNKNOWN_EVT 40 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00 @@ -1241,6 +1248,39 @@ typedef struct { UINT16 max_ce_len; } tBTM_BLE_CONN_PARAMS; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + UINT8 status; +} tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_PERIOD_ADV_SET_INFO_TRANS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; + UINT16 service_data; + UINT16 sync_handle; + UINT8 adv_sid; + UINT8 adv_addr_type; + BD_ADDR adv_addr; + UINT8 adv_phy; + UINT16 adv_interval; + UINT8 adv_clk_accuracy; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) typedef union { UINT8 status; @@ -1275,6 +1315,13 @@ typedef union { tBTM_PERIOD_ADV_REPORT period_adv_report; tBTM_BLE_PERIOD_ADV_SYNC_LOST sync_lost; tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL per_adv_recv_enable; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL per_adv_sync_trans; + tBTM_BLE_PERIOD_ADV_SET_INFO_TRANS_CMPL per_adv_set_info_trans; + tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL set_past_params; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv; +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -1288,21 +1335,6 @@ typedef void (*tBTM_BLE_5_HCI_CBACK)(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_5_GAP_ #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) -#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -typedef struct { - UINT8 status; - UINT16 conn_handle; - UINT16 service_data; - UINT16 sync_handle; - UINT8 adv_sid; - UINT8 adv_addr_type; - BD_ADDR adv_addr; - UINT8 adv_phy; - UINT16 period_adv_interval; - UINT8 adv_clk_accuracy; -} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; -#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) - /***************************************************************************** ** EXTERNAL FUNCTION DECLARATIONS *****************************************************************************/ @@ -2655,6 +2687,10 @@ void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *pa #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable); + +void BTM_BlePeriodicAdvSyncTrans(BD_ADDR bd_addr, UINT16 service_data, UINT16 sync_handle); + void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle); void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index aee16e8d78..7b9cb75af6 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -389,7 +389,8 @@ #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SET_INFO_TRANS (0x005B | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS (0x005C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) // Vendor OGF define #define HCI_VENDOR_OGF 0x3F diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index e50b6510b5..0cf65865fa 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -1033,18 +1033,30 @@ UINT8 btsnd_hcic_ble_read_rf_path_compensation(void); UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_path); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); -UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); - -UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); - -UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); -#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_TOUT_OFF 2 +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE 3 +#define HCI_PERIODIC_ADV_RECV_REPORT_EN 1 +#define HCI_PERIODIC_ADV_RECV_DUP_FILTER_EN 2 +#define HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS 6 +#define HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS 5 +#define HCIC_PARAM_SIZE_SET_PAST_PARAMS 8 +#define HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS 6 + +UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); + +BOOLEAN btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); + +BOOLEAN btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); + +BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); + +UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif From 11e8970a45f2753899447942b2cbc7b70d529422 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Wed, 4 Jan 2023 15:00:09 +0800 Subject: [PATCH 12/12] bluedroid: add GATT read multi variable API and evt --- .../bt/host/bluedroid/api/esp_gattc_api.c | 35 +++++++++++ .../bluedroid/api/include/api/esp_gattc_api.h | 18 ++++++ .../host/bluedroid/bta/gatt/bta_gattc_act.c | 38 +++++++++++- .../host/bluedroid/bta/gatt/bta_gattc_api.c | 61 +++++++++++-------- .../host/bluedroid/bta/gatt/bta_gattc_main.c | 10 ++- .../bta/gatt/include/bta_gattc_int.h | 2 + .../bluedroid/bta/include/bta/bta_gatt_api.h | 16 +++++ .../btc/profile/std/gatt/btc_gattc.c | 22 ++++++- .../btc/profile/std/include/btc_gattc.h | 1 + 9 files changed, 173 insertions(+), 30 deletions(-) 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 db33823127..0cd4f312aa 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 @@ -60,6 +60,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; @@ -651,6 +652,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 361955262b..97b2d47e7c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -1174,6 +1174,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 @@ -1289,7 +1320,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; @@ -1426,7 +1458,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 45caacf67b..9797c4793c 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 89059c3c4d..183e3acc5a 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; @@ -1136,6 +1137,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 a7b5346bd7..1c332af628 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 48481a8f9a..eeebb427f2 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 @@ -24,6 +24,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,