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 "common/bt_target.h"
23 
24 #if (BLE_INCLUDED == TRUE)
25 #include "stack/bt_types.h"
26 #include "stack/hcimsgs.h"
27 #include "stack/btu.h"
28 #include "btm_int.h"
29 #include "osi/allocator.h"
30 #include "stack/hcidefs.h"
31 #include "stack/btm_ble_api.h"
32 #include "device/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 #if BTM_DYNAMIC_MEMORY == FALSE
52 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
53 tBTM_BLE_VSC_CB cmn_ble_adv_vsc_cb;
54 #else
55 tBTM_BLE_ADV_FILTER_CB *btm_ble_adv_filt_cb_ptr;
56 tBTM_BLE_VSC_CB *cmn_ble_adv_vsc_cb_ptr;
57 #define btm_ble_adv_filt_cb (*btm_ble_adv_filt_cb_ptr)
58 #define cmn_ble_adv_vsc_cb  (*cmn_ble_adv_vsc_cb_ptr)
59 #endif
60 
61 static const BD_ADDR     na_bda = {0};
62 
63 static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
64         UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available);
65 
66 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y)
67 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x)    ((x) >> 4)
68 #define BTM_BLE_GET_SCAN_PF_ACTION(x)    ((x) & 0x0f)
69 #define BTM_BLE_INVALID_COUNTER     0xff
70 
71 
72 /* length of each multi adv sub command */
73 #define BTM_BLE_ADV_FILTER_ENB_LEN                       3
74 
75 /* length of each batch scan command */
76 #define BTM_BLE_ADV_FILTER_CLEAR_LEN            3
77 #define BTM_BLE_ADV_FILTER_LEN     2
78 
79 #define BTM_BLE_ADV_FILT_CB_EVT_MASK       0xF0
80 #define BTM_BLE_ADV_FILT_SUBCODE_MASK      0x0F
81 
82 /*******************************************************************************
83 **
84 ** Function         btm_ble_obtain_vsc_details
85 **
86 ** Description      This function obtains the VSC details
87 **
88 ** Parameters
89 **
90 ** Returns          status
91 **
92 *******************************************************************************/
btm_ble_obtain_vsc_details(void)93 tBTM_STATUS btm_ble_obtain_vsc_details(void)
94 {
95     tBTM_STATUS st = BTM_SUCCESS;
96 
97 #if BLE_VND_INCLUDED == TRUE
98     BTM_BleGetVendorCapabilities(&cmn_ble_adv_vsc_cb);
99     if (0 == cmn_ble_adv_vsc_cb.max_filter) {
100         st = BTM_MODE_UNSUPPORTED;
101         return st;
102     }
103 #else
104     cmn_ble_adv_vsc_cb.max_filter = BTM_BLE_MAX_FILTER_COUNTER;
105 #endif
106     return st;
107 }
108 
109 /*******************************************************************************
110 **
111 ** Function         btm_ble_advfilt_enq_op_q
112 **
113 ** Description      enqueue an adv filter operation in q to check command complete
114 **                  status
115 **
116 ** Returns          void
117 **
118 *******************************************************************************/
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)119 void btm_ble_advfilt_enq_op_q(UINT8 action, UINT8 ocf, tBTM_BLE_FILT_CB_EVT cb_evt,
120                               tBTM_BLE_REF_VALUE ref, tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
121                               tBTM_BLE_PF_PARAM_CBACK  *p_filt_param_cback)
122 {
123     btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx] = (action | (ocf << 4));
124     btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.next_idx] = ref;
125     btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.next_idx] = cb_evt;
126     btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.next_idx] = p_cmpl_cback;
127     btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.next_idx]
128         = p_filt_param_cback;
129     BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_ocf:%d, action:%d, ocf:%d,cb_evt;%d, cback:%p",
130                     btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx], action,
131                     ocf, cb_evt, p_cmpl_cback);
132     btm_ble_adv_filt_cb.op_q.next_idx = (btm_ble_adv_filt_cb.op_q.next_idx + 1)
133                                         % BTM_BLE_PF_TYPE_MAX;
134 }
135 
136 /*******************************************************************************
137 **
138 ** Function         btm_ble_advfilt_deq_op_q
139 **
140 ** Description      dequeue an adv filter operation from q when command complete
141 **                  is received
142 **
143 ** Returns          void
144 **
145 *******************************************************************************/
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)146 void btm_ble_advfilt_deq_op_q(UINT8 *p_action, UINT8 *p_ocf, tBTM_BLE_FILT_CB_EVT *p_cb_evt,
147                               tBTM_BLE_REF_VALUE *p_ref, tBTM_BLE_PF_CFG_CBACK **p_cmpl_cback,
148                               tBTM_BLE_PF_PARAM_CBACK  **p_filt_param_cback)
149 {
150     *p_ocf = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx] >> 4);
151     *p_action = (btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.pending_idx]
152                  & BTM_BLE_ADV_FILT_SUBCODE_MASK);
153     *p_ref = btm_ble_adv_filt_cb.op_q.ref_value[btm_ble_adv_filt_cb.op_q.pending_idx];
154     *p_cb_evt = btm_ble_adv_filt_cb.op_q.cb_evt[btm_ble_adv_filt_cb.op_q.pending_idx];
155     *p_cmpl_cback = btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.pending_idx];
156     *p_filt_param_cback =
157         btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.pending_idx];
158 
159     btm_ble_adv_filt_cb.op_q.pending_idx = (btm_ble_adv_filt_cb.op_q.pending_idx + 1)
160                                            % BTM_BLE_PF_TYPE_MAX;
161     BTM_TRACE_DEBUG("btm_ble_advfilt_deq_op_q: ocf:%d, action:%d, ref_value:%d, cb_evt:%x",
162                     *p_ocf, *p_action, *p_ref, *p_cb_evt);
163 }
164 
165 /*******************************************************************************
166 **
167 ** Function         btm_ble_condtype_to_ocf
168 **
169 ** Description      Convert cond_type to OCF
170 **
171 ** Returns          Returns ocf value
172 **
173 *******************************************************************************/
btm_ble_condtype_to_ocf(UINT8 cond_type)174 UINT8 btm_ble_condtype_to_ocf(UINT8 cond_type)
175 {
176     UINT8 ocf = 0;
177 
178     switch (cond_type) {
179     case BTM_BLE_PF_ADDR_FILTER:
180         ocf = BTM_BLE_META_PF_ADDR;
181         break;
182     case BTM_BLE_PF_SRVC_UUID:
183         ocf = BTM_BLE_META_PF_UUID;
184         break;
185     case BTM_BLE_PF_SRVC_SOL_UUID:
186         ocf = BTM_BLE_META_PF_SOL_UUID;
187         break;
188     case BTM_BLE_PF_LOCAL_NAME:
189         ocf = BTM_BLE_META_PF_LOCAL_NAME;
190         break;
191     case BTM_BLE_PF_MANU_DATA:
192         ocf = BTM_BLE_META_PF_MANU_DATA;
193         break;
194     case BTM_BLE_PF_SRVC_DATA_PATTERN:
195         ocf = BTM_BLE_META_PF_SRVC_DATA;
196         break;
197     case BTM_BLE_PF_TYPE_ALL:
198         ocf = BTM_BLE_META_PF_ALL;
199         break;
200     default:
201         ocf = BTM_BLE_PF_TYPE_MAX;
202         break;
203     }
204     return ocf;
205 }
206 
207 /*******************************************************************************
208 **
209 ** Function         btm_ble_ocf_to_condtype
210 **
211 ** Description      Convert OCF to cond type
212 **
213 ** Returns          Returns condtype value
214 **
215 *******************************************************************************/
btm_ble_ocf_to_condtype(UINT8 ocf)216 UINT8 btm_ble_ocf_to_condtype(UINT8 ocf)
217 {
218     UINT8 cond_type = 0;
219 
220     switch (ocf) {
221     case BTM_BLE_META_PF_FEAT_SEL:
222         cond_type = BTM_BLE_META_PF_FEAT_SEL;
223         break;
224     case BTM_BLE_META_PF_ADDR:
225         cond_type = BTM_BLE_PF_ADDR_FILTER;
226         break;
227     case BTM_BLE_META_PF_UUID:
228         cond_type = BTM_BLE_PF_SRVC_UUID;
229         break;
230     case BTM_BLE_META_PF_SOL_UUID:
231         cond_type = BTM_BLE_PF_SRVC_SOL_UUID;
232         break;
233     case BTM_BLE_META_PF_LOCAL_NAME:
234         cond_type = BTM_BLE_PF_LOCAL_NAME;
235         break;
236     case BTM_BLE_META_PF_MANU_DATA:
237         cond_type = BTM_BLE_PF_MANU_DATA;
238         break;
239     case BTM_BLE_META_PF_SRVC_DATA:
240         cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN;
241         break;
242     case BTM_BLE_META_PF_ALL:
243         cond_type = BTM_BLE_PF_TYPE_ALL;
244         break;
245     default:
246         cond_type = BTM_BLE_PF_TYPE_MAX;
247         break;
248     }
249     return cond_type;
250 }
251 
252 /*******************************************************************************
253 **
254 ** Function         btm_ble_scan_pf_cmpl_cback
255 **
256 ** Description      the BTM BLE customer feature VSC complete callback for ADV PF filtering
257 **
258 ** Returns          pointer to the counter if found; NULL otherwise.
259 **
260 *******************************************************************************/
btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL * p_params)261 void btm_ble_scan_pf_cmpl_cback(tBTM_VSC_CMPL *p_params)
262 {
263     UINT8  status = 0;
264     UINT8  *p = p_params->p_param_buf, op_subcode = 0, action = 0xff;
265     UINT16  evt_len = p_params->param_len;
266     UINT8   ocf = BTM_BLE_META_PF_ALL, cond_type = 0;
267     UINT8   num_avail = 0, cb_evt = 0;
268     tBTM_BLE_REF_VALUE ref_value = 0;
269     tBTM_BLE_PF_CFG_CBACK *p_scan_cfg_cback = NULL;
270     tBTM_BLE_PF_PARAM_CBACK *p_filt_param_cback = NULL;
271 
272     if (evt_len < 3 || evt_len > 4) {
273         BTM_TRACE_ERROR("%s cannot interpret APCF callback status = %d, length = %d",
274                         __func__, status, evt_len);
275         btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback,
276                                  &p_filt_param_cback);
277         return;
278     }
279 
280     btm_ble_advfilt_deq_op_q(&action, &ocf, &cb_evt, &ref_value, &p_scan_cfg_cback,
281                              &p_filt_param_cback);
282 
283     STREAM_TO_UINT8(status, p);
284     STREAM_TO_UINT8(op_subcode, p);
285     STREAM_TO_UINT8(action, p);
286 
287     /* Ignore the event, if it is not the same one expected */
288     if (3 == evt_len) {
289         if (ocf != op_subcode) {
290             BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:3-Incorrect opcode :%d, %d, %d, %d, %d, %d",
291                             ocf, op_subcode, action, evt_len, ref_value, status);
292             return;
293         } else {
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             }
297             BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback enabled/disabled, %d, %d, %d, %d",
298                             ocf, action, status, ref_value);
299             return;
300         }
301     }
302 
303     if (4 == evt_len && ocf != op_subcode) {
304         BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback:4-Incorrect opcode: %d, %d, %d, %d, %d",
305                         ocf, op_subcode, action, status, ref_value);
306         return;
307     }
308 
309     STREAM_TO_UINT8(num_avail, p);
310     switch (op_subcode) {
311     case BTM_BLE_META_PF_ADDR:
312     case BTM_BLE_META_PF_UUID:
313     case BTM_BLE_META_PF_SOL_UUID:
314     case BTM_BLE_META_PF_LOCAL_NAME:
315     case BTM_BLE_META_PF_MANU_DATA:
316     case BTM_BLE_META_PF_SRVC_DATA:
317         cond_type = btm_ble_ocf_to_condtype(ocf);
318         BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback Recd: %d, %d, %d, %d, %d, %d", op_subcode,
319                         ocf, action, status, ref_value, num_avail);
320         if (HCI_SUCCESS == status) {
321             if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda, BD_ADDR_LEN) == 0) {
322                 btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail);
323             } else {
324                 btm_ble_cs_update_pf_counter(action, cond_type,
325                                              &btm_ble_adv_filt_cb.cur_filter_target, num_avail);
326             }
327         }
328 
329         /* send ADV PF operation complete */
330         btm_ble_adv_filt_cb.op_type = 0;
331         break;
332 
333     case BTM_BLE_META_PF_FEAT_SEL:
334         BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback-Feat sel event: %d, %d, %d, %d",
335                         action, status, ref_value, num_avail);
336         break;
337 
338     default:
339         BTM_TRACE_ERROR("btm_ble_scan_pf_cmpl_cback: unknown operation: %d", op_subcode);
340         break;
341     }
342 
343     BTM_TRACE_DEBUG("btm_ble_scan_pf_cmpl_cback: calling the cback: %d", cb_evt);
344     switch (cb_evt) {
345     case BTM_BLE_FILT_CFG:
346         if (NULL != p_scan_cfg_cback) {
347             p_scan_cfg_cback(action, cond_type, num_avail, status, ref_value);
348         }
349         break;
350     case BTM_BLE_FILT_ADV_PARAM:
351         if (NULL != p_filt_param_cback) {
352             p_filt_param_cback(action, num_avail, ref_value, status);
353         }
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 
378     for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) {
379         if (p_addr_filter->in_use &&
380                 memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
381             return p_addr_filter;
382         }
383     }
384     return NULL;
385 }
386 
387 /*******************************************************************************
388 **
389 ** Function         btm_ble_alloc_addr_filter_counter
390 **
391 ** Description      allocate the per device adv payload filter counter.
392 **
393 ** Returns          pointer to the counter if allocation succeed; NULL otherwise.
394 **
395 *******************************************************************************/
btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)396 tBTM_BLE_PF_COUNT *btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)
397 {
398     UINT8               i;
399     tBTM_BLE_PF_COUNT   *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
400 
401     for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) {
402         if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
403             memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN);
404             p_addr_filter->in_use = TRUE;
405             return p_addr_filter;
406         }
407     }
408     return NULL;
409 }
410 /*******************************************************************************
411 **
412 ** Function         btm_ble_dealloc_addr_filter_counter
413 **
414 ** Description      de-allocate the per device adv payload filter counter.
415 **
416 ** Returns          TRUE if deallocation succeed; FALSE otherwise.
417 **
418 *******************************************************************************/
btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR * p_bd_addr,UINT8 filter_type)419 BOOLEAN btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR *p_bd_addr, UINT8 filter_type)
420 {
421     UINT8               i;
422     tBTM_BLE_PF_COUNT   *p_addr_filter = &btm_ble_adv_filt_cb.p_addr_filter_count[1];
423     BOOLEAN             found = FALSE;
424 
425     if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr) {
426         memset(&btm_ble_adv_filt_cb.p_addr_filter_count[0], 0, sizeof(tBTM_BLE_PF_COUNT));
427     }
428 
429     for (i = 0; i < cmn_ble_adv_vsc_cb.max_filter; i ++, p_addr_filter ++) {
430         if ((p_addr_filter->in_use) && (NULL == p_bd_addr ||
431                                         (NULL != p_bd_addr &&
432                                          memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) {
433             found = TRUE;
434             memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
435 
436             if (NULL != p_bd_addr) {
437                 break;
438             }
439         }
440     }
441     return found;
442 }
443 
444 /*******************************************************************************
445 **
446 ** Function         btm_ble_update_pf_local_name
447 **
448 ** Description      this function update(add,delete or clear) the adv lcoal name filtering condition.
449 **
450 **
451 ** Returns          BTM_SUCCESS if sucessful,
452 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
453 **
454 *******************************************************************************/
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)455 tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action,
456         tBTM_BLE_PF_FILT_INDEX filt_index,
457         tBTM_BLE_PF_COND_PARAM *p_cond)
458 {
459     tBTM_BLE_PF_LOCAL_NAME_COND *p_local_name = (p_cond == NULL) ? NULL : &p_cond->local_name;
460     UINT8       param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
461                 *p = param,
462                  len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
463     tBTM_STATUS st = BTM_ILLEGAL_VALUE;
464 
465     memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
466 
467     UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME);
468     UINT8_TO_STREAM(p, action);
469 
470     /* Filter index */
471     UINT8_TO_STREAM(p, filt_index);
472 
473     if (BTM_BLE_SCAN_COND_ADD == action ||
474             BTM_BLE_SCAN_COND_DELETE == action) {
475         if (NULL == p_local_name) {
476             return st;
477         }
478 
479         if (p_local_name->data_len > BTM_BLE_PF_STR_LEN_MAX) {
480             p_local_name->data_len = BTM_BLE_PF_STR_LEN_MAX;
481         }
482 
483         ARRAY_TO_STREAM(p, p_local_name->p_data, p_local_name->data_len);
484         len += p_local_name->data_len;
485     }
486 
487     /* send local name filter */
488     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
489                                          len,
490                                          param,
491                                          btm_ble_scan_pf_cmpl_cback))
492             != BTM_NO_RESOURCES) {
493         memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
494     } else {
495         BTM_TRACE_ERROR("Local Name PF filter update failed");
496     }
497 
498     return st;
499 }
500 
501 
502 /*******************************************************************************
503 **
504 ** Function         btm_ble_update_srvc_data_change
505 **
506 ** Description      this function update(add/remove) service data change filter.
507 **
508 **
509 ** Returns          BTM_SUCCESS if sucessful,
510 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
511 **
512 *******************************************************************************/
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)513 tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action,
514         tBTM_BLE_PF_FILT_INDEX filt_index,
515         tBTM_BLE_PF_COND_PARAM *p_cond)
516 {
517     tBTM_STATUS st = BTM_ILLEGAL_VALUE;
518     tBLE_BD_ADDR   *p_bd_addr = p_cond ? &p_cond->target_addr : NULL;
519     UINT8           num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1;
520 
521     if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail)
522             != BTM_BLE_INVALID_COUNTER) {
523         st = BTM_SUCCESS;
524     }
525 
526     return st;
527 }
528 
529 /*******************************************************************************
530 **
531 ** Function         btm_ble_update_pf_manu_data
532 **
533 ** Description      this function update(add,delete or clear) the adv manufacturer
534 **                  data filtering condition.
535 **
536 **
537 ** Returns          BTM_SUCCESS if sucessful,
538 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
539 **
540 *******************************************************************************/
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)541 tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action,
542                                         tBTM_BLE_PF_FILT_INDEX filt_index,
543                                         tBTM_BLE_PF_COND_PARAM *p_data,
544                                         tBTM_BLE_PF_COND_TYPE cond_type,
545                                         tBTM_BLE_FILT_CB_EVT cb_evt,
546                                         tBTM_BLE_REF_VALUE ref_value)
547 {
548     tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data;
549     tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data;
550 
551     UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
552           *p = param,
553            len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
554     tBTM_STATUS st = BTM_ILLEGAL_VALUE;
555 
556     if (NULL == p_data) {
557         return st;
558     }
559 
560     memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX
561            + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
562 
563     if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) {
564         UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA);
565     } else {
566         UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA);
567     }
568 
569     UINT8_TO_STREAM(p, action);
570 
571     /* Filter index */
572     UINT8_TO_STREAM(p, filt_index);
573 
574     if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action) {
575         if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) {
576             if (NULL == p_srvc_data) {
577                 return st;
578             }
579             if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) {
580                 p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
581             }
582 
583             if (p_srvc_data->data_len > 0) {
584                 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len);
585                 len += (p_srvc_data->data_len);
586                 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len);
587             }
588 
589             len += (p_srvc_data->data_len);
590             BTM_TRACE_DEBUG("Service data length: %d", len);
591         } else {
592             if (NULL == p_manu_data) {
593                 BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data");
594                 return st;
595             }
596             BTM_TRACE_EVENT("btm_ble_update_pf_manu_data length: %d",
597                             p_manu_data->data_len);
598             if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) {
599                 p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2);
600             }
601 
602             UINT16_TO_STREAM(p, p_manu_data->company_id);
603             if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) {
604                 ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len);
605                 len += (p_manu_data->data_len + 2);
606             } else {
607                 len += 2;
608             }
609 
610             if (p_manu_data->company_id_mask != 0) {
611                 UINT16_TO_STREAM (p, p_manu_data->company_id_mask);
612             } else {
613                 memset(p, 0xff, 2);
614                 p += 2;
615             }
616             len += 2;
617 
618             if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) {
619                 ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len);
620                 len += (p_manu_data->data_len);
621             }
622 
623             BTM_TRACE_DEBUG("Manuf data length: %d", len);
624         }
625     }
626 
627     /* send manufacturer*/
628     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
629                                          len,
630                                          param,
631                                          btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) {
632         memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
633     } else {
634         BTM_TRACE_ERROR("manufacturer data PF filter update failed");
635     }
636 
637     return st;
638 }
639 
640 /*******************************************************************************
641 **
642 ** Function         btm_ble_cs_update_pf_counter
643 **
644 ** Description      this function is to update the adv data payload filter counter
645 **
646 ** Returns          current number of the counter; BTM_BLE_INVALID_COUNTER if
647 **                  counter update failed.
648 **
649 *******************************************************************************/
btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,UINT8 cond_type,tBLE_BD_ADDR * p_bd_addr,UINT8 num_available)650 UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
651                                    UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr,
652                                    UINT8 num_available)
653 {
654     tBTM_BLE_PF_COUNT   *p_addr_filter = NULL;
655     UINT8               *p_counter = NULL;
656 
657     btm_ble_obtain_vsc_details();
658 
659     if (cond_type > BTM_BLE_PF_TYPE_ALL) {
660         BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type);
661         return BTM_BLE_INVALID_COUNTER;
662     }
663 
664     /* for these three types of filter, always generic */
665     if (BTM_BLE_PF_ADDR_FILTER == cond_type ||
666             BTM_BLE_PF_MANU_DATA == cond_type ||
667             BTM_BLE_PF_LOCAL_NAME == cond_type ||
668             BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) {
669         p_bd_addr = NULL;
670     }
671 
672     if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
673             BTM_BLE_SCAN_COND_ADD == action) {
674         p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
675     }
676 
677     if (NULL != p_addr_filter) {
678         /* all filter just cleared */
679         if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) ||
680                 /* or bd address filter been deleted */
681                 (BTM_BLE_PF_ADDR_FILTER == cond_type &&
682                  (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action))) {
683             btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
684         }
685         /* if not feature selection, update new addition/reduction of the filter counter */
686         else if (cond_type != BTM_BLE_PF_TYPE_ALL) {
687             p_counter = p_addr_filter->pf_counter;
688             if (num_available > 0) {
689                 p_counter[cond_type] += 1;
690             }
691 
692             BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d",
693                             p_counter[cond_type], cmn_ble_adv_vsc_cb.max_filter, num_available);
694             return p_counter[cond_type];
695         }
696     } else {
697         BTM_TRACE_ERROR("no matching filter counter found");
698     }
699     /* no matching filter located and updated */
700     return BTM_BLE_INVALID_COUNTER;
701 }
702 
703 
704 /*******************************************************************************
705 **
706 ** Function         btm_ble_update_addr_filter
707 **
708 ** Description      this function update(add,delete or clear) the address filter of adv.
709 **
710 **
711 ** Returns          BTM_SUCCESS if sucessful,
712 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
713 **
714 *******************************************************************************/
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)715 tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action,
716                                        tBTM_BLE_PF_FILT_INDEX filt_index,
717                                        tBTM_BLE_PF_COND_PARAM *p_cond)
718 {
719     UINT8       param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
720                 * p = param;
721     tBTM_STATUS st = BTM_ILLEGAL_VALUE;
722     tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr;
723 
724     memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
725 
726     UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
727     UINT8_TO_STREAM(p, action);
728 
729     /* Filter index */
730     UINT8_TO_STREAM(p, filt_index);
731 
732     if (BTM_BLE_SCAN_COND_ADD == action ||
733             BTM_BLE_SCAN_COND_DELETE == action) {
734         if (NULL == p_addr) {
735             return st;
736         }
737 
738         BDADDR_TO_STREAM(p, p_addr->bda);
739         UINT8_TO_STREAM(p, p_addr->type);
740     }
741     /* send address filter */
742     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
743                                          (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
744                                          param,
745                                          btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) {
746         memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
747     } else {
748         BTM_TRACE_ERROR("Broadcaster Address Filter Update failed");
749     }
750     return st;
751 }
752 
753 /*******************************************************************************
754 **
755 ** Function         btm_ble_update_uuid_filter
756 **
757 ** Description      this function update(add,delete or clear) service UUID filter.
758 **
759 **
760 ** Returns          BTM_SUCCESS if sucessful,
761 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
762 **
763 *******************************************************************************/
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)764 tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
765                                        tBTM_BLE_PF_FILT_INDEX filt_index,
766                                        tBTM_BLE_PF_COND_TYPE filter_type,
767                                        tBTM_BLE_PF_COND_PARAM *p_cond,
768                                        tBTM_BLE_FILT_CB_EVT cb_evt,
769                                        tBTM_BLE_REF_VALUE ref_value)
770 {
771     UINT8       param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH],
772                 * p = param,
773                   len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
774     tBTM_STATUS st = BTM_ILLEGAL_VALUE;
775     tBTM_BLE_PF_UUID_COND *p_uuid_cond;
776     UINT8           evt_type;
777 
778     memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH);
779 
780     if (BTM_BLE_PF_SRVC_UUID == filter_type) {
781         evt_type = BTM_BLE_META_PF_UUID;
782         p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL;
783     } else {
784         evt_type = BTM_BLE_META_PF_SOL_UUID;
785         p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL;
786     }
787 
788     if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR) {
789         BTM_TRACE_ERROR("Illegal param for add/delete UUID filter");
790         return st;
791     }
792 
793     /* need to add address filter first, if adding per bda UUID filter without address filter */
794     if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond &&
795             p_uuid_cond->p_target_addr &&
796             btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL) {
797         UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
798         UINT8_TO_STREAM(p, action);
799 
800         /* Filter index */
801         UINT8_TO_STREAM(p, filt_index);
802 
803         BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda);
804         UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type);
805 
806         /* send address filter */
807         if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
808                                              (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN),
809                                              param,
810                                              btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES) {
811             BTM_TRACE_ERROR("Update Address filter into controller failed.");
812             return st;
813         }
814 
815         btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_ADDR, cb_evt, ref_value, NULL, NULL);
816         BTM_TRACE_DEBUG("Updated Address filter");
817     }
818 
819     p = param;
820     UINT8_TO_STREAM(p, evt_type);
821     UINT8_TO_STREAM(p, action);
822 
823     /* Filter index */
824     UINT8_TO_STREAM(p, filt_index);
825 
826     if ((BTM_BLE_SCAN_COND_ADD == action ||
827             BTM_BLE_SCAN_COND_DELETE == action) &&
828             NULL != p_uuid_cond) {
829         if (p_uuid_cond->uuid.len == LEN_UUID_16) {
830             UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16);
831             len += LEN_UUID_16;
832         } else if (p_uuid_cond->uuid.len == LEN_UUID_32) { /*4 bytes */
833             UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32);
834             len += LEN_UUID_32;
835         } else if (p_uuid_cond->uuid.len == LEN_UUID_128) {
836             ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128);
837             len += LEN_UUID_128;
838         } else {
839             BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len);
840             return BTM_ILLEGAL_VALUE;
841         }
842 
843         if (NULL != p_uuid_cond->p_uuid_mask) {
844             if (p_uuid_cond->uuid.len == LEN_UUID_16) {
845                 UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask);
846                 len += LEN_UUID_16;
847             } else if (p_uuid_cond->uuid.len == LEN_UUID_32) { /*4 bytes */
848                 UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask);
849                 len += LEN_UUID_32;
850             } else if (p_uuid_cond->uuid.len == LEN_UUID_128) {
851                 ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128);
852                 len += LEN_UUID_128;
853             }
854         } else {
855             memset(p, 0xff, p_uuid_cond->uuid.len);
856             len += p_uuid_cond->uuid.len;
857         }
858         BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type,
859                         p_uuid_cond->uuid.len, len);
860     }
861 
862     /* send UUID filter update */
863     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
864                                          len,
865                                          param,
866                                          btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) {
867         if (p_uuid_cond && p_uuid_cond->p_target_addr) {
868             memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr,
869                    sizeof(tBLE_BD_ADDR));
870         }
871         else {
872             memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
873         }
874     } else {
875         BTM_TRACE_ERROR("UUID filter udpating failed");
876     }
877 
878     return st;
879 }
880 
881 
882 /*******************************************************************************
883 **
884 ** Function         btm_ble_clear_scan_pf_filter
885 **
886 ** Description      clear all adv payload filter by de-select all the adv pf feature bits
887 **
888 **
889 ** Returns          BTM_SUCCESS if sucessful,
890 **                  BTM_ILLEGAL_VALUE if paramter is not valid.
891 **
892 *******************************************************************************/
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)893 tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action,
894         tBTM_BLE_PF_FILT_INDEX filt_index,
895         tBTM_BLE_PF_COND_PARAM *p_cond,
896         tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
897         tBTM_BLE_FILT_CB_EVT cb_evt,
898         tBTM_BLE_REF_VALUE ref_value)
899 {
900     tBLE_BD_ADDR *p_target = (p_cond == NULL) ? NULL : &p_cond->target_addr;
901     tBTM_BLE_PF_COUNT *p_bda_filter;
902     tBTM_STATUS     st = BTM_WRONG_MODE;
903     UINT8           param[20], *p;
904 
905     if (BTM_BLE_SCAN_COND_CLEAR != action) {
906         BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action);
907         return BTM_ILLEGAL_VALUE;
908     }
909 
910     p = param;
911     memset(param, 0, 20);
912 
913     p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
914 
915     if (NULL == p_bda_filter ||
916             /* not a generic filter */
917             (p_target != NULL && p_bda_filter)) {
918         BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!");
919         return st;
920     }
921 
922     /* clear the general filter entry */
923     if (NULL == p_target) {
924         /* clear manufacturer data filter */
925         st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
926                                          BTM_BLE_PF_MANU_DATA, cb_evt, ref_value);
927         if (BTM_CMD_STARTED == st) {
928             btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_MANU_DATA, cb_evt,
929                                      ref_value, NULL, NULL);
930         }
931 
932         /* clear local name filter */
933         st = btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
934         if (BTM_CMD_STARTED == st) {
935             btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_LOCAL_NAME, cb_evt,
936                                      ref_value, NULL, NULL);
937         }
938 
939         /* update the counter for service data */
940         st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL);
941 
942         /* clear UUID filter */
943         st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
944                                         BTM_BLE_PF_SRVC_UUID, NULL, cb_evt, ref_value);
945         if (BTM_CMD_STARTED == st) {
946             btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_UUID, cb_evt, ref_value, NULL, NULL);
947         }
948 
949         st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
950                                         BTM_BLE_PF_SRVC_SOL_UUID, NULL, cb_evt, ref_value);
951         if (BTM_CMD_STARTED == st) {
952             btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SOL_UUID, cb_evt,
953                                      ref_value, NULL, NULL);
954         }
955 
956         /* clear service data filter */
957         st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL,
958                                          BTM_BLE_PF_SRVC_DATA_PATTERN, cb_evt, ref_value);
959         if (BTM_CMD_STARTED == st) {
960             btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SRVC_DATA, cb_evt,
961                                      ref_value, NULL, NULL);
962         }
963     }
964 
965     /* select feature based on control block settings */
966     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
967     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
968 
969     /* Filter index */
970     UINT8_TO_STREAM(p, filt_index);
971 
972     /* set PCF selection */
973     UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE);
974     /* set logic condition as OR as default */
975     UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR);
976 
977     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
978                                          (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN),
979                                          param,
980                                          btm_ble_scan_pf_cmpl_cback))
981             != BTM_NO_RESOURCES) {
982         if (p_target) {
983             memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR));
984         } else {
985             memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
986         }
987     }
988     return st;
989 }
990 
991 /*******************************************************************************
992 **
993 ** Function         BTM_BleAdvFilterParamSetup
994 **
995 ** Description      This function is called to setup the adv data payload filter
996 **                  condition.
997 **
998 ** Parameters       action - Type of action to be performed
999 **                       filt_index - Filter index
1000 **                       p_filt_params - Filter parameters
1001 **                       p_target - Target device
1002 **                       p_cmpl_back - Callback pointer
1003 **                       ref_value - reference value
1004 **
1005 ** Returns          void
1006 **
1007 *******************************************************************************/
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)1008 tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index,
1009                                        tBTM_BLE_PF_FILT_PARAMS *p_filt_params,
1010                                        tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback,
1011                                        tBTM_BLE_REF_VALUE ref_value)
1012 {
1013     tBTM_STATUS st = BTM_WRONG_MODE;
1014     tBTM_BLE_PF_COUNT *p_bda_filter = NULL;
1015     UINT8 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1016                 BTM_BLE_ADV_FILT_TRACK_NUM;
1017     UINT8 param[len], *p;
1018 
1019     if (BTM_SUCCESS  != btm_ble_obtain_vsc_details()) {
1020         return st;
1021     }
1022 
1023     p = param;
1024     memset(param, 0, len);
1025     BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup");
1026 
1027     if (BTM_BLE_SCAN_COND_ADD == action) {
1028         p_bda_filter = btm_ble_find_addr_filter_counter(p_target);
1029         if (NULL == p_bda_filter) {
1030             BTM_TRACE_ERROR("BD Address not found!");
1031             return st;
1032         }
1033 
1034         BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_filt_params->feat_seln);
1035         /* select feature based on control block settings */
1036         UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1037         UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD);
1038 
1039         /* Filter index */
1040         UINT8_TO_STREAM(p, filt_index);
1041 
1042         /* set PCF selection */
1043         UINT16_TO_STREAM(p, p_filt_params->feat_seln);
1044         /* set logic type */
1045         UINT16_TO_STREAM(p, p_filt_params->logic_type);
1046         /* set logic condition */
1047         UINT8_TO_STREAM(p, p_filt_params->filt_logic_type);
1048         /* set RSSI high threshold */
1049         UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres);
1050         /* set delivery mode */
1051         UINT8_TO_STREAM(p, p_filt_params->dely_mode);
1052 
1053         if (0x01 == p_filt_params->dely_mode) {
1054             /* set onfound timeout */
1055             UINT16_TO_STREAM(p, p_filt_params->found_timeout);
1056             /* set onfound timeout count*/
1057             UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt);
1058             /* set RSSI low threshold */
1059             UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres);
1060             /* set onlost timeout */
1061             UINT16_TO_STREAM(p, p_filt_params->lost_timeout);
1062             /* set num_of_track_entries for firmware greater than L-release version */
1063             if (cmn_ble_adv_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) {
1064                 UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries);
1065             }
1066         }
1067 
1068         if (cmn_ble_adv_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION) {
1069             len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN;
1070         } else {
1071             len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
1072                   BTM_BLE_ADV_FILT_TRACK_NUM;
1073         }
1074 
1075         if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1076                                              (UINT8)len,
1077                                              param,
1078                                              btm_ble_scan_pf_cmpl_cback))
1079                 == BTM_NO_RESOURCES) {
1080             return st;
1081         }
1082         btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM,
1083                                  ref_value, NULL, p_cmpl_cback);
1084     } else if (BTM_BLE_SCAN_COND_DELETE == action) {
1085         /* select feature based on control block settings */
1086         UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1087         UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE);
1088         /* Filter index */
1089         UINT8_TO_STREAM(p, filt_index);
1090 
1091         if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1092                                              (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
1093                                              param,
1094                                              btm_ble_scan_pf_cmpl_cback))
1095                 == BTM_NO_RESOURCES) {
1096             return st;
1097         }
1098         btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL,  BTM_BLE_FILT_ADV_PARAM,
1099                                  ref_value, NULL, p_cmpl_cback);
1100     } else if (BTM_BLE_SCAN_COND_CLEAR == action) {
1101         /* Deallocate all filters here */
1102         btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
1103 
1104         /* select feature based on control block settings */
1105         UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
1106         UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
1107 
1108         if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1109                                              (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH - 1),
1110                                              param,
1111                                              btm_ble_scan_pf_cmpl_cback))
1112                 == BTM_NO_RESOURCES) {
1113             return st;
1114         }
1115         btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL,  BTM_BLE_FILT_ADV_PARAM,
1116                                  ref_value, NULL, p_cmpl_cback);
1117     }
1118 
1119     return st;
1120 }
1121 
1122 /*******************************************************************************
1123 **
1124 ** Function         BTM_BleEnableDisableFilterFeature
1125 **
1126 ** Description      This function is called to enable / disable the APCF feature
1127 **
1128 ** Parameters  enable the generic scan condition.
1129 **                  enable: enable or disable the filter condition
1130 **                  p_stat_cback - Status callback pointer
1131 **                  ref_value   - Ref value
1132 ** Returns          void
1133 **
1134 *******************************************************************************/
BTM_BleEnableDisableFilterFeature(UINT8 enable,tBTM_BLE_PF_STATUS_CBACK * p_stat_cback,tBTM_BLE_REF_VALUE ref_value)1135 tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable,
1136         tBTM_BLE_PF_STATUS_CBACK *p_stat_cback,
1137         tBTM_BLE_REF_VALUE ref_value)
1138 {
1139     UINT8           param[20], *p;
1140     tBTM_STATUS     st = BTM_WRONG_MODE;
1141 
1142     if (BTM_SUCCESS  != btm_ble_obtain_vsc_details()) {
1143         return st;
1144     }
1145 
1146     p = param;
1147     memset(param, 0, 20);
1148 
1149     /* enable the content filter in controller */
1150     p = param;
1151     UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE);
1152     /* enable adv data payload filtering */
1153     UINT8_TO_STREAM(p, enable);
1154 
1155     if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF,
1156                                          BTM_BLE_PCF_ENABLE_LEN, param,
1157                                          btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED) {
1158         btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback;
1159         btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, BTM_BLE_FILT_ENABLE_DISABLE,
1160                                  ref_value, NULL, NULL);
1161     }
1162     return st;
1163 }
1164 
1165 /*******************************************************************************
1166 **
1167 ** Function         BTM_BleCfgFilterCondition
1168 **
1169 ** Description      This function is called to configure the adv data payload filter
1170 **                  condition.
1171 **
1172 ** Parameters       action: to read/write/clear
1173 **                  cond_type: filter condition type.
1174 **                  filt_index - Filter index
1175 **                  p_cond: filter condition parameter
1176 **                  p_cmpl_cback  - Config callback pointer
1177 **                  ref_value - Reference value
1178 **
1179 ** Returns          void
1180 **
1181 *******************************************************************************/
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)1182 tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action,
1183                                       tBTM_BLE_PF_COND_TYPE cond_type,
1184                                       tBTM_BLE_PF_FILT_INDEX filt_index,
1185                                       tBTM_BLE_PF_COND_PARAM *p_cond,
1186                                       tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback,
1187                                       tBTM_BLE_REF_VALUE ref_value)
1188 {
1189     tBTM_STATUS     st = BTM_ILLEGAL_VALUE;
1190     UINT8 ocf = 0;
1191     BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action,
1192                      cond_type, filt_index);
1193 
1194     if (BTM_SUCCESS  != btm_ble_obtain_vsc_details()) {
1195         return st;
1196     }
1197 
1198     switch (cond_type) {
1199     /* write service data filter */
1200     case BTM_BLE_PF_SRVC_DATA_PATTERN:
1201     /* write manufacturer data filter */
1202     case BTM_BLE_PF_MANU_DATA:
1203         st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type, 0, ref_value);
1204         break;
1205 
1206     /* write local name filter */
1207     case BTM_BLE_PF_LOCAL_NAME:
1208         st = btm_ble_update_pf_local_name(action, filt_index, p_cond);
1209         break;
1210 
1211     /* filter on advertiser address */
1212     case BTM_BLE_PF_ADDR_FILTER:
1213         st = btm_ble_update_addr_filter(action, filt_index, p_cond);
1214         break;
1215 
1216     /* filter on service/solicited UUID */
1217     case BTM_BLE_PF_SRVC_UUID:
1218     case BTM_BLE_PF_SRVC_SOL_UUID:
1219         st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond, 0, ref_value);
1220         break;
1221 
1222     case BTM_BLE_PF_SRVC_DATA:
1223         st = btm_ble_update_srvc_data_change(action, filt_index, p_cond);
1224         break;
1225 
1226     case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */
1227         st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, p_cmpl_cback,
1228                                           0, ref_value);
1229         break;
1230 
1231     default:
1232         BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type);
1233         break;
1234     }
1235 
1236     if (BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL) {
1237         ocf = btm_ble_condtype_to_ocf(cond_type);
1238         btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, p_cmpl_cback, NULL);
1239     } else if (BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type) {
1240         btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_CFG,
1241                                  ref_value, p_cmpl_cback, NULL);
1242     }
1243     return st;
1244 }
1245 
1246 /*******************************************************************************
1247 **
1248 ** Function         btm_ble_adv_filter_init
1249 **
1250 ** Description      This function initializes the adv filter control block
1251 **
1252 ** Parameters
1253 **
1254 ** Returns          status
1255 **
1256 *******************************************************************************/
btm_ble_adv_filter_init(void)1257 void btm_ble_adv_filter_init(void)
1258 {
1259 #if BTM_DYNAMIC_MEMORY == TRUE
1260     btm_ble_adv_filt_cb_ptr = (tBTM_BLE_ADV_FILTER_CB *)osi_malloc(sizeof(tBTM_BLE_ADV_FILTER_CB));
1261     cmn_ble_adv_vsc_cb_ptr = (tBTM_BLE_VSC_CB *)osi_malloc(sizeof(tBTM_BLE_VSC_CB));
1262     if (btm_ble_adv_filt_cb_ptr == NULL || cmn_ble_adv_vsc_cb_ptr == NULL) {
1263         BTM_TRACE_ERROR("%s malloc failed", __func__);
1264         return;
1265     }
1266     memset((void *)btm_ble_adv_filt_cb_ptr, 0, sizeof(tBTM_BLE_ADV_FILTER_CB));
1267     memset((void *)cmn_ble_adv_vsc_cb_ptr, 0, sizeof(tBTM_BLE_VSC_CB));
1268 #endif
1269     memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_ADV_FILTER_CB));
1270     if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) {
1271         return;
1272     }
1273 
1274     if (cmn_ble_adv_vsc_cb.max_filter > 0) {
1275         btm_ble_adv_filt_cb.p_addr_filter_count =
1276             (tBTM_BLE_PF_COUNT *) osi_malloc( sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_adv_vsc_cb.max_filter);
1277     }
1278 }
1279 
1280 /*******************************************************************************
1281 **
1282 ** Function         btm_ble_adv_filter_cleanup
1283 **
1284 ** Description      This function de-initializes the adv filter control block
1285 **
1286 ** Parameters
1287 **
1288 ** Returns          status
1289 **
1290 *******************************************************************************/
btm_ble_adv_filter_cleanup(void)1291 void btm_ble_adv_filter_cleanup(void)
1292 {
1293     if (btm_ble_adv_filt_cb.p_addr_filter_count) {
1294         osi_free(btm_ble_adv_filt_cb.p_addr_filter_count);
1295         btm_ble_adv_filt_cb.p_addr_filter_count = NULL;
1296     }
1297 
1298 #if BTM_DYNAMIC_MEMORY == TRUE
1299     osi_free(btm_ble_adv_filt_cb_ptr);
1300     btm_ble_adv_filt_cb_ptr = NULL;
1301     osi_free(cmn_ble_adv_vsc_cb_ptr);
1302     cmn_ble_adv_vsc_cb_ptr = NULL;
1303 #endif
1304 }
1305 
1306 #endif
1307