1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Broadcom Corporation
4 *
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:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "bt_btm_ble"
20
21 #include <string.h>
22 #include "bt_target.h"
23
24 #if (BLE_INCLUDED == TRUE)
25 #include "bt_types.h"
26 #include "hcimsgs.h"
27 #include "btu.h"
28 #include "btm_int.h"
29 #include "bt_utils.h"
30 #include "hcidefs.h"
31 #include "btm_ble_api.h"
32 #include "device/include/controller.h"
33
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
37
38 #define BTM_BLE_PF_SELECT_NONE 0
39
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
44
45 #define BTM_BLE_META_ADDR_LEN 7
46 #define BTM_BLE_META_UUID_LEN 40
47
48 #define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x))
49
50
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};
54
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);
57
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
62
63
64 /* length of each multi adv sub command */
65 #define BTM_BLE_ADV_FILTER_ENB_LEN 3
66
67 /* length of each batch scan command */
68 #define BTM_BLE_ADV_FILTER_CLEAR_LEN 3
69 #define BTM_BLE_ADV_FILTER_LEN 2
70
71 #define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0
72 #define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F
73
74 /*******************************************************************************
75 **
76 ** Function btm_ble_obtain_vsc_details
77 **
78 ** Description This function obtains the VSC details
79 **
80 ** Parameters
81 **
82 ** Returns status
83 **
84 *******************************************************************************/
btm_ble_obtain_vsc_details()85 tBTM_STATUS btm_ble_obtain_vsc_details()
86 {
87 tBTM_STATUS st = BTM_SUCCESS;
88
89 #if BLE_VND_INCLUDED == TRUE
90 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
91 if (0 == cmn_ble_vsc_cb.max_filter)
92 {
93 st = BTM_MODE_UNSUPPORTED;
94 return st;
95 }
96 #else
97 cmn_ble_vsc_cb.max_filter = BTM_BLE_MAX_FILTER_COUNTER;
98 #endif
99 return st;
100 }
101
102 /*******************************************************************************
103 **
104 ** Function btm_ble_advfilt_enq_op_q
105 **
106 ** Description enqueue an adv filter operation in q to check command complete
107 ** status
108 **
109 ** Returns void
110 **
111 *******************************************************************************/
btm_ble_advfilt_enq_op_q(UINT8 action,UINT8 ocf,tBTM_BLE_FILT_CB_EVT cb_evt,tBTM_BLE_REF_VALUE ref,tBTM_BLE_PF_CFG_CBACK * p_cmpl_cback,tBTM_BLE_PF_PARAM_CBACK * p_filt_param_cback)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)
115 {
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;
127 }
128
129 /*******************************************************************************
130 **
131 ** Function btm_ble_advfilt_deq_op_q
132 **
133 ** Description dequeue an adv filter operation from q when command complete
134 ** is received
135 **
136 ** Returns void
137 **
138 *******************************************************************************/
btm_ble_advfilt_deq_op_q(UINT8 * p_action,UINT8 * p_ocf,tBTM_BLE_FILT_CB_EVT * p_cb_evt,tBTM_BLE_REF_VALUE * p_ref,tBTM_BLE_PF_CFG_CBACK ** p_cmpl_cback,tBTM_BLE_PF_PARAM_CBACK ** p_filt_param_cback)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)
142 {
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];
151
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);
156 }
157
158 /*******************************************************************************
159 **
160 ** Function btm_ble_condtype_to_ocf
161 **
162 ** Description Convert cond_type to OCF
163 **
164 ** Returns Returns ocf value
165 **
166 *******************************************************************************/
btm_ble_condtype_to_ocf(UINT8 cond_type)167 UINT8 btm_ble_condtype_to_ocf(UINT8 cond_type)
168 {
169 UINT8 ocf = 0;
170
171 switch(cond_type)
172 {
173 case BTM_BLE_PF_ADDR_FILTER:
174 ocf = BTM_BLE_META_PF_ADDR;
175 break;
176 case BTM_BLE_PF_SRVC_UUID:
177 ocf = BTM_BLE_META_PF_UUID;
178 break;
179 case BTM_BLE_PF_SRVC_SOL_UUID:
180 ocf = BTM_BLE_META_PF_SOL_UUID;
181 break;
182 case BTM_BLE_PF_LOCAL_NAME:
183 ocf = BTM_BLE_META_PF_LOCAL_NAME;
184 break;
185 case BTM_BLE_PF_MANU_DATA:
186 ocf = BTM_BLE_META_PF_MANU_DATA;
187 break;
188 case BTM_BLE_PF_SRVC_DATA_PATTERN:
189 ocf = BTM_BLE_META_PF_SRVC_DATA;
190 break;
191 case BTM_BLE_PF_TYPE_ALL:
192 ocf = BTM_BLE_META_PF_ALL;
193 break;
194 default:
195 ocf = BTM_BLE_PF_TYPE_MAX;
196 break;
197 }
198 return ocf;
199 }
200
201 /*******************************************************************************
202 **
203 ** Function btm_ble_ocf_to_condtype
204 **
205 ** Description Convert OCF to cond type
206 **
207 ** Returns Returns condtype value
208 **
209 *******************************************************************************/
btm_ble_ocf_to_condtype(UINT8 ocf)210 UINT8 btm_ble_ocf_to_condtype(UINT8 ocf)
211 {
212 UINT8 cond_type = 0;
213
214 switch(ocf)
215 {
216 case BTM_BLE_META_PF_FEAT_SEL:
217 cond_type = BTM_BLE_META_PF_FEAT_SEL;
218 break;
219 case BTM_BLE_META_PF_ADDR:
220 cond_type = BTM_BLE_PF_ADDR_FILTER;
221 break;
222 case BTM_BLE_META_PF_UUID:
223 cond_type = BTM_BLE_PF_SRVC_UUID;
224 break;
225 case BTM_BLE_META_PF_SOL_UUID:
226 cond_type = BTM_BLE_PF_SRVC_SOL_UUID;
227 break;
228 case BTM_BLE_META_PF_LOCAL_NAME:
229 cond_type = BTM_BLE_PF_LOCAL_NAME;
230 break;
231 case BTM_BLE_META_PF_MANU_DATA:
232 cond_type = BTM_BLE_PF_MANU_DATA;
233 break;
234 case BTM_BLE_META_PF_SRVC_DATA:
235 cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN;
236 break;
237 case BTM_BLE_META_PF_ALL:
238 cond_type = BTM_BLE_PF_TYPE_ALL;
239 break;
240 default:
241 cond_type = BTM_BLE_PF_TYPE_MAX;
242 break;
243 }
244 return cond_type;
245 }
246
247 /*******************************************************************************
248 **
249 ** Function btm_ble_scan_pf_cmpl_cback
250 **
251 ** Description the BTM BLE customer feature VSC complete callback for ADV PF filtering
252 **
253 ** Returns pointer to the counter if found; NULL otherwise.
254 **
255 *******************************************************************************/
btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL * p_params)256 void btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params)
257 {
258 UINT8 status = 0;
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;
266
267 if (evt_len < 3 || evt_len > 4)
268 {
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);
273 return;
274 }
275
276 btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback,
277 &p_filt_param_cback);
278
279 STREAM_TO_UINT8(status, p);
280 STREAM_TO_UINT8(op_subcode, p);
281 STREAM_TO_UINT8(action, p);
282
283 /* Ignore the event, if it is not the same one expected */
284 if (3 == evt_len)
285 {
286 if(ocf != op_subcode)
287 {
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);
290 return;
291 }
292 else
293 {
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);
298 return;
299 }
300 }
301
302 if (4 == evt_len && ocf != op_subcode)
303 {
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);
306 return;
307 }
308
309 STREAM_TO_UINT8(num_avail, p);
310 switch (op_subcode)
311 {
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)
322 {
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);
325 else
326 btm_ble_cs_update_pf_counter(action, cond_type,
327 &btm_ble_adv_filt_cb.cur_filter_target, num_avail);
328 }
329
330 /* send ADV PF operation complete */
331 btm_ble_adv_filt_cb.op_type = 0;
332 break;
333
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);
337 break;
338
339 default:
340 BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback: unknown operation: %d", op_subcode);
341 break;
342 }
343
344 switch(cb_evt)
345 {
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);
350 break;
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);
354 break;
355 default:
356 break;
357 }
358 }
359
360 /*******************************************************************************
361 **
362 ** Function btm_ble_find_addr_filter_counter
363 **
364 ** Description find the per bd address ADV payload filter counter by BD_ADDR.
365 **
366 ** Returns pointer to the counter if found; NULL otherwise.
367 **
368 *******************************************************************************/
btm_ble_find_addr_filter_counter(tBLE_BD_ADDR * p_le_bda)369 tBTM_BLE_PF_COUNT* btm_ble_find_addr_filter_counter(tBLE_BD_ADDR *p_le_bda)
370 {
371 UINT8 i;
372 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
373
374 if (p_le_bda == NULL)
375 return &btm_ble_adv_filt_cb.p_addr_filter_count[0];
376
377 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
378 {
379 if (p_addr_filter->in_use &&
380 memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)
381 {
382 return p_addr_filter;
383 }
384 }
385 return NULL;
386 }
387
388 /*******************************************************************************
389 **
390 ** Function btm_ble_alloc_addr_filter_counter
391 **
392 ** Description allocate the per device adv payload filter counter.
393 **
394 ** Returns pointer to the counter if allocation succeed; NULL otherwise.
395 **
396 *******************************************************************************/
btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)397 tBTM_BLE_PF_COUNT * btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)
398 {
399 UINT8 i;
400 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
401
402 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
403 {
404 if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0)
405 {
406 memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN);
407 p_addr_filter->in_use = TRUE;
408 return p_addr_filter;
409 }
410 }
411 return NULL;
412 }
413 /*******************************************************************************
414 **
415 ** Function btm_ble_dealloc_addr_filter_counter
416 **
417 ** Description de-allocate the per device adv payload filter counter.
418 **
419 ** Returns TRUE if deallocation succeed; FALSE otherwise.
420 **
421 *******************************************************************************/
btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR * p_bd_addr,UINT8 filter_type)422 BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type)
423 {
424 UINT8 i;
425 tBTM_BLE_PF_COUNT *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
426 BOOLEAN found = FALSE;
427
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));
430
431 for (i = 0; i < cmn_ble_vsc_cb.max_filter; i ++, p_addr_filter ++)
432 {
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)))
436 {
437 found = TRUE;
438 memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
439
440 if (NULL != p_bd_addr) break;
441 }
442 }
443 return found;
444 }
445
446 /*******************************************************************************
447 **
448 ** Function btm_ble_update_pf_local_name
449 **
450 ** Description this function update(add,delete or clear) the adv lcoal name filtering condition.
451 **
452 **
453 ** Returns BTM_SUCCESS if sucessful,
454 ** BTM_ILLEGAL_VALUE if paramter is not valid.
455 **
456 *******************************************************************************/
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)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)
460 {
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],
463 *p = param,
464 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
465 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
466
467 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
468
469 UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME);
470 UINT8_TO_STREAM(p, action);
471
472 /* Filter index */
473 UINT8_TO_STREAM(p, filt_index);
474
475 if (BTM_BLE_SCAN_COND_ADD == action ||
476 BTM_BLE_SCAN_COND_DELETE == action)
477 {
478 if (NULL == p_local_name)
479 return st;
480
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;
483
484 ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len);
485 len += p_local_name->data_len;
486 }
487
488 /* send local name filter */
489 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
490 len,
491 param,
492 btm_ble_scan_pf_cmpl_cback))
493 != BTM_NO_RESOURCES)
494 {
495 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
496 }
497 else
498 {
499 BTM_TRACE_ERROR("Local Name PF filter update failed");
500 }
501
502 return st;
503 }
504
505
506 /*******************************************************************************
507 **
508 ** Function btm_ble_update_srvc_data_change
509 **
510 ** Description this function update(add/remove) service data change filter.
511 **
512 **
513 ** Returns BTM_SUCCESS if sucessful,
514 ** BTM_ILLEGAL_VALUE if paramter is not valid.
515 **
516 *******************************************************************************/
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)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)
520 {
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;
524
525 if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail)
526 != BTM_BLE_INVALID_COUNTER)
527 st = BTM_SUCCESS;
528
529 return st;
530 }
531
532 /*******************************************************************************
533 **
534 ** Function btm_ble_update_pf_manu_data
535 **
536 ** Description this function update(add,delete or clear) the adv manufacturer
537 ** data filtering condition.
538 **
539 **
540 ** Returns BTM_SUCCESS if sucessful,
541 ** BTM_ILLEGAL_VALUE if paramter is not valid.
542 **
543 *******************************************************************************/
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_FILT_CB_EVT cb_evt,tBTM_BLE_REF_VALUE ref_value)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)
550 {
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;
553
554 UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
555 *p = param,
556 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
557 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
558
559 if (NULL == p_data)
560 return st;
561
562 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX
563 + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
564
565 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
566 {
567 UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA);
568 }
569 else
570 {
571 UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA);
572 }
573
574 UINT8_TO_STREAM(p, action);
575
576 /* Filter index */
577 UINT8_TO_STREAM(p, filt_index);
578
579 if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action)
580 {
581 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
582 {
583 if (NULL == p_srvc_data)
584 return st;
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);
587
588 if (p_srvc_data->data_len > 0)
589 {
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);
593 }
594
595 len += (p_srvc_data->data_len);
596 BTM_TRACE_DEBUG("Service data length: %d", len);
597 }
598 else
599 {
600 if (NULL == p_manu_data)
601 {
602 BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data");
603 return st;
604 }
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);
609
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)
612 {
613 ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len);
614 len += (p_manu_data->data_len + 2);
615 }
616 else
617 len += 2;
618
619 if (p_manu_data->company_id_mask != 0)
620 {
621 UINT16_TO_STREAM (p, p_manu_data->company_id_mask);
622 }
623 else
624 {
625 memset(p, 0xff, 2);
626 p += 2;
627 }
628 len += 2;
629
630 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL)
631 {
632 ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len);
633 len += (p_manu_data->data_len);
634 }
635
636 BTM_TRACE_DEBUG("Manuf data length: %d", len);
637 }
638 }
639
640 /* send manufacturer*/
641 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
642 len,
643 param,
644 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
645 {
646 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
647 }
648 else
649 {
650 BTM_TRACE_ERROR("manufacturer data PF filter update failed");
651 }
652
653 return st;
654 }
655
656 /*******************************************************************************
657 **
658 ** Function btm_ble_cs_update_pf_counter
659 **
660 ** Description this function is to update the adv data payload filter counter
661 **
662 ** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if
663 ** counter update failed.
664 **
665 *******************************************************************************/
btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,UINT8 cond_type,tBLE_BD_ADDR * p_bd_addr,UINT8 num_available)666 UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
667 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr,
668 UINT8 num_available)
669 {
670 tBTM_BLE_PF_COUNT *p_addr_filter = NULL;
671 UINT8 *p_counter = NULL;
672
673 btm_ble_obtain_vsc_details();
674
675 if (cond_type > BTM_BLE_PF_TYPE_ALL)
676 {
677 BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type);
678 return BTM_BLE_INVALID_COUNTER;
679 }
680
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)
686 p_bd_addr = NULL;
687
688 if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
689 BTM_BLE_SCAN_COND_ADD == action)
690 {
691 p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
692 }
693
694 if (NULL != p_addr_filter)
695 {
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)))
701 {
702 btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
703 }
704 /* if not feature selection, update new addition/reduction of the filter counter */
705 else if (cond_type != BTM_BLE_PF_TYPE_ALL)
706 {
707 p_counter = p_addr_filter->pf_counter;
708 if (num_available > 0)
709 p_counter[cond_type] += 1;
710
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];
714 }
715 }
716 else
717 {
718 BTM_TRACE_ERROR("no matching filter counter found");
719 }
720 /* no matching filter located and updated */
721 return BTM_BLE_INVALID_COUNTER;
722 }
723
724
725 /*******************************************************************************
726 **
727 ** Function btm_ble_update_addr_filter
728 **
729 ** Description this function update(add,delete or clear) the address filter of adv.
730 **
731 **
732 ** Returns BTM_SUCCESS if sucessful,
733 ** BTM_ILLEGAL_VALUE if paramter is not valid.
734 **
735 *******************************************************************************/
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)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)
739 {
740 UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
741 * p= param;
742 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
743 tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr;
744
745 memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
746
747 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
748 UINT8_TO_STREAM(p, action);
749
750 /* Filter index */
751 UINT8_TO_STREAM(p, filt_index);
752
753 if (BTM_BLE_SCAN_COND_ADD == action ||
754 BTM_BLE_SCAN_COND_DELETE == action)
755 {
756 if (NULL == p_addr)
757 return st;
758
759 BDADDR_TO_STREAM(p, p_addr->bda);
760 UINT8_TO_STREAM(p, p_addr->type);
761 }
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),
765 param,
766 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
767 {
768 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
769 }
770 else
771 {
772 BTM_TRACE_ERROR("Broadcaster Address Filter Update failed");
773 }
774 return st;
775 }
776
777 /*******************************************************************************
778 **
779 ** Function btm_ble_update_uuid_filter
780 **
781 ** Description this function update(add,delete or clear) service UUID filter.
782 **
783 **
784 ** Returns BTM_SUCCESS if sucessful,
785 ** BTM_ILLEGAL_VALUE if paramter is not valid.
786 **
787 *******************************************************************************/
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_FILT_CB_EVT cb_evt,tBTM_BLE_REF_VALUE ref_value)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)
794 {
795 UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
796 * p= param,
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;
800 UINT8 evt_type;
801
802 memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
803
804 if (BTM_BLE_PF_SRVC_UUID == filter_type)
805 {
806 evt_type = BTM_BLE_META_PF_UUID;
807 p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL;
808 }
809 else
810 {
811 evt_type = BTM_BLE_META_PF_SOL_UUID;
812 p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL;
813 }
814
815 if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR)
816 {
817 BTM_TRACE_ERROR("Illegal param for add/delete UUID filter");
818 return st;
819 }
820
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)
825 {
826 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
827 UINT8_TO_STREAM(p, action);
828
829 /* Filter index */
830 UINT8_TO_STREAM(p, filt_index);
831
832 BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda);
833 UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type);
834
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),
838 param,
839 btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES)
840 {
841 BTM_TRACE_ERROR("Update Address filter into controller failed.");
842 return st;
843 }
844
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");
847 }
848
849 p = param;
850 UINT8_TO_STREAM(p, evt_type);
851 UINT8_TO_STREAM(p, action);
852
853 /* Filter index */
854 UINT8_TO_STREAM(p, filt_index);
855
856 if ((BTM_BLE_SCAN_COND_ADD == action ||
857 BTM_BLE_SCAN_COND_DELETE == action) &&
858 NULL != p_uuid_cond)
859 {
860 if (p_uuid_cond->uuid.len == LEN_UUID_16)
861 {
862 UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16);
863 len += LEN_UUID_16;
864 }
865 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
866 {
867 UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32);
868 len += LEN_UUID_32;
869 }
870 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
871 {
872 ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128);
873 len += LEN_UUID_128;
874 }
875 else
876 {
877 BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len);
878 return BTM_ILLEGAL_VALUE;
879 }
880
881 if (NULL != p_uuid_cond->p_uuid_mask)
882 {
883 if (p_uuid_cond->uuid.len == LEN_UUID_16)
884 {
885 UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask);
886 len += LEN_UUID_16;
887 }
888 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
889 {
890 UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask);
891 len += LEN_UUID_32;
892 }
893 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
894 {
895 ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128);
896 len += LEN_UUID_128;
897 }
898 }
899 else
900 {
901 memset(p, 0xff, p_uuid_cond->uuid.len);
902 len += p_uuid_cond->uuid.len;
903 }
904 BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type,
905 p_uuid_cond->uuid.len, len);
906 }
907
908 /* send UUID filter update */
909 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
910 len,
911 param,
912 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
913 {
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));
917 else
918 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
919 }
920 else
921 {
922 BTM_TRACE_ERROR("UUID filter udpating failed");
923 }
924
925 return st;
926 }
927
928
929 /*******************************************************************************
930 **
931 ** Function btm_ble_clear_scan_pf_filter
932 **
933 ** Description clear all adv payload filter by de-select all the adv pf feature bits
934 **
935 **
936 ** Returns BTM_SUCCESS if sucessful,
937 ** BTM_ILLEGAL_VALUE if paramter is not valid.
938 **
939 *******************************************************************************/
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 * p_cmpl_cback,tBTM_BLE_FILT_CB_EVT cb_evt,tBTM_BLE_REF_VALUE ref_value)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)
946 {
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;
950 UINT8 param[20], *p;
951
952 if (BTM_BLE_SCAN_COND_CLEAR != action)
953 {
954 BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action);
955 return BTM_ILLEGAL_VALUE;
956 }
957
958 p = param;
959 memset(param, 0, 20);
960
961 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
962
963 if (NULL == p_bda_filter ||
964 /* not a generic filter */
965 (p_target != NULL && p_bda_filter))
966 {
967 BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!");
968 return st;
969 }
970
971 /* clear the general filter entry */
972 if (NULL == p_target)
973 {
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);
980
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);
986
987 /* update the counter for service data */
988 st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
989
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);
995
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);
1001
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);
1008 }
1009
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);
1013
1014 /* Filter index */
1015 UINT8_TO_STREAM(p, filt_index);
1016
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);
1021
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),
1024 param,
1025 btm_ble_scan_pf_cmpl_cback))
1026 != BTM_NO_RESOURCES)
1027 {
1028 if (p_target)
1029 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR));
1030 else
1031 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
1032 }
1033 return st;
1034 }
1035
1036 /*******************************************************************************
1037 **
1038 ** Function BTM_BleAdvFilterParamSetup
1039 **
1040 ** Description This function is called to setup the adv data payload filter
1041 ** condition.
1042 **
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
1049 **
1050 ** Returns void
1051 **
1052 *******************************************************************************/
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)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)
1057 {
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;
1063
1064 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1065 return st;
1066
1067 p = param;
1068 memset(param, 0, len);
1069 BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup");
1070
1071 if (BTM_BLE_SCAN_COND_ADD == action)
1072 {
1073 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
1074 if (NULL == p_bda_filter)
1075 {
1076 BTM_TRACE_ERROR("BD Address not found!");
1077 return st;
1078 }
1079
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);
1084
1085 /* Filter index */
1086 UINT8_TO_STREAM(p, filt_index);
1087
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);
1098
1099 if (0x01 == p_filt_params->dely_mode)
1100 {
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);
1112 }
1113
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;
1116 else
1117 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1118 BTM_BLE_ADV_FILT_TRACK_NUM;
1119
1120 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1121 (UINT8)len,
1122 param,
1123 btm_ble_scan_pf_cmpl_cback))
1124 == BTM_NO_RESOURCES)
1125 {
1126 return st;
1127 }
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);
1130 }
1131 else
1132 if (BTM_BLE_SCAN_COND_DELETE == action)
1133 {
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);
1137 /* Filter index */
1138 UINT8_TO_STREAM(p, filt_index);
1139
1140 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1141 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
1142 param,
1143 btm_ble_scan_pf_cmpl_cback))
1144 == BTM_NO_RESOURCES)
1145 {
1146 return st;
1147 }
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);
1150 }
1151 else
1152 if (BTM_BLE_SCAN_COND_CLEAR == action)
1153 {
1154 /* Deallocate all filters here */
1155 btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
1156
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);
1160
1161 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1162 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH-1),
1163 param,
1164 btm_ble_scan_pf_cmpl_cback))
1165 == BTM_NO_RESOURCES)
1166 {
1167 return st;
1168 }
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);
1171 }
1172
1173 return st;
1174 }
1175
1176 /*******************************************************************************
1177 **
1178 ** Function BTM_BleEnableDisableFilterFeature
1179 **
1180 ** Description This function is called to enable / disable the APCF feature
1181 **
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
1186 ** Returns void
1187 **
1188 *******************************************************************************/
BTM_BleEnableDisableFilterFeature(UINT8 enable,tBTM_BLE_PF_STATUS_CBACK * p_stat_cback,tBTM_BLE_REF_VALUE ref_value)1189 tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
1190 tBTM_BLE_PF_STATUS_CBACK *p_stat_cback,
1191 tBTM_BLE_REF_VALUE ref_value)
1192 {
1193 UINT8 param[20], *p;
1194 tBTM_STATUS st = BTM_WRONG_MODE;
1195
1196 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1197 return st;
1198
1199 p = param;
1200 memset(param, 0, 20);
1201
1202 /* enable the content filter in controller */
1203 p = param;
1204 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE);
1205 /* enable adv data payload filtering */
1206 UINT8_TO_STREAM(p, enable);
1207
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)
1211 {
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);
1215 }
1216 return st;
1217 }
1218
1219 /*******************************************************************************
1220 **
1221 ** Function BTM_BleCfgFilterCondition
1222 **
1223 ** Description This function is called to configure the adv data payload filter
1224 ** condition.
1225 **
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
1232 **
1233 ** Returns void
1234 **
1235 *******************************************************************************/
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)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)
1242 {
1243 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
1244 UINT8 ocf = 0;
1245 BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action,
1246 cond_type, filt_index);
1247
1248 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1249 return st;
1250
1251 switch (cond_type)
1252 {
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);
1258 break;
1259
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);
1263 break;
1264
1265 /* filter on advertiser address */
1266 case BTM_BLE_PF_ADDR_FILTER:
1267 st = btm_ble_update_addr_filter(action, filt_index, p_cond);
1268 break;
1269
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);
1274 break;
1275
1276 case BTM_BLE_PF_SRVC_DATA:
1277 st = btm_ble_update_srvc_data_change(action, filt_index, p_cond);
1278 break;
1279
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,
1282 0, ref_value);
1283 break;
1284
1285 default:
1286 BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type);
1287 break;
1288 }
1289
1290 if(BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL)
1291 {
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);
1294 }
1295 else
1296 if(BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type)
1297 {
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);
1300 }
1301 return st;
1302 }
1303
1304 /*******************************************************************************
1305 **
1306 ** Function btm_ble_adv_filter_init
1307 **
1308 ** Description This function initializes the adv filter control block
1309 **
1310 ** Parameters
1311 **
1312 ** Returns status
1313 **
1314 *******************************************************************************/
btm_ble_adv_filter_init(void)1315 void btm_ble_adv_filter_init(void)
1316 {
1317 memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
1318 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1319 return;
1320
1321 if (cmn_ble_vsc_cb.max_filter > 0)
1322 {
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);
1325 }
1326 }
1327
1328 /*******************************************************************************
1329 **
1330 ** Function btm_ble_adv_filter_cleanup
1331 **
1332 ** Description This function de-initializes the adv filter control block
1333 **
1334 ** Parameters
1335 **
1336 ** Returns status
1337 **
1338 *******************************************************************************/
btm_ble_adv_filter_cleanup(void)1339 void btm_ble_adv_filter_cleanup(void)
1340 {
1341 if (btm_ble_adv_filt_cb.p_addr_filter_count)
1342 GKI_freebuf (btm_ble_adv_filt_cb.p_addr_filter_count);
1343 }
1344
1345 #endif
1346