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