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