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