mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'feature/support_ble_53_host_feat_v5.0' into 'release/v5.0'
Support BLE host feature for PTS (backport v5.0) See merge request espressif/esp-idf!25646
This commit is contained in:
commit
87aeb49cff
@ -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"
|
||||
|
@ -215,6 +215,27 @@ 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_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
|
||||
@ -1100,6 +1121,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))
|
||||
@ -1113,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
|
||||
|
@ -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)
|
||||
@ -1338,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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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;
|
||||
|
||||
@ -586,6 +592,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 +625,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)
|
||||
@ -902,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
|
||||
*/
|
||||
@ -1300,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;
|
||||
|
||||
/**
|
||||
@ -1790,6 +1867,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) */
|
||||
|
||||
/**
|
||||
@ -2166,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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
@ -5775,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
|
||||
|
@ -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 */
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -3112,4 +3161,72 @@ 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)
|
||||
void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable)
|
||||
{
|
||||
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__);
|
||||
}
|
||||
}
|
||||
|
||||
void BTA_DmBleGapPeriodicAdvSyncTrans(BD_ADDR peer_addr, UINT16 service_data, UINT16 sync_handle)
|
||||
{
|
||||
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)
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
@ -200,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)
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
@ -198,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
|
||||
};
|
||||
|
||||
@ -401,8 +409,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;
|
||||
@ -1014,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 */
|
||||
@ -1055,6 +1107,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;
|
||||
@ -1153,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;
|
||||
@ -1614,6 +1673,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 */
|
||||
@ -1707,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 */
|
||||
|
@ -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;
|
||||
@ -1171,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
|
||||
@ -1286,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;
|
||||
@ -1423,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;
|
||||
|
@ -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
|
||||
@ -1103,4 +1139,83 @@ 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;
|
||||
}
|
||||
/* End BLE PTS */
|
||||
#endif /* defined(GATTC_INCLUDED) && (GATTC_INCLUDED == TRUE) */
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -640,4 +640,41 @@ 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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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,91 @@ BOOLEAN bta_gatts_co_load_handle_range(UINT8 index,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** 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 // #if (SMP_INCLUDED == TRUE)
|
||||
#endif // #if (GATTS_INCLUDED == TRUE)
|
||||
#endif // #if (BLE_INCLUDED == TRUE)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
@ -394,6 +395,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];
|
||||
@ -468,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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
@ -1590,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;
|
||||
@ -1600,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
|
||||
*****************************************************************************/
|
||||
@ -1934,7 +1957,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 +1967,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 */
|
||||
|
||||
/*******************************************************************************
|
||||
@ -2981,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 {
|
||||
|
@ -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);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -1542,6 +1558,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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
@ -922,5 +924,79 @@ int btc_storage_get_num_ble_bond_devices(void)
|
||||
|
||||
return num_dev;
|
||||
}
|
||||
|
||||
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
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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);
|
||||
@ -944,6 +948,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;
|
||||
|
@ -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__
|
||||
|
@ -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
|
||||
*/
|
||||
@ -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;
|
||||
}
|
||||
@ -1335,6 +1369,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 +1515,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 +1788,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);
|
||||
@ -1922,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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
@ -84,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 */
|
||||
@ -201,6 +209,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;
|
||||
@ -335,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)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
@ -288,12 +294,36 @@
|
||||
#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 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
|
||||
#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
|
||||
|
@ -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
|
||||
@ -493,6 +499,24 @@
|
||||
#define GATTS_SEND_SERVICE_CHANGE_MODE UC_BT_GATTS_SEND_SERVICE_CHANGE_MODE
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY UC_BT_BLE_ACT_SCAN_REP_ADV_SCAN
|
||||
#endif
|
||||
@ -503,6 +527,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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1032,7 +1032,6 @@ void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *p
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void btm_ble_extended_init(void)
|
||||
{
|
||||
|
||||
@ -1283,3 +1282,144 @@ 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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;
|
||||
@ -535,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
|
||||
}
|
||||
|
@ -1086,6 +1086,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
|
||||
********************************************
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
#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;
|
||||
@ -413,6 +415,11 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
|
||||
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_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
|
||||
}
|
||||
break;
|
||||
#endif /* BLE_INCLUDED */
|
||||
@ -1110,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) */
|
||||
|
||||
@ -2306,6 +2328,39 @@ 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)
|
||||
{
|
||||
UINT16 conn_handle;
|
||||
tL2C_LCB *p_lcb = NULL;
|
||||
tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv = {0};
|
||||
|
||||
if (!p) {
|
||||
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
/**********************************************
|
||||
** End of BLE Events Handler
|
||||
***********************************************/
|
||||
|
@ -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 ++;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
@ -167,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;
|
||||
|
||||
@ -398,7 +414,8 @@ 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 {
|
||||
if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) {
|
||||
gatt_update_for_database_change();
|
||||
if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) {
|
||||
gatt_proc_srv_chg();
|
||||
}
|
||||
}
|
||||
@ -510,7 +527,8 @@ 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) {
|
||||
if (GATTS_SEND_SERVICE_CHANGE_MODE == GATTS_SEND_SERVICE_CHANGE_AUTO) {
|
||||
gatt_update_for_database_change();
|
||||
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*/
|
||||
@ -980,6 +998,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));
|
||||
@ -1171,6 +1190,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
|
||||
|
||||
/*******************************************************************************/
|
||||
@ -1543,7 +1568,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;
|
||||
@ -1675,4 +1701,78 @@ 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;
|
||||
}
|
||||
|
||||
tGATT_STATUS GATTS_ShowLocalDatabase(void)
|
||||
{
|
||||
gatts_show_local_database();
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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,109 @@ 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
bta_gatts_co_cl_feat_save(p_tcb->peer_bda, &p_tcb->cl_supp_feat);
|
||||
#endif
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function gatt_proc_write_req
|
||||
@ -213,12 +299,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 +347,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 +473,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 +692,106 @@ 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)
|
||||
{
|
||||
#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) {
|
||||
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};
|
||||
#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;
|
||||
}
|
||||
|
||||
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) {
|
||||
#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;
|
||||
|
||||
GATT_TRACE_DEBUG("%s status %d", __func__, chg_aware);
|
||||
}
|
||||
#endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */
|
||||
|
@ -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,8 @@ 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);}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -107,6 +110,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 +188,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 +420,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 +487,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 +525,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 +556,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 +649,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 +659,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 +668,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 +700,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 +726,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 +805,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 +835,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 +851,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 +860,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 +1000,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);
|
||||
}
|
||||
@ -1088,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);
|
||||
@ -1107,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 {
|
||||
@ -1133,6 +1200,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 +1222,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;
|
||||
|
||||
@ -1163,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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
@ -1563,6 +1680,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 +1729,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 +1839,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 */
|
||||
@ -1678,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;
|
||||
|
||||
|
256
components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c
Normal file
256
components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c
Normal file
@ -0,0 +1,256 @@
|
||||
#include "common/bt_target.h"
|
||||
#include "osi/allocator.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "gatt_int.h"
|
||||
#include "stack/l2c_api.h"
|
||||
#include "l2c_int.h"
|
||||
#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;
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
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 */
|
@ -1090,6 +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;
|
||||
}
|
||||
@ -2910,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
|
||||
|
@ -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;
|
||||
|
||||
@ -540,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{
|
||||
@ -609,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);
|
||||
@ -759,4 +776,11 @@ 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 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);
|
||||
#endif
|
||||
|
@ -1776,4 +1776,112 @@ 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;
|
||||
UINT8 *pp;
|
||||
|
||||
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, HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE);
|
||||
|
||||
UINT16_TO_STREAM(pp, sync_handle);
|
||||
UINT8_TO_STREAM(pp, enable);
|
||||
|
||||
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
}
|
||||
|
||||
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, 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, 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);
|
||||
|
||||
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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, 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, 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);
|
||||
|
||||
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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, HCIC_PARAM_SIZE_SET_PAST_PARAMS);
|
||||
|
||||
pp = (UINT8 *)(p + 1);
|
||||
|
||||
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);
|
||||
UINT16_TO_STREAM(pp, skip);
|
||||
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)
|
||||
#endif
|
||||
|
@ -1777,6 +1777,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;
|
||||
|
@ -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 {
|
||||
@ -1809,6 +1856,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);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -2614,7 +2684,16 @@ 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_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);
|
||||
#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
@ -108,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 */
|
||||
|
||||
@ -413,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 */
|
||||
};
|
||||
@ -432,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
|
||||
@ -655,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 **********************/
|
||||
|
||||
@ -1032,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);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -1226,6 +1251,45 @@ 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);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** 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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -385,6 +385,13 @@
|
||||
#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_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
|
||||
|
||||
@ -802,6 +809,9 @@
|
||||
#define HCI_BLE_SCAN_REQ_RECEIVED_EVT 0x13
|
||||
#define HCI_BLE_CHANNEL_SELECT_ALG 0x14
|
||||
#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
|
||||
|
@ -1031,10 +1031,32 @@ 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);
|
||||
|
||||
#endif // #if (BLE_50_FEATURE_SUPPORT == 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user