OSDN Git Service

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