1 /******************************************************************************
3 * Copyright (C) 2014 Broadcom Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 #define LOG_TAG "bt_btm_ble"
22 #include "bt_target.h"
24 #if (BLE_INCLUDED == TRUE)
31 #include "btm_ble_api.h"
32 #include "device/include/controller.h"
34 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
35 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13
36 #define BTM_BLE_ADV_FILT_TRACK_NUM 2
38 #define BTM_BLE_PF_SELECT_NONE 0
40 /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */
41 #define BTM_BLE_META_HDR_LENGTH 3
42 #define BTM_BLE_PF_FEAT_SEL_LEN 18
43 #define BTM_BLE_PCF_ENABLE_LEN 2
45 #define BTM_BLE_META_ADDR_LEN 7
46 #define BTM_BLE_META_UUID_LEN 40
48 #define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x))
51 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
52 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
53 static const BD_ADDR na_bda= {0};
55 static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
56 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available);
58 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y)
59 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4)
60 #define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f)
61 #define BTM_BLE_INVALID_COUNTER 0xff
64 /* length of each multi adv sub command */
65 #define BTM_BLE_ADV_FILTER_ENB_LEN 3
67 /* length of each batch scan command */
68 #define BTM_BLE_ADV_FILTER_CLEAR_LEN 3
69 #define BTM_BLE_ADV_FILTER_LEN 2
71 #define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0
72 #define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F
74 /*******************************************************************************
76 ** Function btm_ble_obtain_vsc_details
78 ** Description This function obtains the VSC details
84 *******************************************************************************/
85 tBTM_STATUS btm_ble_obtain_vsc_details()
87 tBTM_STATUS st = BTM_SUCCESS;
89 #if BLE_VND_INCLUDED == TRUE
90 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
91 if (0 == cmn_ble_vsc_cb.max_filter)
93 st = BTM_MODE_UNSUPPORTED;
97 cmn_ble_vsc_cb.max_filter = BTM_BLE_MAX_FILTER_COUNTER;
102 /*******************************************************************************
104 ** Function btm_ble_advfilt_enq_op_q
106 ** Description enqueue an adv filter operation in q to check command complete
111 *******************************************************************************/
112 void btm_ble_advfilt_enq_op_q(UINT8 action, UINT8 ocf, tBTM_BLE_FILT_CB_EVT cb_evt,
113 tBTM_BLE_REF_VALUE ref, tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
114 tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback)
116 btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx] = (action |(ocf << 4));
117 btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.next_idx] = ref;
118 btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.next_idx] = cb_evt;
119 btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.next_idx] = p_cmpl_cback;
120 btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.next_idx]
121 = p_filt_param_cback;
122 BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_ocf:%d, action:%d, ocf:%d,cb_evt;%d, cback:%x",
123 btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx], action,
124 ocf, cb_evt, p_cmpl_cback);
125 btm_ble_adv_filt_cb.op_q.next_idx = (btm_ble_adv_filt_cb.op_q.next_idx + 1)
126 % BTM_BLE_PF_TYPE_MAX;
129 /*******************************************************************************
131 ** Function btm_ble_advfilt_deq_op_q
133 ** Description dequeue an adv filter operation from q when command complete
138 *******************************************************************************/
139 void btm_ble_advfilt_deq_op_q(UINT8 *p_action,UINT8 *p_ocf, tBTM_BLE_FILT_CB_EVT *p_cb_evt,
140 tBTM_BLE_REF_VALUE *p_ref, tBTM_BLE_PF_CFG_CBACK ** p_cmpl_cback,
141 tBTM_BLE_PF_PARAM_CBACK **p_filt_param_cback)
143 *p_ocf = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx] >> 4);
144 *p_action = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx]
145 & BTM_BLE_ADV_FILT_SUBCODE_MASK);
146 *p_ref = btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.pending_idx];
147 *p_cb_evt = btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.pending_idx];
148 *p_cmpl_cback = btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.pending_idx];
149 *p_filt_param_cback =
150 btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.pending_idx];
152 btm_ble_adv_filt_cb.op_q.pending_idx = (btm_ble_adv_filt_cb.op_q.pending_idx + 1)
153 % BTM_BLE_PF_TYPE_MAX;
154 BTM_TRACE_DEBUG("btm_ble_advfilt_deq_op_q: ocf:%d, action:%d, ref_value:%d, cb_evt:%x",
155 *p_ocf,*p_action, *p_ref, *p_cb_evt);
158 /*******************************************************************************
160 ** Function btm_ble_condtype_to_ocf
162 ** Description Convert cond_type to OCF
164 ** Returns Returns ocf value
166 *******************************************************************************/
167 UINT8 btm_ble_condtype_to_ocf(UINT8 cond_type)
173 case BTM_BLE_PF_ADDR_FILTER:
174 ocf = BTM_BLE_META_PF_ADDR;
176 case BTM_BLE_PF_SRVC_UUID:
177 ocf = BTM_BLE_META_PF_UUID;
179 case BTM_BLE_PF_SRVC_SOL_UUID:
180 ocf = BTM_BLE_META_PF_SOL_UUID;
182 case BTM_BLE_PF_LOCAL_NAME:
183 ocf = BTM_BLE_META_PF_LOCAL_NAME;
185 case BTM_BLE_PF_MANU_DATA:
186 ocf = BTM_BLE_META_PF_MANU_DATA;
188 case BTM_BLE_PF_SRVC_DATA_PATTERN:
189 ocf = BTM_BLE_META_PF_SRVC_DATA;
191 case BTM_BLE_PF_TYPE_ALL:
192 ocf = BTM_BLE_META_PF_ALL;
195 ocf = BTM_BLE_PF_TYPE_MAX;
201 /*******************************************************************************
203 ** Function btm_ble_ocf_to_condtype
205 ** Description Convert OCF to cond type
207 ** Returns Returns condtype value
209 *******************************************************************************/
210 UINT8 btm_ble_ocf_to_condtype(UINT8 ocf)
216 case BTM_BLE_META_PF_FEAT_SEL:
217 cond_type = BTM_BLE_META_PF_FEAT_SEL;
219 case BTM_BLE_META_PF_ADDR:
220 cond_type = BTM_BLE_PF_ADDR_FILTER;
222 case BTM_BLE_META_PF_UUID:
223 cond_type = BTM_BLE_PF_SRVC_UUID;
225 case BTM_BLE_META_PF_SOL_UUID:
226 cond_type = BTM_BLE_PF_SRVC_SOL_UUID;
228 case BTM_BLE_META_PF_LOCAL_NAME:
229 cond_type = BTM_BLE_PF_LOCAL_NAME;
231 case BTM_BLE_META_PF_MANU_DATA:
232 cond_type = BTM_BLE_PF_MANU_DATA;
234 case BTM_BLE_META_PF_SRVC_DATA:
235 cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN;
237 case BTM_BLE_META_PF_ALL:
238 cond_type = BTM_BLE_PF_TYPE_ALL;
241 cond_type = BTM_BLE_PF_TYPE_MAX;
247 /*******************************************************************************
249 ** Function btm_ble_scan_pf_cmpl_cback
251 ** Description the BTM BLE customer feature VSC complete callback for ADV PF filtering
253 ** Returns pointer to the counter if found; NULL otherwise.
255 *******************************************************************************/
256 void btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params)
259 UINT8 *p = p_params->p_param_buf, op_subcode = 0, action = 0xff;
260 UINT16 evt_len = p_params->param_len;
261 UINT8 ocf = BTM_BLE_META_PF_ALL, cond_type = 0;
262 UINT8 num_avail = 0, cb_evt = 0;
263 tBTM_BLE_REF_VALUE ref_value = 0;
264 tBTM_BLE_PF_CFG_CBACK *p_scan_cfg_cback = NULL;
265 tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback = NULL;
267 if (evt_len < 3 || evt_len > 4)
269 BTM_TRACE_ERROR("%s cannot interpret APCF callback status = %d, length = %d",
270 __func__, status, evt_len);
271 btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback,
272 &p_filt_param_cback);
276 btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback,
277 &p_filt_param_cback);
279 STREAM_TO_UINT8(status, p);
280 STREAM_TO_UINT8(op_subcode, p);
281 STREAM_TO_UINT8(action, p);
283 /* Ignore the event, if it is not the same one expected */
286 if(ocf != op_subcode)
288 BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:3-Incorrect opcode :%d, %d, %d, %d, %d, %d",
289 ocf, op_subcode, action, evt_len, ref_value, status);
294 if(NULL != btm_ble_adv_filt_cb.p_filt_stat_cback)
295 btm_ble_adv_filt_cb.p_filt_stat_cback(action, status, ref_value);
296 BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback enabled/disabled, %d, %d, %d, %d",
297 ocf, action, status, ref_value);
302 if (4 == evt_len && ocf != op_subcode)
304 BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:4-Incorrect opcode: %d, %d, %d, %d, %d",
305 ocf, op_subcode, action, status, ref_value);
309 STREAM_TO_UINT8(num_avail, p);
312 case BTM_BLE_META_PF_ADDR:
313 case BTM_BLE_META_PF_UUID:
314 case BTM_BLE_META_PF_SOL_UUID:
315 case BTM_BLE_META_PF_LOCAL_NAME:
316 case BTM_BLE_META_PF_MANU_DATA:
317 case BTM_BLE_META_PF_SRVC_DATA:
318 cond_type = btm_ble_ocf_to_condtype(ocf);
319 BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback Recd: %d, %d, %d, %d, %d, %d", op_subcode,
320 ocf, action, status, ref_value, num_avail);
321 if (HCI_SUCCESS == status)
323 if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda, BD_ADDR_LEN) == 0)
324 btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail);
326 btm_ble_cs_update_pf_counter(action, cond_type,
327 &btm_ble_adv_filt_cb.cur_filter_target, num_avail);
330 /* send ADV PF operation complete */
331 btm_ble_adv_filt_cb.op_type = 0;
334 case BTM_BLE_META_PF_FEAT_SEL:
335 BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback-Feat sel event: %d, %d, %d, %d",
336 action, status, ref_value, num_avail);
340 BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback: unknown operation: %d", op_subcode);
346 BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback: calling the cback: %d", cb_evt);
347 case BTM_BLE_FILT_CFG:
348 if(NULL != p_scan_cfg_cback)
349 p_scan_cfg_cback(action, cond_type, num_avail, status, ref_value);
351 case BTM_BLE_FILT_ADV_PARAM:
352 if(NULL != p_filt_param_cback)
353 p_filt_param_cback(action, num_avail, ref_value, status);
360 /*******************************************************************************
362 ** Function btm_ble_find_addr_filter_counter
364 ** Description find the per bd address ADV payload filter counter by BD_ADDR.
366 ** Returns pointer to the counter if found; NULL otherwise.
368 *******************************************************************************/
369 tBTM_BLE_PF_COUNT* btm_ble_find_addr_filter_counter(tBLE_BD_ADDR *p_le_bda)
372 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
374 if (p_le_bda == NULL)
375 return &btm_ble_adv_filt_cb.p_addr_filter_count[0];
377 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
379 if (p_addr_filter->in_use &&
380 memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)
382 return p_addr_filter;
388 /*******************************************************************************
390 ** Function btm_ble_alloc_addr_filter_counter
392 ** Description allocate the per device adv payload filter counter.
394 ** Returns pointer to the counter if allocation succeed; NULL otherwise.
396 *******************************************************************************/
397 tBTM_BLE_PF_COUNT * btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)
400 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
402 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
404 if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)
406 memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN);
407 p_addr_filter->in_use = TRUE;
408 return p_addr_filter;
413 /*******************************************************************************
415 ** Function btm_ble_dealloc_addr_filter_counter
417 ** Description de-allocate the per device adv payload filter counter.
419 ** Returns TRUE if deallocation succeed; FALSE otherwise.
421 *******************************************************************************/
422 BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type)
425 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
426 BOOLEAN found = FALSE;
428 if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr)
429 memset(&btm_ble_adv_filt_cb.p_addr_filter_count[0], 0, sizeof(tBTM_BLE_PF_COUNT));
431 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
433 if ((p_addr_filter->in_use) && (NULL == p_bd_addr ||
434 (NULL != p_bd_addr &&
435 memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)))
438 memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
440 if (NULL != p_bd_addr) break;
446 /*******************************************************************************
448 ** Function btm_ble_update_pf_local_name
450 ** Description this function update(add,delete or clear) the adv lcoal name filtering condition.
453 ** Returns BTM_SUCCESS if sucessful,
454 ** BTM_ILLEGAL_VALUE if paramter is not valid.
456 *******************************************************************************/
457 tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action,
458 tBTM_BLE_PF_FILT_INDEX filt_index,
459 tBTM_BLE_PF_COND_PARAM *p_cond)
461 tBTM_BLE_PF_LOCAL_NAME_COND *p_local_name = (p_cond == NULL) ? NULL : &p_cond->local_name;
462 UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
464 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
465 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
467 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
469 UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME);
470 UINT8_TO_STREAM(p, action);
473 UINT8_TO_STREAM(p, filt_index);
475 if (BTM_BLE_SCAN_COND_ADD == action ||
476 BTM_BLE_SCAN_COND_DELETE == action)
478 if (NULL == p_local_name)
481 if (p_local_name->data_len > BTM_BLE_PF_STR_LEN_MAX)
482 p_local_name->data_len = BTM_BLE_PF_STR_LEN_MAX;
484 ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len);
485 len += p_local_name->data_len;
488 /* send local name filter */
489 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
492 btm_ble_scan_pf_cmpl_cback))
495 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
499 BTM_TRACE_ERROR("Local Name PF filter update failed");
506 /*******************************************************************************
508 ** Function btm_ble_update_srvc_data_change
510 ** Description this function update(add/remove) service data change filter.
513 ** Returns BTM_SUCCESS if sucessful,
514 ** BTM_ILLEGAL_VALUE if paramter is not valid.
516 *******************************************************************************/
517 tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action,
518 tBTM_BLE_PF_FILT_INDEX filt_index,
519 tBTM_BLE_PF_COND_PARAM *p_cond)
521 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
522 tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL;
523 UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1;
525 if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail)
526 != BTM_BLE_INVALID_COUNTER)
532 /*******************************************************************************
534 ** Function btm_ble_update_pf_manu_data
536 ** Description this function update(add,delete or clear) the adv manufacturer
537 ** data filtering condition.
540 ** Returns BTM_SUCCESS if sucessful,
541 ** BTM_ILLEGAL_VALUE if paramter is not valid.
543 *******************************************************************************/
544 tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action,
545 tBTM_BLE_PF_FILT_INDEX filt_index,
546 tBTM_BLE_PF_COND_PARAM *p_data,
547 tBTM_BLE_PF_COND_TYPE cond_type,
548 tBTM_BLE_FILT_CB_EVT cb_evt,
549 tBTM_BLE_REF_VALUE ref_value)
551 tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data;
552 tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data;
554 UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
556 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
557 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
562 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX
563 + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
565 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
567 UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA);
571 UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA);
574 UINT8_TO_STREAM(p, action);
577 UINT8_TO_STREAM(p, filt_index);
579 if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action)
581 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
583 if (NULL == p_srvc_data)
585 if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2))
586 p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
588 if (p_srvc_data->data_len > 0)
590 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len);
591 len += (p_srvc_data->data_len);
592 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len);
595 len += (p_srvc_data->data_len);
596 BTM_TRACE_DEBUG("Service data length: %d", len);
600 if (NULL == p_manu_data)
602 BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data");
605 BTM_TRACE_EVENT("btm_ble_update_pf_manu_data length: %d",
606 p_manu_data->data_len);
607 if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2))
608 p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
610 UINT16_TO_STREAM(p, p_manu_data->company_id);
611 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL)
613 ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len);
614 len += (p_manu_data->data_len + 2);
619 if (p_manu_data->company_id_mask != 0)
621 UINT16_TO_STREAM (p, p_manu_data->company_id_mask);
630 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL)
632 ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len);
633 len += (p_manu_data->data_len);
636 BTM_TRACE_DEBUG("Manuf data length: %d", len);
640 /* send manufacturer*/
641 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
644 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
646 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
650 BTM_TRACE_ERROR("manufacturer data PF filter update failed");
656 /*******************************************************************************
658 ** Function btm_ble_cs_update_pf_counter
660 ** Description this function is to update the adv data payload filter counter
662 ** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if
663 ** counter update failed.
665 *******************************************************************************/
666 UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
667 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr,
670 tBTM_BLE_PF_COUNT *p_addr_filter = NULL;
671 UINT8 *p_counter = NULL;
673 btm_ble_obtain_vsc_details();
675 if (cond_type > BTM_BLE_PF_TYPE_ALL)
677 BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type);
678 return BTM_BLE_INVALID_COUNTER;
681 /* for these three types of filter, always generic */
682 if (BTM_BLE_PF_ADDR_FILTER == cond_type ||
683 BTM_BLE_PF_MANU_DATA == cond_type ||
684 BTM_BLE_PF_LOCAL_NAME == cond_type ||
685 BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
688 if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
689 BTM_BLE_SCAN_COND_ADD == action)
691 p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
694 if (NULL != p_addr_filter)
696 /* all filter just cleared */
697 if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) ||
698 /* or bd address filter been deleted */
699 (BTM_BLE_PF_ADDR_FILTER == cond_type &&
700 (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action)))
702 btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
704 /* if not feature selection, update new addition/reduction of the filter counter */
705 else if (cond_type != BTM_BLE_PF_TYPE_ALL)
707 p_counter = p_addr_filter->pf_counter;
708 if (num_available > 0)
709 p_counter[cond_type] += 1;
711 BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d",
712 p_counter[cond_type], cmn_ble_vsc_cb.max_filter, num_available);
713 return p_counter[cond_type];
718 BTM_TRACE_ERROR("no matching filter counter found");
720 /* no matching filter located and updated */
721 return BTM_BLE_INVALID_COUNTER;
725 /*******************************************************************************
727 ** Function btm_ble_update_addr_filter
729 ** Description this function update(add,delete or clear) the address filter of adv.
732 ** Returns BTM_SUCCESS if sucessful,
733 ** BTM_ILLEGAL_VALUE if paramter is not valid.
735 *******************************************************************************/
736 tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action,
737 tBTM_BLE_PF_FILT_INDEX filt_index,
738 tBTM_BLE_PF_COND_PARAM *p_cond)
740 UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
742 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
743 tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr;
745 memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
747 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
748 UINT8_TO_STREAM(p, action);
751 UINT8_TO_STREAM(p, filt_index);
753 if (BTM_BLE_SCAN_COND_ADD == action ||
754 BTM_BLE_SCAN_COND_DELETE == action)
759 BDADDR_TO_STREAM(p, p_addr->bda);
760 UINT8_TO_STREAM(p, p_addr->type);
762 /* send address filter */
763 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
764 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
766 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
768 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
772 BTM_TRACE_ERROR("Broadcaster Address Filter Update failed");
777 /*******************************************************************************
779 ** Function btm_ble_update_uuid_filter
781 ** Description this function update(add,delete or clear) service UUID filter.
784 ** Returns BTM_SUCCESS if sucessful,
785 ** BTM_ILLEGAL_VALUE if paramter is not valid.
787 *******************************************************************************/
788 tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
789 tBTM_BLE_PF_FILT_INDEX filt_index,
790 tBTM_BLE_PF_COND_TYPE filter_type,
791 tBTM_BLE_PF_COND_PARAM *p_cond,
792 tBTM_BLE_FILT_CB_EVT cb_evt,
793 tBTM_BLE_REF_VALUE ref_value)
795 UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
797 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
798 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
799 tBTM_BLE_PF_UUID_COND *p_uuid_cond;
802 memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
804 if (BTM_BLE_PF_SRVC_UUID == filter_type)
806 evt_type = BTM_BLE_META_PF_UUID;
807 p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL;
811 evt_type = BTM_BLE_META_PF_SOL_UUID;
812 p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL;
815 if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR)
817 BTM_TRACE_ERROR("Illegal param for add/delete UUID filter");
821 /* need to add address filter first, if adding per bda UUID filter without address filter */
822 if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond &&
823 p_uuid_cond->p_target_addr &&
824 btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL)
826 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
827 UINT8_TO_STREAM(p, action);
830 UINT8_TO_STREAM(p, filt_index);
832 BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda);
833 UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type);
835 /* send address filter */
836 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
837 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
839 btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES)
841 BTM_TRACE_ERROR("Update Address filter into controller failed.");
845 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_ADDR, cb_evt, ref_value, NULL, NULL);
846 BTM_TRACE_DEBUG("Updated Address filter");
850 UINT8_TO_STREAM(p, evt_type);
851 UINT8_TO_STREAM(p, action);
854 UINT8_TO_STREAM(p, filt_index);
856 if ((BTM_BLE_SCAN_COND_ADD == action ||
857 BTM_BLE_SCAN_COND_DELETE == action) &&
860 if (p_uuid_cond->uuid.len == LEN_UUID_16)
862 UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16);
865 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
867 UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32);
870 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
872 ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128);
877 BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len);
878 return BTM_ILLEGAL_VALUE;
881 if (NULL != p_uuid_cond->p_uuid_mask)
883 if (p_uuid_cond->uuid.len == LEN_UUID_16)
885 UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask);
888 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
890 UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask);
893 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
895 ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128);
901 memset(p, 0xff, p_uuid_cond->uuid.len);
902 len += p_uuid_cond->uuid.len;
904 BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type,
905 p_uuid_cond->uuid.len, len);
908 /* send UUID filter update */
909 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
912 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
914 if (p_uuid_cond && p_uuid_cond->p_target_addr)
915 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr,
916 sizeof(tBLE_BD_ADDR));
918 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
922 BTM_TRACE_ERROR("UUID filter udpating failed");
929 /*******************************************************************************
931 ** Function btm_ble_clear_scan_pf_filter
933 ** Description clear all adv payload filter by de-select all the adv pf feature bits
936 ** Returns BTM_SUCCESS if sucessful,
937 ** BTM_ILLEGAL_VALUE if paramter is not valid.
939 *******************************************************************************/
940 tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action,
941 tBTM_BLE_PF_FILT_INDEX filt_index,
942 tBTM_BLE_PF_COND_PARAM *p_cond,
943 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
944 tBTM_BLE_FILT_CB_EVT cb_evt,
945 tBTM_BLE_REF_VALUE ref_value)
947 tBLE_BD_ADDR *p_target = (p_cond == NULL)? NULL : &p_cond->target_addr;
948 tBTM_BLE_PF_COUNT *p_bda_filter;
949 tBTM_STATUS st = BTM_WRONG_MODE;
952 if (BTM_BLE_SCAN_COND_CLEAR != action)
954 BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action);
955 return BTM_ILLEGAL_VALUE;
959 memset(param, 0, 20);
961 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
963 if (NULL == p_bda_filter ||
964 /* not a generic filter */
965 (p_target != NULL && p_bda_filter))
967 BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!");
971 /* clear the general filter entry */
972 if (NULL == p_target)
974 /* clear manufactuer data filter */
975 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
976 BTM_BLE_PF_MANU_DATA, cb_evt, ref_value);
977 if(BTM_CMD_STARTED == st)
978 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_MANU_DATA, cb_evt,
979 ref_value, NULL, NULL);
981 /* clear local name filter */
982 st = btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
983 if(BTM_CMD_STARTED == st)
984 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_LOCAL_NAME, cb_evt,
985 ref_value, NULL, NULL);
987 /* update the counter for service data */
988 st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
990 /* clear UUID filter */
991 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
992 BTM_BLE_PF_SRVC_UUID, NULL, cb_evt, ref_value);
993 if(BTM_CMD_STARTED == st)
994 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_UUID, cb_evt, ref_value, NULL, NULL);
996 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
997 BTM_BLE_PF_SRVC_SOL_UUID, NULL, cb_evt, ref_value);
998 if(BTM_CMD_STARTED == st)
999 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SOL_UUID, cb_evt,
1000 ref_value, NULL, NULL);
1002 /* clear service data filter */
1003 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
1004 BTM_BLE_PF_SRVC_DATA_PATTERN, cb_evt, ref_value);
1005 if(BTM_CMD_STARTED == st)
1006 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SRVC_DATA, cb_evt,
1007 ref_value, NULL, NULL);
1010 /* select feature based on control block settings */
1011 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1012 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
1015 UINT8_TO_STREAM(p, filt_index);
1017 /* set PCF selection */
1018 UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE);
1019 /* set logic condition as OR as default */
1020 UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR);
1022 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1023 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN),
1025 btm_ble_scan_pf_cmpl_cback))
1026 != BTM_NO_RESOURCES)
1029 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR));
1031 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
1036 /*******************************************************************************
1038 ** Function BTM_BleAdvFilterParamSetup
1040 ** Description This function is called to setup the adv data payload filter
1043 ** Parameters action - Type of action to be performed
1044 ** filt_index - Filter index
1045 ** p_filt_params - Filter parameters
1046 ** p_target - Target device
1047 ** p_cmpl_back - Callback pointer
1048 ** ref_value - reference value
1052 *******************************************************************************/
1053 tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index,
1054 tBTM_BLE_PF_FILT_PARAMS *p_filt_params,
1055 tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback,
1056 tBTM_BLE_REF_VALUE ref_value)
1058 tBTM_STATUS st = BTM_WRONG_MODE;
1059 tBTM_BLE_PF_COUNT *p_bda_filter = NULL;
1060 UINT8 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1061 BTM_BLE_ADV_FILT_TRACK_NUM;
1062 UINT8 param[len], *p;
1064 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1068 memset(param, 0, len);
1069 BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup");
1071 if (BTM_BLE_SCAN_COND_ADD == action)
1073 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
1074 if (NULL == p_bda_filter)
1076 BTM_TRACE_ERROR("BD Address not found!");
1080 BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_filt_params->feat_seln);
1081 /* select feature based on control block settings */
1082 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1083 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD);
1086 UINT8_TO_STREAM(p, filt_index);
1088 /* set PCF selection */
1089 UINT16_TO_STREAM(p, p_filt_params->feat_seln);
1090 /* set logic type */
1091 UINT16_TO_STREAM(p, p_filt_params->logic_type);
1092 /* set logic condition */
1093 UINT8_TO_STREAM(p, p_filt_params->filt_logic_type);
1094 /* set RSSI high threshold */
1095 UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres);
1096 /* set delivery mode */
1097 UINT8_TO_STREAM(p, p_filt_params->dely_mode);
1099 if (0x01 == p_filt_params->dely_mode)
1101 /* set onfound timeout */
1102 UINT16_TO_STREAM(p, p_filt_params->found_timeout);
1103 /* set onfound timeout count*/
1104 UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt);
1105 /* set RSSI low threshold */
1106 UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres);
1107 /* set onlost timeout */
1108 UINT16_TO_STREAM(p, p_filt_params->lost_timeout);
1109 /* set num_of_track_entries for firmware greater than L-release version */
1110 if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION)
1111 UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries);
1114 if (cmn_ble_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION)
1115 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN;
1117 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1118 BTM_BLE_ADV_FILT_TRACK_NUM;
1120 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1123 btm_ble_scan_pf_cmpl_cback))
1124 == BTM_NO_RESOURCES)
1128 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1129 ref_value, NULL, p_cmpl_cback);
1132 if (BTM_BLE_SCAN_COND_DELETE == action)
1134 /* select feature based on control block settings */
1135 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1136 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE);
1138 UINT8_TO_STREAM(p, filt_index);
1140 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1141 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
1143 btm_ble_scan_pf_cmpl_cback))
1144 == BTM_NO_RESOURCES)
1148 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1149 ref_value, NULL, p_cmpl_cback);
1152 if (BTM_BLE_SCAN_COND_CLEAR == action)
1154 /* Deallocate all filters here */
1155 btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
1157 /* select feature based on control block settings */
1158 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1159 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
1161 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1162 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH-1),
1164 btm_ble_scan_pf_cmpl_cback))
1165 == BTM_NO_RESOURCES)
1169 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1170 ref_value, NULL, p_cmpl_cback);
1176 /*******************************************************************************
1178 ** Function BTM_BleEnableDisableFilterFeature
1180 ** Description This function is called to enable / disable the APCF feature
1182 ** Parameters enable the generic scan condition.
1183 ** enable: enable or disable the filter condition
1184 ** p_stat_cback - Status callback pointer
1185 ** ref_value - Ref value
1188 *******************************************************************************/
1189 tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
1190 tBTM_BLE_PF_STATUS_CBACK *p_stat_cback,
1191 tBTM_BLE_REF_VALUE ref_value)
1193 UINT8 param[20], *p;
1194 tBTM_STATUS st = BTM_WRONG_MODE;
1196 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1200 memset(param, 0, 20);
1202 /* enable the content filter in controller */
1204 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE);
1205 /* enable adv data payload filtering */
1206 UINT8_TO_STREAM(p, enable);
1208 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1209 BTM_BLE_PCF_ENABLE_LEN, param,
1210 btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED)
1212 btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback;
1213 btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, BTM_BLE_FILT_ENABLE_DISABLE,
1214 ref_value, NULL, NULL);
1219 /*******************************************************************************
1221 ** Function BTM_BleCfgFilterCondition
1223 ** Description This function is called to configure the adv data payload filter
1226 ** Parameters action: to read/write/clear
1227 ** cond_type: filter condition type.
1228 ** filt_index - Filter index
1229 ** p_cond: filter condition parameter
1230 ** p_cmpl_cback - Config callback pointer
1231 ** ref_value - Reference value
1235 *******************************************************************************/
1236 tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action,
1237 tBTM_BLE_PF_COND_TYPE cond_type,
1238 tBTM_BLE_PF_FILT_INDEX filt_index,
1239 tBTM_BLE_PF_COND_PARAM *p_cond,
1240 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
1241 tBTM_BLE_REF_VALUE ref_value)
1243 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
1245 BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action,
1246 cond_type, filt_index);
1248 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1253 /* write service data filter */
1254 case BTM_BLE_PF_SRVC_DATA_PATTERN:
1255 /* write manufacturer data filter */
1256 case BTM_BLE_PF_MANU_DATA:
1257 st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type, 0, ref_value);
1260 /* write local name filter */
1261 case BTM_BLE_PF_LOCAL_NAME:
1262 st = btm_ble_update_pf_local_name(action, filt_index, p_cond);
1265 /* filter on advertiser address */
1266 case BTM_BLE_PF_ADDR_FILTER:
1267 st = btm_ble_update_addr_filter(action, filt_index, p_cond);
1270 /* filter on service/solicitated UUID */
1271 case BTM_BLE_PF_SRVC_UUID:
1272 case BTM_BLE_PF_SRVC_SOL_UUID:
1273 st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond, 0, ref_value);
1276 case BTM_BLE_PF_SRVC_DATA:
1277 st = btm_ble_update_srvc_data_change(action, filt_index, p_cond);
1280 case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */
1281 st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, p_cmpl_cback,
1286 BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type);
1290 if(BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL)
1292 ocf = btm_ble_condtype_to_ocf(cond_type);
1293 btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, p_cmpl_cback, NULL);
1296 if(BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type)
1298 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_CFG,
1299 ref_value, p_cmpl_cback, NULL);
1304 /*******************************************************************************
1306 ** Function btm_ble_adv_filter_init
1308 ** Description This function initializes the adv filter control block
1314 *******************************************************************************/
1315 void btm_ble_adv_filter_init(void)
1317 memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
1318 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1321 if (cmn_ble_vsc_cb.max_filter > 0)
1323 btm_ble_adv_filt_cb.p_addr_filter_count =
1324 (tBTM_BLE_PF_COUNT*) GKI_getbuf( sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter);
1328 /*******************************************************************************
1330 ** Function btm_ble_adv_filter_cleanup
1332 ** Description This function de-initializes the adv filter control block
1338 *******************************************************************************/
1339 void btm_ble_adv_filter_cleanup(void)
1341 if (btm_ble_adv_filt_cb.p_addr_filter_count)
1342 GKI_freebuf (btm_ble_adv_filt_cb.p_addr_filter_count);