From: Satya Calloji Date: Thu, 5 Jun 2014 20:15:15 +0000 (-0700) Subject: LE ADV Filter changes X-Git-Tag: android-x86-7.1-r1~1507^2~12 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5e177043;p=android-x86%2Fsystem-bt.git LE ADV Filter changes BTIF and stack layer changes for ADV filter feature DO NOT MERGE Change-Id: I865e57c41802751e172248547b8510598261ec94 --- diff --git a/bta/Android.mk b/bta/Android.mk index 4f8ca9106..6feeff211 100644 --- a/bta/Android.mk +++ b/bta/Android.mk @@ -86,7 +86,6 @@ LOCAL_SRC_FILES:= \ ./jv/bta_jv_cfg.c \ ./jv/bta_jv_main.c \ ./jv/bta_jv_api.c \ - ../vnd/ble/bta_vendor.c LOCAL_MODULE := libbt-brcm_bta LOCAL_MODULE_CLASS := STATIC_LIBRARIES diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index f340ff170..762dfdee9 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2003-2012 Broadcom Corporation + * Copyright (C) 2003-2014 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -5461,6 +5461,162 @@ void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_v bta_dm_cb.p_setup_cback(bta_evt, ref_value, status); } + +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE +/******************************************************************************* +** +** Function bta_ble_scan_pf_cmpl +** +** Description ADV payload filtering operation complete callback +** +** +** Returns TRUE if handled, otherwise FALSE. +** +*******************************************************************************/ +static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op, + tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status, + tBTM_BLE_REF_VALUE ref_value) +{ + tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE; + + APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status); + + if(bta_dm_cb.p_scan_filt_cfg_cback) + bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value); +} + +/******************************************************************************* +** +** Function bta_ble_enable_scan_cmpl +** +** Description ADV payload filtering enable / disable complete callback +** +** +** Returns None +** +*******************************************************************************/ +static void bta_ble_status_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_REF_VALUE ref_value, + tBTM_STATUS status) +{ + tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE; + + APPL_TRACE_DEBUG("bta_ble_status_cmpl: %d, %d", action, status); + + if(bta_dm_cb.p_scan_filt_status_cback) + bta_dm_cb.p_scan_filt_status_cback(action, ref_value, st); +} + +/******************************************************************************* +** +** Function bta_dm_cfg_filter_cond +** +** Description This function configure adv payload filtering condition +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data) +{ + tBTM_STATUS st = BTM_MODE_UNSUPPORTED; + tBTA_STATUS status = BTA_FAILURE; + + tBTM_BLE_VSC_CB cmn_vsc_cb; + + APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond"); + BTM_BleGetVendorCapabilities(&cmn_vsc_cb); + if(0 != cmn_vsc_cb.filter_support) + { + if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action, + p_data->ble_cfg_filter_cond.cond_type, + (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index, + (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param, + bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value)) + == BTM_CMD_STARTED) + { + bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback; + return; + } + } + + if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback) + p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT, + p_data->ble_cfg_filter_cond.cond_type, 0, status, + p_data->ble_cfg_filter_cond.ref_value); + return; +} + +/******************************************************************************* +** +** Function bta_dm_enable_scan_filter +** +** Description This function enable/disable adv payload filtering condition +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data) +{ + tBTM_STATUS st = BTM_MODE_UNSUPPORTED; + tBTA_STATUS status = BTA_FAILURE; + + tBTM_BLE_VSC_CB cmn_vsc_cb; + APPL_TRACE_DEBUG("bta_dm_enable_scan_filter"); + BTM_BleGetVendorCapabilities(&cmn_vsc_cb); + + if(0 != cmn_vsc_cb.filter_support) + { + if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action, + p_data->ble_enable_scan_filt.p_filt_status_cback, + (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) + bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback; + return; + } + + if (p_data->ble_enable_scan_filt.p_filt_status_cback) + p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT, + p_data->ble_enable_scan_filt.ref_value, status); + +} +/******************************************************************************* +** +** Function bta_dm_scan_filter_param_setup +** +** Description This function sets up scan filter params +** +** Parameters: +** +*******************************************************************************/ +void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data) +{ + tBTM_STATUS st = BTM_MODE_UNSUPPORTED; + tBTA_STATUS status = BTA_FAILURE; + + tBTM_BLE_VSC_CB cmn_vsc_cb; + + APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup"); + BTM_BleGetVendorCapabilities(&cmn_vsc_cb); + if(0 != cmn_vsc_cb.filter_support) + { + if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action, + p_data->ble_scan_filt_param_setup.filt_index, + (tBTM_BLE_PF_FILT_PARAMS *)p_data->ble_scan_filt_param_setup.p_filt_params, + p_data->ble_scan_filt_param_setup.p_target, + p_data->ble_scan_filt_param_setup.p_filt_param_cback, + p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) + { + bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback; + return; + } + } + + if (p_data->ble_scan_filt_param_setup.p_filt_param_cback) + p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0, + p_data->ble_scan_filt_param_setup.ref_value, status); + + return; +} +#endif + #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 @@ -5798,49 +5954,6 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) #endif /* BTA_GATT_INCLUDED */ -#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -/******************************************************************************* -** -** Function bta_dm_enable_scan_filter -** -** Description This function enable/disable adv payload filtering condition -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_enable_scan_filter (tBTA_DM_MSG *p_data) -{ - tBTA_SYS_VS_BLE_SCAN_PF_ENABLE param; - - param.enable = p_data->ble_enable_scan_filter.enable; - param.p_target = p_data->ble_enable_scan_filter.p_target; - param.p_cmpl_cback = p_data->ble_enable_scan_filter.p_cmpl_cback; - - bta_sys_vs_hdl(BTA_VS_BLE_SCAN_PF_ENABLE_EVT, (void *)¶m); -} - -/******************************************************************************* -** -** Function bta_dm_cfg_filter_cond -** -** Description This function configure adv payload filtering condition -** -** Parameters: -** -*******************************************************************************/ -void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data) -{ - tBTA_SYS_VS_BLE_SCAN_PF_COND param; - - param.action = p_data->ble_cfg_filter_cond.action; - param.cond_type = p_data->ble_cfg_filter_cond.cond_type; - param.p_cond = (void *)p_data->ble_cfg_filter_cond.p_cond_param; - param.p_cmpl_cback = p_data->ble_cfg_filter_cond.p_cmpl_cback; - - bta_sys_vs_hdl(BTA_VS_BLE_SCAN_PF_COND_EVT, (void *)¶m); -} -#endif /* BLE_ANDROID_CONTROLLER_SCAN_FILTER */ - /******************************************************************************* ** ** Function bta_dm_ctrl_features_rd_cmpl_cback diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c index bf739adee..3c3602c7b 100644 --- a/bta/dm/bta_dm_api.c +++ b/bta/dm/bta_dm_api.c @@ -1628,6 +1628,7 @@ BTA_API extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, ** scan_window - Scan window ** discard_rule -Discard rules ** addr_type - Address type +** ref_value - Reference value ** ** Returns None ** @@ -1659,7 +1660,7 @@ BTA_API extern void BTA_DmBleEnableBatchScan(tBTA_BLE_SCAN_MODE scan_mode, ** ** Description This function is called to disable the batch scan ** -** Parameters +** Parameters ref_value - Reference value ** ** Returns None ** @@ -1684,6 +1685,7 @@ BTA_API extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value) ** Description This function is called to read scan reports ** ** Parameters scan_type -Batch scan mode +** ref_value - Reference value ** ** Returns None ** @@ -2136,6 +2138,212 @@ tBTA_STATUS BTA_BleDisableAdvInstance (UINT8 inst_id) /******************************************************************************* ** +** Function BTA_DmBleCfgFilterCondition +** +** Description This function is called to configure the adv data payload filter +** condition. +** +** Parameters action: to read/write/clear +** cond_type: filter condition type +** filt_index - Filter index +** p_cond: filter condition parameter +** p_cmpl_back - Command completed callback +** ref_value - Reference value +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, + tBTA_DM_BLE_PF_COND_TYPE cond_type, + tBTA_DM_BLE_PF_FILT_INDEX filt_index, + tBTA_DM_BLE_PF_COND_PARAM *p_cond, + tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value) +{ +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE + tBTA_DM_API_CFG_FILTER_COND *p_msg; + APPL_TRACE_API ("BTA_DmBleCfgFilterCondition: %d, %d", action, cond_type); + + UINT16 len = sizeof(tBTA_DM_API_CFG_FILTER_COND) + sizeof(tBTA_DM_BLE_PF_COND_PARAM) + \ + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + sizeof(tBTA_DM_BLE_PF_COND_MASK); + + UINT8 *p; + + if ((p_msg = (tBTA_DM_API_CFG_FILTER_COND *) GKI_getbuf(len)) != NULL) + { + memset (p_msg, 0, len); + + p_msg->hdr.event = BTA_DM_API_CFG_FILTER_COND_EVT; + p_msg->action = action; + p_msg->cond_type = cond_type; + p_msg->filt_index = filt_index; + p_msg->p_filt_cfg_cback = p_cmpl_cback; + p_msg->ref_value = ref_value; + if (p_cond) + { + p_msg->p_cond_param = (tBTA_DM_BLE_PF_COND_PARAM *)(p_msg + 1); + memcpy(p_msg->p_cond_param, p_cond, sizeof(tBTA_DM_BLE_PF_COND_PARAM)); + + p = (UINT8 *)(p_msg->p_cond_param + 1); + + if (cond_type == BTA_DM_BLE_PF_SRVC_DATA_PATTERN || + cond_type == BTA_DM_BLE_PF_MANU_DATA) + { + p_msg->p_cond_param->manu_data.p_pattern = p; + p_msg->p_cond_param->manu_data.data_len = p_cond->manu_data.data_len; + memcpy(p_msg->p_cond_param->manu_data.p_pattern, p_cond->manu_data.p_pattern, + p_cond->manu_data.data_len); + p += p_cond->manu_data.data_len; + + if (cond_type == BTA_DM_BLE_PF_MANU_DATA) + { + p_msg->p_cond_param->manu_data.company_id_mask = + p_cond->manu_data.company_id_mask; + if ( p_cond->manu_data.p_pattern_mask != NULL) + { + p_msg->p_cond_param->manu_data.p_pattern_mask = p; + memcpy(p_msg->p_cond_param->manu_data.p_pattern_mask, + p_cond->manu_data.p_pattern_mask, p_cond->manu_data.data_len); + } + } + } + else if (cond_type == BTA_DM_BLE_PF_LOCAL_NAME) + { + p_msg->p_cond_param->local_name.p_data = p; + memcpy(p_msg->p_cond_param->local_name.p_data, + p_cond->local_name.p_data, p_cond->local_name.data_len); + } + else if ((cond_type == BTM_BLE_PF_SRVC_UUID || cond_type == BTM_BLE_PF_SRVC_SOL_UUID)) + { + if (p_cond->srvc_uuid.p_target_addr != NULL) + { + p_msg->p_cond_param->srvc_uuid.p_target_addr = (tBLE_BD_ADDR *)(p); + p_msg->p_cond_param->srvc_uuid.p_target_addr->type = + p_cond->srvc_uuid.p_target_addr->type; + memcpy(p_msg->p_cond_param->srvc_uuid.p_target_addr->bda, + p_cond->srvc_uuid.p_target_addr->bda, BD_ADDR_LEN); + p = (UINT8*)( p_msg->p_cond_param->srvc_uuid.p_target_addr + 1); + } + if (p_cond->srvc_uuid.p_uuid_mask) + { + p_msg->p_cond_param->srvc_uuid.p_uuid_mask = (tBTA_DM_BLE_PF_COND_MASK *)p; + memcpy(p_msg->p_cond_param->srvc_uuid.p_uuid_mask, + p_cond->srvc_uuid.p_uuid_mask, sizeof(tBTA_DM_BLE_PF_COND_MASK)); + } + } + } + + bta_sys_sendmsg(p_msg); + } +#else + UNUSED(action); + UNUSED(cond_type); + UNUSED(filt_index); + UNUSED(p_cond); + UNUSED(p_cmpl_cback); + UNUSED(ref_value); +#endif +} + +/******************************************************************************* +** +** Function BTA_DmBleScanFilterSetup +** +** Description This function is called to setup the adv data payload filter param +** +** Parameters p_target: enable the filter condition on a target device; if NULL +** filt_index - Filter index +** p_filt_params -Filter parameters +** ref_value - Reference value +** action - Add, delete or clear +** p_cmpl_back - Command completed callback +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBleScanFilterSetup(UINT8 action, tBTA_DM_BLE_PF_FILT_INDEX filt_index, + tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params, + tBLE_BD_ADDR *p_target, + tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value) +{ +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE + tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *p_msg; + APPL_TRACE_API ("BTA_DmBleScanFilterSetup: %d", action); + + UINT16 len = sizeof(tBTA_DM_API_SCAN_FILTER_PARAM_SETUP) + sizeof(tBLE_BD_ADDR); + + if ((p_msg = (tBTA_DM_API_SCAN_FILTER_PARAM_SETUP *) GKI_getbuf(len)) != NULL) + { + memset (p_msg, 0, len); + + p_msg->hdr.event = BTA_DM_API_SCAN_FILTER_SETUP_EVT; + p_msg->action = action; + p_msg->filt_index = filt_index; + p_msg->p_filt_params = p_filt_params; + p_msg->p_filt_param_cback = p_cmpl_cback; + p_msg->ref_value = ref_value; + + if (p_target) + { + p_msg->p_target = (tBLE_BD_ADDR *)(p_msg + 1); + memcpy(p_msg->p_target, p_target, sizeof(tBLE_BD_ADDR)); + } + + bta_sys_sendmsg(p_msg); + } +#else + UNUSED(action); + UNUSED(filt_index); + UNUSED(p_filt_params); + UNUSED(p_target); + UNUSED(p_cmpl_cback); + UNUSED(ref_value); +#endif +} + +/******************************************************************************* +** +** Function BTA_DmEnableScanFilter +** +** Description This function is called to enable the adv data payload filter +** +** Parameters action - enable or disable the APCF feature +** p_cmpl_cback - Command completed callback +** ref_value - Reference value +** +** Returns void +** +*******************************************************************************/ +void BTA_DmEnableScanFilter(UINT8 action, tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value) +{ +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE + tBTA_DM_API_ENABLE_SCAN_FILTER *p_msg; + APPL_TRACE_API ("BTA_DmEnableScanFilter: %d", action); + + UINT16 len = sizeof(tBTA_DM_API_ENABLE_SCAN_FILTER) + sizeof(tBLE_BD_ADDR); + + if ((p_msg = (tBTA_DM_API_ENABLE_SCAN_FILTER *) GKI_getbuf(len)) != NULL) + { + memset (p_msg, 0, len); + + p_msg->hdr.event = BTA_DM_API_SCAN_FILTER_ENABLE_EVT; + p_msg->action = action; + p_msg->ref_value = ref_value; + p_msg->p_filt_status_cback = p_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +#else + UNUSED(action); + UNUSED(p_cmpl_cback); + UNUSED(ref_value); +#endif +} + +/******************************************************************************* +** ** Function BTA_DmBleUpdateConnectionParams ** ** Description Update connection parameters, can only be used when connection is up. diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h index 0a1e967b0..0b8cde67b 100644 --- a/bta/dm/bta_dm_int.h +++ b/bta/dm/bta_dm_int.h @@ -112,7 +112,8 @@ enum #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE BTA_DM_API_CFG_FILTER_COND_EVT, - BTA_DM_API_ENABLE_SCAN_FILTER_EVT, + BTA_DM_API_SCAN_FILTER_SETUP_EVT, + BTA_DM_API_SCAN_FILTER_ENABLE_EVT, #endif BTA_DM_API_BLE_MULTI_ADV_ENB_EVT, BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT, @@ -694,17 +695,30 @@ typedef struct BT_HDR hdr; tBTA_DM_BLE_SCAN_COND_OP action; tBTA_DM_BLE_PF_COND_TYPE cond_type; + tBTA_DM_BLE_PF_FILT_INDEX filt_index; tBTA_DM_BLE_PF_COND_PARAM *p_cond_param; - void *p_cmpl_cback; + tBTA_DM_BLE_PF_CFG_CBACK *p_filt_cfg_cback; + tBTA_DM_BLE_REF_VALUE ref_value; }tBTA_DM_API_CFG_FILTER_COND; typedef struct { BT_HDR hdr; - BOOLEAN enable; - tBLE_BD_ADDR *p_target; - void *p_cmpl_cback; + UINT8 action; + tBTA_DM_BLE_PF_STATUS_CBACK *p_filt_status_cback; + tBTA_DM_BLE_REF_VALUE ref_value; }tBTA_DM_API_ENABLE_SCAN_FILTER; + +typedef struct +{ + BT_HDR hdr; + UINT8 action; + tBTA_DM_BLE_PF_FILT_INDEX filt_index; + tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params; + tBLE_BD_ADDR *p_target; + tBTA_DM_BLE_PF_PARAM_CBACK *p_filt_param_cback; + tBTA_DM_BLE_REF_VALUE ref_value; +}tBTA_DM_API_SCAN_FILTER_PARAM_SETUP; #endif /* union of all data types */ @@ -783,8 +797,9 @@ typedef union tBTA_DM_API_BLE_ADV_PARAMS ble_set_adv_params; tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data; #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE - tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filter; + tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup; tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond; + tBTA_DM_API_ENABLE_SCAN_FILTER ble_enable_scan_filt; #endif tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params; tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb; @@ -900,7 +915,9 @@ typedef struct tBTA_DM_ACTIVE_LINK device_list; tBTA_DM_SEC_CBACK *p_sec_cback; tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback; - void *p_ref; + tBTA_DM_BLE_PF_CFG_CBACK *p_scan_filt_cfg_cback; + tBTA_DM_BLE_PF_STATUS_CBACK *p_scan_filt_status_cback; + tBTA_DM_BLE_PF_PARAM_CBACK *p_scan_filt_param_cback; TIMER_LIST_ENT signal_strength_timer; tBTA_SIG_STRENGTH_MASK signal_strength_mask; UINT16 state; @@ -1167,8 +1184,9 @@ extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data); extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data); #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -extern void bta_dm_enable_scan_filter (tBTA_DM_MSG *p_data); extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data); +extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data); +extern void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data); #endif extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data); diff --git a/bta/dm/bta_dm_main.c b/bta/dm/bta_dm_main.c index ac0b9308f..df5001df3 100644 --- a/bta/dm/bta_dm_main.c +++ b/bta/dm/bta_dm_main.c @@ -106,7 +106,8 @@ const tBTA_DM_ACTION bta_dm_action[] = bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */ #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */ - bta_dm_enable_scan_filter, /* BTA_DM_API_ENABLE_SCAN_FILTER_EVT */ + bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */ + bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */ #endif bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/ bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */ diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h index 429e88dfb..677383883 100644 --- a/bta/include/bta_api.h +++ b/bta/include/bta_api.h @@ -525,6 +525,13 @@ enum }; typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP; +/* ADV payload filtering vendor specific call event */ +enum +{ + BTA_BLE_SCAN_PF_ENABLE_EVT = 7, + BTA_BLE_SCAN_PF_COND_EVT +}; + /* filter selection bit index */ #define BTA_DM_BLE_PF_ADDR_FILTER BTM_BLE_PF_ADDR_FILTER #define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA @@ -533,8 +540,6 @@ typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP; #define BTA_DM_BLE_PF_LOCAL_NAME BTM_BLE_PF_LOCAL_NAME #define BTA_DM_BLE_PF_MANU_DATA BTM_BLE_PF_MANU_DATA #define BTA_DM_BLE_PF_SRVC_DATA_PATTERN BTM_BLE_PF_SRVC_DATA_PATTERN -#define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX -#define BTA_DM_BLE_PF_SRVC_DATA BTM_BLE_PF_SRVC_DATA #define BTA_DM_BLE_PF_TYPE_ALL BTM_BLE_PF_TYPE_ALL #define BTA_DM_BLE_PF_TYPE_MAX BTM_BLE_PF_TYPE_MAX typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE; @@ -575,6 +580,8 @@ typedef struct UINT16 uuid; /* service ID */ UINT8 data_len; /* <= 20 bytes */ UINT8 *p_pattern; + UINT8 *p_pattern_mask; /* Service data matching mask, same length + as data pattern, set to all 0xff, match exact data */ }tBTA_DM_BLE_PF_SRVC_PATTERN_COND; typedef union @@ -587,6 +594,9 @@ typedef union tBTA_DM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ }tBTA_DM_BLE_PF_COND_PARAM; +typedef UINT8 tBTA_DM_BLE_PF_FILT_INDEX; +typedef UINT8 tBTA_DM_BLE_PF_AVBL_SPACE; + typedef INT8 tBTA_DM_RSSI_VALUE; typedef UINT8 tBTA_DM_LINK_QUALITY_VALUE; @@ -949,6 +959,73 @@ typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event, UINT8 inst_id, void *p_ref, tBTA_STATUS status); typedef UINT8 tBTA_DM_BLE_REF_VALUE; +#define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE +#define BTA_DM_BLE_PF_CONFIG_EVT BTM_BLE_PF_CONFIG +typedef UINT8 tBTA_DM_BLE_PF_EVT; + +typedef UINT8 tBTA_DM_BLE_PF_COND_TYPE; + +#define BTA_DM_BLE_PF_LOGIC_OR 0 +#define BTA_DM_BLE_PF_LOGIC_AND 1 +typedef UINT8 tBTA_DM_BLE_PF_LOGIC_TYPE; + +#define BTA_DM_BLE_PF_ENABLE 1 +#define BTA_DM_BLE_PF_CONFIG 2 +typedef UINT8 tBTA_DM_BLE_PF_ACTION; + +typedef UINT8 tBTA_DM_BLE_PF_FILT_INDEX; + +typedef UINT8 tBTA_DM_BLE_PF_AVBL_SPACE; + +/* Config callback */ +typedef void (tBTA_DM_BLE_PF_CFG_CBACK) (tBTA_DM_BLE_PF_ACTION action, + tBTA_DM_BLE_PF_COND_TYPE cfg_cond, + tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_STATUS status, + tBTA_DM_BLE_REF_VALUE ref_value); +/* Param callback */ +typedef void (tBTA_DM_BLE_PF_PARAM_CBACK) (UINT8 action_type, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, + tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status); + +/* Status callback */ +typedef void (tBTA_DM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTA_DM_BLE_REF_VALUE ref_value, + tBTA_STATUS status); + + +#define BTA_DM_BLE_PF_BRDCAST_ADDR_FILT 1 +#define BTA_DM_BLE_PF_SERV_DATA_CHG_FILT 2 +#define BTA_DM_BLE_PF_SERV_UUID 4 +#define BTA_DM_BLE_PF_SERV_SOLC_UUID 8 +#define BTA_DM_BLE_PF_LOC_NAME_CHECK 16 +#define BTA_DM_BLE_PF_MANUF_NAME_CHECK 32 +#define BTA_DM_BLE_PF_SERV_DATA_CHECK 64 +typedef UINT16 tBTA_DM_BLE_PF_FEAT_SEL; + +#define BTA_DM_BLE_PF_LIST_LOGIC_OR 1 +#define BTA_DM_BLE_PF_LIST_LOGIC_AND 2 +typedef UINT16 tBTA_DM_BLE_PF_LIST_LOGIC_TYPE; + +#define BTA_DM_BLE_PF_FILT_LOGIC_OR 0 +#define BTA_DM_BLE_PF_FILT_LOGIC_AND 1 +typedef UINT16 tBTA_DM_BLE_PF_FILT_LOGIC_TYPE; + +typedef UINT8 tBTA_DM_BLE_PF_RSSI_THRESHOLD; +typedef UINT8 tBTA_DM_BLE_PF_DELIVERY_MODE; +typedef UINT16 tBTA_DM_BLE_PF_TIMEOUT; +typedef UINT8 tBTA_DM_BLE_PF_TIMEOUT_CNT; + +typedef struct +{ + tBTA_DM_BLE_PF_FEAT_SEL feat_seln; + tBTA_DM_BLE_PF_LIST_LOGIC_TYPE list_logic_type; + tBTA_DM_BLE_PF_FILT_LOGIC_TYPE filt_logic_type; + tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_high_thres; + tBTA_DM_BLE_PF_RSSI_THRESHOLD rssi_low_thres; + tBTA_DM_BLE_PF_DELIVERY_MODE dely_mode; + tBTA_DM_BLE_PF_TIMEOUT found_timeout; + tBTA_DM_BLE_PF_TIMEOUT lost_timeout; + tBTA_DM_BLE_PF_TIMEOUT_CNT found_timeout_cnt; +} tBTA_DM_BLE_PF_FILT_PARAMS; + /* Vendor Specific Command Callback */ typedef tBTM_VSC_CMPL_CB tBTA_VENDOR_CMPL_CBACK; @@ -1052,7 +1129,7 @@ typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, typedef tBTM_BLE_SEC_ACT tBTA_DM_BLE_SEC_ACT; typedef void (tBTA_BLE_SCAN_THRESHOLD_CBACK)(tBTA_DM_BLE_REF_VALUE ref_value); -typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format, +typedef void (tBTA_BLE_SCAN_REP_CBACK) (tBTA_DM_BLE_REF_VALUE ref_value, UINT8 report_format, UINT8 num_records, UINT16 data_len, UINT8* p_rep_data, tBTA_STATUS status); typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt, tBTA_DM_BLE_REF_VALUE ref_value, @@ -2256,7 +2333,7 @@ BTA_API extern void BTA_DmBleSetStorageParams(UINT8 batch_scan_full_max, UINT8 batch_scan_notify_threshold, tBTA_BLE_SCAN_SETUP_CBACK *p_setup_cback, tBTA_BLE_SCAN_THRESHOLD_CBACK *p_thres_cback, - tBTA_BLE_SCAN_REP_CBACK* p_rep_cback, + tBTA_BLE_SCAN_REP_CBACK* p_rep_cback, tBTA_DM_BLE_REF_VALUE ref_value); /******************************************************************************* @@ -2307,6 +2384,63 @@ BTA_API extern void BTA_DmBleReadScanReports(tBTA_BLE_SCAN_MODE scan_type, *******************************************************************************/ BTA_API extern void BTA_DmBleDisableBatchScan(tBTA_DM_BLE_REF_VALUE ref_value); +/******************************************************************************* +** +** Function BTA_DmEnableScanFilter +** +** Description This function is called to enable the adv data payload filter +** +** Parameters action -1: enable the filter condition, 0 - disables the filter condition +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmEnableScanFilter(UINT8 action, + tBTA_DM_BLE_PF_STATUS_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTA_DmBleScanFilterSetup +** +** Description This function is called to setup the filter params +** +** Parameters action: to read/write/clear +** filt_index - filter index +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleScanFilterSetup(UINT8 action, + tBTA_DM_BLE_PF_FILT_INDEX filt_index, + tBTA_DM_BLE_PF_FILT_PARAMS *p_filt_params, + tBLE_BD_ADDR *p_target, + tBTA_DM_BLE_PF_PARAM_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTA_DmBleCfgFilterCondition +** +** Description This function is called to configure the adv data payload filter +** condition. +** +** Parameters action: to read/write/clear +** cond_type: filter condition type. +** filt_index - filter index +** p_cond: filter condition parameter +** ref_value: Reference +** +** Returns void +** +*******************************************************************************/ +BTA_API extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, + tBTA_DM_BLE_PF_COND_TYPE cond_type, + tBTA_DM_BLE_PF_FILT_INDEX filt_index, + tBTA_DM_BLE_PF_COND_PARAM *p_cond, + tBTA_DM_BLE_PF_CFG_CBACK *p_cmpl_cback, + tBTA_DM_BLE_REF_VALUE ref_value); + #endif #ifdef __cplusplus diff --git a/bta/include/bta_gatt_api.h b/bta/include/bta_gatt_api.h index 3de755815..8e70dae4e 100644 --- a/bta/include/bta_gatt_api.h +++ b/bta/include/bta_gatt_api.h @@ -135,12 +135,15 @@ typedef UINT8 tBTA_GATT_STATUS; #define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */ #define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */ #define BTA_GATTC_CONGEST_EVT 24 /* Congestion event */ -#define BTA_GATTC_BTH_SCAN_ENB_EVT 25 /* Enable batch scan event */ -#define BTA_GATTC_BTH_SCAN_CFG_EVT 26 /* Config storage event */ -#define BTA_GATTC_BTH_SCAN_RD_EVT 27 /* Batch scan reports read event */ -#define BTA_GATTC_BTH_SCAN_THR_EVT 28 /* Batch scan threshold event */ -#define BTA_GATTC_BTH_SCAN_PARAM_EVT 29 /* Batch scan param event */ -#define BTA_GATTC_BTH_SCAN_DIS_EVT 30 /* Disable batch scan event */ +#define BTA_GATTC_BTH_SCAN_ENB_EVT 24 /* Enable batch scan event */ +#define BTA_GATTC_BTH_SCAN_CFG_EVT 25 /* Config storage event */ +#define BTA_GATTC_BTH_SCAN_RD_EVT 26 /* Batch scan reports read event */ +#define BTA_GATTC_BTH_SCAN_THR_EVT 27 /* Batch scan threshold event */ +#define BTA_GATTC_BTH_SCAN_PARAM_EVT 28 /* Batch scan param event */ +#define BTA_GATTC_BTH_SCAN_DIS_EVT 29 /* Disable batch scan event */ +#define BTA_GATTC_SCAN_FLT_CFG_EVT 30 /* Scan filter config event */ +#define BTA_GATTC_SCAN_FLT_PARAM_EVT 31 /* Param filter event */ +#define BTA_GATTC_SCAN_FLT_STATUS_EVT 32 /* Filter status event */ typedef UINT8 tBTA_GATTC_EVT; diff --git a/bta/sys/bta_sys.h b/bta/sys/bta_sys.h index 8a662491b..7b60b1fa7 100644 --- a/bta/sys/bta_sys.h +++ b/bta/sys/bta_sys.h @@ -30,27 +30,6 @@ /***************************************************************************** ** Constants and data types *****************************************************************************/ -/* ADV payload filtering vendor specific call event */ -enum -{ - BTA_VS_BLE_SCAN_PF_ENABLE_EVT = 7, - BTA_VS_BLE_SCAN_PF_COND_EVT -}; - -typedef struct -{ - BOOLEAN enable; - tBLE_BD_ADDR *p_target; - void *p_cmpl_cback; -}tBTA_SYS_VS_BLE_SCAN_PF_ENABLE; - -typedef struct -{ - UINT8 action; - INT8 cond_type; - void *p_cond; - void *p_cmpl_cback; -}tBTA_SYS_VS_BLE_SCAN_PF_COND; /* vendor specific event handler function type */ typedef BOOLEAN (tBTA_SYS_VS_EVT_HDLR)(UINT16 evt, void *p); diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c index 0247f1a17..97b5ff10f 100644 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -50,7 +50,6 @@ #include "btif_pan.h" #include "btif_profile_queue.h" #include "btif_config.h" -#include "bta_vendor_api.h" /************************************************************************************ ** Constants & Macros ************************************************************************************/ @@ -608,9 +607,8 @@ void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd) /* callback to HAL */ if (status == BTA_SUCCESS) { -#if (BLE_INCLUDED == TRUE ) - BTA_BrcmInit(); -#endif + /* initialize a2dp service */ + btif_av_init(); /* init rfcomm & l2cap api */ btif_sock_init(); diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c index 59c9b6b78..21e64e1f1 100644 --- a/btif/src/btif_gatt_client.c +++ b/btif/src/btif_gatt_client.c @@ -51,7 +51,6 @@ #include "btif_dm.h" #include "btif_storage.h" -#include "bta_vendor_api.h" #include "vendor_api.h" /******************************************************************************* @@ -93,9 +92,10 @@ typedef enum { BTIF_GATTC_LISTEN, BTIF_GATTC_SET_ADV_DATA, BTIF_GATTC_CONFIGURE_MTU, - BTIF_GATTC_SCAN_FILTER_ENABLE, + BTIF_GATTC_SCAN_FILTER_PARAM_SETUP, BTIF_GATTC_SCAN_FILTER_CONFIG, BTIF_GATTC_SCAN_FILTER_CLEAR, + BTIF_GATTC_SCAN_FILTER_ENABLE, BTIF_GATTC_SET_SCAN_PARAMS, BTIF_GATTC_ADV_INSTANCE_ENABLE, BTIF_GATTC_ADV_INSTANCE_UPDATE, @@ -142,6 +142,31 @@ typedef struct btgatt_batch_reports read_reports; } btgatt_batch_track_cb_t; +typedef tBTA_DM_BLE_PF_FILT_PARAMS btgatt_adv_filt_param_t; + +typedef struct +{ + uint8_t client_if; + uint8_t action; + tBTA_DM_BLE_PF_COND_TYPE filt_type; + bt_bdaddr_t bd_addr; + uint8_t value[BTGATT_MAX_ATTR_LEN]; + uint8_t value_len; + uint8_t filt_index; + uint16_t conn_id; + uint16_t company_id_mask; + bt_uuid_t uuid; + bt_uuid_t uuid_mask; + uint8_t value_mask[BTGATT_MAX_ATTR_LEN]; + uint8_t value_mask_len; + uint8_t has_mask; + uint8_t addr_type; + uint8_t status; + tBTA_DM_BLE_PF_AVBL_SPACE avbl_space; + tBTA_DM_BLE_SCAN_COND_OP cond_op; + btgatt_adv_filt_param_t adv_filt_param; +} btgatt_adv_filter_cb_t; + typedef struct { uint8_t value[BTGATT_MAX_ATTR_LEN]; @@ -580,14 +605,6 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) break; } - case BTIF_GATTC_SCAN_FILTER_EVT: - { - btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param; - HAL_CBACK(bt_gatt_callbacks, client->scan_filter_cb, p_btif_cb->action, - p_btif_cb->status); - break; - } - case BTA_GATTC_MULT_ADV_ENB_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param; @@ -701,6 +718,36 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) break; } + case BTA_GATTC_SCAN_FLT_CFG_EVT: + { + btgatt_adv_filter_cb_t *p_btif_cb = (btgatt_adv_filter_cb_t*)p_param; + HAL_CBACK(bt_gatt_callbacks, client->scan_filter_cfg_cb, p_btif_cb->action, + p_btif_cb->client_if, p_btif_cb->status, p_btif_cb->cond_op, + p_btif_cb->avbl_space); + break; + } + + case BTA_GATTC_SCAN_FLT_PARAM_EVT: + { + btgatt_adv_filter_cb_t *p_data = (btgatt_adv_filter_cb_t*) p_param; + BTIF_TRACE_DEBUG("BTA_GATTC_SCAN_FLT_PARAM_EVT: %d, %d, %d, %d",p_data->client_if, + p_data->action, p_data->avbl_space, p_data->status); + HAL_CBACK(bt_gatt_callbacks, client->scan_filter_param_cb + , p_data->action, p_data->client_if, p_data->status + , p_data->avbl_space); + break; + } + + case BTA_GATTC_SCAN_FLT_STATUS_EVT: + { + btgatt_adv_filter_cb_t *p_data = (btgatt_adv_filter_cb_t*) p_param; + BTIF_TRACE_DEBUG("BTA_GATTC_SCAN_FLT_STATUS_EVT: %d, %d, %d",p_data->client_if, + p_data->action, p_data->status); + HAL_CBACK(bt_gatt_callbacks, client->scan_filter_status_cb + , p_data->action, p_data->client_if, p_data->status); + break; + } + default: ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event); break; @@ -783,7 +830,7 @@ static void bta_batch_scan_setup_cb (tBTA_BLE_BATCH_SCAN_EVT evt, btif_scan_track_cb.status = status; btif_scan_track_cb.client_if = ref_value; - BTIF_TRACE_DEBUG3("bta_batch_scan_setup_cb-Status:%x, client_if:%d, evt=%d", + BTIF_TRACE_DEBUG("bta_batch_scan_setup_cb-Status:%x, client_if:%d, evt=%d", status, ref_value, evt); switch(evt) @@ -833,7 +880,7 @@ static void bta_batch_scan_threshold_cb(tBTA_DM_BLE_REF_VALUE ref_value) btif_scan_track_cb.status = 0; btif_scan_track_cb.client_if = ref_value; - BTIF_TRACE_DEBUG2("%s - client_if:%d",__FUNCTION__, ref_value); + BTIF_TRACE_DEBUG("%s - client_if:%d",__FUNCTION__, ref_value); btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_BTH_SCAN_THR_EVT, (char*) &btif_scan_track_cb, sizeof(btif_gattc_cb_t), NULL); @@ -844,7 +891,7 @@ static void bta_batch_scan_reports_cb(tBTA_DM_BLE_REF_VALUE ref_value, UINT8 rep UINT8* p_rep_data, tBTA_STATUS status) { btgatt_batch_track_cb_t btif_scan_track_cb; - BTIF_TRACE_DEBUG5("%s - client_if:%d, %d, %d, %d",__FUNCTION__, ref_value, status, num_records, + BTIF_TRACE_DEBUG("%s - client_if:%d, %d, %d, %d",__FUNCTION__, ref_value, status, num_records, data_len); btif_scan_track_cb.status = status; @@ -920,14 +967,44 @@ static void btm_read_rssi_cb (tBTM_RSSI_RESULTS *p_result) (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); } -static void bta_scan_filter_cmpl_cb(tBTA_DM_BLE_PF_EVT event, - tBTA_DM_BLE_PF_COND_TYPE cfg_cond, tBTA_STATUS status) +static void bta_scan_filt_cfg_cb(tBTA_DM_BLE_PF_ACTION action, tBTA_DM_BLE_SCAN_COND_OP cfg_op, + tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_STATUS status, + tBTA_DM_BLE_REF_VALUE ref_value) { - btif_gattc_cb_t btif_cb; + btgatt_adv_filter_cb_t btif_cb; btif_cb.status = status; - btif_cb.action = event; - btif_transfer_context(btif_gattc_upstreams_evt, BTIF_GATTC_SCAN_FILTER_EVT, - (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); + btif_cb.action = action; + btif_cb.cond_op = cfg_op; + btif_cb.avbl_space = avbl_space; + btif_cb.client_if = ref_value; + btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_CFG_EVT, + (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL); +} + +static void bta_scan_filt_param_setup_cb(UINT8 action_type, + tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, + tBTA_DM_BLE_REF_VALUE ref_value, tBTA_STATUS status) +{ + btgatt_adv_filter_cb_t btif_cb; + + btif_cb.status = status; + btif_cb.action = action_type; + btif_cb.client_if = ref_value; + btif_cb.avbl_space = avbl_space; + btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_PARAM_EVT, + (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL); +} + +static void bta_scan_filt_status_cb(UINT8 action, tBTA_STATUS status, + tBTA_DM_BLE_REF_VALUE ref_value) +{ + btgatt_adv_filter_cb_t btif_cb; + + btif_cb.status = status; + btif_cb.action = action; + btif_cb.client_if = ref_value; + btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_SCAN_FLT_STATUS_EVT, + (char*) &btif_cb, sizeof(btgatt_adv_filter_cb_t), NULL); } static void btgattc_handle_event(uint16_t event, char* p_param) @@ -948,6 +1025,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param) btif_adv_data_t *p_adv_data = NULL; btgatt_multi_adv_inst_cb *p_inst_cb = NULL; btgatt_batch_track_cb_t *p_scan_track_cb = NULL; + btgatt_adv_filter_cb_t *p_adv_filt_cb = NULL; if(BTIF_GATTC_ADV_INSTANCE_ENABLE == event || BTIF_GATTC_ADV_INSTANCE_DISABLE == event || BTIF_GATTC_ADV_INSTANCE_UPDATE == event) @@ -963,10 +1041,14 @@ static void btgattc_handle_event(uint16_t event, char* p_param) || BTIF_GATTC_READ_BATCH_SCAN_REPORTS == event || BTIF_GATTC_DISABLE_BATCH_SCAN == event) p_scan_track_cb = (btgatt_batch_track_cb_t *) p_param; else + if(BTIF_GATTC_SCAN_FILTER_PARAM_SETUP == event || BTIF_GATTC_SCAN_FILTER_CONFIG == event + || BTIF_GATTC_SCAN_FILTER_CLEAR == event || BTIF_GATTC_SCAN_FILTER_ENABLE == event) + p_adv_filt_cb = (btgatt_adv_filter_cb_t *) p_param; + else p_cb = (btif_gattc_cb_t*)p_param; } - if (!p_cb && !p_adv_data && !p_inst_cb && !p_scan_track_cb) return; + if (!p_cb && !p_adv_data && !p_inst_cb && !p_scan_track_cb && !p_adv_filt_cb) return; ALOGD("%s: Event %d", __FUNCTION__, event); @@ -1236,29 +1318,38 @@ static void btgattc_handle_event(uint16_t event, char* p_param) BTM_ReadRSSI (p_cb->bd_addr.address, (tBTM_CMPL_CB *)btm_read_rssi_cb); break; - case BTIF_GATTC_SCAN_FILTER_ENABLE: - BTA_DmBleEnableFilterCondition(p_cb->action, NULL, bta_scan_filter_cmpl_cb); + case BTIF_GATTC_SCAN_FILTER_PARAM_SETUP: + { + if(NULL == p_adv_filt_cb) + return; + BTA_DmBleScanFilterSetup(p_adv_filt_cb->action, p_adv_filt_cb->filt_index, + &p_adv_filt_cb->adv_filt_param, NULL, bta_scan_filt_param_setup_cb, + p_adv_filt_cb->client_if); break; + } case BTIF_GATTC_SCAN_FILTER_CONFIG: { + if(NULL == p_adv_filt_cb) + return; tBTA_DM_BLE_PF_COND_PARAM cond; memset(&cond, 0, sizeof(cond)); - switch (p_cb->action) + switch (p_adv_filt_cb->filt_type) { case BTA_DM_BLE_PF_ADDR_FILTER: // 0 - bdcpy(cond.target_addr.bda, p_cb->bd_addr.address); - cond.target_addr.type = p_cb->addr_type; - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, &cond, - bta_scan_filter_cmpl_cb); + bdcpy(cond.target_addr.bda, p_adv_filt_cb->bd_addr.address); + cond.target_addr.type = p_adv_filt_cb->addr_type; + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); break; case BTA_DM_BLE_PF_SRVC_DATA: // 1 - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, NULL, - bta_scan_filter_cmpl_cb); + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + NULL, bta_scan_filt_cfg_cb, p_adv_filt_cb->client_if); break; case BTA_DM_BLE_PF_SRVC_UUID: // 2 @@ -1267,17 +1358,18 @@ static void btgattc_handle_event(uint16_t event, char* p_param) cond.srvc_uuid.p_target_addr = NULL; cond.srvc_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND; - btif_to_bta_uuid(&cond.srvc_uuid.uuid, &p_cb->uuid); + btif_to_bta_uuid(&cond.srvc_uuid.uuid, &p_adv_filt_cb->uuid); cond.srvc_uuid.p_uuid_mask = NULL; - if (p_cb->has_mask) + if (p_adv_filt_cb->has_mask) { - btif_to_bta_uuid_mask(&uuid_mask, &p_cb->uuid_mask); + btif_to_bta_uuid_mask(&uuid_mask, &p_adv_filt_cb->uuid_mask); cond.srvc_uuid.p_uuid_mask = &uuid_mask; } - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, &cond, - bta_scan_filter_cmpl_cb); + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); break; } @@ -1285,36 +1377,51 @@ static void btgattc_handle_event(uint16_t event, char* p_param) { cond.solicitate_uuid.p_target_addr = NULL; cond.solicitate_uuid.cond_logic = BTA_DM_BLE_PF_LOGIC_AND; - btif_to_bta_uuid(&cond.solicitate_uuid.uuid, &p_cb->uuid); - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, &cond, - bta_scan_filter_cmpl_cb); + btif_to_bta_uuid(&cond.solicitate_uuid.uuid, &p_adv_filt_cb->uuid); + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); break; } case BTA_DM_BLE_PF_LOCAL_NAME: // 4 { - cond.local_name.data_len = p_cb->len; - cond.local_name.p_data = p_cb->value; - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, &cond, - bta_scan_filter_cmpl_cb); + cond.local_name.data_len = p_adv_filt_cb->value_len; + cond.local_name.p_data = p_adv_filt_cb->value; + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); break; } case BTA_DM_BLE_PF_MANU_DATA: // 5 { - cond.manu_data.company_id = p_cb->conn_id; - cond.manu_data.company_id_mask = p_cb->mask; - cond.manu_data.data_len = p_cb->len; - cond.manu_data.p_pattern = p_cb->value; - cond.manu_data.p_pattern_mask = &p_cb->value[p_cb->len]; - BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_ADD, - p_cb->action, &cond, - bta_scan_filter_cmpl_cb); + cond.manu_data.company_id = p_adv_filt_cb->conn_id; + cond.manu_data.company_id_mask = p_adv_filt_cb->company_id_mask; + cond.manu_data.data_len = p_adv_filt_cb->value_len; + cond.manu_data.p_pattern = p_adv_filt_cb->value; + cond.manu_data.p_pattern_mask = p_adv_filt_cb->value_mask; + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); break; } + case BTA_DM_BLE_PF_SRVC_DATA_PATTERN: //6 + { + cond.srvc_data.data_len = p_adv_filt_cb->value_len; + cond.srvc_data.p_pattern = p_adv_filt_cb->value; + cond.srvc_data.p_pattern_mask = p_adv_filt_cb->value_mask; + BTA_DmBleCfgFilterCondition(p_adv_filt_cb->action, + p_adv_filt_cb->filt_type, p_adv_filt_cb->filt_index, + &cond, bta_scan_filt_cfg_cb, + p_adv_filt_cb->client_if); + break; + } + default: ALOGE("%s: Unknown filter type (%d)!", __FUNCTION__, p_cb->action); break; @@ -1324,8 +1431,19 @@ static void btgattc_handle_event(uint16_t event, char* p_param) case BTIF_GATTC_SCAN_FILTER_CLEAR: { + if(NULL == p_adv_filt_cb) + return; BTA_DmBleCfgFilterCondition(BTA_DM_BLE_SCAN_COND_CLEAR, BTA_DM_BLE_PF_TYPE_ALL, - NULL, bta_scan_filter_cmpl_cb); + 0, NULL, bta_scan_filt_cfg_cb, p_adv_filt_cb->client_if); + break; + } + + case BTIF_GATTC_SCAN_FILTER_ENABLE: + { + if(NULL == p_adv_filt_cb) + return; + BTA_DmEnableScanFilter(p_adv_filt_cb->action, bta_scan_filt_status_cb, + p_adv_filt_cb->client_if); break; } @@ -1777,50 +1895,97 @@ static bt_status_t btif_gattc_configure_mtu(int conn_id, int mtu) (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); } -static bt_status_t btif_gattc_scan_filter_enable(int enable ) +static bt_status_t btif_gattc_scan_filter_param_setup(int client_if, int action, + int filt_index, int feat_seln, int list_logic_type, int filt_logic_type, int rssi_high_thres, + int rssi_low_thres, int dely_mode, int found_timeout, int lost_timeout, int found_timeout_cnt) { CHECK_BTGATT_INIT(); - btif_gattc_cb_t btif_cb; - btif_cb.action = enable; - return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_ENABLE, - (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); + BTIF_TRACE_DEBUG("%s", __FUNCTION__); + btgatt_adv_filter_cb_t btif_filt_cb; + btif_filt_cb.action = action; + btif_filt_cb.client_if = client_if; + btif_filt_cb.filt_index = filt_index; + btif_filt_cb.adv_filt_param.feat_seln = feat_seln; + btif_filt_cb.adv_filt_param.list_logic_type = list_logic_type; + btif_filt_cb.adv_filt_param.filt_logic_type = filt_logic_type; + btif_filt_cb.adv_filt_param.rssi_high_thres = rssi_high_thres; + btif_filt_cb.adv_filt_param.rssi_low_thres = rssi_low_thres; + btif_filt_cb.adv_filt_param.dely_mode = dely_mode; + btif_filt_cb.adv_filt_param.found_timeout = found_timeout; + btif_filt_cb.adv_filt_param.lost_timeout = lost_timeout; + btif_filt_cb.adv_filt_param.found_timeout_cnt = found_timeout_cnt; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_PARAM_SETUP, + (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL); } -static bt_status_t btif_gattc_scan_filter_add(int type, int company_id, int company_mask, - int len, const bt_uuid_t *p_uuid, const bt_uuid_t *p_uuid_mask, - const bt_bdaddr_t *bd_addr, char addr_type, const char* p_value) +static bt_status_t btif_gattc_scan_filter_add_remove(int client_if, int action, + int filt_type, int filt_index, int company_id, + int company_id_mask, const bt_uuid_t *p_uuid, + const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr, + char addr_type, int data_len, char* p_data, int mask_len, + char* p_mask) { CHECK_BTGATT_INIT(); - btif_gattc_cb_t btif_cb; - - if (len > (BTGATT_MAX_ATTR_LEN / 2)) - len = BTGATT_MAX_ATTR_LEN / 2; - - btif_cb.action = type; - btif_cb.len = len; - btif_cb.conn_id = company_id; - btif_cb.mask = company_mask ? company_mask : 0xFFFF; + btgatt_adv_filter_cb_t btif_filt_cb; + BTIF_TRACE_DEBUG("%s, %d, %d", __FUNCTION__, action, filt_type); + + /* If data is passed, both mask and data have to be the same length */ + if(data_len != mask_len && NULL != p_data && NULL != p_mask) + return BT_STATUS_PARM_INVALID; + + btif_filt_cb.client_if = client_if; + btif_filt_cb.action = action; + btif_filt_cb.filt_index = filt_index; + btif_filt_cb.filt_type = filt_type; + btif_filt_cb.conn_id = company_id; + btif_filt_cb.company_id_mask = company_id_mask ? company_id_mask : 0xFFFF; if(bd_addr) - bdcpy(btif_cb.bd_addr.address, bd_addr->address); - btif_cb.addr_type = addr_type; - btif_cb.has_mask = (p_uuid_mask != NULL); + bdcpy(btif_filt_cb.bd_addr.address, bd_addr->address); + + btif_filt_cb.addr_type = addr_type; + btif_filt_cb.has_mask = (p_uuid_mask != NULL); if (p_uuid != NULL) - memcpy(&btif_cb.uuid, p_uuid, sizeof(bt_uuid_t)); + memcpy(&btif_filt_cb.uuid, p_uuid, sizeof(bt_uuid_t)); if (p_uuid_mask != NULL) - memcpy(&btif_cb.uuid_mask, p_uuid_mask, sizeof(bt_uuid_t)); - if (p_value != NULL && len != 0) - memcpy(btif_cb.value, p_value, len * 2 /* PATTERN CONTAINS MASK */); + memcpy(&btif_filt_cb.uuid_mask, p_uuid_mask, sizeof(bt_uuid_t)); + if (p_data != NULL && data_len != 0) + { + memcpy(btif_filt_cb.value, p_data, data_len); + btif_filt_cb.value_len = data_len; + memcpy(btif_filt_cb.value_mask, p_mask, mask_len); + btif_filt_cb.value_mask_len = mask_len; + } return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_CONFIG, - (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); + (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL); } -static bt_status_t btif_gattc_scan_filter_clear() +static bt_status_t btif_gattc_scan_filter_clear(int client_if, int filt_index) { CHECK_BTGATT_INIT(); - btif_gattc_cb_t btif_cb; - return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_CLEAR, - (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL); + BTIF_TRACE_DEBUG("%s, %d", __FUNCTION__, filt_index); + + btgatt_adv_filter_cb_t btif_filt_cb; + btif_filt_cb.client_if = client_if; + btif_filt_cb.filt_index = filt_index; + btif_filt_cb.action = BTA_DM_BLE_SCAN_COND_CLEAR; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_CONFIG, + (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL); +} + +static bt_status_t btif_gattc_scan_filter_enable(int client_if, bool enable) +{ + int action = 0; + CHECK_BTGATT_INIT(); + BTIF_TRACE_DEBUG("%s, %d", __FUNCTION__, enable); + + btgatt_adv_filter_cb_t btif_filt_cb; + btif_filt_cb.client_if = client_if; + if(true == enable) + action = 1; + btif_filt_cb.action = action; + return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SCAN_FILTER_ENABLE, + (char*) &btif_filt_cb, sizeof(btgatt_adv_filter_cb_t), NULL); } static bt_status_t btif_gattc_set_scan_parameters(int scan_interval, int scan_window) @@ -1997,9 +2162,10 @@ const btgatt_client_interface_t btgattClientInterface = { btif_gattc_reg_for_notification, btif_gattc_dereg_for_notification, btif_gattc_read_remote_rssi, - btif_gattc_scan_filter_enable, - btif_gattc_scan_filter_add, + btif_gattc_scan_filter_param_setup, + btif_gattc_scan_filter_add_remove, btif_gattc_scan_filter_clear, + btif_gattc_scan_filter_enable, btif_gattc_get_device_type, btif_gattc_set_adv_data, btif_gattc_configure_mtu, diff --git a/stack/Android.mk b/stack/Android.mk index 9afd69c47..12c08c950 100644 --- a/stack/Android.mk +++ b/stack/Android.mk @@ -67,6 +67,7 @@ LOCAL_SRC_FILES:= \ ./btm/btm_main.c \ ./btm/btm_dev.c \ ./btm/btm_ble_gap.c \ + ./btm/btm_ble_adv_filter.c \ ./btm/btm_ble_multi_adv.c \ ./btm/btm_ble_batchscan.c \ ./btm/btm_acl.c \ diff --git a/stack/btm/btm_ble_adv_filter.c b/stack/btm/btm_ble_adv_filter.c new file mode 100644 index 000000000..5c0fb8b98 --- /dev/null +++ b/stack/btm/btm_ble_adv_filter.c @@ -0,0 +1,1179 @@ +/****************************************************************************** + * + * Copyright (C) 2014 Broadcom Corporation + * + * 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 +#include "bt_target.h" + +#if (BLE_INCLUDED == TRUE) +#if BLE_BATCH_SCAN_INCLUDED == TRUE +#include "bt_types.h" +#include "hcimsgs.h" +#include "btu.h" +#include "btm_int.h" +#include "bt_utils.h" +#include "hcidefs.h" +#include "btm_ble_api.h" +#include "vendor_ble.h" + +#define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3 +#define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13 + +#define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x)) + + +tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb; +tBTM_BLE_VSC_CB cmn_ble_vsc_cb; +static const BD_ADDR na_bda= {0}; + +static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, + UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available); + +#define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y) +#define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4) +#define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f) +#define BTM_BLE_INVALID_COUNTER 0xff + + +/* length of each multi adv sub command */ +#define BTM_BLE_ADV_FILTER_ENB_LEN 3 + +/* length of each batch scan command */ +#define BTM_BLE_ADV_FILTER_CLEAR_LEN 3 +#define BTM_BLE_ADV_FILTER_LEN 2 + +#define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0 +#define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F + + +/******************************************************************************* +** +** Function btm_ble_advfilt_enq_op_q +** +** Description enqueue an adv filter operation in q to check command complete +** status +** +** Returns void +** +*******************************************************************************/ +void btm_ble_advfilt_enq_op_q(UINT8 action, UINT8 cond_type, tBTM_BLE_REF_VALUE ref) +{ + btm_ble_adv_filt_cb.op_q.action_condtype[btm_ble_adv_filt_cb.op_q.next_idx] = + (action |(cond_type << 4)); + btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.next_idx] = ref; + BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_condtype:%d, action:%d, Cond_type:%d", + btm_ble_adv_filt_cb.op_q.action_condtype[btm_ble_adv_filt_cb.op_q.next_idx], action, cond_type); + btm_ble_adv_filt_cb.op_q.next_idx = (btm_ble_adv_filt_cb.op_q.next_idx + 1) + % BTM_BLE_PF_TYPE_MAX; +} + +/******************************************************************************* +** +** Function btm_ble_advfilt_deq_op_q +** +** Description dequeue an adv filter operation from q when command complete +** is received +** +** Returns void +** +*******************************************************************************/ +void btm_ble_advfilt_deq_op_q(UINT8 *p_action,UINT8 *p_cond_type, tBTM_BLE_REF_VALUE *p_ref) +{ + *p_cond_type = + (btm_ble_adv_filt_cb.op_q.action_condtype[btm_ble_adv_filt_cb.op_q.pending_idx] >> 4); + *p_action = + (btm_ble_adv_filt_cb.op_q.action_condtype[btm_ble_adv_filt_cb.op_q.pending_idx] + & BTM_BLE_ADV_FILT_SUBCODE_MASK); + *p_ref = btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.pending_idx]; + btm_ble_adv_filt_cb.op_q.pending_idx = (btm_ble_adv_filt_cb.op_q.pending_idx + 1) + % BTM_BLE_PF_TYPE_MAX; +} + +/******************************************************************************* +** +** Function btm_ble_ocf_to_condtype +** +** Description Convert OCF to cond type +** +** Returns Returns ocf value +** +*******************************************************************************/ +UINT8 btm_ble_ocf_to_condtype(UINT8 ocf) +{ + UINT8 cond_type = 0; + + switch(ocf) + { + case BTM_BLE_META_PF_FEAT_SEL: + cond_type = BTM_BLE_META_PF_FEAT_SEL; + break; + case BTM_BLE_META_PF_ADDR: + cond_type = BTM_BLE_PF_ADDR_FILTER; + break; + case BTM_BLE_META_PF_UUID: + cond_type = BTM_BLE_PF_SRVC_UUID; + break; + case BTM_BLE_META_PF_SOL_UUID: + cond_type = BTM_BLE_PF_SRVC_SOL_UUID; + break; + case BTM_BLE_META_PF_LOCAL_NAME: + cond_type = BTM_BLE_PF_LOCAL_NAME; + break; + case BTM_BLE_META_PF_MANU_DATA: + cond_type = BTM_BLE_PF_MANU_DATA; + break; + case BTM_BLE_META_PF_SRVC_DATA: + cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN; + break; + case BTM_BLE_META_PF_ALL: + cond_type = BTM_BLE_PF_TYPE_ALL; + break; + default: + cond_type = BTM_BLE_PF_TYPE_MAX; + break; + } + return cond_type; +} + +/******************************************************************************* +** +** Function btm_ble_scan_pf_cmpl_cback +** +** Description the BTM BLE customer feature VSC complete callback for ADV PF filtering +** +** Returns pointer to the counter if found; NULL otherwise. +** +*******************************************************************************/ +void btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params) +{ + UINT8 status = 0; + UINT8 *p = p_params->p_param_buf, op_subcode = 0, action = 0xff; + UINT16 evt_len = p_params->param_len; + UINT8 cond_type = BTM_BLE_PF_TYPE_MAX; + UINT8 num_avail = 0; + tBTM_BLE_REF_VALUE ref_value = 0; + + if (evt_len < 3 || evt_len > 4) + { + BTM_TRACE_ERROR("cannot interpret APCF callback status = %d, length = %d", status, evt_len); + btm_ble_advfilt_deq_op_q(&action, &cond_type, &ref_value); + return; + } + + STREAM_TO_UINT8(status, p); + + btm_ble_advfilt_deq_op_q(&action, &cond_type, &ref_value); + + STREAM_TO_UINT8(op_subcode, p); + STREAM_TO_UINT8(action, p); + + /* Ignore the event, if it is not the same one expected */ + if(3 == evt_len) + { + if(cond_type != op_subcode) + { + BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback-Incorrect opcode :%d, %d, %d, %d, %d, %d", + cond_type, op_subcode, action, evt_len, ref_value, status); + return; + } + else + { + btm_ble_adv_filt_cb.p_filt_stat_cback(action, status, ref_value); + BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback enabled/disabled, %d, %d, %d, %d", + cond_type, action, status, ref_value); + return; + } + } + + if (4 == evt_len && cond_type != btm_ble_ocf_to_condtype(op_subcode)) + { + BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback-Incorrect opcode: %d, %d, %d, %d, %d", + cond_type, op_subcode, action, status, ref_value); + return; + } + + STREAM_TO_UINT8(num_avail, p); + switch (op_subcode) + { + case BTM_BLE_META_PF_ADDR: + case BTM_BLE_META_PF_UUID: + case BTM_BLE_META_PF_SOL_UUID: + case BTM_BLE_META_PF_LOCAL_NAME: + case BTM_BLE_META_PF_MANU_DATA: + case BTM_BLE_META_PF_SRVC_DATA: + BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback: %d, %d, %d, %d, %d", cond_type, action, + status, ref_value, num_avail); + + if (HCI_SUCCESS == status) + { + if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda, BD_ADDR_LEN) == 0) + btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail); + else + btm_ble_cs_update_pf_counter(action, cond_type, + &btm_ble_adv_filt_cb.cur_filter_target, num_avail); + } + + /* send ADV PF operation complete */ + btm_ble_adv_filt_cb.op_type = 0; + btm_ble_adv_filt_cb.p_scan_cfg_cback(action, cond_type, num_avail, status, ref_value); + break; + + case BTM_BLE_META_PF_FEAT_SEL: + if(NULL != btm_ble_adv_filt_cb.p_filt_param_cback) + btm_ble_adv_filt_cb.p_filt_param_cback(action, num_avail, ref_value, status); + BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback-Feat sel event: %d, %d, %d, %d, %d", + cond_type, action, status, ref_value, num_avail); + break; + + default: + BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback: unknown operation: %d", op_subcode); + break; + } +} + +/******************************************************************************* +** +** Function btm_ble_find_addr_filter_counter +** +** Description find the per bd address ADV payload filter counter by BD_ADDR. +** +** Returns pointer to the counter if found; NULL otherwise. +** +*******************************************************************************/ +tBTM_BLE_PF_COUNT* btm_ble_find_addr_filter_counter(tBLE_BD_ADDR *p_le_bda) +{ + UINT8 i; + tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.addr_filter_count[1]; + + if (p_le_bda == NULL) + return &btm_ble_adv_filt_cb.addr_filter_count[0]; + + for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++) + { + if (p_addr_filter->in_use && + memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) + { + return p_addr_filter; + } + } + return NULL; +} + +/******************************************************************************* +** +** Function btm_ble_alloc_addr_filter_counter +** +** Description allocate the per device adv payload filter counter. +** +** Returns pointer to the counter if allocation succeed; NULL otherwise. +** +*******************************************************************************/ +tBTM_BLE_PF_COUNT * btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr) +{ + UINT8 i; + tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.addr_filter_count[1]; + + for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++) + { + if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) + { + memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN); + p_addr_filter->in_use = TRUE; + return p_addr_filter; + } + } + return NULL; +} +/******************************************************************************* +** +** Function btm_ble_dealloc_addr_filter_counter +** +** Description de-allocate the per device adv payload filter counter. +** +** Returns TRUE if deallocation succeed; FALSE otherwise. +** +*******************************************************************************/ +BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type) +{ + UINT8 i; + tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.addr_filter_count[1]; + BOOLEAN found = FALSE; + + if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr) + memset(&btm_ble_adv_filt_cb.addr_filter_count[0], 0, sizeof(tBTM_BLE_PF_COUNT)); + + for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++) + { + if ((p_addr_filter->in_use) && (NULL == p_bd_addr || + (NULL != p_bd_addr && + memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) + { + found = TRUE; + memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT)); + + if (NULL != p_bd_addr) break; + } + } + return found; +} + +/******************************************************************************* +** +** Function btm_ble_update_pf_local_name +** +** Description this function update(add,delete or clear) the adv lcoal name filtering condition. +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond) +{ + tBTM_BLE_PF_LOCAL_NAME_COND *p_local_name = (p_cond == NULL) ? NULL : &p_cond->local_name; + UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH], + *p = param, + len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + + memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH); + + UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME); + UINT8_TO_STREAM(p, action); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + if (BTM_BLE_SCAN_COND_ADD == action || + BTM_BLE_SCAN_COND_DELETE == action) + { + if (NULL == p_local_name) + return st; + + if (p_local_name->data_len > BTM_BLE_PF_STR_LEN_MAX) + p_local_name->data_len = BTM_BLE_PF_STR_LEN_MAX; + + ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len); + len += p_local_name->data_len; + } + + /* send local name filter */ + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + len, + param, + btm_ble_scan_pf_cmpl_cback)) + != BTM_NO_RESOURCES) + { + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); + } + else + { + BTM_TRACE_ERROR("Local Name PF filter update failed"); + } + + return st; +} + + +/******************************************************************************* +** +** Function btm_ble_update_srvc_data_change +** +** Description this function update(add/remove) service data change filter. +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond) +{ + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL; + UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1; + + if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail) + != BTM_BLE_INVALID_COUNTER) + st = BTM_SUCCESS; + + return st; +} + +/******************************************************************************* +** +** Function btm_ble_update_pf_manu_data +** +** Description this function update(add,delete or clear) the adv manufacturer +** data filtering condition. +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_data, + tBTM_BLE_PF_COND_TYPE cond_type) +{ + tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data; + tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data; + + UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH], + *p = param, + len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + + if(NULL!= p_data && 0 == p_data->manu_data.data_len && 0 == p_data->srvc_data.data_len) + return st; + + memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + + BTM_BLE_ADV_FILT_META_HDR_LENGTH); + + if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) + { + UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA); + } + else + { + UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA); + } + + UINT8_TO_STREAM(p, action); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + if (BTM_BLE_SCAN_COND_ADD == action || + BTM_BLE_SCAN_COND_DELETE == action) + { + if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) + { + if (NULL == p_srvc_data) + return st; + if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) + p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); + + if(p_srvc_data->data_len > 0) + { + ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len); + len += (p_srvc_data->data_len); + ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len); + } + + len += (p_srvc_data->data_len); + BTM_TRACE_DEBUG("Service data length: %d", len); + } + else + { + if (NULL == p_manu_data) + return st; + if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) + p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); + + UINT16_TO_STREAM(p, p_manu_data->company_id); + + if(p_manu_data->data_len > 0) + ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len); + len += (p_manu_data->data_len + 2); + + if (p_manu_data->company_id_mask != 0) + { + UINT16_TO_STREAM (p, p_manu_data->company_id_mask); + } + else + { + memset(p, 0xff, 2); + p += 2; + } + + if(p_manu_data->data_len > 0) + ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len); + len += (p_manu_data->data_len + 2); + + BTM_TRACE_DEBUG("Manuf data length: %d", len); + } + } + + /* send manufacturer*/ + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + len, + param, + btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) + { + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); + } + else + { + BTM_TRACE_ERROR("manufacturer data PF filter update failed"); + } + + return st; +} + +/******************************************************************************* +** +** Function btm_ble_cs_update_pf_counter +** +** Description this function is to update the adv data payload filter counter +** +** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if +** counter update failed. +** +*******************************************************************************/ +UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, + UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, + UINT8 num_available) +{ + tBTM_BLE_PF_COUNT *p_addr_filter = NULL; + UINT8 *p_counter = NULL; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + + if (cond_type > BTM_BLE_PF_TYPE_ALL) + { + BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type); + return BTM_BLE_INVALID_COUNTER; + } + + /* for these three types of filter, always generic */ + if (BTM_BLE_PF_ADDR_FILTER == cond_type || + BTM_BLE_PF_MANU_DATA == cond_type || + BTM_BLE_PF_LOCAL_NAME == cond_type || + BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) + p_bd_addr = NULL; + + if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL && + BTM_BLE_SCAN_COND_ADD == action) + { + p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda); + } + + if (NULL != p_addr_filter) + { + /* all filter just cleared */ + if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) || + /* or bd address filter been deleted */ + (BTM_BLE_PF_ADDR_FILTER == cond_type && + (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action))) + { + btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type); + } + /* if not feature selection, update new addition/reduction of the filter counter */ + else if (cond_type != BTM_BLE_PF_TYPE_ALL) + { + p_counter = p_addr_filter->pf_counter; + if(num_available > 0) + p_counter[cond_type] += 1; + + /* update corresponding feature mask */ + if (num_available > 0) + p_addr_filter->feat_mask |= (BTM_BLE_PF_BIT_TO_MASK(cond_type)); + else + p_addr_filter->feat_mask &= ~(BTM_BLE_PF_BIT_TO_MASK(cond_type)); + + BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d, feat_mask = %d", + p_counter[cond_type], cmn_ble_vsc_cb.max_filter, num_available, + p_addr_filter->feat_mask); + return p_counter[cond_type]; + } + } + else + { + BTM_TRACE_ERROR("no matching filter counter found"); + } + /* no matching filter located and updated */ + return BTM_BLE_INVALID_COUNTER; +} + + +/******************************************************************************* +** +** Function btm_ble_update_addr_filter +** +** Description this function update(add,delete or clear) the address filter of adv. +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond) +{ + UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], + * p= param; + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr; + + memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); + + UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); + UINT8_TO_STREAM(p, action); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + if (BTM_BLE_SCAN_COND_ADD == action || + BTM_BLE_SCAN_COND_DELETE == action) + { + if (NULL == p_addr) + return st; + + BDADDR_TO_STREAM(p, p_addr->bda); + UINT8_TO_STREAM(p, p_addr->type); + } + /* send address filter */ + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), + param, + btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) + { + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); + } + else + { + BTM_TRACE_ERROR("Broadcaster Address Filter Update failed"); + } + return st; +} + +/******************************************************************************* +** +** Function btm_ble_update_uuid_filter +** +** Description this function update(add,delete or clear) service UUID filter. +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_TYPE filter_type, + tBTM_BLE_PF_COND_PARAM *p_cond) +{ + UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], + * p= param, + len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + tBTM_BLE_PF_UUID_COND *p_uuid_cond; + UINT8 evt_type; + + memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); + + if (BTM_BLE_PF_SRVC_UUID == filter_type) + { + evt_type = BTM_BLE_META_PF_UUID; + p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL; + } + else + { + evt_type = BTM_BLE_META_PF_SOL_UUID; + p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL; + } + + if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR) + { + BTM_TRACE_ERROR("Illegal param for add/delete UUID filter"); + return st; + } + + /* need to add address fitler first, if adding per bda UUID filter without address filter */ + if (BTM_BLE_SCAN_COND_ADD == action && + p_uuid_cond->p_target_addr && + btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL) + { + UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); + UINT8_TO_STREAM(p, action); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); + UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); + + /* send address filter */ + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), + param, + btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES) + { + BTM_TRACE_ERROR("Update Address filter into controller failed."); + return st; + } + BTM_TRACE_DEBUG("Updated Address filter"); + } + + p = param; + UINT8_TO_STREAM(p, evt_type); + UINT8_TO_STREAM(p, action); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + if (BTM_BLE_SCAN_COND_ADD == action || + BTM_BLE_SCAN_COND_DELETE == action) + { + if (p_uuid_cond->uuid.len == LEN_UUID_16) + { + UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); + len += LEN_UUID_16; + } + else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ + { + UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32); + len += LEN_UUID_32; + } + else if (p_uuid_cond->uuid.len == LEN_UUID_128) + { + ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128); + len += LEN_UUID_128; + } + else + { + BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len); + return BTM_ILLEGAL_VALUE; + } + + if (NULL != p_uuid_cond->p_uuid_mask) + { + if (p_uuid_cond->uuid.len == LEN_UUID_16) + { + UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask); + len += LEN_UUID_16; + } + else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ + { + UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask); + len += LEN_UUID_32; + } + else if (p_uuid_cond->uuid.len == LEN_UUID_128) + { + ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128); + len += LEN_UUID_128; + } + } + else + { + memset(p, 0xff, p_uuid_cond->uuid.len); + len += p_uuid_cond->uuid.len; + } + } + + BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type, + p_uuid_cond->uuid.len, len); + /* send UUID filter update */ + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + len, + param, + btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) + { + if (p_uuid_cond && p_uuid_cond->p_target_addr) + memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr, + sizeof(tBLE_BD_ADDR)); + else + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); + } + else + { + BTM_TRACE_ERROR("UUID filter udpating failed"); + } + + return st; +} + + +/******************************************************************************* +** +** Function btm_ble_clear_scan_pf_filter +** +** Description clear all adv payload filter by de-select all the adv pf feature bits +** +** +** Returns BTM_SUCCESS if sucessful, +** BTM_ILLEGAL_VALUE if paramter is not valid. +** +*******************************************************************************/ +tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond, + tBTM_BLE_REF_VALUE ref_value) +{ + tBLE_BD_ADDR *p_target = (p_cond == NULL)? NULL : &p_cond->target_addr; + tBTM_BLE_PF_COUNT *p_bda_filter; + tBTM_STATUS st = BTM_WRONG_MODE; + UINT8 param[20], *p; + + if (BTM_BLE_SCAN_COND_CLEAR != action) + { + BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action); + return BTM_ILLEGAL_VALUE; + } + + p = param; + memset(param, 0, 20); + + p_bda_filter = btm_ble_find_addr_filter_counter(p_target); + + if (NULL == p_bda_filter || + /* not a generic filter, and feature selection is empty */ + (p_target != NULL && p_bda_filter && 0 == p_bda_filter->feat_mask)) + { + BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!"); + return st; + } + + /* clear the general filter entry */ + if (NULL == p_target) + { + /* clear manufactuer data filter */ + btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, + BTM_BLE_PF_MANU_DATA); + /* clear local name filter */ + btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); + /* update the counter for service data */ + btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); + /* clear UUID filter */ + btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, + BTM_BLE_PF_SRVC_UUID, NULL); + btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, + BTM_BLE_PF_SRVC_SOL_UUID, NULL); + /* clear service data filter */ + btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, + BTM_BLE_PF_SRVC_DATA_PATTERN); + } + + /* select feature based on control block settings */ + UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); + UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + /* set PCF selection */ + UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE); + /* set logic condition as OR as default */ + UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR); + + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), + param, + btm_ble_scan_pf_cmpl_cback)) + != BTM_NO_RESOURCES) + { + if (p_bda_filter) + p_bda_filter->feat_mask = BTM_BLE_PF_SELECT_NONE; + + if (p_target) + memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR)); + else + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); + } + + btm_ble_advfilt_enq_op_q(action, BTM_BLE_PF_TYPE_MAX, ref_value); + return st; +} + +/******************************************************************************* +** +** Function BTM_BleAdvFilterParamSetup +** +** Description This function is called to setup the adv data payload filter +** condition. +** +** Parameters action - Type of action to be performed +** filt_index - Filter index +** p_filt_params - Filter parameters +** p_target - Target device +** p_cmpl_back - Callback pointer +** ref_value - reference value +** +** Returns void +** +*******************************************************************************/ +tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_FILT_PARAMS *p_filt_params, + tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback, + tBTM_BLE_REF_VALUE ref_value) +{ + UINT8 param[20], *p; + tBTM_STATUS st = BTM_WRONG_MODE; + tBTM_BLE_PF_COUNT *p_bda_filter = NULL; + UINT8 len =0; + + p = param; + memset(param, 0, 20); + BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup"); + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + if (0 == cmn_ble_vsc_cb.max_filter) + { + st = BTM_MODE_UNSUPPORTED; + return st; + } + + btm_ble_adv_filt_cb.p_filt_param_cback = p_cmpl_cback; + + if (BTM_BLE_SCAN_COND_ADD == action) + { + p_bda_filter = btm_ble_find_addr_filter_counter(p_target); + if (NULL == p_bda_filter) + { + BTM_TRACE_ERROR("BD Address not found!"); + return st; + } + + BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_bda_filter->feat_mask); + /* select feature based on control block settings */ + UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); + UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); + + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + /* set PCF selection */ + UINT16_TO_STREAM(p, p_filt_params->feat_seln); + /* set logic type */ + UINT16_TO_STREAM(p, p_filt_params->logic_type); + /* set logic condition */ + UINT8_TO_STREAM(p, p_filt_params->filt_logic_type); + /* set RSSI high threshold */ + UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres); + /* set delivery mode */ + UINT8_TO_STREAM(p, p_filt_params->dely_mode); + + if(0x01 == p_filt_params->dely_mode) + { + /* set onfound timeout */ + UINT16_TO_STREAM(p, p_filt_params->found_timeout); + /* set onfound timeout count*/ + UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt); + /* set RSSI low threshold */ + UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres); + /* set onlost timeout */ + UINT16_TO_STREAM(p, p_filt_params->lost_timeout); + } + + len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN; + + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)len, + param, + btm_ble_scan_pf_cmpl_cback)) + == BTM_NO_RESOURCES) + { + return st; + } + btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, ref_value); + } + else + if(BTM_BLE_SCAN_COND_DELETE == action) + { + /* select feature based on control block settings */ + UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); + UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE); + /* Filter index */ + UINT8_TO_STREAM(p, filt_index); + + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH), + param, + btm_ble_scan_pf_cmpl_cback)) + == BTM_NO_RESOURCES) + { + return st; + } + btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, ref_value); + } + else + if(BTM_BLE_SCAN_COND_CLEAR == action) + { + /* Deallocate all filters here */ + btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL); + + /* select feature based on control block settings */ + UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); + UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); + + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH-1), + param, + btm_ble_scan_pf_cmpl_cback)) + == BTM_NO_RESOURCES) + { + return st; + } + btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, ref_value); + } + + return st; +} + +/******************************************************************************* +** +** Function BTM_BleEnableDisableFilterFeature +** +** Description This function is called to enable / disable the APCF feature +** +** Parameters enable the generic scan condition. +** enable: enable or disable the filter condition +** p_stat_cback - Status callback pointer +** ref_value - Ref value +** Returns void +** +*******************************************************************************/ +tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, + tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, + tBTM_BLE_REF_VALUE ref_value) +{ + UINT8 param[20], *p; + tBTM_STATUS st = BTM_WRONG_MODE; + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + if (0 == cmn_ble_vsc_cb.max_filter) + { + st = BTM_MODE_UNSUPPORTED; + return st; + } + + p = param; + memset(param, 0, 20); + + /* enable the content filter in controller */ + p = param; + UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE); + /* enable adv data payload filtering */ + UINT8_TO_STREAM(p, enable); + + if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, + BTM_BLE_PCF_ENABLE_LEN, param, + btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED) + { + btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback; + btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, ref_value); + } + return st; +} + +/******************************************************************************* +** +** Function BTM_BleCfgFilterCondition +** +** Description This function is called to configure the adv data payload filter +** condition. +** +** Parameters action: to read/write/clear +** cond_type: filter condition type. +** filt_index - Filter index +** p_cond: filter condition parameter +** p_cmpl_cback - Config callback pointer +** ref_value - Reference value +** +** Returns void +** +*******************************************************************************/ +tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_COND_TYPE cond_type, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond, + tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, + tBTM_BLE_REF_VALUE ref_value) +{ + tBTM_STATUS st = BTM_ILLEGAL_VALUE; + BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action, + cond_type, filt_index); + + BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); + if (0 == cmn_ble_vsc_cb.max_filter) + { + st = BTM_MODE_UNSUPPORTED; + return st; + } + + switch (cond_type) + { + /* write service data filter */ + case BTM_BLE_PF_SRVC_DATA_PATTERN: + /* write manufacturer data filter */ + case BTM_BLE_PF_MANU_DATA: + st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type); + break; + + /* write local name filter */ + case BTM_BLE_PF_LOCAL_NAME: + st = btm_ble_update_pf_local_name(action, filt_index, p_cond); + break; + + /* filter on advertiser address */ + case BTM_BLE_PF_ADDR_FILTER: + st = btm_ble_update_addr_filter(action, filt_index, p_cond); + break; + + /* filter on service/solicitated UUID */ + case BTM_BLE_PF_SRVC_UUID: + case BTM_BLE_PF_SRVC_SOL_UUID: + st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond); + break; + + case BTM_BLE_PF_SRVC_DATA: + st = btm_ble_update_srvc_data_change(action, filt_index, p_cond); + break; + + case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */ + st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, ref_value); + break; + + default: + BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type); + break; + } + + if (BTM_CMD_STARTED == st) + btm_ble_adv_filt_cb.p_scan_cfg_cback = p_cmpl_cback; + if(BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL) + btm_ble_advfilt_enq_op_q(action, cond_type, ref_value); + + return st; +} + +/******************************************************************************* +** +** Function btm_ble_adv_filter_init +** +** Description This function initializes the adv filter control block +** +** Parameters +** +** Returns status +** +*******************************************************************************/ +void btm_ble_adv_filter_init(void) +{ + memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB)); + if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) + return; +} + +#endif +#endif diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index 7aedb29f6..7e3771a75 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -484,7 +484,7 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_ *******************************************************************************/ BTM_API extern void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB *p_cmn_vsc_cb) { - BTM_TRACE_DEBUG("btm_ble_vendor_capability_init"); + BTM_TRACE_DEBUG("BTM_BleGetVendorCapabilities"); if(NULL != p_cmn_vsc_cb) { @@ -2921,6 +2921,9 @@ void btm_ble_init (void) btm_ble_batchscan_init(); #endif +#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE + btm_ble_adv_filter_init(); +#endif } /******************************************************************************* diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h index 76dc9e38b..ac36a770e 100644 --- a/stack/btm/btm_ble_int.h +++ b/stack/btm/btm_ble_int.h @@ -398,6 +398,7 @@ extern void btm_ble_multi_adv_init(void); extern void btm_ble_batchscan_init(void); extern void btm_ble_multi_adv_reenable(UINT8 inst_id); extern void btm_ble_multi_adv_enb_privacy(BOOLEAN enable); +extern void btm_ble_adv_filter_init(void); extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state); extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state); diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h index e327b0040..ed2334482 100644 --- a/stack/include/btm_ble_api.h +++ b/stack/include/btm_ble_api.h @@ -413,7 +413,7 @@ typedef struct typedef void (tBTM_BLE_SCAN_THRESHOLD_CBACK)(tBTM_BLE_REF_VALUE ref_value); typedef void (tBTM_BLE_SCAN_REP_CBACK)(tBTM_BLE_REF_VALUE ref_value, UINT8 report_format, UINT8 num_records, UINT16 total_len, - UINT8* p_rep_data, UINT8 status); + UINT8* p_rep_data, UINT8 status); typedef void (tBTM_BLE_SCAN_SETUP_CBACK)(UINT8 evt, tBTM_BLE_REF_VALUE ref_value, UINT8 status); #ifndef BTM_BLE_BATCH_SCAN_MAX @@ -449,6 +449,203 @@ typedef struct tBTM_BLE_REF_VALUE ref_value; }tBTM_BLE_BATCH_SCAN_CB; +/* filter selection bit index */ +#define BTM_BLE_PF_ADDR_FILTER 0 +#define BTM_BLE_PF_SRVC_DATA 1 +#define BTM_BLE_PF_SRVC_UUID 2 +#define BTM_BLE_PF_SRVC_SOL_UUID 3 +#define BTM_BLE_PF_LOCAL_NAME 4 +#define BTM_BLE_PF_MANU_DATA 5 +#define BTM_BLE_PF_SRVC_DATA_PATTERN 6 +#define BTM_BLE_PF_TYPE_ALL 7 /* when passed in payload filter type all, only clear action is applicable */ +#define BTM_BLE_PF_TYPE_MAX 8 + +/* max number of filter spot for different filter type */ +#ifndef BTM_BLE_MAX_UUID_FILTER +#define BTM_BLE_MAX_UUID_FILTER 8 +#endif +#ifndef BTM_BLE_MAX_ADDR_FILTER +#define BTM_BLE_MAX_ADDR_FILTER 8 +#endif +#ifndef BTM_BLE_PF_STR_COND_MAX +#define BTM_BLE_PF_STR_COND_MAX 4 /* apply to manu data , or local name */ +#endif +#ifndef BTM_BLE_PF_STR_LEN_MAX +#define BTM_BLE_PF_STR_LEN_MAX 29 /* match for first 29 bytes */ +#endif + +typedef UINT8 tBTM_BLE_PF_COND_TYPE; + +#define BTM_BLE_PF_LOGIC_OR 0 +#define BTM_BLE_PF_LOGIC_AND 1 +typedef UINT8 tBTM_BLE_PF_LOGIC_TYPE; + +#define BTM_BLE_PF_ENABLE 1 +#define BTM_BLE_PF_CONFIG 2 +typedef UINT8 tBTM_BLE_PF_ACTION; + +typedef UINT8 tBTM_BLE_PF_FILT_INDEX; + +typedef UINT8 tBTM_BLE_PF_AVBL_SPACE; + +#define BTM_BLE_PF_BRDCAST_ADDR_FILT 1 +#define BTM_BLE_PF_SERV_DATA_CHG_FILT 2 +#define BTM_BLE_PF_SERV_UUID 4 +#define BTM_BLE_PF_SERV_SOLC_UUID 8 +#define BTM_BLE_PF_LOC_NAME_CHECK 16 +#define BTM_BLE_PF_MANUF_NAME_CHECK 32 +#define BTM_BLE_PF_SERV_DATA_CHECK 64 +typedef UINT16 tBTM_BLE_PF_FEAT_SEL; + +#define BTM_BLE_PF_LIST_LOGIC_OR 1 +#define BTM_BLE_PF_LIST_LOGIC_AND 2 +typedef UINT16 tBTM_BLE_PF_LIST_LOGIC_TYPE; + +#define BTM_BLE_PF_FILT_LOGIC_OR 0 +#define BTM_BLE_PF_FILT_LOGIC_AND 1 +typedef UINT16 tBTM_BLE_PF_FILT_LOGIC_TYPE; + +typedef UINT8 tBTM_BLE_PF_RSSI_THRESHOLD; +typedef UINT8 tBTM_BLE_PF_DELIVERY_MODE; +typedef UINT16 tBTM_BLE_PF_TIMEOUT; +typedef UINT8 tBTM_BLE_PF_TIMEOUT_CNT; + +typedef struct +{ + tBTM_BLE_PF_FEAT_SEL feat_seln; + tBTM_BLE_PF_LIST_LOGIC_TYPE logic_type; + tBTM_BLE_PF_FILT_LOGIC_TYPE filt_logic_type; + tBTM_BLE_PF_RSSI_THRESHOLD rssi_high_thres; + tBTM_BLE_PF_RSSI_THRESHOLD rssi_low_thres; + tBTM_BLE_PF_DELIVERY_MODE dely_mode; + tBTM_BLE_PF_TIMEOUT found_timeout; + tBTM_BLE_PF_TIMEOUT lost_timeout; + tBTM_BLE_PF_TIMEOUT_CNT found_timeout_cnt; +}tBTM_BLE_PF_FILT_PARAMS; + +enum +{ + BTM_BLE_SCAN_COND_ADD, + BTM_BLE_SCAN_COND_DELETE, + BTM_BLE_SCAN_COND_CLEAR = 2 +}; +typedef UINT8 tBTM_BLE_SCAN_COND_OP; + +enum +{ + BTM_BLE_FILT_DISABLE = 0, + BTM_BLE_FILT_ENABLE = 1 +}; +typedef UINT8 tBTM_BLE_FILT_OP; + +/* BLE adv payload filtering config complete callback */ +typedef void (tBTM_BLE_PF_CFG_CBACK)(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op, + tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status, + tBTM_BLE_REF_VALUE ref_value); + +typedef void (tBTM_BLE_PF_CMPL_CBACK) (tBTM_BLE_PF_CFG_CBACK); + +/* BLE adv payload filtering status setup complete callback */ +typedef void (tBTM_BLE_PF_STATUS_CBACK) (UINT8 action, tBTM_STATUS status, + tBTM_BLE_REF_VALUE ref_value); + +/* BLE adv payload filtering param setup complete callback */ +typedef void (tBTM_BLE_PF_PARAM_CBACK) (tBTM_BLE_PF_ACTION action_type, + tBTM_BLE_PF_AVBL_SPACE avbl_space, + tBTM_BLE_REF_VALUE ref_value, tBTM_STATUS status); + +typedef union +{ + UINT16 uuid16_mask; + UINT32 uuid32_mask; + UINT8 uuid128_mask[LEN_UUID_128]; +}tBTM_BLE_PF_COND_MASK; + +typedef struct +{ + tBLE_BD_ADDR *p_target_addr; /* target address, if NULL, generic UUID filter */ + tBT_UUID uuid; /* UUID condition */ + tBTM_BLE_PF_LOGIC_TYPE cond_logic; /* AND/OR */ + tBTM_BLE_PF_COND_MASK *p_uuid_mask; /* UUID mask */ +}tBTM_BLE_PF_UUID_COND; + +typedef struct +{ + UINT8 data_len; /* <= 20 bytes */ + UINT8 *p_data; +}tBTM_BLE_PF_LOCAL_NAME_COND; + +typedef struct +{ + UINT16 company_id; /* company ID */ + UINT8 data_len; /* <= 20 bytes */ + UINT8 *p_pattern; + UINT16 company_id_mask; /* UUID value mask */ + UINT8 *p_pattern_mask; /* Manufactuer data matching mask, same length as data pattern, + set to all 0xff, match exact data */ +}tBTM_BLE_PF_MANU_COND; + +typedef struct +{ + UINT16 uuid; /* service ID */ + UINT8 data_len; /* <= 20 bytes */ + UINT8 *p_pattern; + UINT8 *p_pattern_mask; /* Service data matching mask, same length as data pattern, + set to all 0xff, match exact data */ +}tBTM_BLE_PF_SRVC_PATTERN_COND; + + +typedef union +{ + tBLE_BD_ADDR target_addr; + tBTM_BLE_PF_LOCAL_NAME_COND local_name; /* lcoal name filtering */ + tBTM_BLE_PF_MANU_COND manu_data; /* manufactuer data filtering */ + tBTM_BLE_PF_UUID_COND srvc_uuid; /* service UUID filtering */ + tBTM_BLE_PF_UUID_COND solicitate_uuid; /* solicitated service UUID filtering */ + tBTM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ +}tBTM_BLE_PF_COND_PARAM; + +typedef struct +{ + UINT8 action_condtype[BTM_BLE_PF_TYPE_MAX]; + tBTM_BLE_REF_VALUE ref_value[BTM_BLE_PF_TYPE_MAX]; + UINT8 pending_idx; + UINT8 next_idx; +}tBTM_BLE_ADV_FILTER_ADV_OPQ; + +#define BTM_BLE_MAX_FILTER_COUNTER (BTM_BLE_MAX_ADDR_FILTER + 1) /* per device filter + one generic filter indexed by 0 */ + +typedef struct +{ + BOOLEAN in_use; + BD_ADDR bd_addr; + UINT16 feat_mask; /* per BD_ADDR feature mask */ + UINT8 pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed by tBTM_BLE_PF_COND_TYPE */ +}tBTM_BLE_PF_COUNT; + +typedef struct +{ + BOOLEAN enable; + UINT8 op_type; + tBTM_BLE_PF_COUNT addr_filter_count[BTM_BLE_MAX_FILTER_COUNTER]; /* per BDA filter indexed by tBTM_BLE_PF_COND_TYPE */ + tBLE_BD_ADDR cur_filter_target; + tBTM_BLE_PF_CFG_CBACK *p_scan_cfg_cback; + tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback; + tBTM_BLE_PF_STATUS_CBACK *p_filt_stat_cback; + tBTM_BLE_ADV_FILTER_ADV_OPQ op_q; +}tBTM_BLE_ADV_FILTER_CB; + +/* Sub codes */ +#define BTM_BLE_META_PF_ENABLE 0x00 +#define BTM_BLE_META_PF_FEAT_SEL 0x01 +#define BTM_BLE_META_PF_ADDR 0x02 +#define BTM_BLE_META_PF_UUID 0x03 +#define BTM_BLE_META_PF_SOL_UUID 0x04 +#define BTM_BLE_META_PF_LOCAL_NAME 0x05 +#define BTM_BLE_META_PF_MANU_DATA 0x06 +#define BTM_BLE_META_PF_SRVC_DATA 0x07 +#define BTM_BLE_META_PF_ALL 0x08 + /* These are the fields returned in each device adv packet. It ** is returned in the results callback if registered. */ @@ -1295,6 +1492,64 @@ BTM_API extern tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan *******************************************************************************/ BTM_API extern tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id); +/******************************************************************************* +** +** Function BTM_BleAdvFilterParamSetup +** +** Description This function is called to setup the adv data payload filter +** condition. +** +** Parameters p_target: enabble the filter condition on a target device; if NULL +** enable the generic scan condition. +** enable: enable or disable the filter condition +** +** Returns void +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_FILT_PARAMS *p_filt_params, + tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback, + tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleCfgFilterCondition +** +** Description This function is called to configure the adv data payload filter +** condition. +** +** Parameters action: to read/write/clear +** cond_type: filter condition type. +** p_cond: filter condition paramter +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_COND_TYPE cond_type, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_PARAM *p_cond, + tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, + tBTM_BLE_REF_VALUE ref_value); + +/******************************************************************************* +** +** Function BTM_BleEnableDisableFilterFeature +** +** Description This function is called to enable or disable the APCF feature +** +** Parameters enable - TRUE - enables the APCF, FALSE - disables the APCF +** ref_value - Ref value +** +** Returns tBTM_STATUS +** +*******************************************************************************/ +BTM_API extern tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, + tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, + tBTM_BLE_REF_VALUE ref_value); + + #ifdef __cplusplus } #endif diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h index 07aacad0e..d2ff6e8e3 100644 --- a/stack/include/hcidefs.h +++ b/stack/include/hcidefs.h @@ -343,6 +343,9 @@ /* Batch scan OCF */ #define HCI_BLE_BATCH_SCAN_OCF (0x0156 | HCI_GRP_VENDOR_SPECIFIC) +/* ADV filter OCF */ +#define HCI_BLE_ADV_FILTER_OCF (0x0157 | HCI_GRP_VENDOR_SPECIFIC) + /* Tracking OCF */ #define HCI_BLE_TRACK_ADV_OCF (0x0158 | HCI_GRP_VENDOR_SPECIFIC) diff --git a/vnd/ble/vendor_ble.c b/vnd/ble/vendor_ble.c index 6c9afad53..d84efd3c3 100644 --- a/vnd/ble/vendor_ble.c +++ b/vnd/ble/vendor_ble.c @@ -34,890 +34,13 @@ #include "vendor_hcidefs.h" #include "gatt_int.h" -#define BTM_BLE_INVALID_COUNTER 0xff - - -static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, - UINT8 cond_type, - tBLE_BD_ADDR *p_bd_addr, - UINT8 num_available); - -#define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y) -#define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4) -#define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f) - -/* max number of filter available for different filter type, controller dependent number */ -static const UINT8 btm_ble_cs_filter_max[BTM_BLE_PF_TYPE_MAX] = -{ - BTM_BLE_MAX_ADDR_FILTER, /* address filter */ - 1, /* no limit for service data change, always enable or disable */ - BTM_BLE_MAX_UUID_FILTER, /* service UUID filter */ - BTM_BLE_MAX_UUID_FILTER, /* solicitated UUID filter */ - BTM_BLE_PF_STR_COND_MAX, /* local name filter */ - BTM_BLE_PF_STR_COND_MAX /* manufacturer data filter */ -}; - /*** This needs to be moved to a VSC control block eventually per coding conventions ***/ #if VENDOR_DYNAMIC_MEMORY == FALSE tBTM_BLE_VENDOR_CB btm_ble_vendor_cb; #endif -static const UINT8 op_code_to_cond_type[] = -{ - BTM_BLE_PF_TYPE_ALL, - BTM_BLE_PF_ADDR_FILTER, - BTM_BLE_PF_SRVC_UUID, - BTM_BLE_PF_SRVC_SOL_UUID, - BTM_BLE_PF_LOCAL_NAME, - BTM_BLE_PF_MANU_DATA, - BTM_BLE_PF_SRVC_DATA_PATTERN -}; - static const BD_ADDR na_bda= {0}; -/******************************************************************************* -** -** Function btm_ble_vendor_scan_pf_cmpl_cback -** -** Description the BTM BLE customer feature VSC complete callback for ADV PF -** filtering -** -** Returns pointer to the counter if found; NULL otherwise. -** -*******************************************************************************/ -void btm_ble_vendor_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params) -{ - UINT8 status; - UINT8 *p = p_params->p_param_buf, op_subcode, action = 0xff; - UINT16 evt_len = p_params->param_len; - UINT8 num_avail = 0, cond_type = BTM_BLE_PF_TYPE_MAX; - tBTM_BLE_PF_CMPL_CBACK *p_cmpl_cback = btm_ble_vendor_cb.p_scan_pf_cback; - UINT8 op = BTM_BLE_GET_SCAN_PF_ACTION(btm_ble_vendor_cb.op_type); - UINT8 subcode = BTM_BLE_GET_SCAN_PF_SUBCODE(btm_ble_vendor_cb.op_type); - - STREAM_TO_UINT8(status, p); - - evt_len--; - - if (evt_len < 1 ) - { - BTM_TRACE_ERROR("can not interpret ADV PF filter setting callback. status = %d", status); - return; - } - op_subcode = *p ++; - switch (op_subcode) - { - case BTM_BLE_META_PF_LOCAL_NAME: - case BTM_BLE_META_PF_MANU_DATA: - case BTM_BLE_META_PF_ADDR: - case BTM_BLE_META_PF_UUID: - case BTM_BLE_META_PF_SOL_UUID: - case BTM_BLE_META_PF_FEAT_SEL: - case BTM_BLE_META_PF_SRVC_DATA: - cond_type = op_code_to_cond_type[op_subcode - BTM_BLE_META_PF_FEAT_SEL]; - if (status == HCI_SUCCESS) - { - action = *p ++; - if (op_subcode != BTM_BLE_META_PF_FEAT_SEL) - { - STREAM_TO_UINT8(num_avail, p); - } - - if (memcmp(&btm_ble_vendor_cb.cur_filter_target.bda, &na_bda, BD_ADDR_LEN) == 0) - btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail); - else - btm_ble_cs_update_pf_counter(action, cond_type, &btm_ble_vendor_cb.cur_filter_target, num_avail); - } - break; - - case BTM_BLE_META_PF_ENABLE: - cond_type = BTM_BLE_META_PF_ENABLE; - BTM_TRACE_DEBUG("CS feature Enabled"); - break; - - default: - BTM_TRACE_ERROR("unknow operation: %d", op_subcode); - break; - } - - /* send ADV PF opeartion complete */ - if (p_cmpl_cback && subcode == cond_type) - { - btm_ble_vendor_cb.p_scan_pf_cback = NULL; - btm_ble_vendor_cb.op_type = 0; - (* p_cmpl_cback)(op, subcode, status); - } -} -/******************************************************************************* -** adv payload filtering functions -*******************************************************************************/ -/******************************************************************************* -** -** Function btm_ble_find_addr_filter_counter -** -** Description find the per bd address ADV payload filter counter by BD_ADDR. -** -** Returns pointer to the counter if found; NULL otherwise. -** -*******************************************************************************/ -tBTM_BLE_PF_COUNT * btm_ble_find_addr_filter_counter(tBLE_BD_ADDR *p_le_bda) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_vendor_cb.addr_filter_count[1]; - - if (p_le_bda == NULL) - return &btm_ble_vendor_cb.addr_filter_count[0]; - - for (i = 0; i < BTM_BLE_MAX_FILTER_COUNTER; i ++, p_addr_filter ++) - { - if (p_addr_filter->in_use && - memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) - { - return p_addr_filter; - } - } - return NULL; -} - -/******************************************************************************* -** -** Function btm_ble_alloc_addr_filter_counter -** -** Description allocate the per device adv payload filter counter. -** -** Returns pointer to the counter if allocation succeed; NULL otherwise. -** -*******************************************************************************/ -tBTM_BLE_PF_COUNT * btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_vendor_cb.addr_filter_count[1]; - - for (i = 0; i < BTM_BLE_MAX_FILTER_COUNTER; i ++, p_addr_filter ++) - { - if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) - { - memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN); - p_addr_filter->in_use = TRUE; - return p_addr_filter; - } - } - return NULL; -} -/******************************************************************************* -** -** Function btm_ble_dealloc_addr_filter_counter -** -** Description de-allocate the per device adv payload filter counter. -** -** Returns TRUE if deallocation succeed; FALSE otherwise. -** -*******************************************************************************/ -BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type) -{ - UINT8 i; - tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_vendor_cb.addr_filter_count[1]; - BOOLEAN found = FALSE; - - if (filter_type == BTM_BLE_PF_TYPE_ALL && p_bd_addr == NULL) - memset(&btm_ble_vendor_cb.addr_filter_count[0], 0, sizeof(tBTM_BLE_PF_COUNT)); - - for (i = 0; i < BTM_BLE_MAX_FILTER_COUNTER; i ++, p_addr_filter ++) - { - if ((p_addr_filter->in_use) && - (p_bd_addr == NULL || - (p_bd_addr != NULL && memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) - { - found = TRUE; - memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT)); - - if (p_bd_addr != NULL) break; - } - } - return found; -} -/******************************************************************************* -** -** Function btm_ble_cs_update_pf_counter -** -** Description this function is to update the adv data payload filter counter -** -** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if -** counter update failed. -** -*******************************************************************************/ -UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, - UINT8 cond_type, - tBLE_BD_ADDR *p_bd_addr, - UINT8 num_available) -{ - tBTM_BLE_PF_COUNT *p_addr_filter = NULL; - UINT8 *p_counter = NULL; - UINT32 *p_feat_mask = NULL; - - - if (cond_type > BTM_BLE_PF_TYPE_ALL) - { - BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type); - return BTM_BLE_INVALID_COUNTER; - } - /* for these three types of filter, always generic */ - if (cond_type == BTM_BLE_PF_ADDR_FILTER || - cond_type == BTM_BLE_PF_MANU_DATA || - cond_type == BTM_BLE_PF_LOCAL_NAME || - cond_type == BTM_BLE_PF_SRVC_DATA_PATTERN) - p_bd_addr = NULL; - - if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL && - action == BTM_BLE_SCAN_COND_ADD) - { - p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda); - } - - if (p_addr_filter != NULL) - { - /* all filter just cleared */ - if ((cond_type == BTM_BLE_PF_TYPE_ALL && action == BTM_BLE_SCAN_COND_CLEAR) || - /* or bd address filter been deleted */ - (cond_type == BTM_BLE_PF_ADDR_FILTER && - (action == BTM_BLE_SCAN_COND_DELETE || action == BTM_BLE_SCAN_COND_CLEAR))) - { - btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type); - } - /* if not feature selection, update new addition/reduction of the filter counter */ - else if (cond_type != BTM_BLE_PF_TYPE_ALL) - { - p_counter = p_addr_filter->pf_counter; - p_feat_mask = &p_addr_filter->feat_mask; - - p_counter[cond_type] = btm_ble_cs_filter_max[cond_type] - num_available; - - BTM_TRACE_DEBUG("current filter counter number = %d", p_counter[cond_type]); - - /* update corresponding feature mask */ - if (p_counter[cond_type] > 0) - *p_feat_mask |= (BTM_BLE_PF_BIT_TO_MASK(cond_type)); - else - *p_feat_mask &= ~(BTM_BLE_PF_BIT_TO_MASK(cond_type)); - - return p_counter[cond_type]; - } - } - else - { - BTM_TRACE_ERROR("no matching filter counter found"); - } - /* no matching filter located and updated */ - return BTM_BLE_INVALID_COUNTER; -} -/******************************************************************************* -** -** Function btm_ble_update_pf_manu_data -** -** Description this function update(add,delete or clear) the adv manufacturer -** data filtering condition. -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_PARAM *p_data, - tBTM_BLE_PF_COND_TYPE cond_type) -{ - tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data; - tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data; - UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_META_HDR_LENGTH], - *p = param, - len = BTM_BLE_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - - memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_META_HDR_LENGTH); - - if (cond_type == BTM_BLE_PF_SRVC_DATA_PATTERN) - { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA); - } - else - { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA); - } - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - if (action == BTM_BLE_SCAN_COND_ADD || - action == BTM_BLE_SCAN_COND_DELETE) - { - if (p_manu_data == NULL) - return st; - if (cond_type == BTM_BLE_PF_SRVC_DATA_PATTERN) - { - if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) - p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); - - UINT16_TO_STREAM(p, p_srvc_data->uuid); - ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len); - len += (p_srvc_data->data_len + 2); - } - else - { - if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) - p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); - - UINT16_TO_STREAM(p, p_manu_data->company_id); - ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len); - len += (p_manu_data->data_len + 2); - - if (p_manu_data->company_id_mask != 0) - { - UINT16_TO_STREAM (p, p_manu_data->company_id_mask); - } - else - { - memset(p, 0xff, 2); - p += 2; - } - if (p_manu_data->p_pattern_mask != NULL) - { - ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len); - } - else - memset(p, 0xff, p_manu_data->data_len); - len += (p_manu_data->data_len + 2); - } - } - - /* send manufacturer*/ - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - len, - param, - btm_ble_vendor_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) - { - memset(&btm_ble_vendor_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - else - { - BTM_TRACE_ERROR("manufacturer data PF filter update failed"); - } - - return st; -} -/******************************************************************************* -** -** Function btm_ble_update_pf_local_name -** -** Description this function update(add,delete or clear) the adv lcoal name -** filtering condition. -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - tBTM_BLE_PF_LOCAL_NAME_COND *p_local_name = (p_cond == NULL) ? NULL : &p_cond->local_name; - UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_META_HDR_LENGTH], - *p = param, - len = BTM_BLE_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - - memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_META_HDR_LENGTH); - - UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - if (action == BTM_BLE_SCAN_COND_ADD || - action == BTM_BLE_SCAN_COND_DELETE) - { - if (p_local_name == NULL) - return st; - - if (p_local_name->data_len > BTM_BLE_PF_STR_LEN_MAX) - p_local_name->data_len = BTM_BLE_PF_STR_LEN_MAX; - - ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len); - len += p_local_name->data_len; - } - /* send local name filter */ - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - len, - param, - btm_ble_vendor_scan_pf_cmpl_cback)) - != BTM_NO_RESOURCES) - { - memset(&btm_ble_vendor_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - else - { - BTM_TRACE_ERROR("Local Name PF filter update failed"); - } - - return st; -} -/******************************************************************************* -** -** Function btm_ble_update_addr_filter -** -** Description this function update(add,delete or clear) the address filter of adv. -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_META_HDR_LENGTH], - * p= param; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr; - - memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_META_HDR_LENGTH); - - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - if (action == BTM_BLE_SCAN_COND_ADD || - action == BTM_BLE_SCAN_COND_DELETE) - { - if (p_addr == NULL) - return st; - - BDADDR_TO_STREAM(p, p_addr->bda); - UINT8_TO_STREAM(p, p_addr->type); - } - /* send address filter */ - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - (UINT8)(BTM_BLE_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), - param, - btm_ble_vendor_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) - { - memset(&btm_ble_vendor_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - else - { - BTM_TRACE_ERROR("Broadcaster Address Filter Update failed"); - } - return st; -} -/******************************************************************************* -** -** Function btm_ble_update_uuid_filter -** -** Description this function update(add,delete or clear) service UUID filter. -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_TYPE filter_type, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_META_HDR_LENGTH], - * p= param, - len = BTM_BLE_META_HDR_LENGTH; - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBTM_BLE_PF_UUID_COND *p_uuid_cond; - UINT8 evt_type; - - memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_META_HDR_LENGTH); - - if (filter_type == BTM_BLE_PF_SRVC_UUID) - { - evt_type = BTM_BLE_META_PF_UUID; - p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL; - } - else - { - evt_type = BTM_BLE_META_PF_SOL_UUID; - p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL; - } - - if (p_uuid_cond == NULL && action != BTM_BLE_SCAN_COND_CLEAR) - { - BTM_TRACE_ERROR("Illegal param for add/delete UUID filter"); - return st; - } - - /* need to add address fitler first, if adding per bda UUID filter without address filter */ - if (action == BTM_BLE_SCAN_COND_ADD && - p_uuid_cond->p_target_addr && - btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL) - { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); - UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); - - /* send address filter */ - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - (UINT8)(BTM_BLE_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), - param, - btm_ble_vendor_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES) - { - BTM_TRACE_ERROR("Update Address filter into controller failed."); - return st; - } - } - - p= param; - UINT8_TO_STREAM(p, evt_type); - UINT8_TO_STREAM(p, action); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - if (action == BTM_BLE_SCAN_COND_ADD || - action == BTM_BLE_SCAN_COND_DELETE) - { - if (p_uuid_cond->uuid.len == LEN_UUID_16) - { - UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); - len += LEN_UUID_16; - } - else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ - { - UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32); - len += LEN_UUID_32; - } - else if (p_uuid_cond->uuid.len == LEN_UUID_128) - { - ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128); - len += LEN_UUID_128; - } - else - { - BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len); - return BTM_ILLEGAL_VALUE; - } -#if !(defined VENDOR_ADV_PCF_LEGACY && VENDOR_ADV_PCF_LEGACY == TRUE) - if (p_uuid_cond->p_uuid_mask != NULL) - { - if (p_uuid_cond->uuid.len == LEN_UUID_16) - { - UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask); - len += LEN_UUID_16; - } - else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ - { - UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask); - len += LEN_UUID_32; - } - else if (p_uuid_cond->uuid.len == LEN_UUID_128) - { - ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128); - len += LEN_UUID_128; - } - } - else - { - memset(p, 0xff, p_uuid_cond->uuid.len); - len += p_uuid_cond->uuid.len; - } -#endif - } - - /* send UUID filter update */ - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - len, - param, - btm_ble_vendor_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) - { - if (p_uuid_cond && p_uuid_cond->p_target_addr) - memcpy(&btm_ble_vendor_cb.cur_filter_target, p_uuid_cond->p_target_addr, sizeof(tBLE_BD_ADDR)); - else - memset(&btm_ble_vendor_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - else - { - BTM_TRACE_ERROR("UUID filter udpating failed"); - } - - return st; -} -/******************************************************************************* -** -** Function btm_ble_update_srvc_data_change -** -** Description this function update(add/remove) service data change filter. -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL; - UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1; - - if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail) - != BTM_BLE_INVALID_COUNTER) - st = BTM_SUCCESS; - - return st; -} - -/******************************************************************************* -** -** Function btm_ble_clear_scan_pf_filter -** -** Description clear all adv payload filter by de-select all the adv pf feature bits -** -** -** Returns BTM_SUCCESS if sucessful, -** BTM_ILLEGAL_VALUE if paramter is not valid. -** -*******************************************************************************/ -tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_PARAM *p_cond) -{ - tBLE_BD_ADDR *p_target = (p_cond == NULL)? NULL : &p_cond->target_addr; - tBTM_BLE_PF_COUNT *p_bda_filter; - tBTM_STATUS st = BTM_WRONG_MODE; - UINT8 param[20], *p; - - if (action != BTM_BLE_SCAN_COND_CLEAR) - { - BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action); - return BTM_ILLEGAL_VALUE; - } - - p = param; - memset(param, 0, 20); - - p_bda_filter = btm_ble_find_addr_filter_counter(p_target); - - if (p_bda_filter == NULL || - /* not a generic filter, and feature selection is empty */ - (p_target != NULL && p_bda_filter && p_bda_filter->feat_mask == 0)) - { - BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!"); - return st; - } - - /* clear the general filter entry */ - if (p_target == NULL) - { - /* clear manufactuer data filter */ - btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, NULL, BTM_BLE_PF_MANU_DATA); - /* clear local name filter */ - btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, NULL); - /* update the counter for service data */ - btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, NULL); - /* clear UUID filter */ - btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, BTM_BLE_PF_SRVC_UUID, NULL); - btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, BTM_BLE_META_PF_SOL_UUID, NULL); - /* clear service data filter */ - btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, NULL, BTM_BLE_PF_MANU_DATA); - } - - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - /* set PCF selection */ - UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE); - /* set logic condition as OR as default */ - UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR); - - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - (UINT8)(BTM_BLE_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), - param, - btm_ble_vendor_scan_pf_cmpl_cback)) - != BTM_NO_RESOURCES) - { - if (p_bda_filter) - p_bda_filter->feat_mask = BTM_BLE_PF_SELECT_NONE; - - if (p_target) - memcpy(&btm_ble_vendor_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR)); - else - memset(&btm_ble_vendor_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - } - - return st; -} -/******************************************************************************* -** -** Function BTM_BleEnableFilterCondition -** -** Description This function is called to enable the adv data payload filter -** condition. -** -** Parameters p_target: enabble the filter condition on a target device; if NULL -** enable the generic scan condition. -** enable: enable or disable the filter condition -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleEnableFilterCondition(BOOLEAN enable, tBLE_BD_ADDR *p_target, - tBTM_BLE_PF_CMPL_CBACK *p_cmpl_cback) -{ - UINT8 param[20], *p; - tBTM_STATUS st = BTM_WRONG_MODE; - tBTM_BLE_PF_COUNT *p_bda_filter; - - p = param; - memset(param, 0, 20); - - if (btm_ble_vendor_cb.p_scan_pf_cback) - { - BTM_TRACE_ERROR("ADV PF Filter activity busy"); - return BTM_BUSY; - } - - if (enable) - { - p_bda_filter = btm_ble_find_addr_filter_counter(p_target); - - if (p_bda_filter == NULL || - (p_bda_filter && p_bda_filter->feat_mask == BTM_BLE_PF_SELECT_NONE)) - { - BTM_TRACE_ERROR("No PF filter has been configured!"); - return st; - } - - /* select feature based on control block settings */ - UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); - UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); - - /* Filter index */ - UINT8_TO_STREAM(p, 0); - - /* set PCF selection */ - UINT32_TO_STREAM(p, p_bda_filter->feat_mask); - /* set logic condition as OR as default */ - UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR); - - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - (UINT8)(BTM_BLE_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), - param, - btm_ble_vendor_scan_pf_cmpl_cback)) - == BTM_NO_RESOURCES) - { - return st; - } - - /* enable the content filter in controller */ - p = param; - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE); - /* enable adv data payload filtering */ - UINT8_TO_STREAM(p, enable); - } - else - { - UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE); - /* disable adv data payload filtering */ - UINT8_TO_STREAM(p, enable); - } - - if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_PCF_VSC, - BTM_BLE_PCF_ENABLE_LEN, - param, - btm_ble_vendor_scan_pf_cmpl_cback)) - == BTM_CMD_STARTED) - { - btm_ble_vendor_cb.op_type = BTM_BLE_SET_SCAN_PF_OPCODE(BTM_BLE_META_PF_ENABLE, BTM_BLE_PF_ENABLE); - btm_ble_vendor_cb.p_scan_pf_cback = p_cmpl_cback; - } - - return st; -} -/******************************************************************************* -** -** Function BTM_BleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type. -** p_cond: filter condition paramter -** -** Returns void -** -*******************************************************************************/ -tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_TYPE cond_type, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_PF_CMPL_CBACK *p_cmpl_cback) -{ - tBTM_STATUS st = BTM_ILLEGAL_VALUE; - - if (btm_ble_vendor_cb.p_scan_pf_cback != NULL) - return BTM_BUSY; - - switch (cond_type) - { - case BTM_BLE_PF_SRVC_DATA_PATTERN: - /* write manufacture data filter */ - case BTM_BLE_PF_MANU_DATA: - st = btm_ble_update_pf_manu_data(action, p_cond, cond_type); - break; - - /* write local name filter */ - case BTM_BLE_PF_LOCAL_NAME: - st = btm_ble_update_pf_local_name(action, p_cond); - break; - - /* filter on advertiser address */ - case BTM_BLE_PF_ADDR_FILTER: - st = btm_ble_update_addr_filter(action, p_cond); - break; - - /* filter on service/solicitated UUID */ - case BTM_BLE_PF_SRVC_UUID: - case BTM_BLE_PF_SRVC_SOL_UUID: - st = btm_ble_update_uuid_filter(action, cond_type, p_cond); - break; - - case BTM_BLE_PF_SRVC_DATA: - st = btm_ble_update_srvc_data_change(action, p_cond); - break; - - case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */ - st = btm_ble_clear_scan_pf_filter(action, p_cond); - break; - - default: - BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type); - break; - } - if (st == BTM_CMD_STARTED - /* no vsc needed for service data change */ - && cond_type != BTM_BLE_PF_SRVC_DATA) - { - btm_ble_vendor_cb.op_type = BTM_BLE_SET_SCAN_PF_OPCODE(cond_type, BTM_BLE_PF_CONFIG); - btm_ble_vendor_cb.p_scan_pf_cback = p_cmpl_cback; - } - - return st; -} /******************************************************************************* ** Resolve Address Using IRK List functions @@ -1512,27 +635,6 @@ tBTM_STATUS BTM_BleEnableIRKFeature(BOOLEAN enable) } #endif - - -/******************************************************************************* -** -** Function btm_ble_vendor_init -** -** Description Initialize customer specific feature information in host stack -** -** Parameters -** -** Returns status -** -*******************************************************************************/ -void btm_ble_vendor_init(void) -{ - //memset(&btm_ble_vendor_cb, 0, sizeof(tBTM_BLE_VENDOR_CB)); - - if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) - return; -} - #endif diff --git a/vnd/ble/vendor_hcidefs.h b/vnd/ble/vendor_hcidefs.h index f85e7fdff..b5e770b08 100644 --- a/vnd/ble/vendor_hcidefs.h +++ b/vnd/ble/vendor_hcidefs.h @@ -50,15 +50,5 @@ /* VSC */ #define HCI_VENDOR_BLE_PCF_VSC (0x0157 | HCI_GRP_VENDOR_SPECIFIC) -/* Sub codes */ -#define BTM_BLE_META_PF_ENABLE 0x00 -#define BTM_BLE_META_PF_FEAT_SEL 0x01 -#define BTM_BLE_META_PF_ADDR 0x02 -#define BTM_BLE_META_PF_UUID 0x03 -#define BTM_BLE_META_PF_SOL_UUID 0x04 -#define BTM_BLE_META_PF_LOCAL_NAME 0x05 -#define BTM_BLE_META_PF_MANU_DATA 0x06 -#define BTM_BLE_META_PF_SRVC_DATA 0x07 - #endif diff --git a/vnd/include/bta_vendor_api.h b/vnd/include/bta_vendor_api.h index 0935b146a..9ff5d30d0 100644 --- a/vnd/include/bta_vendor_api.h +++ b/vnd/include/bta_vendor_api.h @@ -32,32 +32,9 @@ #include "vendor_api.h" -#define BTA_DM_BLE_PF_ENABLE_EVT BTM_BLE_PF_ENABLE -#define BTA_DM_BLE_PF_CONFIG_EVT BTM_BLE_PF_CONFIG -typedef UINT8 tBTA_DM_BLE_PF_EVT; - -/* Search callback */ -typedef void (tBTA_DM_SCAN_PF_CBACK)(tBTA_DM_BLE_PF_EVT event, tBTA_DM_BLE_PF_COND_TYPE cfg_cond, tBTA_STATUS status);; #if (BLE_INCLUDED == TRUE && BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE) -/******************************************************************************* -** -** Function BTA_DmBleEnableFilterCondition -** -** Description This function is called to enable the adv data payload filter -** condition. -** -** Parameters p_target: enabble the filter condition on a target device; if NULL -** enable the generic scan condition. -** enable: enable or disable the filter condition -** -** Returns void -** -*******************************************************************************/ -BTA_API extern void BTA_DmBleEnableFilterCondition(BOOLEAN enable, - tBLE_BD_ADDR *p_target, - tBTA_DM_SCAN_PF_CBACK *p_cmpl_cback); /******************************************************************************* ** @@ -70,25 +47,6 @@ BTA_API extern void BTA_DmBleEnableFilterCondition(BOOLEAN enable, *******************************************************************************/ BTA_API extern void BTA_BrcmInit (void); - -/******************************************************************************* -** -** Function BTA_DmBleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type. -** p_cond: filter condition paramter -** -** Returns void -** -*******************************************************************************/ -BTA_API extern void BTA_DmBleCfgFilterCondition(tBTA_DM_BLE_SCAN_COND_OP action, - tBTA_DM_BLE_PF_COND_TYPE cond_type, - tBTA_DM_BLE_PF_COND_PARAM *p_cond, - tBTA_DM_SCAN_PF_CBACK *p_cmpl_cback); #endif #ifdef __cplusplus diff --git a/vnd/include/vendor_api.h b/vnd/include/vendor_api.h index c69c42012..12519cd05 100644 --- a/vnd/include/vendor_api.h +++ b/vnd/include/vendor_api.h @@ -29,100 +29,6 @@ enum ** Advertising packet filter VSC specific definitions ******************************************************************************/ -enum -{ - BTM_BLE_SCAN_COND_ADD, - BTM_BLE_SCAN_COND_DELETE, - BTM_BLE_SCAN_COND_CLEAR = 2 -}; -typedef UINT8 tBTM_BLE_SCAN_COND_OP; - -/* filter selection bit index */ -#define BTM_BLE_PF_ADDR_FILTER 0 -#define BTM_BLE_PF_SRVC_DATA 1 -#define BTM_BLE_PF_SRVC_UUID 2 -#define BTM_BLE_PF_SRVC_SOL_UUID 3 -#define BTM_BLE_PF_LOCAL_NAME 4 -#define BTM_BLE_PF_MANU_DATA 5 -#define BTM_BLE_PF_SRVC_DATA_PATTERN 6 -#define BTM_BLE_PF_TYPE_ALL 7 /* when passed in payload filter type all, only clear action is applicable */ -#define BTM_BLE_PF_TYPE_MAX 8 - -typedef UINT8 tBTM_BLE_PF_COND_TYPE; - -#define BTM_BLE_PF_LOGIC_OR 0 -#define BTM_BLE_PF_LOGIC_AND 1 -typedef UINT8 tBTM_BLE_PF_LOGIC_TYPE; - -/* max number of filter spot for different filter type */ -#ifndef BTM_BLE_MAX_UUID_FILTER -#define BTM_BLE_MAX_UUID_FILTER 8 -#endif -#ifndef BTM_BLE_MAX_ADDR_FILTER -#define BTM_BLE_MAX_ADDR_FILTER 8 -#endif -#ifndef BTM_BLE_PF_STR_COND_MAX -#define BTM_BLE_PF_STR_COND_MAX 4 /* apply to manu data , or local name */ -#endif -#ifndef BTM_BLE_PF_STR_LEN_MAX -#define BTM_BLE_PF_STR_LEN_MAX 20 /* match for first 20 bytes */ -#endif - -#define BTM_BLE_PF_ENABLE 1 -#define BTM_BLE_PF_CONFIG 2 -typedef UINT8 tBTM_BLE_PF_ACTION; - -/* BLE adv payload filtering operation complete callback */ -typedef void (tBTM_BLE_PF_CMPL_CBACK)(tBTM_BLE_PF_ACTION action, tBTM_BLE_PF_COND_TYPE cfg_cond, tBTM_STATUS status); - -typedef union -{ - UINT16 uuid16_mask; - UINT32 uuid32_mask; - UINT8 uuid128_mask[LEN_UUID_128]; -}tBTM_BLE_PF_COND_MASK; - -typedef struct -{ - tBLE_BD_ADDR *p_target_addr; /* target address, if NULL, generic UUID filter */ - tBT_UUID uuid; /* UUID condition */ - tBTM_BLE_PF_LOGIC_TYPE cond_logic; /* AND/OR */ - tBTM_BLE_PF_COND_MASK *p_uuid_mask; /* UUID mask */ -}tBTM_BLE_PF_UUID_COND; - -typedef struct -{ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_data; -}tBTM_BLE_PF_LOCAL_NAME_COND; - -typedef struct -{ - UINT16 company_id; /* company ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; - UINT16 company_id_mask; /* UUID value mask */ - UINT8 *p_pattern_mask; /* Manufactuer data matching mask, same length as data pattern, - set to all 0xff, match exact data */ -}tBTM_BLE_PF_MANU_COND; - -typedef struct -{ - UINT16 uuid; /* service ID */ - UINT8 data_len; /* <= 20 bytes */ - UINT8 *p_pattern; -}tBTM_BLE_PF_SRVC_PATTERN_COND; - - -typedef union -{ - tBLE_BD_ADDR target_addr; - tBTM_BLE_PF_LOCAL_NAME_COND local_name; /* lcoal name filtering */ - tBTM_BLE_PF_MANU_COND manu_data; /* manufactuer data filtering */ - tBTM_BLE_PF_UUID_COND srvc_uuid; /* service UUID filtering */ - tBTM_BLE_PF_UUID_COND solicitate_uuid; /* solicitated service UUID filtering */ - tBTM_BLE_PF_SRVC_PATTERN_COND srvc_data; /* service data pattern */ -}tBTM_BLE_PF_COND_PARAM; #ifdef __cplusplus @@ -134,43 +40,6 @@ extern "C" { ******************************************************************************/ #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE -/******************************************************************************* -** -** Function BTM_BleEnableFilterCondition -** -** Description This function is called to enable the adv data payload filter -** condition. -** -** Parameters p_target: enabble the filter condition on a target device; if NULL -** enable the generic scan condition. -** enable: enable or disable the filter condition -** -** Returns void -** -*******************************************************************************/ -BTM_API extern tBTM_STATUS BTM_BleEnableFilterCondition(BOOLEAN enable, - tBLE_BD_ADDR *p_target, - tBTM_BLE_PF_CMPL_CBACK *p_cmpl_cback); - -/******************************************************************************* -** -** Function BTM_BleCfgFilterCondition -** -** Description This function is called to configure the adv data payload filter -** condition. -** -** Parameters action: to read/write/clear -** cond_type: filter condition type. -** p_cond: filter condition paramter -** -** Returns tBTM_STATUS -** -*******************************************************************************/ -BTM_API extern tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, - tBTM_BLE_PF_COND_TYPE cond_type, - tBTM_BLE_PF_COND_PARAM *p_cond, - tBTM_BLE_PF_CMPL_CBACK *p_cmpl_cback); - #endif diff --git a/vnd/include/vendor_ble.h b/vnd/include/vendor_ble.h index 39c529e3d..bd4aa3307 100644 --- a/vnd/include/vendor_ble.h +++ b/vnd/include/vendor_ble.h @@ -51,7 +51,6 @@ #define BTM_BLE_META_READ_IRK_LEN 2 #define BTM_BLE_META_ADD_WL_ATTR_LEN 9 -#define BTM_BLE_PF_BIT_TO_MASK(x) (UINT32)(1 << (x)) #define BTM_BLE_PF_SELECT_NONE 0 #define BTM_BLE_PF_ADDR_FILTER_BIT BTM_BLE_PF_BIT_TO_MASK(BTM_BLE_PF_ADDR_FILTER) #define BTM_BLE_PF_SRVC_DATA_BIT BTM_BLE_PF_BIT_TO_MASK(BTM_BLE_PF_SRVC_DATA) @@ -63,16 +62,6 @@ typedef UINT8 tBTM_BLE_PF_SEL_MASK; -#define BTM_BLE_MAX_FILTER_COUNTER (BTM_BLE_MAX_ADDR_FILTER + 1) /* per device filter + one generic filter indexed by 0 */ - -typedef struct -{ - BOOLEAN in_use; - BD_ADDR bd_addr; - UINT32 feat_mask; /* per BD_ADDR feature mask */ - UINT8 pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed by tBTM_BLE_PF_COND_TYPE */ -}tBTM_BLE_PF_COUNT; - #ifndef BTM_CS_IRK_LIST_MAX #define BTM_CS_IRK_LIST_MAX 0x20 #endif