OVMS3-idf/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c
Tian Hao b9382b29fa fix TX power value in ble adv data is incorrect
refence to https://github.com/espressif/esp-idf/issues/2284
Before fixing, the tx power in adv data is always 0xeb(-21dbm).

restriction:
    If change BLE advertising TX power, please call esp_ble_gap_config_adv_data()
    after BLE adv TX power changed.

    Later, will implement set BLE advertising TX power via HCI, then the
    TX power value in adv data can be update automatically after BLE adv
    TX power changed.
2018-09-12 20:23:45 +08:00

1280 lines
45 KiB
C

// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "osi/allocator.h"
#include "stack/bt_types.h"
#include "common/bt_defs.h"
#include "bta/bta_api.h"
#include "bta/bta_dm_co.h"
#include "btc/btc_task.h"
#include "btc/btc_manage.h"
#include "btc_gap_ble.h"
#include "btc_gatt_util.h"
#include "esp_bt_defs.h"
#include "esp_gap_ble_api.h"
#include "btc/btc_ble_storage.h"
#include "btc/btc_dm.h"
#include "btc/btc_util.h"
#include "osi/mutex.h"
#include "esp_bt.h"
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
#if SCAN_QUEUE_CONGEST_CHECK
static list_t *adv_filter_list;
static osi_mutex_t adv_list_lock;
bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type);
uint32_t btc_get_adv_list_length(void);
void btc_adv_list_refresh(void);
void btc_adv_list_lock(void);
void btc_adv_list_unlock(void);
static uint16_t btc_adv_list_count = 0;
#define BTC_ADV_LIST_MAX_LENGTH 50
#define BTC_ADV_LIST_MAX_COUNT 200
#endif
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE);
if (btc_gap_ble_cb) {
btc_gap_ble_cb(event, param);
}
}
static void btc_gap_adv_point_cleanup(void **buf)
{
if (NULL == *buf) {
return;
}
osi_free(*buf);
*buf = NULL;
}
static void btc_cleanup_adv_data(tBTA_BLE_ADV_DATA *bta_adv_data)
{
if (bta_adv_data == NULL) {
return;
}
// Manufacturer data cleanup
if (bta_adv_data->p_manu != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_manu->p_val);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_manu);
}
// Proprietary data cleanup
if (bta_adv_data->p_proprietary != NULL) {
int i = 0;
tBTA_BLE_PROP_ELEM *p_elem = bta_adv_data->p_proprietary->p_elem;
while (i++ != bta_adv_data->p_proprietary->num_elem
&& p_elem) {
btc_gap_adv_point_cleanup((void **) &p_elem->p_val);
++p_elem;
}
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_proprietary->p_elem);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_proprietary);
}
// Service list cleanup
if (bta_adv_data->p_services != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_services->p_uuid);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_services);
}
// Service data cleanup
if (bta_adv_data->p_service_data != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_service_data->p_val);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_service_data);
}
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_services_128b);
if (bta_adv_data->p_service_32b != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_service_32b->p_uuid);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_service_32b);
}
if (bta_adv_data->p_sol_services != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_sol_services->p_uuid);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_sol_services);
}
if (bta_adv_data->p_sol_service_32b != NULL) {
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_sol_service_32b->p_uuid);
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_sol_service_32b);
}
btc_gap_adv_point_cleanup((void **) &bta_adv_data->p_sol_service_128b);
}
static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DATA *bta_adv_data, uint32_t *data_mask)
{
uint32_t mask;
btc_cleanup_adv_data(bta_adv_data);
memset(bta_adv_data, 0, sizeof(tBTA_BLE_ADV_DATA));
mask = 0;
if (p_adv_data->flag != 0) {
mask = BTM_BLE_AD_BIT_FLAGS;
bta_adv_data->flag = p_adv_data->flag;
}
if (p_adv_data->include_name) {
mask |= BTM_BLE_AD_BIT_DEV_NAME;
}
if (p_adv_data->include_txpower) {
mask |= BTM_BLE_AD_BIT_TX_PWR;
bta_adv_data->tx_power = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV);
}
if (p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
p_adv_data->max_interval >= p_adv_data->min_interval) {
mask |= BTM_BLE_AD_BIT_INT_RANGE;
bta_adv_data->int_range.low = p_adv_data->min_interval;
bta_adv_data->int_range.hi = p_adv_data->max_interval;
}
if (p_adv_data->include_txpower) {
//TODO
}
if (p_adv_data->appearance != 0) {
mask |= BTM_BLE_AD_BIT_APPEARANCE;
bta_adv_data->appearance = p_adv_data->appearance;
}
if (p_adv_data->manufacturer_len > 0 && p_adv_data->p_manufacturer_data != NULL) {
bta_adv_data->p_manu = osi_malloc(sizeof(tBTA_BLE_MANU));
if (bta_adv_data->p_manu != NULL) {
bta_adv_data->p_manu->p_val = osi_malloc(p_adv_data->manufacturer_len);
if (bta_adv_data->p_manu->p_val != NULL) {
mask |= BTM_BLE_AD_BIT_MANU;
bta_adv_data->p_manu->len = p_adv_data->manufacturer_len;
memcpy(bta_adv_data->p_manu->p_val, p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
}
}
}
tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
if (p_adv_data->service_data_len > 0 && p_adv_data->p_service_data != NULL) {
p_elem_service_data = osi_malloc(sizeof(tBTA_BLE_PROP_ELEM));
if (p_elem_service_data != NULL) {
p_elem_service_data->p_val = osi_malloc(p_adv_data->service_data_len);
if (p_elem_service_data->p_val != NULL) {
p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
p_elem_service_data->len = p_adv_data->service_data_len;
memcpy(p_elem_service_data->p_val, p_adv_data->p_service_data,
p_adv_data->service_data_len);
} else {
osi_free(p_elem_service_data);
p_elem_service_data = NULL;
}
}
}
if (NULL != p_elem_service_data) {
bta_adv_data->p_proprietary = osi_malloc(sizeof(tBTA_BLE_PROPRIETARY));
if (NULL != bta_adv_data->p_proprietary) {
tBTA_BLE_PROP_ELEM *p_elem = NULL;
tBTA_BLE_PROPRIETARY *p_prop = bta_adv_data->p_proprietary;
p_prop->num_elem = 0;
mask |= BTM_BLE_AD_BIT_PROPRIETARY;
p_prop->num_elem = 1;
p_prop->p_elem = osi_malloc(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
p_elem = p_prop->p_elem;
if (NULL != p_elem) {
memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
}
osi_free(p_elem_service_data);
}
}
if (p_adv_data->service_uuid_len && p_adv_data->p_service_uuid) {
UINT16 *p_uuid_out16 = NULL;
UINT32 *p_uuid_out32 = NULL;
for (int position = 0; position < p_adv_data->service_uuid_len; position += LEN_UUID_128) {
tBT_UUID bt_uuid;
btc128_to_bta_uuid(&bt_uuid, p_adv_data->p_service_uuid + position);
switch (bt_uuid.len) {
case (LEN_UUID_16): {
if (NULL == bta_adv_data->p_services) {
bta_adv_data->p_services = osi_malloc(sizeof(tBTA_BLE_SERVICE));
bta_adv_data->p_services->list_cmpl = FALSE;
bta_adv_data->p_services->num_service = 0;
bta_adv_data->p_services->p_uuid = osi_malloc(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
p_uuid_out16 = bta_adv_data->p_services->p_uuid;
}
if (NULL != bta_adv_data->p_services->p_uuid) {
BTC_TRACE_DEBUG("%s - In 16-UUID_data", __FUNCTION__);
mask |= BTM_BLE_AD_BIT_SERVICE;
++bta_adv_data->p_services->num_service;
*p_uuid_out16++ = bt_uuid.uu.uuid16;
}
break;
}
case (LEN_UUID_32): {
if (NULL == bta_adv_data->p_service_32b) {
bta_adv_data->p_service_32b =
osi_malloc(sizeof(tBTA_BLE_32SERVICE));
bta_adv_data->p_service_32b->list_cmpl = FALSE;
bta_adv_data->p_service_32b->num_service = 0;
bta_adv_data->p_service_32b->p_uuid =
osi_malloc(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_32);
p_uuid_out32 = bta_adv_data->p_service_32b->p_uuid;
}
if (NULL != bta_adv_data->p_service_32b->p_uuid) {
BTC_TRACE_DEBUG("%s - In 32-UUID_data", __FUNCTION__);
mask |= BTM_BLE_AD_BIT_SERVICE_32;
++bta_adv_data->p_service_32b->num_service;
*p_uuid_out32++ = bt_uuid.uu.uuid32;
}
break;
}
case (LEN_UUID_128): {
/* Currently, only one 128-bit UUID is supported */
if (NULL == bta_adv_data->p_services_128b) {
bta_adv_data->p_services_128b =
osi_malloc(sizeof(tBTA_BLE_128SERVICE));
if (NULL != bta_adv_data->p_services_128b) {
BTC_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
mask |= BTM_BLE_AD_BIT_SERVICE_128;
memcpy(bta_adv_data->p_services_128b->uuid128,
bt_uuid.uu.uuid128, LEN_UUID_128);
BTC_TRACE_DEBUG("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", bt_uuid.uu.uuid128[0],
bt_uuid.uu.uuid128[1], bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
bt_uuid.uu.uuid128[4], bt_uuid.uu.uuid128[5], bt_uuid.uu.uuid128[6],
bt_uuid.uu.uuid128[7], bt_uuid.uu.uuid128[8], bt_uuid.uu.uuid128[9],
bt_uuid.uu.uuid128[10], bt_uuid.uu.uuid128[11], bt_uuid.uu.uuid128[12],
bt_uuid.uu.uuid128[13], bt_uuid.uu.uuid128[14], bt_uuid.uu.uuid128[15]);
bta_adv_data->p_services_128b->list_cmpl = TRUE;
}
}
break;
}
default:
break;
}
}
}
*data_mask = mask;
}
static void btc_adv_data_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT;
param.adv_data_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_scan_rsp_data_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT;
param.scan_rsp_data_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_adv_data_raw_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT;
param.adv_data_raw_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_scan_rsp_data_raw_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT;
param.scan_rsp_data_raw_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_set_adv_data(esp_ble_adv_data_t *adv_data,
tBTA_SET_ADV_DATA_CMPL_CBACK p_adv_data_cback)
{
tBTA_BLE_AD_MASK data_mask = 0;
if (!adv_data->set_scan_rsp) {
btc_to_bta_adv_data(adv_data, &gl_bta_adv_data, &data_mask);
BTA_DmBleSetAdvConfig(data_mask, &gl_bta_adv_data, p_adv_data_cback);
} else {
btc_to_bta_adv_data(adv_data, &gl_bta_scan_rsp_data, &data_mask);
BTA_DmBleSetScanRsp(data_mask, &gl_bta_scan_rsp_data, p_adv_data_cback);
}
}
static void btc_ble_set_adv_data_raw(uint8_t *raw_adv, uint32_t raw_adv_len,
tBTA_SET_ADV_DATA_CMPL_CBACK p_adv_data_cback)
{
BTA_DmBleSetAdvConfigRaw(raw_adv, raw_adv_len, p_adv_data_cback);
}
static void btc_ble_set_scan_rsp_data_raw(uint8_t *raw_scan_rsp, uint32_t raw_scan_rsp_len,
tBTA_SET_ADV_DATA_CMPL_CBACK p_scan_rsp_data_cback)
{
BTA_DmBleSetScanRspRaw(raw_scan_rsp, raw_scan_rsp_len, p_scan_rsp_data_cback);
}
static void btc_start_adv_callback(uint8_t status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_ADV_START_COMPLETE_EVT;
param.adv_start_cmpl.status = btc_hci_to_esp_status(status);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_stop_adv_callback(uint8_t status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT;
param.adv_stop_cmpl.status = btc_hci_to_esp_status(status);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback)
{
tBLE_BD_ADDR peer_addr;
esp_bt_status_t status = ESP_BT_STATUS_SUCCESS;
if (!BLE_ISVALID_PARAM(ble_adv_params->adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
!BLE_ISVALID_PARAM(ble_adv_params->adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) {
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting interval parameters.\n");
}
if ((ble_adv_params->adv_type < ADV_TYPE_IND) ||
(ble_adv_params->adv_type > ADV_TYPE_DIRECT_IND_LOW) ) {
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting type parameters.\n");
}
if ((ble_adv_params->adv_filter_policy < ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY) ||
(ble_adv_params->adv_filter_policy > ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST) ) {
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting type parameters.\n");
}
if((ble_adv_params->channel_map | ADV_CHNL_ALL) != ADV_CHNL_ALL || ble_adv_params->channel_map == 0) {
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting channel map parameters.\n");
}
if(status != ESP_BT_STATUS_SUCCESS) {
if(start_adv_cback) {
start_adv_cback(status);
}
return;
}
BTC_TRACE_DEBUG("API_Ble_AppStartAdvertising\n");
memcpy(peer_addr.bda, ble_adv_params->peer_addr, ESP_BD_ADDR_LEN);
peer_addr.type = ble_adv_params->peer_addr_type;
BTA_DmSetBleAdvParamsAll(ble_adv_params->adv_int_min,
ble_adv_params->adv_int_max,
ble_adv_params->adv_type,
ble_adv_params->own_addr_type,
ble_adv_params->channel_map,
ble_adv_params->adv_filter_policy,
&peer_addr,
start_adv_cback);
}
static void btc_scan_params_callback(tGATT_IF gatt_if, tBTM_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT;
param.scan_param_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
{
if (BLE_ISVALID_PARAM(scan_params->scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
BLE_ISVALID_PARAM(scan_params->scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) &&
BLE_ISVALID_PARAM(scan_params->own_addr_type, BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_RPA_RANDOM) &&
BLE_ISVALID_PARAM(scan_params->scan_filter_policy, BLE_SCAN_FILTER_ALLOW_ALL, BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR) &&
BLE_ISVALID_PARAM(scan_params->scan_duplicate, BLE_SCAN_DUPLICATE_DISABLE, BLE_SCAN_DUPLICATE_MAX -1) &&
(scan_params->scan_type == BTM_BLE_SCAN_MODE_ACTI || scan_params->scan_type == BTM_BLE_SCAN_MODE_PASS)) {
BTA_DmSetBleScanFilterParams(ESP_DEFAULT_GATT_IF, /*client_if*/
scan_params->scan_interval,
scan_params->scan_window,
scan_params->scan_type,
scan_params->scan_filter_policy,
scan_params->own_addr_type,
scan_params->scan_duplicate,
scan_param_setup_cback);
} else {
btc_scan_params_callback(ESP_DEFAULT_GATT_IF, BTM_ILLEGAL_VALUE);
}
}
static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
esp_ble_gap_cb_param_t param;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_RESULT_EVT;
param.scan_rst.search_evt = event;
switch (event) {
case BTA_DM_INQ_RES_EVT: {
#if SCAN_QUEUE_CONGEST_CHECK
if(btc_check_queue_is_congest()) {
BTC_TRACE_DEBUG("BtcQueue is congested");
if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
btc_adv_list_refresh();
btc_adv_list_count = 0;
}
if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
return;
}
}
btc_adv_list_count ++;
#endif
bdcpy(param.scan_rst.bda, p_data->inq_res.bd_addr);
param.scan_rst.dev_type = p_data->inq_res.device_type;
param.scan_rst.rssi = p_data->inq_res.rssi;
param.scan_rst.ble_addr_type = p_data->inq_res.ble_addr_type;
param.scan_rst.ble_evt_type = p_data->inq_res.ble_evt_type;
param.scan_rst.flag = p_data->inq_res.flag;
param.scan_rst.num_resps = 1;
param.scan_rst.adv_data_len = p_data->inq_res.adv_data_len;
param.scan_rst.scan_rsp_len = p_data->inq_res.scan_rsp_len;
memcpy(param.scan_rst.ble_adv, p_data->inq_res.p_eir, sizeof(param.scan_rst.ble_adv));
break;
}
case BTA_DM_INQ_CMPL_EVT: {
param.scan_rst.num_resps = p_data->inq_cmpl.num_resps;
BTC_TRACE_DEBUG("%s BLE observe complete. Num Resp %d\n", __FUNCTION__, p_data->inq_cmpl.num_resps);
break;
}
case BTA_DM_DISC_RES_EVT:
BTC_TRACE_DEBUG("BTA_DM_DISC_RES_EVT\n");
break;
case BTA_DM_DISC_BLE_RES_EVT:
BTC_TRACE_DEBUG("BTA_DM_DISC_BLE_RES_EVT\n");
break;
case BTA_DM_DISC_CMPL_EVT:
BTC_TRACE_DEBUG("BTA_DM_DISC_CMPL_EVT\n");
break;
case BTA_DM_DI_DISC_CMPL_EVT:
BTC_TRACE_DEBUG("BTA_DM_DI_DISC_CMPL_EVT\n");
break;
case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
BTC_TRACE_DEBUG("BTA_DM_SEARCH_CANCEL_CMPL_EVT\n");
break;
default:
BTC_TRACE_ERROR("%s : Unknown event 0x%x\n", __FUNCTION__, event);
return;
}
btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL);
}
static void btc_start_scan_callback(uint8_t status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_START_COMPLETE_EVT;
param.scan_start_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_stop_scan_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT;
param.scan_stop_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_refresh();
#endif
}
void btc_update_conn_param_callback (UINT8 status, BD_ADDR bd_addr, tBTM_LE_UPDATE_CONN_PRAMS *update_conn_params)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT;
param.update_conn_params.status = btc_hci_to_esp_status(status);
param.update_conn_params.min_int = update_conn_params->min_conn_int;
param.update_conn_params.max_int = update_conn_params->max_conn_int;
param.update_conn_params.conn_int = update_conn_params->conn_int;
param.update_conn_params.latency = update_conn_params->slave_latency;
param.update_conn_params.timeout = update_conn_params->supervision_tout;
memcpy(param.update_conn_params.bda, bd_addr, sizeof(esp_bd_addr_t));
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_set_pkt_length_callback(UINT8 status, tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS *data_len_params)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT;
param.pkt_data_lenth_cmpl.status = btc_btm_status_to_esp_status(status);
param.pkt_data_lenth_cmpl.params.rx_len = data_len_params->rx_len;
param.pkt_data_lenth_cmpl.params.tx_len = data_len_params->tx_len;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_add_whitelist_complete_callback(UINT8 status, tBTM_WL_OPERATION wl_opration)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT;
param.update_whitelist_cmpl.status = btc_hci_to_esp_status(status);
param.update_whitelist_cmpl.wl_opration = wl_opration;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_set_rand_addr_callback(UINT8 status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
param.set_rand_addr_cmpl.status = btc_btm_status_to_esp_status(status); //todo status
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_set_local_privacy_callback(UINT8 status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT;
param.local_privacy_cmpl.status = btc_btm_status_to_esp_status(status);
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
#if (SMP_INCLUDED == TRUE)
static void btc_set_encryption_callback(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS enc_status)
{
UNUSED(bd_addr);
UNUSED(transport);
BTC_TRACE_DEBUG("enc_status = %x\n", enc_status);
return;
}
#endif ///SMP_INCLUDED == TRUE
static void btc_read_ble_rssi_cmpl_callback(void *p_data)
{
tBTA_RSSI_RESULTS *result = (tBTA_RSSI_RESULTS *)p_data;
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT;
param.read_rssi_cmpl.rssi = result->rssi;
param.read_rssi_cmpl.status = btc_btm_status_to_esp_status(result->status);
memcpy(param.read_rssi_cmpl.remote_addr, result->rem_bda, sizeof(BD_ADDR));
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
void btc_get_whitelist_size(uint16_t *length)
{
BTM_BleGetWhiteListSize(length);
return;
}
static void btc_ble_start_scanning(uint32_t duration,
tBTA_DM_SEARCH_CBACK *results_cb,
tBTA_START_STOP_SCAN_CMPL_CBACK *start_scan_cb)
{
if ((results_cb != NULL) && (start_scan_cb != NULL)) {
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_refresh();
#endif
//Start scan the device
BTA_DmBleScan(true, duration, results_cb, start_scan_cb);
} else {
BTC_TRACE_ERROR("The start_scan_cb or results_cb invalid\n");
}
}
static void btc_ble_stop_scanning(tBTA_START_STOP_SCAN_CMPL_CBACK *stop_scan_cb)
{
uint8_t duration = 0;
BTA_DmBleScan(false, duration, NULL, stop_scan_cb);
}
static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb)
{
bool stop_adv = false;
BTA_DmBleBroadcast(stop_adv, stop_adv_cb);
}
static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int,
uint16_t max_int, uint16_t latency, uint16_t timeout)
{
if (min_int > max_int) {
min_int = max_int;
}
if (min_int < BTM_BLE_CONN_INT_MIN || max_int > BTM_BLE_CONN_INT_MAX) {
BTC_TRACE_ERROR("Invalid interval value.\n");
}
BTA_DmBleUpdateConnectionParams(bd_addr, min_int, max_int,
latency, timeout);
}
static void btc_ble_set_pkt_data_len(BD_ADDR remote_device, uint16_t tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback)
{
if (tx_data_length > BTM_BLE_DATA_SIZE_MAX) {
tx_data_length = BTM_BLE_DATA_SIZE_MAX;
} else if (tx_data_length < BTM_BLE_DATA_SIZE_MIN) {
tx_data_length = BTM_BLE_DATA_SIZE_MIN;
}
BTA_DmBleSetDataLength(remote_device, tx_data_length, p_set_pkt_data_cback);
}
static void btc_ble_config_local_icon(uint16_t icon)
{
BTA_DmBleConfigLocalIcon(icon);
}
static void btc_ble_set_rand_addr (BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_set_rand_addr_cback)
{
if (rand_addr != NULL) {
/*
A static address is a 48-bit randomly generated address and shall meet the following requirements:
• The two most significant bits of the address shall be equal to 1
• All bits of the random part of the address shall not be equal to 1
• All bits of the random part of the address shall not be equal to 0
*/
BD_ADDR invalid_rand_addr_a, invalid_rand_addr_b;
memset(invalid_rand_addr_a, 0xff, sizeof(BD_ADDR));
memset(invalid_rand_addr_b, 0x00, sizeof(BD_ADDR));
invalid_rand_addr_b[0] = invalid_rand_addr_b[0] | BT_STATIC_RAND_ADDR_MASK;
if((rand_addr[0] & BT_STATIC_RAND_ADDR_MASK) == BT_STATIC_RAND_ADDR_MASK
&& memcmp(invalid_rand_addr_a, rand_addr, BD_ADDR_LEN) != 0
&& memcmp(invalid_rand_addr_b, rand_addr, BD_ADDR_LEN) != 0){
BTA_DmSetRandAddress(rand_addr, btc_set_rand_addr_callback);
} else {
btc_set_rand_addr_callback(BTM_INVALID_STATIC_RAND_ADDR);
BTC_TRACE_ERROR("Invalid random address, the high bit should be 0b11, all bits of the random part shall not be to 1 or 0");
}
} else {
btc_set_rand_addr_callback(BTM_INVALID_STATIC_RAND_ADDR);
BTC_TRACE_ERROR("Invalid random addressm, the address value is NULL");
}
}
static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
{
BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback);
}
static void btc_ble_disconnect(BD_ADDR bd_addr)
{
BTA_DmBleDisconnect(bd_addr);
}
void btc_gap_ble_cb_handler(btc_msg_t *msg)
{
esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg;
if (msg->act < ESP_GAP_BLE_EVT_MAX) {
btc_gap_ble_cb_to_app(msg->act, param);
} else {
BTC_TRACE_ERROR("%s, unknow msg->act = %d", __func__, msg->act);
}
btc_gap_ble_cb_deep_free(msg);
}
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
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->cfg_adv_data.adv_data.p_manufacturer_data) {
dst->cfg_adv_data.adv_data.p_manufacturer_data = osi_malloc(src->cfg_adv_data.adv_data.manufacturer_len);
memcpy(dst->cfg_adv_data.adv_data.p_manufacturer_data, src->cfg_adv_data.adv_data.p_manufacturer_data,
src->cfg_adv_data.adv_data.manufacturer_len);
}
if (src->cfg_adv_data.adv_data.p_service_data) {
dst->cfg_adv_data.adv_data.p_service_data = osi_malloc(src->cfg_adv_data.adv_data.service_data_len);
memcpy(dst->cfg_adv_data.adv_data.p_service_data, src->cfg_adv_data.adv_data.p_service_data, src->cfg_adv_data.adv_data.service_data_len);
}
if (src->cfg_adv_data.adv_data.p_service_uuid) {
dst->cfg_adv_data.adv_data.p_service_uuid = osi_malloc(src->cfg_adv_data.adv_data.service_uuid_len);
memcpy(dst->cfg_adv_data.adv_data.p_service_uuid, src->cfg_adv_data.adv_data.p_service_uuid, src->cfg_adv_data.adv_data.service_uuid_len);
}
break;
}
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: {
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 && src->cfg_adv_data_raw.raw_adv && src->cfg_adv_data_raw.raw_adv_len > 0) {
dst->cfg_adv_data_raw.raw_adv = osi_malloc(src->cfg_adv_data_raw.raw_adv_len);
if (dst->cfg_adv_data_raw.raw_adv) {
memcpy(dst->cfg_adv_data_raw.raw_adv, src->cfg_adv_data_raw.raw_adv, src->cfg_adv_data_raw.raw_adv_len);
}
}
break;
}
case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW: {
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 && src->cfg_scan_rsp_data_raw.raw_scan_rsp && src->cfg_scan_rsp_data_raw.raw_scan_rsp_len > 0) {
dst->cfg_scan_rsp_data_raw.raw_scan_rsp = osi_malloc(src->cfg_scan_rsp_data_raw.raw_scan_rsp_len);
if (dst->cfg_scan_rsp_data_raw.raw_scan_rsp) {
memcpy(dst->cfg_scan_rsp_data_raw.raw_scan_rsp, src->cfg_scan_rsp_data_raw.raw_scan_rsp, src->cfg_scan_rsp_data_raw.raw_scan_rsp_len);
}
}
break;
}
case BTC_GAP_BLE_SET_SECURITY_PARAM_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;
uint8_t length = 0;
if (src->set_security_param.value) {
length = dst->set_security_param.len;
dst->set_security_param.value = osi_malloc(length);
if (dst->set_security_param.value != NULL) {
memcpy(dst->set_security_param.value, src->set_security_param.value, length);
} else {
BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
}
}
break;
}
default:
BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
break;
}
}
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
switch (msg->act) {
default:
BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
break;
}
}
void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
{
BTC_TRACE_DEBUG("%s \n", __func__);
switch (msg->act) {
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
esp_ble_adv_data_t *adv = &((btc_ble_gap_args_t *)msg->arg)->cfg_adv_data.adv_data;
if (adv->p_service_data) {
osi_free(adv->p_service_data);
}
if (adv->p_service_uuid) {
osi_free(adv->p_service_uuid);
}
if (adv->p_manufacturer_data) {
osi_free(adv->p_manufacturer_data);
}
break;
}
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW: {
uint8_t *raw_adv = ((btc_ble_gap_args_t *)msg->arg)->cfg_adv_data_raw.raw_adv;
if (raw_adv) {
osi_free(raw_adv);
}
break;
}
case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW: {
uint8_t *raw_scan_rsp = ((btc_ble_gap_args_t *)msg->arg)->cfg_scan_rsp_data_raw.raw_scan_rsp;
if (raw_scan_rsp) {
osi_free(raw_scan_rsp);
}
break;
}
case BTC_GAP_BLE_SET_SECURITY_PARAM_EVT: {
uint8_t *value = ((btc_ble_gap_args_t *)msg->arg)->set_security_param.value;
if (value) {
osi_free(value);
}
break;
}
default:
BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act);
break;
}
}
void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
{
BTC_TRACE_DEBUG("%s", __func__);
switch (msg->act) {
default:
BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act);
break;
}
}
void btc_gap_ble_call_handler(btc_msg_t *msg)
{
btc_ble_gap_args_t *arg = (btc_ble_gap_args_t *)msg->arg;
BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act);
switch (msg->act) {
case BTC_GAP_BLE_ACT_CFG_ADV_DATA: {
if (arg->cfg_adv_data.adv_data.set_scan_rsp == false) {
btc_ble_set_adv_data(&arg->cfg_adv_data.adv_data, btc_adv_data_callback);
} else {
btc_ble_set_adv_data(&arg->cfg_adv_data.adv_data, btc_scan_rsp_data_callback);
}
break;
}
case BTC_GAP_BLE_ACT_SET_SCAN_PARAM:
btc_ble_set_scan_params(&arg->set_scan_param.scan_params, btc_scan_params_callback);
break;
case BTC_GAP_BLE_ACT_START_SCAN:
btc_ble_start_scanning(arg->start_scan.duration, btc_search_callback, btc_start_scan_callback);
break;
case BTC_GAP_BLE_ACT_STOP_SCAN:
btc_ble_stop_scanning(btc_stop_scan_callback);
break;
case BTC_GAP_BLE_ACT_START_ADV:
btc_ble_start_advertising(&arg->start_adv.adv_params, btc_start_adv_callback);
break;
case BTC_GAP_BLE_ACT_STOP_ADV:
btc_ble_stop_advertising(btc_stop_adv_callback);
break;
case BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM:
btc_ble_update_conn_params(arg->conn_update_params.conn_params.bda,
arg->conn_update_params.conn_params.min_int,
arg->conn_update_params.conn_params.max_int,
arg->conn_update_params.conn_params.latency,
arg->conn_update_params.conn_params.timeout);
break;
case BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN:
btc_ble_set_pkt_data_len(arg->set_pkt_data_len.remote_device, arg->set_pkt_data_len.tx_data_length, btc_set_pkt_length_callback);
break;
case BTC_GAP_BLE_ACT_SET_RAND_ADDRESS: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->set_rand_addr.rand_addr, sizeof(BD_ADDR));
btc_ble_set_rand_addr(bd_addr, btc_set_rand_addr_callback);
break;
}
case BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY:
btc_ble_config_local_privacy(arg->cfg_local_privacy.privacy_enable, btc_set_local_privacy_callback);
break;
case BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON:
btc_ble_config_local_icon(arg->cfg_local_icon.icon);
break;
case BTC_GAP_BLE_ACT_UPDATE_WHITE_LIST:
BTA_DmUpdateWhiteList(arg->update_white_list.add_remove, arg->update_white_list.remote_bda, btc_add_whitelist_complete_callback);
break;
case BTC_GAP_BLE_ACT_READ_RSSI:
BTA_DmBleReadRSSI(arg->read_rssi.remote_addr, BTA_TRANSPORT_LE, btc_read_ble_rssi_cmpl_callback);
break;
case BTC_GAP_BLE_ACT_SET_CONN_PARAMS:
BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int,
arg->set_conn_params.max_conn_int, arg->set_conn_params.slave_latency,
arg->set_conn_params.supervision_tout);
break;
case BTC_GAP_BLE_ACT_SET_DEV_NAME:
BTA_DmSetDeviceName(arg->set_dev_name.device_name);
break;
case BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW:
btc_ble_set_adv_data_raw(arg->cfg_adv_data_raw.raw_adv,
arg->cfg_adv_data_raw.raw_adv_len,
btc_adv_data_raw_callback);
break;
case BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW:
btc_ble_set_scan_rsp_data_raw(arg->cfg_scan_rsp_data_raw.raw_scan_rsp,
arg->cfg_scan_rsp_data_raw.raw_scan_rsp_len,
btc_scan_rsp_data_raw_callback);
break;
#if (SMP_INCLUDED == TRUE)
case BTC_GAP_BLE_SET_ENCRYPTION_EVT: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->set_encryption.bd_addr, sizeof(BD_ADDR));
BTA_DmSetEncryption(bd_addr, BT_TRANSPORT_LE, btc_set_encryption_callback,
(tBTA_DM_BLE_SEC_ACT)arg->set_encryption.sec_act);
break;
}
case BTC_GAP_BLE_SET_SECURITY_PARAM_EVT: {
uint8_t *value = arg->set_security_param.value;
switch(arg->set_security_param.param_type) {
case ESP_BLE_SM_PASSKEY:
break;
case ESP_BLE_SM_AUTHEN_REQ_MODE: {
uint8_t authen_req = 0;
STREAM_TO_UINT8(authen_req, value);
bta_dm_co_ble_set_auth_req(authen_req);
break;
}
case ESP_BLE_SM_IOCAP_MODE: {
uint8_t iocap = 0;
STREAM_TO_UINT8(iocap, value);
bta_dm_co_ble_set_io_cap(iocap);
break;
}
case ESP_BLE_SM_SET_INIT_KEY: {
uint8_t init_key = 0;
STREAM_TO_UINT8(init_key, value);
bta_dm_co_ble_set_init_key_req(init_key);
break;
}
case ESP_BLE_SM_SET_RSP_KEY: {
uint8_t rsp_key = 0;
STREAM_TO_UINT8(rsp_key, value);
bta_dm_co_ble_set_rsp_key_req(rsp_key);
break;
}
case ESP_BLE_SM_MAX_KEY_SIZE: {
uint8_t key_size = 0;
STREAM_TO_UINT8(key_size, value);
bta_dm_co_ble_set_max_key_size(key_size);
break;
}
case ESP_BLE_SM_SET_STATIC_PASSKEY: {
uint32_t passkey = 0;
for(uint8_t i = 0; i < arg->set_security_param.len; i++)
{
passkey += (((uint8_t *)value)[i]<<(8*i));
}
BTA_DmBleSetStaticPasskey(true, passkey);
break;
}
case ESP_BLE_SM_CLEAR_STATIC_PASSKEY: {
BTA_DmBleSetStaticPasskey(false, 0);
break;
}
default:
break;
}
break;
}
case BTC_GAP_BLE_SECURITY_RSP_EVT: {
BD_ADDR bd_addr;
tBTA_DM_BLE_SEC_GRANT res = arg->sec_rsp.accept ? BTA_DM_SEC_GRANTED : BTA_DM_SEC_PAIR_NOT_SPT;
memcpy(bd_addr, arg->sec_rsp.bd_addr, sizeof(BD_ADDR));
BTA_DmBleSecurityGrant(bd_addr, res);
break;
}
case BTC_GAP_BLE_PASSKEY_REPLY_EVT: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->enc_passkey_replay.bd_addr, sizeof(BD_ADDR));
BTA_DmBlePasskeyReply(bd_addr, arg->enc_passkey_replay.accept, arg->enc_passkey_replay.passkey);
break;
}
case BTC_GAP_BLE_CONFIRM_REPLY_EVT: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->enc_comfirm_replay.bd_addr, sizeof(BD_ADDR));
BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept);
break;
}
case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
BD_ADDR bd_addr;
memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
BTA_DmRemoveDevice(bd_addr, BT_TRANSPORT_LE);
break;
}
#endif ///SMP_INCLUDED == TRUE
case BTC_GAP_BLE_DISCONNECT_EVT:
btc_ble_disconnect(arg->disconnect.remote_device);
break;
default:
break;
}
btc_gap_ble_arg_deep_free(msg);
}
//register connection parameter update callback
void btc_gap_callback_init(void)
{
BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback);
}
void btc_gap_ble_deinit(void)
{
btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
}
#if SCAN_QUEUE_CONGEST_CHECK
void btc_adv_list_free(void *data)
{
osi_free(data);
}
void btc_adv_list_init(void)
{
osi_mutex_new(&adv_list_lock);
adv_filter_list = list_new(btc_adv_list_free);
}
void btc_adv_list_deinit(void)
{
osi_mutex_free(&adv_list_lock);
if(adv_filter_list) {
list_free(adv_filter_list);
adv_filter_list = NULL;
}
}
void btc_adv_list_add_packet(void * data)
{
if(!data) {
BTC_TRACE_ERROR("%s data is NULL", __func__);
return;
}
btc_adv_list_lock();
list_prepend(adv_filter_list, data);
btc_adv_list_unlock();
}
uint32_t btc_get_adv_list_length(void)
{
if(!adv_filter_list) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return 0;
}
btc_adv_list_lock();
size_t length = list_length(adv_filter_list);
btc_adv_list_unlock();
return length;
}
void btc_adv_list_refresh(void)
{
if(!adv_filter_list) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return ;
}
btc_adv_list_lock();
list_clear(adv_filter_list);
btc_adv_list_unlock();
}
bool btc_check_adv_list(uint8_t * addr, uint8_t addr_type)
{
bool found = false;
if(!adv_filter_list || !addr) {
BTC_TRACE_ERROR("%s adv_filter_list is NULL", __func__);
return found;
}
btc_adv_list_lock();
for (const list_node_t *node = list_begin(adv_filter_list); node != list_end(adv_filter_list); node = list_next(node)) {
btc_adv_packet_t *packet = (btc_adv_packet_t *)list_node(node);
if(!bdcmp(addr, packet->addr) && packet->addr_type == addr_type) {
found = true;
break;
}
}
btc_adv_list_unlock();
if(!found) {
btc_adv_packet_t *adv_packet = osi_malloc(sizeof(btc_adv_packet_t));
if(adv_packet) {
adv_packet->addr_type = addr_type;
bdcpy(adv_packet->addr, addr);
btc_adv_list_add_packet(adv_packet);
} else {
BTC_TRACE_ERROR("%s adv_packet malloc failed", __func__);
}
}
return found;
}
void btc_adv_list_lock(void)
{
osi_mutex_lock(&adv_list_lock, OSI_MUTEX_MAX_TIMEOUT);
}
void btc_adv_list_unlock(void)
{
osi_mutex_unlock(&adv_list_lock);
}
#endif