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 <base/bind.h>
22 #include <string.h>
23 #include <algorithm>
24 #include <vector>
25 
26 #include "bt_target.h"
27 
28 #include "bt_types.h"
29 #include "bt_utils.h"
30 #include "btm_ble_api.h"
31 #include "btm_int.h"
32 #include "btu.h"
33 #include "device/include/controller.h"
34 #include "hcidefs.h"
35 #include "hcimsgs.h"
36 
37 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
38 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13
39 #define BTM_BLE_ADV_FILT_TRACK_NUM 2
40 
41 #define BTM_BLE_PF_SELECT_NONE 0
42 
43 /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */
44 #define BTM_BLE_META_HDR_LENGTH 3
45 #define BTM_BLE_PF_FEAT_SEL_LEN 18
46 #define BTM_BLE_PCF_ENABLE_LEN 2
47 
48 #define BTM_BLE_META_ADDR_LEN 7
49 #define BTM_BLE_META_UUID_LEN 40
50 
51 #define BTM_BLE_PF_BIT_TO_MASK(x) (uint16_t)(1 << (x))
52 
53 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
54 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
55 static const BD_ADDR na_bda = {0};
56 
57 static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
58                                             uint8_t cond_type,
59                                             tBLE_BD_ADDR* p_bd_addr,
60                                             uint8_t num_available);
61 
62 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x) << 4) | (y))
63 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4)
64 #define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x)&0x0f)
65 #define BTM_BLE_INVALID_COUNTER 0xff
66 
67 /* length of each multi adv sub command */
68 #define BTM_BLE_ADV_FILTER_ENB_LEN 3
69 
70 /* length of each batch scan command */
71 #define BTM_BLE_ADV_FILTER_CLEAR_LEN 3
72 #define BTM_BLE_ADV_FILTER_LEN 2
73 
74 #define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0
75 #define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F
76 
77 /*******************************************************************************
78  *
79  * Function         btm_ble_obtain_vsc_details
80  *
81  * Description      This function obtains the VSC details
82  *
83  * Parameters
84  *
85  * Returns          status
86  *
87  ******************************************************************************/
btm_ble_obtain_vsc_details()88 tBTM_STATUS btm_ble_obtain_vsc_details() {
89   tBTM_STATUS st = BTM_SUCCESS;
90 
91 #if (BLE_VND_INCLUDED == TRUE)
92   BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
93   if (cmn_ble_vsc_cb.filter_support && 0 == cmn_ble_vsc_cb.max_filter) {
94     st = BTM_MODE_UNSUPPORTED;
95     return st;
96   }
97 #else
98   cmn_ble_vsc_cb.max_filter = BTM_BLE_MAX_FILTER_COUNTER;
99 #endif
100   return st;
101 }
102 
103 /*******************************************************************************
104  *
105  * Function         btm_ble_condtype_to_ocf
106  *
107  * Description      Convert cond_type to OCF
108  *
109  * Returns          Returns ocf value
110  *
111  ******************************************************************************/
btm_ble_condtype_to_ocf(uint8_t cond_type)112 uint8_t btm_ble_condtype_to_ocf(uint8_t cond_type) {
113   uint8_t ocf = 0;
114 
115   switch (cond_type) {
116     case BTM_BLE_PF_ADDR_FILTER:
117       ocf = BTM_BLE_META_PF_ADDR;
118       break;
119     case BTM_BLE_PF_SRVC_UUID:
120       ocf = BTM_BLE_META_PF_UUID;
121       break;
122     case BTM_BLE_PF_SRVC_SOL_UUID:
123       ocf = BTM_BLE_META_PF_SOL_UUID;
124       break;
125     case BTM_BLE_PF_LOCAL_NAME:
126       ocf = BTM_BLE_META_PF_LOCAL_NAME;
127       break;
128     case BTM_BLE_PF_MANU_DATA:
129       ocf = BTM_BLE_META_PF_MANU_DATA;
130       break;
131     case BTM_BLE_PF_SRVC_DATA_PATTERN:
132       ocf = BTM_BLE_META_PF_SRVC_DATA;
133       break;
134     case BTM_BLE_PF_TYPE_ALL:
135       ocf = BTM_BLE_META_PF_ALL;
136       break;
137     default:
138       ocf = BTM_BLE_PF_TYPE_MAX;
139       break;
140   }
141   return ocf;
142 }
143 
144 /*******************************************************************************
145  *
146  * Function         btm_ble_ocf_to_condtype
147  *
148  * Description      Convert OCF to cond type
149  *
150  * Returns          Returns condtype value
151  *
152  ******************************************************************************/
btm_ble_ocf_to_condtype(uint8_t ocf)153 uint8_t btm_ble_ocf_to_condtype(uint8_t ocf) {
154   uint8_t cond_type = 0;
155 
156   switch (ocf) {
157     case BTM_BLE_META_PF_FEAT_SEL:
158       cond_type = BTM_BLE_META_PF_FEAT_SEL;
159       break;
160     case BTM_BLE_META_PF_ADDR:
161       cond_type = BTM_BLE_PF_ADDR_FILTER;
162       break;
163     case BTM_BLE_META_PF_UUID:
164       cond_type = BTM_BLE_PF_SRVC_UUID;
165       break;
166     case BTM_BLE_META_PF_SOL_UUID:
167       cond_type = BTM_BLE_PF_SRVC_SOL_UUID;
168       break;
169     case BTM_BLE_META_PF_LOCAL_NAME:
170       cond_type = BTM_BLE_PF_LOCAL_NAME;
171       break;
172     case BTM_BLE_META_PF_MANU_DATA:
173       cond_type = BTM_BLE_PF_MANU_DATA;
174       break;
175     case BTM_BLE_META_PF_SRVC_DATA:
176       cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN;
177       break;
178     case BTM_BLE_META_PF_ALL:
179       cond_type = BTM_BLE_PF_TYPE_ALL;
180       break;
181     default:
182       cond_type = BTM_BLE_PF_TYPE_MAX;
183       break;
184   }
185   return cond_type;
186 }
187 
btm_flt_update_cb(uint8_t expected_ocf,tBTM_BLE_PF_CFG_CBACK cb,uint8_t * p,uint16_t evt_len)188 void btm_flt_update_cb(uint8_t expected_ocf, tBTM_BLE_PF_CFG_CBACK cb,
189                        uint8_t* p, uint16_t evt_len) {
190   if (evt_len != 4) {
191     BTM_TRACE_ERROR("%s: bad length: %d", __func__, evt_len);
192     return;
193   }
194 
195   uint8_t status, op_subcode, action, num_avail;
196   STREAM_TO_UINT8(status, p);
197   STREAM_TO_UINT8(op_subcode, p);
198   STREAM_TO_UINT8(action, p);
199   STREAM_TO_UINT8(num_avail, p);
200 
201   if (expected_ocf != op_subcode) {
202     BTM_TRACE_ERROR("%s: Incorrect opcode: 0x%02x, expected: 0x%02x", __func__,
203                     expected_ocf, op_subcode);
204     return;
205   }
206 
207   if (op_subcode == BTM_BLE_META_PF_FEAT_SEL) {
208     cb.Run(num_avail, action, status);
209     return;
210   }
211 
212   uint8_t cond_type = btm_ble_ocf_to_condtype(expected_ocf);
213   BTM_TRACE_DEBUG("%s: Recd: %d, %d, %d, %d, %d", __func__, op_subcode,
214                   expected_ocf, action, status, num_avail);
215   if (HCI_SUCCESS == status) {
216     if (memcmp(&btm_ble_adv_filt_cb.cur_filter_target.bda, &na_bda,
217                BD_ADDR_LEN) == 0)
218       btm_ble_cs_update_pf_counter(action, cond_type, NULL, num_avail);
219     else
220       btm_ble_cs_update_pf_counter(
221           action, cond_type, &btm_ble_adv_filt_cb.cur_filter_target, num_avail);
222   }
223 
224   /* send ADV PF operation complete */
225   btm_ble_adv_filt_cb.op_type = 0;
226 
227   cb.Run(num_avail, action, status);
228 }
229 
230 /*******************************************************************************
231  *
232  * Function         btm_ble_find_addr_filter_counter
233  *
234  * Description      find the per bd address ADV payload filter counter by
235  *                  BD_ADDR.
236  *
237  * Returns          pointer to the counter if found; NULL otherwise.
238  *
239  ******************************************************************************/
btm_ble_find_addr_filter_counter(tBLE_BD_ADDR * p_le_bda)240 tBTM_BLE_PF_COUNT* btm_ble_find_addr_filter_counter(tBLE_BD_ADDR* p_le_bda) {
241   uint8_t i;
242   tBTM_BLE_PF_COUNT* p_addr_filter =
243       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
244 
245   if (p_le_bda == NULL) return &btm_ble_adv_filt_cb.p_addr_filter_count[0];
246 
247   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
248     if (p_addr_filter->in_use &&
249         memcmp(p_le_bda->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
250       return p_addr_filter;
251     }
252   }
253   return NULL;
254 }
255 
256 /*******************************************************************************
257  *
258  * Function         btm_ble_alloc_addr_filter_counter
259  *
260  * Description      allocate the per device adv payload filter counter.
261  *
262  * Returns          pointer to the counter if allocation succeed; NULL
263  *                  otherwise.
264  *
265  ******************************************************************************/
btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr)266 tBTM_BLE_PF_COUNT* btm_ble_alloc_addr_filter_counter(BD_ADDR bd_addr) {
267   uint8_t i;
268   tBTM_BLE_PF_COUNT* p_addr_filter =
269       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
270 
271   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
272     if (memcmp(na_bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0) {
273       memcpy(p_addr_filter->bd_addr, bd_addr, BD_ADDR_LEN);
274       p_addr_filter->in_use = true;
275       return p_addr_filter;
276     }
277   }
278   return NULL;
279 }
280 /*******************************************************************************
281  *
282  * Function         btm_ble_dealloc_addr_filter_counter
283  *
284  * Description      de-allocate the per device adv payload filter counter.
285  *
286  * Returns          true if deallocation succeed; false otherwise.
287  *
288  ******************************************************************************/
btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR * p_bd_addr,uint8_t filter_type)289 bool btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR* p_bd_addr,
290                                          uint8_t filter_type) {
291   uint8_t i;
292   tBTM_BLE_PF_COUNT* p_addr_filter =
293       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
294   bool found = false;
295 
296   if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr)
297     memset(&btm_ble_adv_filt_cb.p_addr_filter_count[0], 0,
298            sizeof(tBTM_BLE_PF_COUNT));
299 
300   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
301     if ((p_addr_filter->in_use) &&
302         (NULL == p_bd_addr ||
303          (NULL != p_bd_addr &&
304           memcmp(p_bd_addr->bda, p_addr_filter->bd_addr, BD_ADDR_LEN) == 0))) {
305       found = true;
306       memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
307 
308       if (NULL != p_bd_addr) break;
309     }
310   }
311   return found;
312 }
313 
314 /**
315  * This function update(add,delete or clear) the adv local name filtering
316  * condition.
317  */
BTM_LE_PF_local_name(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index,std::vector<uint8_t> name,tBTM_BLE_PF_CFG_CBACK cb)318 void BTM_LE_PF_local_name(tBTM_BLE_SCAN_COND_OP action,
319                           tBTM_BLE_PF_FILT_INDEX filt_index,
320                           std::vector<uint8_t> name, tBTM_BLE_PF_CFG_CBACK cb) {
321   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
322 
323   uint8_t len_max = len + BTM_BLE_PF_STR_LEN_MAX;
324   uint8_t param[len_max];
325   memset(param, 0, len_max);
326 
327   uint8_t* p = param;
328   UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME);
329   UINT8_TO_STREAM(p, action);
330   UINT8_TO_STREAM(p, filt_index);
331 
332   if (action != BTM_BLE_SCAN_COND_CLEAR) {
333     int size = std::min(name.size(), (size_t)BTM_BLE_PF_STR_LEN_MAX);
334     ARRAY_TO_STREAM(p, name.data(), size);
335     len += size;
336   }
337 
338   /* send local name filter */
339   btu_hcif_send_cmd_with_cb(
340       FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
341       base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_LOCAL_NAME, cb));
342 
343   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
344 }
345 
346 /**
347  * this function update(add/remove) service data change filter.
348  */
BTM_LE_PF_srvc_data(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index)349 void BTM_LE_PF_srvc_data(tBTM_BLE_SCAN_COND_OP action,
350                          tBTM_BLE_PF_FILT_INDEX filt_index) {
351   uint8_t num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1;
352 
353   btm_ble_cs_update_pf_counter(action, BTM_BLE_PF_SRVC_DATA, nullptr,
354                                num_avail);
355 }
356 
357 /**
358  * This function update(add,delete or clear) the adv manufacturer data filtering
359  * condition.
360  */
BTM_LE_PF_manu_data(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index,uint16_t company_id,uint16_t company_id_mask,std::vector<uint8_t> data,std::vector<uint8_t> data_mask,tBTM_BLE_PF_CFG_CBACK cb)361 void BTM_LE_PF_manu_data(tBTM_BLE_SCAN_COND_OP action,
362                          tBTM_BLE_PF_FILT_INDEX filt_index, uint16_t company_id,
363                          uint16_t company_id_mask, std::vector<uint8_t> data,
364                          std::vector<uint8_t> data_mask,
365                          tBTM_BLE_PF_CFG_CBACK cb) {
366   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
367   int len_max = len + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX;
368 
369   uint8_t param[len_max];
370   memset(param, 0, len_max);
371 
372   uint8_t* p = param;
373   UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA);
374   UINT8_TO_STREAM(p, action);
375   UINT8_TO_STREAM(p, filt_index);
376 
377   if (action != BTM_BLE_SCAN_COND_CLEAR) {
378     uint8_t size = std::min(data.size(), (size_t)(BTM_BLE_PF_STR_LEN_MAX - 2));
379 
380     UINT16_TO_STREAM(p, company_id);
381     if (size > 0 && data_mask.size() != 0) {
382       ARRAY_TO_STREAM(p, data.data(), size);
383       len += size + 2;
384     } else
385       len += 2;
386 
387     if (company_id_mask != 0) {
388       UINT16_TO_STREAM(p, company_id_mask);
389     } else {
390       UINT16_TO_STREAM(p, (uint16_t)0xFFFF);
391     }
392     len += 2;
393 
394     if (size > 0 && data_mask.size() != 0) {
395       ARRAY_TO_STREAM(p, data_mask.data(), size);
396       len += (size);
397     }
398 
399     BTM_TRACE_DEBUG("Manuf data length: %d", len);
400   }
401 
402   btu_hcif_send_cmd_with_cb(
403       FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
404       base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_MANU_DATA, cb));
405 
406   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
407 }
408 
409 /**
410  * This function update(add,delete or clear) the service data filtering
411  * condition.
412  **/
BTM_LE_PF_srvc_data_pattern(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index,std::vector<uint8_t> data,std::vector<uint8_t> data_mask,tBTM_BLE_PF_CFG_CBACK cb)413 void BTM_LE_PF_srvc_data_pattern(tBTM_BLE_SCAN_COND_OP action,
414                                  tBTM_BLE_PF_FILT_INDEX filt_index,
415                                  std::vector<uint8_t> data,
416                                  std::vector<uint8_t> data_mask,
417                                  tBTM_BLE_PF_CFG_CBACK cb) {
418   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
419   int len_max = len + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX;
420 
421   uint8_t param[len_max];
422   memset(param, 0, len_max);
423 
424   uint8_t* p = param;
425   UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA);
426   UINT8_TO_STREAM(p, action);
427   UINT8_TO_STREAM(p, filt_index);
428 
429   if (action != BTM_BLE_SCAN_COND_CLEAR) {
430     uint8_t size = std::min(data.size(), (size_t)(BTM_BLE_PF_STR_LEN_MAX - 2));
431 
432     if (size > 0) {
433       ARRAY_TO_STREAM(p, data.data(), size);
434       len += size;
435       ARRAY_TO_STREAM(p, data_mask.data(), size);
436       len += size;
437     }
438   }
439 
440   btu_hcif_send_cmd_with_cb(
441       FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
442       base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_SRVC_DATA, cb));
443 
444   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
445 }
446 
447 /*******************************************************************************
448  *
449  * Function         btm_ble_cs_update_pf_counter
450  *
451  * Description      this function is to update the adv data payload filter
452  *                  counter
453  *
454  * Returns          current number of the counter; BTM_BLE_INVALID_COUNTER if
455  *                  counter update failed.
456  *
457  ******************************************************************************/
btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,uint8_t cond_type,tBLE_BD_ADDR * p_bd_addr,uint8_t num_available)458 uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
459                                      uint8_t cond_type, tBLE_BD_ADDR* p_bd_addr,
460                                      uint8_t num_available) {
461   tBTM_BLE_PF_COUNT* p_addr_filter = NULL;
462   uint8_t* p_counter = NULL;
463 
464   btm_ble_obtain_vsc_details();
465 
466   if (cond_type > BTM_BLE_PF_TYPE_ALL) {
467     BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type);
468     return BTM_BLE_INVALID_COUNTER;
469   }
470 
471   /* for these three types of filter, always generic */
472   if (BTM_BLE_PF_ADDR_FILTER == cond_type ||
473       BTM_BLE_PF_MANU_DATA == cond_type || BTM_BLE_PF_LOCAL_NAME == cond_type ||
474       BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
475     p_bd_addr = NULL;
476 
477   if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
478       BTM_BLE_SCAN_COND_ADD == action) {
479     p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
480   }
481 
482   if (NULL != p_addr_filter) {
483     /* all filter just cleared */
484     if ((BTM_BLE_PF_TYPE_ALL == cond_type &&
485          BTM_BLE_SCAN_COND_CLEAR == action) ||
486         /* or bd address filter been deleted */
487         (BTM_BLE_PF_ADDR_FILTER == cond_type &&
488          (BTM_BLE_SCAN_COND_DELETE == action ||
489           BTM_BLE_SCAN_COND_CLEAR == action))) {
490       btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
491     }
492     /* if not feature selection, update new addition/reduction of the filter
493        counter */
494     else if (cond_type != BTM_BLE_PF_TYPE_ALL) {
495       p_counter = p_addr_filter->pf_counter;
496       if (num_available > 0) p_counter[cond_type] += 1;
497 
498       BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d",
499                       p_counter[cond_type], cmn_ble_vsc_cb.max_filter,
500                       num_available);
501       return p_counter[cond_type];
502     }
503   } else {
504     BTM_TRACE_ERROR("no matching filter counter found");
505   }
506   /* no matching filter located and updated */
507   return BTM_BLE_INVALID_COUNTER;
508 }
509 
510 /**
511  * This function updates the address filter of adv.
512  */
BTM_LE_PF_addr_filter(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index,tBLE_BD_ADDR addr,tBTM_BLE_PF_CFG_CBACK cb)513 void BTM_LE_PF_addr_filter(tBTM_BLE_SCAN_COND_OP action,
514                            tBTM_BLE_PF_FILT_INDEX filt_index, tBLE_BD_ADDR addr,
515                            tBTM_BLE_PF_CFG_CBACK cb) {
516   const uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN;
517 
518   uint8_t param[len];
519   memset(param, 0, len);
520 
521   uint8_t* p = param;
522   UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR);
523   UINT8_TO_STREAM(p, action);
524   UINT8_TO_STREAM(p, filt_index);
525 
526   if (action != BTM_BLE_SCAN_COND_CLEAR) {
527     BDADDR_TO_STREAM(p, addr.bda);
528     UINT8_TO_STREAM(p, addr.type);
529   }
530 
531   /* send address filter */
532   btu_hcif_send_cmd_with_cb(
533       FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
534       base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_ADDR, cb));
535 
536   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
537 }
538 
539 /**
540  * This function updates(adds, deletes or clears) the service UUID filter.
541  */
BTM_LE_PF_uuid_filter(tBTM_BLE_SCAN_COND_OP action,tBTM_BLE_PF_FILT_INDEX filt_index,tBTM_BLE_PF_COND_TYPE filter_type,tBT_UUID uuid,tBTM_BLE_PF_LOGIC_TYPE cond_logic,tBTM_BLE_PF_COND_MASK * p_uuid_mask,tBTM_BLE_PF_CFG_CBACK cb)542 void BTM_LE_PF_uuid_filter(tBTM_BLE_SCAN_COND_OP action,
543                            tBTM_BLE_PF_FILT_INDEX filt_index,
544                            tBTM_BLE_PF_COND_TYPE filter_type, tBT_UUID uuid,
545                            tBTM_BLE_PF_LOGIC_TYPE cond_logic,
546                            tBTM_BLE_PF_COND_MASK* p_uuid_mask,
547                            tBTM_BLE_PF_CFG_CBACK cb) {
548   uint8_t evt_type;
549 
550   if (BTM_BLE_PF_SRVC_UUID == filter_type) {
551     evt_type = BTM_BLE_META_PF_UUID;
552   } else {
553     evt_type = BTM_BLE_META_PF_SOL_UUID;
554   }
555 
556   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH;
557   uint8_t max_len = len + BTM_BLE_META_UUID_LEN;
558   uint8_t param[max_len];
559   memset(param, 0, max_len);
560   uint8_t* p = param;
561 
562   UINT8_TO_STREAM(p, evt_type);
563   UINT8_TO_STREAM(p, action);
564   UINT8_TO_STREAM(p, filt_index);
565 
566   if (action != BTM_BLE_SCAN_COND_CLEAR) {
567     if (uuid.len == LEN_UUID_16) {
568       UINT16_TO_STREAM(p, uuid.uu.uuid16);
569       len += LEN_UUID_16;
570     } else if (uuid.len == LEN_UUID_32) {
571       UINT32_TO_STREAM(p, uuid.uu.uuid32);
572       len += LEN_UUID_32;
573     } else if (uuid.len == LEN_UUID_128) {
574       ARRAY_TO_STREAM(p, uuid.uu.uuid128, LEN_UUID_128);
575       len += LEN_UUID_128;
576     } else {
577       BTM_TRACE_ERROR("illegal UUID length: %d", uuid.len);
578       cb.Run(0, BTM_BLE_PF_CONFIG, 1 /*BTA_FAILURE*/);
579       return;
580     }
581 
582     if (p_uuid_mask) {
583       if (uuid.len == LEN_UUID_16) {
584         UINT16_TO_STREAM(p, p_uuid_mask->uuid16_mask);
585         len += LEN_UUID_16;
586       } else if (uuid.len == LEN_UUID_32) {
587         UINT32_TO_STREAM(p, p_uuid_mask->uuid32_mask);
588         len += LEN_UUID_32;
589       } else if (uuid.len == LEN_UUID_128) {
590         ARRAY_TO_STREAM(p, p_uuid_mask->uuid128_mask, LEN_UUID_128);
591         len += LEN_UUID_128;
592       }
593     } else {
594       memset(p, 0xff, uuid.len);
595       len += uuid.len;
596     }
597   }
598 
599   /* send UUID filter update */
600   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
601                             base::Bind(&btm_flt_update_cb, evt_type, cb));
602   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
603 }
604 
605 /**
606  * all adv payload filter by de-selecting all the adv pf feature bits
607  */
BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index,tBTM_BLE_PF_CFG_CBACK cb)608 void BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index,
609                      tBTM_BLE_PF_CFG_CBACK cb) {
610   /* clear the general filter entry */
611   {
612     tBTM_BLE_PF_CFG_CBACK fDoNothing;
613 
614     /* clear manufactuer data filter */
615     BTM_LE_PF_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, 0, 0, {}, {},
616                         fDoNothing);
617 
618     /* clear local name filter */
619     BTM_LE_PF_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, fDoNothing);
620 
621     /* update the counter for service data */
622     BTM_LE_PF_srvc_data(BTM_BLE_SCAN_COND_CLEAR, filt_index);
623 
624     /* clear UUID filter */
625     BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
626                           BTM_BLE_PF_SRVC_UUID, {}, 0, nullptr, fDoNothing);
627 
628     BTM_LE_PF_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index,
629                           BTM_BLE_PF_SRVC_SOL_UUID, {}, 0, nullptr, fDoNothing);
630 
631     /* clear service data filter */
632     BTM_LE_PF_srvc_data_pattern(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, {},
633                                 fDoNothing);
634   }
635 
636   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN;
637   uint8_t param[len];
638   memset(param, 0, len);
639 
640   uint8_t* p = param;
641 
642   /* select feature based on control block settings */
643   UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
644   UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
645   UINT8_TO_STREAM(p, filt_index);
646   /* set PCF selection */
647   UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE);
648   /* set logic condition as OR as default */
649   UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR);
650 
651   btu_hcif_send_cmd_with_cb(
652       FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
653       base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
654 
655   memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR));
656 }
657 
658 /*******************************************************************************
659  *
660  * Function         BTM_BleAdvFilterParamSetup
661  *
662  * Description      This function is called to setup the adv data payload filter
663  *                  condition.
664  *
665  * Parameters       action - Type of action to be performed
666  *                       filt_index - Filter index
667  *                       p_filt_params - Filter parameters
668  *                       cb - Callback
669  *
670  ******************************************************************************/
BTM_BleAdvFilterParamSetup(int action,tBTM_BLE_PF_FILT_INDEX filt_index,std::unique_ptr<btgatt_filt_param_setup_t> p_filt_params,tBTM_BLE_PF_PARAM_CB cb)671 void BTM_BleAdvFilterParamSetup(
672     int action, tBTM_BLE_PF_FILT_INDEX filt_index,
673     std::unique_ptr<btgatt_filt_param_setup_t> p_filt_params,
674     tBTM_BLE_PF_PARAM_CB cb) {
675   tBTM_BLE_PF_COUNT* p_bda_filter = NULL;
676   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH +
677                 BTM_BLE_ADV_FILT_FEAT_SELN_LEN + BTM_BLE_ADV_FILT_TRACK_NUM;
678   uint8_t param[len], *p;
679 
680   if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) {
681     cb.Run(0, BTM_BLE_PF_ENABLE, 1 /* BTA_FAILURE */);
682     return;
683   }
684 
685   p = param;
686   memset(param, 0, len);
687   BTM_TRACE_EVENT("%s", __func__);
688 
689   if (BTM_BLE_SCAN_COND_ADD == action) {
690     p_bda_filter = btm_ble_find_addr_filter_counter(nullptr);
691     if (NULL == p_bda_filter) {
692       BTM_TRACE_ERROR("BD Address not found!");
693       cb.Run(0, BTM_BLE_PF_ENABLE, 1 /* BTA_FAILURE */);
694       return;
695     }
696 
697     BTM_TRACE_DEBUG("%s : Feat mask:%d", __func__, p_filt_params->feat_seln);
698     /* select feature based on control block settings */
699     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
700     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD);
701 
702     /* Filter index */
703     UINT8_TO_STREAM(p, filt_index);
704 
705     /* set PCF selection */
706     UINT16_TO_STREAM(p, p_filt_params->feat_seln);
707     /* set logic type */
708     UINT16_TO_STREAM(p, p_filt_params->list_logic_type);
709     /* set logic condition */
710     UINT8_TO_STREAM(p, p_filt_params->filt_logic_type);
711     /* set RSSI high threshold */
712     UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres);
713     /* set delivery mode */
714     UINT8_TO_STREAM(p, p_filt_params->dely_mode);
715 
716     if (0x01 == p_filt_params->dely_mode) {
717       /* set onfound timeout */
718       UINT16_TO_STREAM(p, p_filt_params->found_timeout);
719       /* set onfound timeout count*/
720       UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt);
721       /* set RSSI low threshold */
722       UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres);
723       /* set onlost timeout */
724       UINT16_TO_STREAM(p, p_filt_params->lost_timeout);
725       /* set num_of_track_entries for firmware greater than L-release version */
726       if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION)
727         UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries);
728     }
729 
730     if (cmn_ble_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION)
731       len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN;
732     else
733       len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
734             BTM_BLE_ADV_FILT_TRACK_NUM;
735 
736     btu_hcif_send_cmd_with_cb(
737         FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param, len,
738         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
739   } else if (BTM_BLE_SCAN_COND_DELETE == action) {
740     /* select feature based on control block settings */
741     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
742     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE);
743     /* Filter index */
744     UINT8_TO_STREAM(p, filt_index);
745 
746     btu_hcif_send_cmd_with_cb(
747         FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param,
748         (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
749         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
750   } else if (BTM_BLE_SCAN_COND_CLEAR == action) {
751     /* Deallocate all filters here */
752     btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
753 
754     /* select feature based on control block settings */
755     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
756     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
757 
758     btu_hcif_send_cmd_with_cb(
759         FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param,
760         (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH - 1),
761         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
762   }
763 }
764 
enable_cmpl_cback(tBTM_BLE_PF_STATUS_CBACK p_stat_cback,uint8_t * p,uint16_t evt_len)765 void enable_cmpl_cback(tBTM_BLE_PF_STATUS_CBACK p_stat_cback, uint8_t* p,
766                        uint16_t evt_len) {
767   uint8_t status, op_subcode, action;
768 
769   if (evt_len != 3) {
770     BTM_TRACE_ERROR("%s: APCF callback length = %d", __func__, evt_len);
771     return;
772   }
773 
774   STREAM_TO_UINT8(status, p);
775   STREAM_TO_UINT8(op_subcode, p);
776   STREAM_TO_UINT8(action, p);
777 
778   if (op_subcode != BTM_BLE_META_PF_ENABLE) {
779     BTM_TRACE_ERROR("%s :bad subcode: 0x%02x", __func__, op_subcode);
780     return;
781   }
782 
783   p_stat_cback.Run(action, status);
784 }
785 
786 /*******************************************************************************
787  *
788  * Function         BTM_BleEnableDisableFilterFeature
789  *
790  * Description      This function is called to enable / disable the APCF feature
791  *
792  * Parameters       enable: enable or disable the filter condition
793  *                  p_stat_cback - Status callback pointer
794  *
795  ******************************************************************************/
BTM_BleEnableDisableFilterFeature(uint8_t enable,tBTM_BLE_PF_STATUS_CBACK p_stat_cback)796 void BTM_BleEnableDisableFilterFeature(uint8_t enable,
797                                        tBTM_BLE_PF_STATUS_CBACK p_stat_cback) {
798   if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) {
799     if (p_stat_cback) p_stat_cback.Run(BTM_BLE_PF_ENABLE, 1 /* BTA_FAILURE */);
800     return;
801   }
802 
803   uint8_t param[20];
804   memset(param, 0, 20);
805 
806   uint8_t* p = param;
807   UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE);
808   UINT8_TO_STREAM(p, enable);
809 
810   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_ADV_FILTER_OCF, param,
811                             BTM_BLE_PCF_ENABLE_LEN,
812                             base::Bind(&enable_cmpl_cback, p_stat_cback));
813 }
814 
815 /*******************************************************************************
816  *
817  * Function         btm_ble_adv_filter_init
818  *
819  * Description      This function initializes the adv filter control block
820  *
821  * Parameters
822  *
823  * Returns          status
824  *
825  ******************************************************************************/
btm_ble_adv_filter_init(void)826 void btm_ble_adv_filter_init(void) {
827   memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_ADV_FILTER_CB));
828   if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) return;
829 
830   if (cmn_ble_vsc_cb.max_filter > 0) {
831     btm_ble_adv_filt_cb.p_addr_filter_count = (tBTM_BLE_PF_COUNT*)osi_malloc(
832         sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter);
833   }
834 }
835 
836 /*******************************************************************************
837  *
838  * Function         btm_ble_adv_filter_cleanup
839  *
840  * Description      This function de-initializes the adv filter control block
841  *
842  * Parameters
843  *
844  * Returns          status
845  *
846  ******************************************************************************/
btm_ble_adv_filter_cleanup(void)847 void btm_ble_adv_filter_cleanup(void) {
848   osi_free_and_reset((void**)&btm_ble_adv_filt_cb.p_addr_filter_count);
849 }
850