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
23 #include "bt_target.h"
24
25 #if (BLE_INCLUDED == TRUE)
26
27 #include "bt_types.h"
28 #include "bt_utils.h"
29 #include "btm_ble_api.h"
30 #include "btm_int.h"
31 #include "btu.h"
32 #include "device/include/controller.h"
33 #include "hcidefs.h"
34 #include "hcimsgs.h"
35
36 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
37 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13
38 #define BTM_BLE_ADV_FILT_TRACK_NUM 2
39
40 #define BTM_BLE_PF_SELECT_NONE 0
41
42 /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */
43 #define BTM_BLE_META_HDR_LENGTH 3
44 #define BTM_BLE_PF_FEAT_SEL_LEN 18
45 #define BTM_BLE_PCF_ENABLE_LEN 2
46
47 #define BTM_BLE_META_ADDR_LEN 7
48 #define BTM_BLE_META_UUID_LEN 40
49
50 #define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x))
51
52 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
53 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
54 static const BD_ADDR na_bda= {0};
55
56 static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
57 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available);
58
59 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y)
60 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4)
61 #define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f)
62 #define BTM_BLE_INVALID_COUNTER 0xff
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 ** Function btm_ble_update_srvc_data_change
508 **
509 ** Description this function update(add/remove) service data change filter.
510 **
511 **
512 ** Returns BTM_SUCCESS if sucessful,
513 ** BTM_ILLEGAL_VALUE if paramter is not valid.
514 **
515 *******************************************************************************/
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)516 tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action,
517 tBTM_BLE_PF_FILT_INDEX filt_index,
518 tBTM_BLE_PF_COND_PARAM *p_cond)
519 {
520 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
521 tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL;
522 UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1;
523
524 if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail)
525 != BTM_BLE_INVALID_COUNTER)
526 st = BTM_SUCCESS;
527
528 return st;
529 }
530
531 /*******************************************************************************
532 **
533 ** Function btm_ble_update_pf_manu_data
534 **
535 ** Description this function update(add,delete or clear) the adv manufacturer
536 ** data filtering condition.
537 **
538 **
539 ** Returns BTM_SUCCESS if sucessful,
540 ** BTM_ILLEGAL_VALUE if paramter is not valid.
541 **
542 *******************************************************************************/
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)543 tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action,
544 tBTM_BLE_PF_FILT_INDEX filt_index,
545 tBTM_BLE_PF_COND_PARAM *p_data,
546 tBTM_BLE_PF_COND_TYPE cond_type,
547 tBTM_BLE_FILT_CB_EVT cb_evt,
548 tBTM_BLE_REF_VALUE ref_value)
549 {
550 tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data;
551 tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data;
552
553 UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
554 *p = param,
555 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
556 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
557
558 if (NULL == p_data)
559 return st;
560
561 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX
562 + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
563
564 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
565 {
566 UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA);
567 }
568 else
569 {
570 UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA);
571 }
572
573 UINT8_TO_STREAM(p, action);
574
575 /* Filter index */
576 UINT8_TO_STREAM(p, filt_index);
577
578 if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action)
579 {
580 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
581 {
582 if (NULL == p_srvc_data)
583 return st;
584 if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2))
585 p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
586
587 if (p_srvc_data->data_len > 0)
588 {
589 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len);
590 len += (p_srvc_data->data_len);
591 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len);
592 }
593
594 len += (p_srvc_data->data_len);
595 BTM_TRACE_DEBUG("Service data length: %d", len);
596 }
597 else
598 {
599 if (NULL == p_manu_data)
600 {
601 BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data");
602 return st;
603 }
604 BTM_TRACE_EVENT("btm_ble_update_pf_manu_data length: %d",
605 p_manu_data->data_len);
606 if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2))
607 p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
608
609 UINT16_TO_STREAM(p, p_manu_data->company_id);
610 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL)
611 {
612 ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len);
613 len += (p_manu_data->data_len + 2);
614 }
615 else
616 len += 2;
617
618 if (p_manu_data->company_id_mask != 0)
619 {
620 UINT16_TO_STREAM (p, p_manu_data->company_id_mask);
621 }
622 else
623 {
624 memset(p, 0xff, 2);
625 p += 2;
626 }
627 len += 2;
628
629 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL)
630 {
631 ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len);
632 len += (p_manu_data->data_len);
633 }
634
635 BTM_TRACE_DEBUG("Manuf data length: %d", len);
636 }
637 }
638
639 /* send manufacturer*/
640 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
641 len,
642 param,
643 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
644 {
645 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
646 }
647 else
648 {
649 BTM_TRACE_ERROR("manufacturer data PF filter update failed");
650 }
651
652 return st;
653 }
654
655 /*******************************************************************************
656 **
657 ** Function btm_ble_cs_update_pf_counter
658 **
659 ** Description this function is to update the adv data payload filter counter
660 **
661 ** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if
662 ** counter update failed.
663 **
664 *******************************************************************************/
btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,UINT8 cond_type,tBLE_BD_ADDR * p_bd_addr,UINT8 num_available)665 UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
666 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr,
667 UINT8 num_available)
668 {
669 tBTM_BLE_PF_COUNT *p_addr_filter = NULL;
670 UINT8 *p_counter = NULL;
671
672 btm_ble_obtain_vsc_details();
673
674 if (cond_type > BTM_BLE_PF_TYPE_ALL)
675 {
676 BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type);
677 return BTM_BLE_INVALID_COUNTER;
678 }
679
680 /* for these three types of filter, always generic */
681 if (BTM_BLE_PF_ADDR_FILTER == cond_type ||
682 BTM_BLE_PF_MANU_DATA == cond_type ||
683 BTM_BLE_PF_LOCAL_NAME == cond_type ||
684 BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
685 p_bd_addr = NULL;
686
687 if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
688 BTM_BLE_SCAN_COND_ADD == action)
689 {
690 p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
691 }
692
693 if (NULL != p_addr_filter)
694 {
695 /* all filter just cleared */
696 if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) ||
697 /* or bd address filter been deleted */
698 (BTM_BLE_PF_ADDR_FILTER == cond_type &&
699 (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action)))
700 {
701 btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
702 }
703 /* if not feature selection, update new addition/reduction of the filter counter */
704 else if (cond_type != BTM_BLE_PF_TYPE_ALL)
705 {
706 p_counter = p_addr_filter->pf_counter;
707 if (num_available > 0)
708 p_counter[cond_type] += 1;
709
710 BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d",
711 p_counter[cond_type], cmn_ble_vsc_cb.max_filter, num_available);
712 return p_counter[cond_type];
713 }
714 }
715 else
716 {
717 BTM_TRACE_ERROR("no matching filter counter found");
718 }
719 /* no matching filter located and updated */
720 return BTM_BLE_INVALID_COUNTER;
721 }
722
723 /*******************************************************************************
724 **
725 ** Function btm_ble_update_addr_filter
726 **
727 ** Description this function update(add,delete or clear) the address filter of adv.
728 **
729 **
730 ** Returns BTM_SUCCESS if sucessful,
731 ** BTM_ILLEGAL_VALUE if paramter is not valid.
732 **
733 *******************************************************************************/
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)734 tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action,
735 tBTM_BLE_PF_FILT_INDEX filt_index,
736 tBTM_BLE_PF_COND_PARAM *p_cond)
737 {
738 UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
739 * p= param;
740 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
741 tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr;
742
743 memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
744
745 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
746 UINT8_TO_STREAM(p, action);
747
748 /* Filter index */
749 UINT8_TO_STREAM(p, filt_index);
750
751 if (BTM_BLE_SCAN_COND_ADD == action ||
752 BTM_BLE_SCAN_COND_DELETE == action)
753 {
754 if (NULL == p_addr)
755 return st;
756
757 BDADDR_TO_STREAM(p, p_addr->bda);
758 UINT8_TO_STREAM(p, p_addr->type);
759 }
760 /* send address filter */
761 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
762 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
763 param,
764 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
765 {
766 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
767 }
768 else
769 {
770 BTM_TRACE_ERROR("Broadcaster Address Filter Update failed");
771 }
772 return st;
773 }
774
775 /*******************************************************************************
776 **
777 ** Function btm_ble_update_uuid_filter
778 **
779 ** Description this function update(add,delete or clear) service UUID filter.
780 **
781 **
782 ** Returns BTM_SUCCESS if sucessful,
783 ** BTM_ILLEGAL_VALUE if paramter is not valid.
784 **
785 *******************************************************************************/
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)786 tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
787 tBTM_BLE_PF_FILT_INDEX filt_index,
788 tBTM_BLE_PF_COND_TYPE filter_type,
789 tBTM_BLE_PF_COND_PARAM *p_cond,
790 tBTM_BLE_FILT_CB_EVT cb_evt,
791 tBTM_BLE_REF_VALUE ref_value)
792 {
793 UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
794 * p= param,
795 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
796 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
797 tBTM_BLE_PF_UUID_COND *p_uuid_cond;
798 UINT8 evt_type;
799
800 memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
801
802 if (BTM_BLE_PF_SRVC_UUID == filter_type)
803 {
804 evt_type = BTM_BLE_META_PF_UUID;
805 p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL;
806 }
807 else
808 {
809 evt_type = BTM_BLE_META_PF_SOL_UUID;
810 p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL;
811 }
812
813 if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR)
814 {
815 BTM_TRACE_ERROR("Illegal param for add/delete UUID filter");
816 return st;
817 }
818
819 /* need to add address filter first, if adding per bda UUID filter without address filter */
820 if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond &&
821 p_uuid_cond->p_target_addr &&
822 btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL)
823 {
824 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
825 UINT8_TO_STREAM(p, action);
826
827 /* Filter index */
828 UINT8_TO_STREAM(p, filt_index);
829
830 BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda);
831 UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type);
832
833 /* send address filter */
834 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
835 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
836 param,
837 btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES)
838 {
839 BTM_TRACE_ERROR("Update Address filter into controller failed.");
840 return st;
841 }
842
843 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_ADDR, cb_evt, ref_value, NULL, NULL);
844 BTM_TRACE_DEBUG("Updated Address filter");
845 }
846
847 p = param;
848 UINT8_TO_STREAM(p, evt_type);
849 UINT8_TO_STREAM(p, action);
850
851 /* Filter index */
852 UINT8_TO_STREAM(p, filt_index);
853
854 if ((BTM_BLE_SCAN_COND_ADD == action ||
855 BTM_BLE_SCAN_COND_DELETE == action) &&
856 NULL != p_uuid_cond)
857 {
858 if (p_uuid_cond->uuid.len == LEN_UUID_16)
859 {
860 UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16);
861 len += LEN_UUID_16;
862 }
863 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
864 {
865 UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32);
866 len += LEN_UUID_32;
867 }
868 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
869 {
870 ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128);
871 len += LEN_UUID_128;
872 }
873 else
874 {
875 BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len);
876 return BTM_ILLEGAL_VALUE;
877 }
878
879 if (NULL != p_uuid_cond->p_uuid_mask)
880 {
881 if (p_uuid_cond->uuid.len == LEN_UUID_16)
882 {
883 UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask);
884 len += LEN_UUID_16;
885 }
886 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */
887 {
888 UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask);
889 len += LEN_UUID_32;
890 }
891 else if (p_uuid_cond->uuid.len == LEN_UUID_128)
892 {
893 ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128);
894 len += LEN_UUID_128;
895 }
896 }
897 else
898 {
899 memset(p, 0xff, p_uuid_cond->uuid.len);
900 len += p_uuid_cond->uuid.len;
901 }
902 BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type,
903 p_uuid_cond->uuid.len, len);
904 }
905
906 /* send UUID filter update */
907 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
908 len,
909 param,
910 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES)
911 {
912 if (p_uuid_cond && p_uuid_cond->p_target_addr)
913 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr,
914 sizeof(tBLE_BD_ADDR));
915 else
916 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
917 }
918 else
919 {
920 BTM_TRACE_ERROR("UUID filter udpating failed");
921 }
922
923 return st;
924 }
925
926 /*******************************************************************************
927 **
928 ** Function btm_ble_clear_scan_pf_filter
929 **
930 ** Description clear all adv payload filter by de-select all the adv pf feature bits
931 **
932 **
933 ** Returns BTM_SUCCESS if sucessful,
934 ** BTM_ILLEGAL_VALUE if paramter is not valid.
935 **
936 *******************************************************************************/
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)937 tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action,
938 tBTM_BLE_PF_FILT_INDEX filt_index,
939 tBTM_BLE_PF_COND_PARAM *p_cond,
940 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
941 tBTM_BLE_FILT_CB_EVT cb_evt,
942 tBTM_BLE_REF_VALUE ref_value)
943 {
944 tBLE_BD_ADDR *p_target = (p_cond == NULL)? NULL : &p_cond->target_addr;
945 tBTM_BLE_PF_COUNT *p_bda_filter;
946 tBTM_STATUS st = BTM_WRONG_MODE;
947 UINT8 param[20], *p;
948
949 if (BTM_BLE_SCAN_COND_CLEAR != action)
950 {
951 BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action);
952 return BTM_ILLEGAL_VALUE;
953 }
954
955 p = param;
956 memset(param, 0, 20);
957
958 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
959
960 if (NULL == p_bda_filter ||
961 /* not a generic filter */
962 (p_target != NULL && p_bda_filter))
963 {
964 BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!");
965 return st;
966 }
967
968 /* clear the general filter entry */
969 if (NULL == p_target)
970 {
971 /* clear manufactuer data filter */
972 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
973 BTM_BLE_PF_MANU_DATA, cb_evt, ref_value);
974 if(BTM_CMD_STARTED == st)
975 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_MANU_DATA, cb_evt,
976 ref_value, NULL, NULL);
977
978 /* clear local name filter */
979 st = btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
980 if(BTM_CMD_STARTED == st)
981 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_LOCAL_NAME, cb_evt,
982 ref_value, NULL, NULL);
983
984 /* update the counter for service data */
985 st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
986
987 /* clear UUID filter */
988 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
989 BTM_BLE_PF_SRVC_UUID, NULL, cb_evt, ref_value);
990 if(BTM_CMD_STARTED == st)
991 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_UUID, cb_evt, ref_value, NULL, NULL);
992
993 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
994 BTM_BLE_PF_SRVC_SOL_UUID, NULL, cb_evt, ref_value);
995 if(BTM_CMD_STARTED == st)
996 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SOL_UUID, cb_evt,
997 ref_value, NULL, NULL);
998
999 /* clear service data filter */
1000 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
1001 BTM_BLE_PF_SRVC_DATA_PATTERN, cb_evt, ref_value);
1002 if(BTM_CMD_STARTED == st)
1003 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SRVC_DATA, cb_evt,
1004 ref_value, NULL, NULL);
1005 }
1006
1007 /* select feature based on control block settings */
1008 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1009 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
1010
1011 /* Filter index */
1012 UINT8_TO_STREAM(p, filt_index);
1013
1014 /* set PCF selection */
1015 UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE);
1016 /* set logic condition as OR as default */
1017 UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR);
1018
1019 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1020 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN),
1021 param,
1022 btm_ble_scan_pf_cmpl_cback))
1023 != BTM_NO_RESOURCES)
1024 {
1025 if (p_target)
1026 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR));
1027 else
1028 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
1029 }
1030 return st;
1031 }
1032
1033 /*******************************************************************************
1034 **
1035 ** Function BTM_BleAdvFilterParamSetup
1036 **
1037 ** Description This function is called to setup the adv data payload filter
1038 ** condition.
1039 **
1040 ** Parameters action - Type of action to be performed
1041 ** filt_index - Filter index
1042 ** p_filt_params - Filter parameters
1043 ** p_target - Target device
1044 ** p_cmpl_back - Callback pointer
1045 ** ref_value - reference value
1046 **
1047 ** Returns void
1048 **
1049 *******************************************************************************/
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)1050 tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index,
1051 tBTM_BLE_PF_FILT_PARAMS *p_filt_params,
1052 tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback,
1053 tBTM_BLE_REF_VALUE ref_value)
1054 {
1055 tBTM_STATUS st = BTM_WRONG_MODE;
1056 tBTM_BLE_PF_COUNT *p_bda_filter = NULL;
1057 UINT8 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1058 BTM_BLE_ADV_FILT_TRACK_NUM;
1059 UINT8 param[len], *p;
1060
1061 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1062 return st;
1063
1064 p = param;
1065 memset(param, 0, len);
1066 BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup");
1067
1068 if (BTM_BLE_SCAN_COND_ADD == action)
1069 {
1070 p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
1071 if (NULL == p_bda_filter)
1072 {
1073 BTM_TRACE_ERROR("BD Address not found!");
1074 return st;
1075 }
1076
1077 BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_filt_params->feat_seln);
1078 /* select feature based on control block settings */
1079 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1080 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD);
1081
1082 /* Filter index */
1083 UINT8_TO_STREAM(p, filt_index);
1084
1085 /* set PCF selection */
1086 UINT16_TO_STREAM(p, p_filt_params->feat_seln);
1087 /* set logic type */
1088 UINT16_TO_STREAM(p, p_filt_params->logic_type);
1089 /* set logic condition */
1090 UINT8_TO_STREAM(p, p_filt_params->filt_logic_type);
1091 /* set RSSI high threshold */
1092 UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres);
1093 /* set delivery mode */
1094 UINT8_TO_STREAM(p, p_filt_params->dely_mode);
1095
1096 if (0x01 == p_filt_params->dely_mode)
1097 {
1098 /* set onfound timeout */
1099 UINT16_TO_STREAM(p, p_filt_params->found_timeout);
1100 /* set onfound timeout count*/
1101 UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt);
1102 /* set RSSI low threshold */
1103 UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres);
1104 /* set onlost timeout */
1105 UINT16_TO_STREAM(p, p_filt_params->lost_timeout);
1106 /* set num_of_track_entries for firmware greater than L-release version */
1107 if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION)
1108 UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries);
1109 }
1110
1111 if (cmn_ble_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION)
1112 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN;
1113 else
1114 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1115 BTM_BLE_ADV_FILT_TRACK_NUM;
1116
1117 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1118 (UINT8)len,
1119 param,
1120 btm_ble_scan_pf_cmpl_cback))
1121 == BTM_NO_RESOURCES)
1122 {
1123 return st;
1124 }
1125 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1126 ref_value, NULL, p_cmpl_cback);
1127 }
1128 else
1129 if (BTM_BLE_SCAN_COND_DELETE == action)
1130 {
1131 /* select feature based on control block settings */
1132 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1133 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE);
1134 /* Filter index */
1135 UINT8_TO_STREAM(p, filt_index);
1136
1137 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1138 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
1139 param,
1140 btm_ble_scan_pf_cmpl_cback))
1141 == BTM_NO_RESOURCES)
1142 {
1143 return st;
1144 }
1145 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1146 ref_value, NULL, p_cmpl_cback);
1147 }
1148 else
1149 if (BTM_BLE_SCAN_COND_CLEAR == action)
1150 {
1151 /* Deallocate all filters here */
1152 btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
1153
1154 /* select feature based on control block settings */
1155 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1156 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
1157
1158 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1159 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH-1),
1160 param,
1161 btm_ble_scan_pf_cmpl_cback))
1162 == BTM_NO_RESOURCES)
1163 {
1164 return st;
1165 }
1166 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1167 ref_value, NULL, p_cmpl_cback);
1168 }
1169
1170 return st;
1171 }
1172
1173 /*******************************************************************************
1174 **
1175 ** Function BTM_BleEnableDisableFilterFeature
1176 **
1177 ** Description This function is called to enable / disable the APCF feature
1178 **
1179 ** Parameters enable the generic scan condition.
1180 ** enable: enable or disable the filter condition
1181 ** p_stat_cback - Status callback pointer
1182 ** ref_value - Ref value
1183 ** Returns void
1184 **
1185 *******************************************************************************/
BTM_BleEnableDisableFilterFeature(UINT8 enable,tBTM_BLE_PF_STATUS_CBACK * p_stat_cback,tBTM_BLE_REF_VALUE ref_value)1186 tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
1187 tBTM_BLE_PF_STATUS_CBACK *p_stat_cback,
1188 tBTM_BLE_REF_VALUE ref_value)
1189 {
1190 UINT8 param[20], *p;
1191 tBTM_STATUS st = BTM_WRONG_MODE;
1192
1193 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1194 return st;
1195
1196 p = param;
1197 memset(param, 0, 20);
1198
1199 /* enable the content filter in controller */
1200 p = param;
1201 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE);
1202 /* enable adv data payload filtering */
1203 UINT8_TO_STREAM(p, enable);
1204
1205 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1206 BTM_BLE_PCF_ENABLE_LEN, param,
1207 btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED)
1208 {
1209 btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback;
1210 btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, BTM_BLE_FILT_ENABLE_DISABLE,
1211 ref_value, NULL, NULL);
1212 }
1213 return st;
1214 }
1215
1216 /*******************************************************************************
1217 **
1218 ** Function BTM_BleCfgFilterCondition
1219 **
1220 ** Description This function is called to configure the adv data payload filter
1221 ** condition.
1222 **
1223 ** Parameters action: to read/write/clear
1224 ** cond_type: filter condition type.
1225 ** filt_index - Filter index
1226 ** p_cond: filter condition parameter
1227 ** p_cmpl_cback - Config callback pointer
1228 ** ref_value - Reference value
1229 **
1230 ** Returns void
1231 **
1232 *******************************************************************************/
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)1233 tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action,
1234 tBTM_BLE_PF_COND_TYPE cond_type,
1235 tBTM_BLE_PF_FILT_INDEX filt_index,
1236 tBTM_BLE_PF_COND_PARAM *p_cond,
1237 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
1238 tBTM_BLE_REF_VALUE ref_value)
1239 {
1240 tBTM_STATUS st = BTM_ILLEGAL_VALUE;
1241 UINT8 ocf = 0;
1242 BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action,
1243 cond_type, filt_index);
1244
1245 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1246 return st;
1247
1248 switch (cond_type)
1249 {
1250 /* write service data filter */
1251 case BTM_BLE_PF_SRVC_DATA_PATTERN:
1252 /* write manufacturer data filter */
1253 case BTM_BLE_PF_MANU_DATA:
1254 st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type, 0, ref_value);
1255 break;
1256
1257 /* write local name filter */
1258 case BTM_BLE_PF_LOCAL_NAME:
1259 st = btm_ble_update_pf_local_name(action, filt_index, p_cond);
1260 break;
1261
1262 /* filter on advertiser address */
1263 case BTM_BLE_PF_ADDR_FILTER:
1264 st = btm_ble_update_addr_filter(action, filt_index, p_cond);
1265 break;
1266
1267 /* filter on service/solicitated UUID */
1268 case BTM_BLE_PF_SRVC_UUID:
1269 case BTM_BLE_PF_SRVC_SOL_UUID:
1270 st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond, 0, ref_value);
1271 break;
1272
1273 case BTM_BLE_PF_SRVC_DATA:
1274 st = btm_ble_update_srvc_data_change(action, filt_index, p_cond);
1275 break;
1276
1277 case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */
1278 st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, p_cmpl_cback,
1279 0, ref_value);
1280 break;
1281
1282 default:
1283 BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type);
1284 break;
1285 }
1286
1287 if(BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL)
1288 {
1289 ocf = btm_ble_condtype_to_ocf(cond_type);
1290 btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, p_cmpl_cback, NULL);
1291 }
1292 else
1293 if(BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type)
1294 {
1295 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_CFG,
1296 ref_value, p_cmpl_cback, NULL);
1297 }
1298 return st;
1299 }
1300
1301 /*******************************************************************************
1302 **
1303 ** Function btm_ble_adv_filter_init
1304 **
1305 ** Description This function initializes the adv filter control block
1306 **
1307 ** Parameters
1308 **
1309 ** Returns status
1310 **
1311 *******************************************************************************/
btm_ble_adv_filter_init(void)1312 void btm_ble_adv_filter_init(void)
1313 {
1314 memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
1315 if (BTM_SUCCESS != btm_ble_obtain_vsc_details())
1316 return;
1317
1318 if (cmn_ble_vsc_cb.max_filter > 0)
1319 {
1320 btm_ble_adv_filt_cb.p_addr_filter_count =
1321 (tBTM_BLE_PF_COUNT*)osi_malloc(sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter);
1322 }
1323 }
1324
1325 /*******************************************************************************
1326 **
1327 ** Function btm_ble_adv_filter_cleanup
1328 **
1329 ** Description This function de-initializes the adv filter control block
1330 **
1331 ** Parameters
1332 **
1333 ** Returns status
1334 **
1335 *******************************************************************************/
btm_ble_adv_filter_cleanup(void)1336 void btm_ble_adv_filter_cleanup(void)
1337 {
1338 osi_free_and_reset((void **)&btm_ble_adv_filt_cb.p_addr_filter_count);
1339 }
1340
1341 #endif
1342