1 /******************************************************************************
2  *
3  *  Copyright 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/functional/bind.h>
22 #include <bluetooth/log.h>
23 
24 #include "btm_ble_api.h"
25 #include "os/log.h"
26 #include "osi/include/allocator.h"
27 #include "stack/btm/btm_ble_int.h"
28 #include "stack/btm/btm_int_types.h"
29 #include "stack/include/bt_types.h"
30 #include "stack/include/btu_hcif.h"
31 #include "types/bluetooth/uuid.h"
32 #include "types/raw_address.h"
33 
34 extern tBTM_CB btm_cb;
35 
36 using namespace bluetooth;
37 using base::Bind;
38 using bluetooth::Uuid;
39 
40 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3
41 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13
42 #define BTM_BLE_ADV_FILT_TRACK_NUM 2
43 
44 #define BTM_BLE_PF_SELECT_NONE 0
45 
46 /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */
47 #define BTM_BLE_META_HDR_LENGTH 3
48 #define BTM_BLE_PF_FEAT_SEL_LEN 18
49 #define BTM_BLE_PCF_ENABLE_LEN 2
50 
51 #define BTM_BLE_META_ADDR_LEN 7
52 #define BTM_BLE_META_UUID_LEN 40
53 
54 #define BTM_BLE_PF_BIT_TO_MASK(x) (uint16_t)(1 << (x))
55 
56 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
57 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
58 
59 static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
60                                             uint8_t cond_type,
61                                             tBLE_BD_ADDR* p_bd_addr,
62                                             uint8_t num_available);
63 
64 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x) << 4) | (y))
65 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4)
66 #define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x)&0x0f)
67 #define BTM_BLE_INVALID_COUNTER 0xff
68 
69 /* length of each multi adv sub command */
70 #define BTM_BLE_ADV_FILTER_ENB_LEN 3
71 
72 /* length of each batch scan command */
73 #define BTM_BLE_ADV_FILTER_CLEAR_LEN 3
74 #define BTM_BLE_ADV_FILTER_LEN 2
75 
76 #define BTM_BLE_ADV_FILT_CB_EVT_MASK 0xF0
77 #define BTM_BLE_ADV_FILT_SUBCODE_MASK 0x0F
78 
is_filtering_supported()79 static bool is_filtering_supported() {
80   return cmn_ble_vsc_cb.filter_support != 0 && cmn_ble_vsc_cb.max_filter != 0;
81 }
82 
83 /*******************************************************************************
84  *
85  * Function         btm_ble_ocf_to_condtype
86  *
87  * Description      Convert OCF to cond type
88  *
89  * Returns          Returns condtype value
90  *
91  ******************************************************************************/
btm_ble_ocf_to_condtype(uint8_t ocf)92 static uint8_t btm_ble_ocf_to_condtype(uint8_t ocf) {
93   uint8_t cond_type = 0;
94 
95   switch (ocf) {
96     case BTM_BLE_META_PF_FEAT_SEL:
97       cond_type = BTM_BLE_META_PF_FEAT_SEL;
98       break;
99     case BTM_BLE_META_PF_ADDR:
100       cond_type = BTM_BLE_PF_ADDR_FILTER;
101       break;
102     case BTM_BLE_META_PF_UUID:
103       cond_type = BTM_BLE_PF_SRVC_UUID;
104       break;
105     case BTM_BLE_META_PF_SOL_UUID:
106       cond_type = BTM_BLE_PF_SRVC_SOL_UUID;
107       break;
108     case BTM_BLE_META_PF_LOCAL_NAME:
109       cond_type = BTM_BLE_PF_LOCAL_NAME;
110       break;
111     case BTM_BLE_META_PF_MANU_DATA:
112       cond_type = BTM_BLE_PF_MANU_DATA;
113       break;
114     case BTM_BLE_META_PF_SRVC_DATA:
115       cond_type = BTM_BLE_PF_SRVC_DATA_PATTERN;
116       break;
117     case BTM_BLE_META_PF_ALL:
118       cond_type = BTM_BLE_PF_TYPE_ALL;
119       break;
120     default:
121       cond_type = BTM_BLE_PF_TYPE_MAX;
122       break;
123   }
124   return cond_type;
125 }
126 
btm_flt_update_cb(uint8_t expected_ocf,tBTM_BLE_PF_CFG_CBACK cb,uint8_t * p,uint16_t evt_len)127 static void btm_flt_update_cb(uint8_t expected_ocf, tBTM_BLE_PF_CFG_CBACK cb,
128                               uint8_t* p, uint16_t evt_len) {
129   if (evt_len != 4) {
130     log::error("bad length: {}", evt_len);
131     return;
132   }
133 
134   uint8_t status, op_subcode, action, num_avail;
135   STREAM_TO_UINT8(status, p);
136   STREAM_TO_UINT8(op_subcode, p);
137   STREAM_TO_UINT8(action, p);
138   STREAM_TO_UINT8(num_avail, p);
139 
140   if (expected_ocf != op_subcode) {
141     log::error("Incorrect opcode: 0x{:02x}, expected: 0x{:02x}", expected_ocf,
142                op_subcode);
143     return;
144   }
145 
146   tBTM_STATUS btm_status = (status == 0) ? BTM_SUCCESS : BTM_ERR_PROCESSING;
147 
148   if (op_subcode == BTM_BLE_META_PF_FEAT_SEL) {
149     cb.Run(num_avail, static_cast<tBTM_BLE_SCAN_COND_OP>(action), btm_status);
150     return;
151   }
152 
153   uint8_t cond_type = btm_ble_ocf_to_condtype(expected_ocf);
154   log::verbose("Recd: {}, {}, {}, {}, {}", op_subcode, expected_ocf, action,
155                status, num_avail);
156   if (HCI_SUCCESS == status) {
157     if (btm_ble_adv_filt_cb.cur_filter_target.bda.IsEmpty())
158       btm_ble_cs_update_pf_counter(static_cast<tBTM_BLE_SCAN_COND_OP>(action),
159                                    cond_type, NULL, num_avail);
160     else
161       btm_ble_cs_update_pf_counter(
162           static_cast<tBTM_BLE_SCAN_COND_OP>(action), cond_type,
163           &btm_ble_adv_filt_cb.cur_filter_target, num_avail);
164   }
165 
166   /* send ADV PF operation complete */
167   btm_ble_adv_filt_cb.op_type = 0;
168 
169   cb.Run(num_avail, static_cast<tBTM_BLE_SCAN_COND_OP>(action), btm_status);
170 }
171 
172 /*******************************************************************************
173  *
174  * Function         btm_ble_find_addr_filter_counter
175  *
176  * Description      find the per bd address ADV payload filter counter by
177  *                  BD_ADDR.
178  *
179  * Returns          pointer to the counter if found; NULL otherwise.
180  *
181  ******************************************************************************/
btm_ble_find_addr_filter_counter(tBLE_BD_ADDR * p_le_bda)182 static tBTM_BLE_PF_COUNT* btm_ble_find_addr_filter_counter(
183     tBLE_BD_ADDR* p_le_bda) {
184   uint8_t i;
185   tBTM_BLE_PF_COUNT* p_addr_filter =
186       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
187 
188   if (p_le_bda == NULL) return &btm_ble_adv_filt_cb.p_addr_filter_count[0];
189 
190   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
191     if (p_addr_filter->in_use && p_le_bda->bda == p_addr_filter->bd_addr) {
192       return p_addr_filter;
193     }
194   }
195   return NULL;
196 }
197 
198 /*******************************************************************************
199  *
200  * Function         btm_ble_alloc_addr_filter_counter
201  *
202  * Description      allocate the per device adv payload filter counter.
203  *
204  * Returns          pointer to the counter if allocation succeed; NULL
205  *                  otherwise.
206  *
207  ******************************************************************************/
btm_ble_alloc_addr_filter_counter(const RawAddress & bd_addr)208 static tBTM_BLE_PF_COUNT* btm_ble_alloc_addr_filter_counter(
209     const RawAddress& bd_addr) {
210   uint8_t i;
211   tBTM_BLE_PF_COUNT* p_addr_filter =
212       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
213 
214   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
215     if (p_addr_filter->bd_addr.IsEmpty()) {
216       p_addr_filter->bd_addr = bd_addr;
217       p_addr_filter->in_use = true;
218       return p_addr_filter;
219     }
220   }
221   return NULL;
222 }
223 /*******************************************************************************
224  *
225  * Function         btm_ble_dealloc_addr_filter_counter
226  *
227  * Description      de-allocate the per device adv payload filter counter.
228  *
229  * Returns          true if deallocation succeed; false otherwise.
230  *
231  ******************************************************************************/
btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR * p_bd_addr,uint8_t filter_type)232 static bool btm_ble_dealloc_addr_filter_counter(tBLE_BD_ADDR* p_bd_addr,
233                                                 uint8_t filter_type) {
234   uint8_t i;
235   tBTM_BLE_PF_COUNT* p_addr_filter =
236       &btm_ble_adv_filt_cb.p_addr_filter_count[1];
237   bool found = false;
238 
239   if (BTM_BLE_PF_TYPE_ALL == filter_type && NULL == p_bd_addr)
240     memset(&btm_ble_adv_filt_cb.p_addr_filter_count[0], 0,
241            sizeof(tBTM_BLE_PF_COUNT));
242 
243   for (i = 0; i < cmn_ble_vsc_cb.max_filter; i++, p_addr_filter++) {
244     if (p_addr_filter->in_use &&
245         (!p_bd_addr || p_bd_addr->bda == p_addr_filter->bd_addr)) {
246       found = true;
247       memset(p_addr_filter, 0, sizeof(tBTM_BLE_PF_COUNT));
248 
249       if (p_bd_addr) break;
250     }
251   }
252   return found;
253 }
254 
255 /*******************************************************************************
256  *
257  * Function         btm_ble_cs_update_pf_counter
258  *
259  * Description      this function is to update the adv data payload filter
260  *                  counter
261  *
262  * Returns          current number of the counter; BTM_BLE_INVALID_COUNTER if
263  *                  counter update failed.
264  *
265  ******************************************************************************/
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)266 static uint8_t btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action,
267                                             uint8_t cond_type,
268                                             tBLE_BD_ADDR* p_bd_addr,
269                                             uint8_t num_available) {
270   tBTM_BLE_PF_COUNT* p_addr_filter = NULL;
271   uint8_t* p_counter = NULL;
272 
273   if (cond_type > BTM_BLE_PF_TYPE_ALL) {
274     log::error("unknown PF filter condition type {}", cond_type);
275     return BTM_BLE_INVALID_COUNTER;
276   }
277 
278   /* for these three types of filter, always generic */
279   if (BTM_BLE_PF_ADDR_FILTER == cond_type ||
280       BTM_BLE_PF_MANU_DATA == cond_type || BTM_BLE_PF_LOCAL_NAME == cond_type ||
281       BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type)
282     p_bd_addr = NULL;
283 
284   if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL &&
285       BTM_BLE_SCAN_COND_ADD == action) {
286     p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda);
287   }
288 
289   if (NULL != p_addr_filter) {
290     /* all filter just cleared */
291     if ((BTM_BLE_PF_TYPE_ALL == cond_type &&
292          BTM_BLE_SCAN_COND_CLEAR == action) ||
293         /* or bd address filter been deleted */
294         (BTM_BLE_PF_ADDR_FILTER == cond_type &&
295          (BTM_BLE_SCAN_COND_DELETE == action ||
296           BTM_BLE_SCAN_COND_CLEAR == action))) {
297       btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type);
298     }
299     /* if not feature selection, update new addition/reduction of the filter
300        counter */
301     else if (cond_type != BTM_BLE_PF_TYPE_ALL) {
302       p_counter = p_addr_filter->pf_counter;
303       if (num_available > 0) p_counter[cond_type] += 1;
304 
305       log::verbose("counter = {}, maxfilt = {}, num_avbl={}",
306                    p_counter[cond_type], cmn_ble_vsc_cb.max_filter,
307                    num_available);
308       return p_counter[cond_type];
309     }
310   } else {
311     log::error("no matching filter counter found");
312   }
313   /* no matching filter located and updated */
314   return BTM_BLE_INVALID_COUNTER;
315 }
316 
317 /*******************************************************************************
318  *
319  * Function         BTM_BleAdvFilterParamSetup
320  *
321  * Description      This function is called to setup the adv data payload filter
322  *                  condition.
323  *
324  * Parameters       action - Type of action to be performed
325  *                       filt_index - Filter index
326  *                       p_filt_params - Filter parameters
327  *                       cb - Callback
328  *
329  ******************************************************************************/
BTM_BleAdvFilterParamSetup(tBTM_BLE_SCAN_COND_OP 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)330 void BTM_BleAdvFilterParamSetup(
331     tBTM_BLE_SCAN_COND_OP action, tBTM_BLE_PF_FILT_INDEX filt_index,
332     std::unique_ptr<btgatt_filt_param_setup_t> p_filt_params,
333     tBTM_BLE_PF_PARAM_CB cb) {
334   tBTM_BLE_PF_COUNT* p_bda_filter = NULL;
335   uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH +
336                 BTM_BLE_ADV_FILT_FEAT_SELN_LEN + BTM_BLE_ADV_FILT_TRACK_NUM;
337   uint8_t param[len], *p;
338 
339   if (!is_filtering_supported()) {
340     cb.Run(0, BTM_BLE_PF_ENABLE, btm_status_value(BTM_MODE_UNSUPPORTED));
341     return;
342   }
343 
344   p = param;
345   memset(param, 0, len);
346   log::verbose("");
347 
348   if (BTM_BLE_SCAN_COND_ADD == action) {
349     p_bda_filter = btm_ble_find_addr_filter_counter(nullptr);
350     if (NULL == p_bda_filter) {
351       log::error("BD Address not found!");
352       cb.Run(0, BTM_BLE_PF_ENABLE, btm_status_value(BTM_UNKNOWN_ADDR));
353       return;
354     }
355 
356     log::verbose("Feat mask:{}", p_filt_params->feat_seln);
357     /* select feature based on control block settings */
358     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
359     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD);
360 
361     /* Filter index */
362     UINT8_TO_STREAM(p, filt_index);
363 
364     /* set PCF selection */
365     UINT16_TO_STREAM(p, p_filt_params->feat_seln);
366     /* set logic type */
367     UINT16_TO_STREAM(p, p_filt_params->list_logic_type);
368     /* set logic condition */
369     UINT8_TO_STREAM(p, p_filt_params->filt_logic_type);
370     /* set RSSI high threshold */
371     UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres);
372     /* set delivery mode */
373     UINT8_TO_STREAM(p, p_filt_params->dely_mode);
374 
375     if (0x01 == p_filt_params->dely_mode) {
376       /* set onfound timeout */
377       UINT16_TO_STREAM(p, p_filt_params->found_timeout);
378       /* set onfound timeout count*/
379       UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt);
380       /* set RSSI low threshold */
381       UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres);
382       /* set onlost timeout */
383       UINT16_TO_STREAM(p, p_filt_params->lost_timeout);
384       /* set num_of_track_entries for firmware greater than L-release version */
385       if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION)
386         UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries);
387     }
388 
389     if (cmn_ble_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION)
390       len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN;
391     else
392       len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN +
393             BTM_BLE_ADV_FILT_TRACK_NUM;
394 
395     btu_hcif_send_cmd_with_cb(
396         FROM_HERE, HCI_BLE_ADV_FILTER, param, len,
397         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
398   } else if (BTM_BLE_SCAN_COND_DELETE == action) {
399     /* select feature based on control block settings */
400     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
401     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE);
402     /* Filter index */
403     UINT8_TO_STREAM(p, filt_index);
404 
405     btu_hcif_send_cmd_with_cb(
406         FROM_HERE, HCI_BLE_ADV_FILTER, param,
407         (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH),
408         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
409 
410   } else if (BTM_BLE_SCAN_COND_CLEAR == action) {
411     /* Deallocate all filters here */
412     btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL);
413 
414     /* select feature based on control block settings */
415     UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL);
416     UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR);
417 
418     btu_hcif_send_cmd_with_cb(
419         FROM_HERE, HCI_BLE_ADV_FILTER, param,
420         (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH - 1),
421         base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb));
422   }
423 }
424 
425 /*******************************************************************************
426  *
427  * Function         btm_ble_adv_filter_init
428  *
429  * Description      This function initializes the adv filter control block
430  *
431  * Parameters
432  *
433  * Returns          status
434  *
435  ******************************************************************************/
btm_ble_adv_filter_init(void)436 void btm_ble_adv_filter_init(void) {
437   memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_ADV_FILTER_CB));
438 
439   BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
440 
441   if (!is_filtering_supported()) return;
442 
443   if (cmn_ble_vsc_cb.max_filter > 0) {
444     btm_ble_adv_filt_cb.p_addr_filter_count = (tBTM_BLE_PF_COUNT*)osi_malloc(
445         sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter);
446   }
447 }
448