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