From 2ffd8da9af4b6ccec249056b4f043d9bb222d4c8 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 4 Jan 2017 07:58:37 -0800 Subject: [PATCH] LE filters without custom data types Bug: 30622771 Test: sl4a FilteringTest Change-Id: Ib4edfa40038ca59c37ae1dfc763f0cac563177d7 --- btif/src/btif_ble_scanner.cc | 144 ++++------ stack/btm/btm_ble_adv_filter.cc | 559 ++++++++++++-------------------------- stack/include/btm_ble_api.h | 49 ++-- stack/include/btm_ble_api_types.h | 43 --- 4 files changed, 251 insertions(+), 544 deletions(-) diff --git a/btif/src/btif_ble_scanner.cc b/btif/src/btif_ble_scanner.cc index b6c8295bc..60aa5f378 100644 --- a/btif/src/btif_ble_scanner.cc +++ b/btif/src/btif_ble_scanner.cc @@ -415,129 +415,87 @@ class BleScannerInterfaceImpl : public BleScannerInterface { if (data.size() != mask.size() && data.size() != 0 && mask.size() != 0) return; - tBTM_BLE_PF_COND_PARAM* p_cond; switch (filt_type) { case BTM_BLE_PF_ADDR_FILTER: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); - - bdcpy(p_cond->target_addr.bda, bd_addr->address); - p_cond->target_addr.type = addr_type; - break; + tBLE_BD_ADDR target_addr; + bdcpy(target_addr.bda, bd_addr->address); + target_addr.type = addr_type; + + do_in_bta_thread( + FROM_HERE, + base::Bind(&BTM_LE_PF_addr_filter, action, filt_index, + std::move(target_addr), + Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); + return; } case BTM_BLE_PF_SRVC_DATA: - p_cond = nullptr; - break; - - case BTM_BLE_PF_SRVC_UUID: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); + do_in_bta_thread(FROM_HERE, + base::Bind(&BTM_LE_PF_srvc_data, action, filt_index)); + return; + case BTM_BLE_PF_SRVC_UUID: + case BTM_BLE_PF_SRVC_SOL_UUID: { tBT_UUID bt_uuid; btif_to_bta_uuid(&bt_uuid, p_uuid); - p_cond->srvc_uuid.cond_logic = BTM_BLE_PF_LOGIC_AND; - p_cond->srvc_uuid.uuid = bt_uuid; - - if (p_uuid_mask != NULL) { - uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_UUID_COND); - p_cond->srvc_uuid.p_uuid_mask = (tBTM_BLE_PF_COND_MASK*)p; - btif_to_bta_uuid_mask(p_cond->srvc_uuid.p_uuid_mask, p_uuid_mask, - p_uuid); + if (p_uuid_mask == NULL) { + do_in_bta_thread( + FROM_HERE, + base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type, + bt_uuid, BTM_BLE_PF_LOGIC_AND, nullptr, + Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); + return; } - break; - } - - case BTM_BLE_PF_SRVC_SOL_UUID: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); - - p_cond->solicitate_uuid.cond_logic = BTM_BLE_PF_LOGIC_AND; - btif_to_bta_uuid(&p_cond->solicitate_uuid.uuid, p_uuid); - break; + tBTM_BLE_PF_COND_MASK* mask = new tBTM_BLE_PF_COND_MASK; + btif_to_bta_uuid_mask(mask, p_uuid_mask, p_uuid); + do_in_bta_thread( + FROM_HERE, + base::Bind(&BTM_LE_PF_uuid_filter, action, filt_index, filt_type, + bt_uuid, BTM_BLE_PF_LOGIC_AND, base::Owned(mask), + Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); + return; } case BTM_BLE_PF_LOCAL_NAME: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); - - uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_LOCAL_NAME_COND); - p_cond->local_name.data_len = data.size(); - p_cond->local_name.p_data = p; - memcpy(p_cond->local_name.p_data, data.data(), data.size()); - break; + do_in_bta_thread( + FROM_HERE, base::Bind(&BTM_LE_PF_local_name, action, filt_index, + std::move(data), Bind(&bta_scan_filt_cfg_cb, + filt_type, client_if))); + return; } case BTM_BLE_PF_MANU_DATA: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); - - uint8_t data_len = data.size(); - - p_cond->manu_data.company_id = company_id; - p_cond->manu_data.company_id_mask = - company_id_mask ? company_id_mask : 0xFFFF; - p_cond->manu_data.data_len = data_len; - - uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_MANU_COND); - p_cond->manu_data.p_pattern = p; - memcpy(p_cond->manu_data.p_pattern, data.data(), data_len); - p += data_len; - - if (mask.size()) { - p_cond->manu_data.p_pattern_mask = p; - memcpy(p_cond->manu_data.p_pattern_mask, mask.data(), mask.size()); - } - break; + do_in_bta_thread( + FROM_HERE, + base::Bind(&BTM_LE_PF_manu_data, action, filt_index, company_id, + company_id_mask, std::move(data), std::move(mask), + Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); + return; } case BTM_BLE_PF_SRVC_DATA_PATTERN: { - p_cond = new tBTM_BLE_PF_COND_PARAM; - memset(p_cond, 0, sizeof(tBTM_BLE_PF_COND_PARAM)); - - p_cond->srvc_data.data_len = data.size(); - - uint8_t* p = (uint8_t*)p_cond + sizeof(tBTM_BLE_PF_UUID_COND); - p_cond->srvc_data.p_pattern = p; - memcpy(p_cond->srvc_data.p_pattern, data.data(), data.size()); - p += data.size(); - if (mask.size()) { - p_cond->srvc_data.p_pattern_mask = p; - memcpy(p_cond->srvc_data.p_pattern_mask, mask.data(), mask.size()); - } - break; + do_in_bta_thread( + FROM_HERE, + base::Bind(&BTM_LE_PF_srvc_data_pattern, action, filt_index, + std::move(data), std::move(mask), + Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); + return; } default: LOG_ERROR(LOG_TAG, "%s: Unknown filter type (%d)!", __func__, action); return; } - - if (p_cond != nullptr) { - do_in_bta_thread( - FROM_HERE, - base::Bind(&BTM_BleCfgFilterCondition, action, filt_type, filt_index, - base::Owned(p_cond), - Bind(&bta_scan_filt_cfg_cb, filt_type, client_if))); - } else { - do_in_bta_thread(FROM_HERE, base::Bind(&BTM_BleCfgFilterCondition, action, - filt_type, filt_index, nullptr, - Bind(&bta_scan_filt_cfg_cb, - filt_type, client_if))); - } } void ScanFilterClear(int client_if, int filter_index) override { BTIF_TRACE_DEBUG("%s: filter_index: %d", __func__, filter_index); - - do_in_bta_thread( - FROM_HERE, - base::Bind( - &BTM_BleCfgFilterCondition, BTM_BLE_SCAN_COND_CLEAR, - BTM_BLE_PF_TYPE_ALL, filter_index, nullptr, - Bind(&bta_scan_filt_cfg_cb, BTM_BLE_PF_TYPE_ALL, client_if))); + do_in_bta_thread(FROM_HERE, + base::Bind(&BTM_LE_PF_clear, filter_index, + Bind(&bta_scan_filt_cfg_cb, BTM_BLE_PF_TYPE_ALL, + client_if))); } void ScanFilterEnable(int client_if, bool enable) override { diff --git a/stack/btm/btm_ble_adv_filter.cc b/stack/btm/btm_ble_adv_filter.cc index d26a5e0d2..5f264d085 100644 --- a/stack/btm/btm_ble_adv_filter.cc +++ b/stack/btm/btm_ble_adv_filter.cc @@ -20,6 +20,8 @@ #include #include +#include +#include #include "bt_target.h" @@ -309,44 +311,28 @@ bool btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR* p_bd_addr, return found; } -/******************************************************************************* - * - * Function btm_ble_update_pf_local_name - * - * Description this function update(add,delete or clear) the adv local - * 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_CFG_CBACK cb) { - tBTM_BLE_PF_LOCAL_NAME_COND* p_local_name = - (p_cond == NULL) ? NULL : &p_cond->local_name; - uint8_t 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); +/** + * This function update(add,delete or clear) the adv local name filtering + * condition. + */ +void BTM_LE_PF_local_name(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + std::vector name, tBTM_BLE_PF_CFG_CBACK cb) { + uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + uint8_t len_max = len + BTM_BLE_PF_STR_LEN_MAX; + uint8_t param[len_max]; + memset(param, 0, len_max); + + uint8_t* p = param; 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; + if (action != BTM_BLE_SCAN_COND_CLEAR) { + int size = std::min(name.size(), (size_t)BTM_BLE_PF_STR_LEN_MAX); + ARRAY_TO_STREAM(p, name.data(), size); + len += size; } /* send local name filter */ @@ -355,127 +341,107 @@ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_LOCAL_NAME, cb)); memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - return BTM_CMD_STARTED; } -/******************************************************************************* - * - * 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. - * -4 -******************************************************************************/ -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; +/** + * this function update(add/remove) service data change filter. + */ +void BTM_LE_PF_srvc_data(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index) { uint8_t 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; + btm_ble_cs_update_pf_counter(action, BTM_BLE_PF_SRVC_DATA, nullptr, + num_avail); } -/******************************************************************************* - * - * 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_CFG_CBACK cb) { - if (!p_data) return BTM_ILLEGAL_VALUE; - - tBTM_BLE_PF_MANU_COND* p_manu_data = &p_data->manu_data; - tBTM_BLE_PF_SRVC_PATTERN_COND* p_srvc_data = &p_data->srvc_data; - - int param_len = BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + - BTM_BLE_ADV_FILT_META_HDR_LENGTH; +/** + * This function update(add,delete or clear) the adv manufacturer data filtering + * condition. + */ +void BTM_LE_PF_manu_data(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, uint16_t company_id, + uint16_t company_id_mask, std::vector data, + std::vector data_mask, + tBTM_BLE_PF_CFG_CBACK cb) { uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + int len_max = len + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX; - uint8_t param[param_len]; - memset(param, 0, param_len); + uint8_t param[len_max]; + memset(param, 0, len_max); uint8_t* p = param; - 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, BTM_BLE_META_PF_MANU_DATA); UINT8_TO_STREAM(p, action); 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 BTM_ILLEGAL_VALUE; - 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 (action != BTM_BLE_SCAN_COND_CLEAR) { + uint8_t size = std::min(data.size(), (size_t)(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); - } + UINT16_TO_STREAM(p, company_id); + if (size > 0 && data_mask.size() != 0) { + ARRAY_TO_STREAM(p, data.data(), size); + len += size + 2; + } else + len += 2; - len += (p_srvc_data->data_len); - BTM_TRACE_DEBUG("Service data length: %d", len); + if (company_id_mask != 0) { + UINT16_TO_STREAM(p, company_id_mask); } else { - if (NULL == p_manu_data) { - BTM_TRACE_ERROR("%s: No manuf data", __func__); - return BTM_ILLEGAL_VALUE; - } - BTM_TRACE_EVENT("%s: length: %d", __func__, p_manu_data->data_len); - 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 && p_manu_data->p_pattern_mask != NULL) { - ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len); - len += (p_manu_data->data_len + 2); - } else - 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; - } - len += 2; + UINT16_TO_STREAM(p, (uint16_t)0xFFFF); + } + len += 2; - if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) { - ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len); - len += (p_manu_data->data_len); - } + if (size > 0 && data_mask.size() != 0) { + ARRAY_TO_STREAM(p, data_mask.data(), size); + len += (size); + } + + BTM_TRACE_DEBUG("Manuf data length: %d", len); + } + + btu_hcif_send_cmd_with_cb( + FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len, + base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_MANU_DATA, cb)); + + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); +} + +/** + * This function update(add,delete or clear) the service data filtering + * condition. + **/ +void BTM_LE_PF_srvc_data_pattern(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + std::vector data, + std::vector data_mask, + tBTM_BLE_PF_CFG_CBACK cb) { + uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + int len_max = len + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX; + + uint8_t param[len_max]; + memset(param, 0, len_max); - BTM_TRACE_DEBUG("Manuf data length: %d", len); + uint8_t* p = param; + UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA); + UINT8_TO_STREAM(p, action); + UINT8_TO_STREAM(p, filt_index); + + if (action != BTM_BLE_SCAN_COND_CLEAR) { + uint8_t size = std::min(data.size(), (size_t)(BTM_BLE_PF_STR_LEN_MAX - 2)); + + if (size > 0) { + ARRAY_TO_STREAM(p, data.data(), size); + len += size; + ARRAY_TO_STREAM(p, data_mask.data(), size); + len += size; } } - uint8_t expected_ocf = btm_ble_condtype_to_ocf(cond_type); - btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len, - base::Bind(&btm_flt_update_cb, expected_ocf, cb)); + btu_hcif_send_cmd_with_cb( + FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len, + base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_SRVC_DATA, cb)); memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - return BTM_CMD_STARTED; } /******************************************************************************* @@ -541,39 +507,25 @@ uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, return BTM_BLE_INVALID_COUNTER; } -/******************************************************************************* - * - * Function btm_ble_update_addr_filter - * - * Description this function updates(adds, deletes or clears) the address - * filter of adv. - * - * - * Returns BTM_CMD_STARTED 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, - tBTM_BLE_PF_CFG_CBACK cb) { +/** + * This function updates the address filter of adv. + */ +void BTM_LE_PF_addr_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, tBLE_BD_ADDR addr, + tBTM_BLE_PF_CFG_CBACK cb) { const uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN; - uint8_t param[len], *p = param; - tBLE_BD_ADDR* p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr; + uint8_t param[len]; memset(param, 0, len); + uint8_t* p = param; 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 BTM_ILLEGAL_VALUE; - - BDADDR_TO_STREAM(p, p_addr->bda); - UINT8_TO_STREAM(p, p_addr->type); + if (action != BTM_BLE_SCAN_COND_CLEAR) { + BDADDR_TO_STREAM(p, addr.bda); + UINT8_TO_STREAM(p, addr.type); } /* send address filter */ @@ -582,216 +534,125 @@ tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_ADDR, cb)); memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); - return BTM_CMD_STARTED; } -/******************************************************************************* - * - * Function btm_ble_update_uuid_filter - * - * Description this function updates(adds, deletes or clears) the service - * UUID filter. - * - * - * Returns BTM_CMD_STARTED 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, - tBTM_BLE_PF_CFG_CBACK cb) { - uint8_t param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], - *p = param, len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; - tBTM_BLE_PF_UUID_COND* p_uuid_cond; +/** + * This function updates(adds, deletes or clears) the service UUID filter. + */ +void BTM_LE_PF_uuid_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_TYPE filter_type, tBT_UUID uuid, + tBTM_BLE_PF_LOGIC_TYPE cond_logic, + tBTM_BLE_PF_COND_MASK* p_uuid_mask, + tBTM_BLE_PF_CFG_CBACK cb) { uint8_t 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 BTM_ILLEGAL_VALUE; } - /* need to add address filter first, if adding per bda UUID filter without - * address filter */ - if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond && - 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); - - tBTM_BLE_PF_CFG_CBACK fDoNothing; - /* send address filter */ - btu_hcif_send_cmd_with_cb( - FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, - (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), - base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_ADDR, fDoNothing)); - BTM_TRACE_DEBUG("Updated Address filter"); - } + uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; + uint8_t max_len = len + BTM_BLE_META_UUID_LEN; + uint8_t param[max_len]; + memset(param, 0, max_len); + uint8_t* p = param; - 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) && - NULL != p_uuid_cond) { - if (p_uuid_cond->uuid.len == LEN_UUID_16) { - UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); + if (action != BTM_BLE_SCAN_COND_CLEAR) { + if (uuid.len == LEN_UUID_16) { + UINT16_TO_STREAM(p, 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); + } else if (uuid.len == LEN_UUID_32) { + UINT32_TO_STREAM(p, 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); + } else if (uuid.len == LEN_UUID_128) { + ARRAY_TO_STREAM(p, 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; + BTM_TRACE_ERROR("illegal UUID length: %d", uuid.len); + cb.Run(0, BTM_BLE_PF_CONFIG, 1 /*BTA_FAILURE*/); + return; } - 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); + if (p_uuid_mask) { + if (uuid.len == LEN_UUID_16) { + UINT16_TO_STREAM(p, 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); + } else if (uuid.len == LEN_UUID_32) { + UINT32_TO_STREAM(p, 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); + } else if (uuid.len == LEN_UUID_128) { + ARRAY_TO_STREAM(p, 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; + memset(p, 0xff, uuid.len); + len += uuid.len; } - BTM_TRACE_DEBUG("%s : %d, %d, %d, %d", __func__, filter_type, evt_type, - p_uuid_cond->uuid.len, len); } /* send UUID filter update */ btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len, base::Bind(&btm_flt_update_cb, evt_type, cb)); - - 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)); - - return BTM_CMD_STARTED; + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); } -/******************************************************************************* - * - * Function btm_ble_clear_scan_pf_filter - * - * Description clear all adv payload filter by de-selecting all the adv pf - * feature bits - * - * - * Returns BTM_CMD_STARTED 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_PF_CFG_CBACK cb) { - tBLE_BD_ADDR* p_target = (p_cond == NULL) ? NULL : &p_cond->target_addr; - tBTM_BLE_PF_COUNT* p_bda_filter; - uint8_t 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 */ - (p_target != NULL && p_bda_filter)) { - BTM_TRACE_ERROR( - "Error: Can not clear filter, No PF filter has been configured!"); - return BTM_WRONG_MODE; - } - - tBTM_BLE_PF_CFG_CBACK fDoNothing; - +/** + * all adv payload filter by de-selecting all the adv pf feature bits + */ +void BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_CFG_CBACK cb) { /* clear the general filter entry */ - if (NULL == p_target) { + { + tBTM_BLE_PF_CFG_CBACK fDoNothing; + /* clear manufactuer data filter */ - btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, - BTM_BLE_PF_MANU_DATA, fDoNothing); + BTM_LE_PF_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, 0, 0, {}, {}, + fDoNothing); /* clear local name filter */ - btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, - fDoNothing); + BTM_LE_PF_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, fDoNothing); /* update the counter for service data */ - btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); + BTM_LE_PF_srvc_data(BTM_BLE_SCAN_COND_CLEAR, filt_index); /* clear UUID filter */ - btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, - BTM_BLE_PF_SRVC_UUID, NULL, fDoNothing); + BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, + BTM_BLE_PF_SRVC_UUID, {}, 0, nullptr, fDoNothing); - btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, - BTM_BLE_PF_SRVC_SOL_UUID, NULL, fDoNothing); + BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, + BTM_BLE_PF_SRVC_SOL_UUID, {}, 0, nullptr, fDoNothing); /* clear service data filter */ - btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, - BTM_BLE_PF_SRVC_DATA_PATTERN, fDoNothing); + BTM_LE_PF_srvc_data_pattern(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, {}, + fDoNothing); } + uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN; + uint8_t param[len]; + memset(param, 0, len); + + uint8_t* p = param; + /* 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); btu_hcif_send_cmd_with_cb( - FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, - (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), + FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len, base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb)); - 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)); - return BTM_CMD_STARTED; + memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); } /******************************************************************************* @@ -953,90 +814,6 @@ void BTM_BleEnableDisableFilterFeature(uint8_t enable, /******************************************************************************* * - * 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 - * cb - Config callback - * - ******************************************************************************/ -void 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 cb) { - BTM_TRACE_EVENT("%s action:%d, cond_type:%d, index:%d", __func__, action, - cond_type, filt_index); - - if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) { - cb.Run(0, BTM_BLE_PF_CONFIG, 1 /*BTA_FAILURE*/); - return; - } - - // uint8_t ocf = btm_ble_condtype_to_ocf(cond_type); - uint8_t 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, - cb); - break; - - /* write local name filter */ - case BTM_BLE_PF_LOCAL_NAME: - st = btm_ble_update_pf_local_name(action, filt_index, p_cond, cb); - break; - - /* filter on advertiser address */ - case BTM_BLE_PF_ADDR_FILTER: - st = btm_ble_update_addr_filter(action, filt_index, p_cond, cb); - 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, cb); - break; - - case BTM_BLE_PF_SRVC_DATA: - st = btm_ble_update_srvc_data_change(action, filt_index, p_cond); - - // TODO(jpawlowski): btm_ble_update_srvc_data_change was not scheduling - // any operation, callback was never called in success case. Must - // investigeate more if this was bug, or just never used. - // cb.Run(0, BTM_BLE_PF_CONFIG, 0 /*BTA_SUCCESS */); - // equivalent of old: - // ocf = btm_ble_condtype_to_ocf(cond_type); - // btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, - // p_cmpl_cback, NULL); - break; - - case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */ - st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, cb); - break; - - default: - BTM_TRACE_WARNING("condition type [%d] not supported currently.", - cond_type); - return; - } - - if (st != BTM_CMD_STARTED) { - cb.Run(0, BTM_BLE_PF_CONFIG, 1 /*BTA_FAILURE*/); - } -} - -/******************************************************************************* - * * Function btm_ble_adv_filter_init * * Description This function initializes the adv filter control block diff --git a/stack/include/btm_ble_api.h b/stack/include/btm_ble_api.h index b117dee42..d7c8b7964 100644 --- a/stack/include/btm_ble_api.h +++ b/stack/include/btm_ble_api.h @@ -828,23 +828,38 @@ extern void BTM_BleAdvFilterParamSetup( std::unique_ptr p_filt_params, tBTM_BLE_PF_PARAM_CB cb); -/******************************************************************************* - * - * 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 - * - ******************************************************************************/ -extern void 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 cb); +/** + * This functions are called to configure the adv data payload filter condition + */ +extern void BTM_LE_PF_srvc_data(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index); +extern void BTM_LE_PF_addr_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBLE_BD_ADDR addr, tBTM_BLE_PF_CFG_CBACK cb); +extern void BTM_LE_PF_local_name(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + std::vector name, + tBTM_BLE_PF_CFG_CBACK cb); +extern void BTM_LE_PF_uuid_filter(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_COND_TYPE filter_type, + tBT_UUID uuid, + tBTM_BLE_PF_LOGIC_TYPE cond_logic, + tBTM_BLE_PF_COND_MASK* p_uuid_mask, + tBTM_BLE_PF_CFG_CBACK cb); +extern void BTM_LE_PF_manu_data(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + uint16_t company_id, uint16_t company_id_mask, + std::vector data, + std::vector data_mask, + tBTM_BLE_PF_CFG_CBACK cb); +extern void BTM_LE_PF_srvc_data_pattern(tBTM_BLE_SCAN_COND_OP action, + tBTM_BLE_PF_FILT_INDEX filt_index, + std::vector data, + std::vector data_mask, + tBTM_BLE_PF_CFG_CBACK cb); +extern void BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index, + tBTM_BLE_PF_CFG_CBACK cb); /******************************************************************************* * diff --git a/stack/include/btm_ble_api_types.h b/stack/include/btm_ble_api_types.h index 4b3fb77e2..f295aae86 100644 --- a/stack/include/btm_ble_api_types.h +++ b/stack/include/btm_ble_api_types.h @@ -490,49 +490,6 @@ typedef union { uint8_t 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_t data_len; /* <= 20 bytes */ - uint8_t* p_data; -} tBTM_BLE_PF_LOCAL_NAME_COND; - -typedef struct { - uint16_t company_id; /* company ID */ - uint8_t data_len; /* <= 20 bytes */ - uint8_t* p_pattern; - uint16_t company_id_mask; /* UUID value mask */ - uint8_t* p_pattern_mask; /* Manufacturer data matching mask, - same length as data pattern, - set to all 0xff, match exact data */ -} tBTM_BLE_PF_MANU_COND; - -typedef struct { - uint16_t uuid; /* service ID */ - uint8_t data_len; /* <= 20 bytes */ - uint8_t* p_pattern; - uint8_t* 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 */ - uint8_t additional_data[2000]; -} tBTM_BLE_PF_COND_PARAM; - /* per device filter + one generic filter indexed by 0 */ #define BTM_BLE_MAX_FILTER_COUNTER (BTM_BLE_MAX_ADDR_FILTER + 1) -- 2.11.0