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