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