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 23 #include "bt_target.h" 24 25 #if (BLE_INCLUDED == TRUE) 26 27 #include "bt_types.h" 28 #include "bt_utils.h" 29 #include "btm_ble_api.h" 30 #include "btm_int.h" 31 #include "btu.h" 32 #include "device/include/controller.h" 33 #include "hcidefs.h" 34 #include "hcimsgs.h" 35 36 #define BTM_BLE_ADV_FILT_META_HDR_LENGTH 3 37 #define BTM_BLE_ADV_FILT_FEAT_SELN_LEN 13 38 #define BTM_BLE_ADV_FILT_TRACK_NUM 2 39 40 #define BTM_BLE_PF_SELECT_NONE 0 41 42 /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */ 43 #define BTM_BLE_META_HDR_LENGTH 3 44 #define BTM_BLE_PF_FEAT_SEL_LEN 18 45 #define BTM_BLE_PCF_ENABLE_LEN 2 46 47 #define BTM_BLE_META_ADDR_LEN 7 48 #define BTM_BLE_META_UUID_LEN 40 49 50 #define BTM_BLE_PF_BIT_TO_MASK(x) (UINT16)(1 << (x)) 51 52 tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb; 53 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 54 static const BD_ADDR na_bda= {0}; 55 56 static UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, 57 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, UINT8 num_available); 58 59 #define BTM_BLE_SET_SCAN_PF_OPCODE(x, y) (((x)<<4)|y) 60 #define BTM_BLE_GET_SCAN_PF_SUBCODE(x) ((x) >> 4) 61 #define BTM_BLE_GET_SCAN_PF_ACTION(x) ((x) & 0x0f) 62 #define BTM_BLE_INVALID_COUNTER 0xff 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 ** Function btm_ble_update_srvc_data_change 508 ** 509 ** Description this function update(add/remove) service data change filter. 510 ** 511 ** 512 ** Returns BTM_SUCCESS if sucessful, 513 ** BTM_ILLEGAL_VALUE if paramter is not valid. 514 ** 515 *******************************************************************************/ 516 tBTM_STATUS btm_ble_update_srvc_data_change(tBTM_BLE_SCAN_COND_OP action, 517 tBTM_BLE_PF_FILT_INDEX filt_index, 518 tBTM_BLE_PF_COND_PARAM *p_cond) 519 { 520 tBTM_STATUS st = BTM_ILLEGAL_VALUE; 521 tBLE_BD_ADDR *p_bd_addr = p_cond ? &p_cond->target_addr : NULL; 522 UINT8 num_avail = (action == BTM_BLE_SCAN_COND_ADD) ? 0 : 1; 523 524 if (btm_ble_cs_update_pf_counter (action, BTM_BLE_PF_SRVC_DATA, p_bd_addr, num_avail) 525 != BTM_BLE_INVALID_COUNTER) 526 st = BTM_SUCCESS; 527 528 return st; 529 } 530 531 /******************************************************************************* 532 ** 533 ** Function btm_ble_update_pf_manu_data 534 ** 535 ** Description this function update(add,delete or clear) the adv manufacturer 536 ** data filtering condition. 537 ** 538 ** 539 ** Returns BTM_SUCCESS if sucessful, 540 ** BTM_ILLEGAL_VALUE if paramter is not valid. 541 ** 542 *******************************************************************************/ 543 tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, 544 tBTM_BLE_PF_FILT_INDEX filt_index, 545 tBTM_BLE_PF_COND_PARAM *p_data, 546 tBTM_BLE_PF_COND_TYPE cond_type, 547 tBTM_BLE_FILT_CB_EVT cb_evt, 548 tBTM_BLE_REF_VALUE ref_value) 549 { 550 tBTM_BLE_PF_MANU_COND *p_manu_data = (p_data == NULL) ? NULL : &p_data->manu_data; 551 tBTM_BLE_PF_SRVC_PATTERN_COND *p_srvc_data = (p_data == NULL) ? NULL : &p_data->srvc_data; 552 553 UINT8 param[BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_ADV_FILT_META_HDR_LENGTH], 554 *p = param, 555 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; 556 tBTM_STATUS st = BTM_ILLEGAL_VALUE; 557 558 if (NULL == p_data) 559 return st; 560 561 memset(param, 0, BTM_BLE_PF_STR_LEN_MAX + BTM_BLE_PF_STR_LEN_MAX 562 + BTM_BLE_ADV_FILT_META_HDR_LENGTH); 563 564 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) 565 { 566 UINT8_TO_STREAM(p, BTM_BLE_META_PF_SRVC_DATA); 567 } 568 else 569 { 570 UINT8_TO_STREAM(p, BTM_BLE_META_PF_MANU_DATA); 571 } 572 573 UINT8_TO_STREAM(p, action); 574 575 /* Filter index */ 576 UINT8_TO_STREAM(p, filt_index); 577 578 if (BTM_BLE_SCAN_COND_ADD == action || BTM_BLE_SCAN_COND_DELETE == action) 579 { 580 if (BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) 581 { 582 if (NULL == p_srvc_data) 583 return st; 584 if (p_srvc_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) 585 p_srvc_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); 586 587 if (p_srvc_data->data_len > 0) 588 { 589 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern, p_srvc_data->data_len); 590 len += (p_srvc_data->data_len); 591 ARRAY_TO_STREAM(p, p_srvc_data->p_pattern_mask, p_srvc_data->data_len); 592 } 593 594 len += (p_srvc_data->data_len); 595 BTM_TRACE_DEBUG("Service data length: %d", len); 596 } 597 else 598 { 599 if (NULL == p_manu_data) 600 { 601 BTM_TRACE_ERROR("btm_ble_update_pf_manu_data - No manuf data"); 602 return st; 603 } 604 BTM_TRACE_EVENT("btm_ble_update_pf_manu_data length: %d", 605 p_manu_data->data_len); 606 if (p_manu_data->data_len > (BTM_BLE_PF_STR_LEN_MAX - 2)) 607 p_manu_data->data_len = (BTM_BLE_PF_STR_LEN_MAX - 2); 608 609 UINT16_TO_STREAM(p, p_manu_data->company_id); 610 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) 611 { 612 ARRAY_TO_STREAM(p, p_manu_data->p_pattern, p_manu_data->data_len); 613 len += (p_manu_data->data_len + 2); 614 } 615 else 616 len += 2; 617 618 if (p_manu_data->company_id_mask != 0) 619 { 620 UINT16_TO_STREAM (p, p_manu_data->company_id_mask); 621 } 622 else 623 { 624 memset(p, 0xff, 2); 625 p += 2; 626 } 627 len += 2; 628 629 if (p_manu_data->data_len > 0 && p_manu_data->p_pattern_mask != NULL) 630 { 631 ARRAY_TO_STREAM(p, p_manu_data->p_pattern_mask, p_manu_data->data_len); 632 len += (p_manu_data->data_len); 633 } 634 635 BTM_TRACE_DEBUG("Manuf data length: %d", len); 636 } 637 } 638 639 /* send manufacturer*/ 640 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 641 len, 642 param, 643 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) 644 { 645 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); 646 } 647 else 648 { 649 BTM_TRACE_ERROR("manufacturer data PF filter update failed"); 650 } 651 652 return st; 653 } 654 655 /******************************************************************************* 656 ** 657 ** Function btm_ble_cs_update_pf_counter 658 ** 659 ** Description this function is to update the adv data payload filter counter 660 ** 661 ** Returns current number of the counter; BTM_BLE_INVALID_COUNTER if 662 ** counter update failed. 663 ** 664 *******************************************************************************/ 665 UINT8 btm_ble_cs_update_pf_counter(tBTM_BLE_SCAN_COND_OP action, 666 UINT8 cond_type, tBLE_BD_ADDR *p_bd_addr, 667 UINT8 num_available) 668 { 669 tBTM_BLE_PF_COUNT *p_addr_filter = NULL; 670 UINT8 *p_counter = NULL; 671 672 btm_ble_obtain_vsc_details(); 673 674 if (cond_type > BTM_BLE_PF_TYPE_ALL) 675 { 676 BTM_TRACE_ERROR("unknown PF filter condition type %d", cond_type); 677 return BTM_BLE_INVALID_COUNTER; 678 } 679 680 /* for these three types of filter, always generic */ 681 if (BTM_BLE_PF_ADDR_FILTER == cond_type || 682 BTM_BLE_PF_MANU_DATA == cond_type || 683 BTM_BLE_PF_LOCAL_NAME == cond_type || 684 BTM_BLE_PF_SRVC_DATA_PATTERN == cond_type) 685 p_bd_addr = NULL; 686 687 if ((p_addr_filter = btm_ble_find_addr_filter_counter(p_bd_addr)) == NULL && 688 BTM_BLE_SCAN_COND_ADD == action) 689 { 690 p_addr_filter = btm_ble_alloc_addr_filter_counter(p_bd_addr->bda); 691 } 692 693 if (NULL != p_addr_filter) 694 { 695 /* all filter just cleared */ 696 if ((BTM_BLE_PF_TYPE_ALL == cond_type && BTM_BLE_SCAN_COND_CLEAR == action) || 697 /* or bd address filter been deleted */ 698 (BTM_BLE_PF_ADDR_FILTER == cond_type && 699 (BTM_BLE_SCAN_COND_DELETE == action || BTM_BLE_SCAN_COND_CLEAR == action))) 700 { 701 btm_ble_dealloc_addr_filter_counter(p_bd_addr, cond_type); 702 } 703 /* if not feature selection, update new addition/reduction of the filter counter */ 704 else if (cond_type != BTM_BLE_PF_TYPE_ALL) 705 { 706 p_counter = p_addr_filter->pf_counter; 707 if (num_available > 0) 708 p_counter[cond_type] += 1; 709 710 BTM_TRACE_DEBUG("counter = %d, maxfilt = %d, num_avbl=%d", 711 p_counter[cond_type], cmn_ble_vsc_cb.max_filter, num_available); 712 return p_counter[cond_type]; 713 } 714 } 715 else 716 { 717 BTM_TRACE_ERROR("no matching filter counter found"); 718 } 719 /* no matching filter located and updated */ 720 return BTM_BLE_INVALID_COUNTER; 721 } 722 723 /******************************************************************************* 724 ** 725 ** Function btm_ble_update_addr_filter 726 ** 727 ** Description this function update(add,delete or clear) the address filter of adv. 728 ** 729 ** 730 ** Returns BTM_SUCCESS if sucessful, 731 ** BTM_ILLEGAL_VALUE if paramter is not valid. 732 ** 733 *******************************************************************************/ 734 tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, 735 tBTM_BLE_PF_FILT_INDEX filt_index, 736 tBTM_BLE_PF_COND_PARAM *p_cond) 737 { 738 UINT8 param[BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], 739 * p= param; 740 tBTM_STATUS st = BTM_ILLEGAL_VALUE; 741 tBLE_BD_ADDR *p_addr = (p_cond == NULL) ? NULL : &p_cond->target_addr; 742 743 memset(param, 0, BTM_BLE_META_ADDR_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); 744 745 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); 746 UINT8_TO_STREAM(p, action); 747 748 /* Filter index */ 749 UINT8_TO_STREAM(p, filt_index); 750 751 if (BTM_BLE_SCAN_COND_ADD == action || 752 BTM_BLE_SCAN_COND_DELETE == action) 753 { 754 if (NULL == p_addr) 755 return st; 756 757 BDADDR_TO_STREAM(p, p_addr->bda); 758 UINT8_TO_STREAM(p, p_addr->type); 759 } 760 /* send address filter */ 761 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 762 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), 763 param, 764 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) 765 { 766 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); 767 } 768 else 769 { 770 BTM_TRACE_ERROR("Broadcaster Address Filter Update failed"); 771 } 772 return st; 773 } 774 775 /******************************************************************************* 776 ** 777 ** Function btm_ble_update_uuid_filter 778 ** 779 ** Description this function update(add,delete or clear) service UUID filter. 780 ** 781 ** 782 ** Returns BTM_SUCCESS if sucessful, 783 ** BTM_ILLEGAL_VALUE if paramter is not valid. 784 ** 785 *******************************************************************************/ 786 tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, 787 tBTM_BLE_PF_FILT_INDEX filt_index, 788 tBTM_BLE_PF_COND_TYPE filter_type, 789 tBTM_BLE_PF_COND_PARAM *p_cond, 790 tBTM_BLE_FILT_CB_EVT cb_evt, 791 tBTM_BLE_REF_VALUE ref_value) 792 { 793 UINT8 param[BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH], 794 * p= param, 795 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH; 796 tBTM_STATUS st = BTM_ILLEGAL_VALUE; 797 tBTM_BLE_PF_UUID_COND *p_uuid_cond; 798 UINT8 evt_type; 799 800 memset(param, 0, BTM_BLE_META_UUID_LEN + BTM_BLE_ADV_FILT_META_HDR_LENGTH); 801 802 if (BTM_BLE_PF_SRVC_UUID == filter_type) 803 { 804 evt_type = BTM_BLE_META_PF_UUID; 805 p_uuid_cond = p_cond ? &p_cond->srvc_uuid : NULL; 806 } 807 else 808 { 809 evt_type = BTM_BLE_META_PF_SOL_UUID; 810 p_uuid_cond = p_cond ? &p_cond->solicitate_uuid : NULL; 811 } 812 813 if (NULL == p_uuid_cond && action != BTM_BLE_SCAN_COND_CLEAR) 814 { 815 BTM_TRACE_ERROR("Illegal param for add/delete UUID filter"); 816 return st; 817 } 818 819 /* need to add address filter first, if adding per bda UUID filter without address filter */ 820 if (BTM_BLE_SCAN_COND_ADD == action && NULL != p_uuid_cond && 821 p_uuid_cond->p_target_addr && 822 btm_ble_find_addr_filter_counter(p_uuid_cond->p_target_addr) == NULL) 823 { 824 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); 825 UINT8_TO_STREAM(p, action); 826 827 /* Filter index */ 828 UINT8_TO_STREAM(p, filt_index); 829 830 BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); 831 UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); 832 833 /* send address filter */ 834 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 835 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_META_ADDR_LEN), 836 param, 837 btm_ble_scan_pf_cmpl_cback)) == BTM_NO_RESOURCES) 838 { 839 BTM_TRACE_ERROR("Update Address filter into controller failed."); 840 return st; 841 } 842 843 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_ADDR, cb_evt, ref_value, NULL, NULL); 844 BTM_TRACE_DEBUG("Updated Address filter"); 845 } 846 847 p = param; 848 UINT8_TO_STREAM(p, evt_type); 849 UINT8_TO_STREAM(p, action); 850 851 /* Filter index */ 852 UINT8_TO_STREAM(p, filt_index); 853 854 if ((BTM_BLE_SCAN_COND_ADD == action || 855 BTM_BLE_SCAN_COND_DELETE == action) && 856 NULL != p_uuid_cond) 857 { 858 if (p_uuid_cond->uuid.len == LEN_UUID_16) 859 { 860 UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); 861 len += LEN_UUID_16; 862 } 863 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ 864 { 865 UINT32_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid32); 866 len += LEN_UUID_32; 867 } 868 else if (p_uuid_cond->uuid.len == LEN_UUID_128) 869 { 870 ARRAY_TO_STREAM (p, p_uuid_cond->uuid.uu.uuid128, LEN_UUID_128); 871 len += LEN_UUID_128; 872 } 873 else 874 { 875 BTM_TRACE_ERROR("illegal UUID length: %d", p_uuid_cond->uuid.len); 876 return BTM_ILLEGAL_VALUE; 877 } 878 879 if (NULL != p_uuid_cond->p_uuid_mask) 880 { 881 if (p_uuid_cond->uuid.len == LEN_UUID_16) 882 { 883 UINT16_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid16_mask); 884 len += LEN_UUID_16; 885 } 886 else if (p_uuid_cond->uuid.len == LEN_UUID_32)/*4 bytes */ 887 { 888 UINT32_TO_STREAM(p, p_uuid_cond->p_uuid_mask->uuid32_mask); 889 len += LEN_UUID_32; 890 } 891 else if (p_uuid_cond->uuid.len == LEN_UUID_128) 892 { 893 ARRAY_TO_STREAM (p, p_uuid_cond->p_uuid_mask->uuid128_mask, LEN_UUID_128); 894 len += LEN_UUID_128; 895 } 896 } 897 else 898 { 899 memset(p, 0xff, p_uuid_cond->uuid.len); 900 len += p_uuid_cond->uuid.len; 901 } 902 BTM_TRACE_DEBUG("btm_ble_update_uuid_filter : %d, %d, %d, %d", filter_type, evt_type, 903 p_uuid_cond->uuid.len, len); 904 } 905 906 /* send UUID filter update */ 907 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 908 len, 909 param, 910 btm_ble_scan_pf_cmpl_cback)) != BTM_NO_RESOURCES) 911 { 912 if (p_uuid_cond && p_uuid_cond->p_target_addr) 913 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_uuid_cond->p_target_addr, 914 sizeof(tBLE_BD_ADDR)); 915 else 916 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); 917 } 918 else 919 { 920 BTM_TRACE_ERROR("UUID filter udpating failed"); 921 } 922 923 return st; 924 } 925 926 /******************************************************************************* 927 ** 928 ** Function btm_ble_clear_scan_pf_filter 929 ** 930 ** Description clear all adv payload filter by de-select all the adv pf feature bits 931 ** 932 ** 933 ** Returns BTM_SUCCESS if sucessful, 934 ** BTM_ILLEGAL_VALUE if paramter is not valid. 935 ** 936 *******************************************************************************/ 937 tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, 938 tBTM_BLE_PF_FILT_INDEX filt_index, 939 tBTM_BLE_PF_COND_PARAM *p_cond, 940 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, 941 tBTM_BLE_FILT_CB_EVT cb_evt, 942 tBTM_BLE_REF_VALUE ref_value) 943 { 944 tBLE_BD_ADDR *p_target = (p_cond == NULL)? NULL : &p_cond->target_addr; 945 tBTM_BLE_PF_COUNT *p_bda_filter; 946 tBTM_STATUS st = BTM_WRONG_MODE; 947 UINT8 param[20], *p; 948 949 if (BTM_BLE_SCAN_COND_CLEAR != action) 950 { 951 BTM_TRACE_ERROR("unable to perform action:%d for generic adv filter type", action); 952 return BTM_ILLEGAL_VALUE; 953 } 954 955 p = param; 956 memset(param, 0, 20); 957 958 p_bda_filter = btm_ble_find_addr_filter_counter(p_target); 959 960 if (NULL == p_bda_filter || 961 /* not a generic filter */ 962 (p_target != NULL && p_bda_filter)) 963 { 964 BTM_TRACE_ERROR("Error: Can not clear filter, No PF filter has been configured!"); 965 return st; 966 } 967 968 /* clear the general filter entry */ 969 if (NULL == p_target) 970 { 971 /* clear manufactuer data filter */ 972 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, 973 BTM_BLE_PF_MANU_DATA, cb_evt, ref_value); 974 if(BTM_CMD_STARTED == st) 975 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_MANU_DATA, cb_evt, 976 ref_value, NULL, NULL); 977 978 /* clear local name filter */ 979 st = btm_ble_update_pf_local_name(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); 980 if(BTM_CMD_STARTED == st) 981 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_LOCAL_NAME, cb_evt, 982 ref_value, NULL, NULL); 983 984 /* update the counter for service data */ 985 st = btm_ble_update_srvc_data_change(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL); 986 987 /* clear UUID filter */ 988 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, 989 BTM_BLE_PF_SRVC_UUID, NULL, cb_evt, ref_value); 990 if(BTM_CMD_STARTED == st) 991 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_UUID, cb_evt, ref_value, NULL, NULL); 992 993 st = btm_ble_update_uuid_filter(BTM_BLE_SCAN_COND_CLEAR, filt_index, 994 BTM_BLE_PF_SRVC_SOL_UUID, NULL, cb_evt, ref_value); 995 if(BTM_CMD_STARTED == st) 996 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SOL_UUID, cb_evt, 997 ref_value, NULL, NULL); 998 999 /* clear service data filter */ 1000 st = btm_ble_update_pf_manu_data(BTM_BLE_SCAN_COND_CLEAR, filt_index, NULL, 1001 BTM_BLE_PF_SRVC_DATA_PATTERN, cb_evt, ref_value); 1002 if(BTM_CMD_STARTED == st) 1003 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_SRVC_DATA, cb_evt, 1004 ref_value, NULL, NULL); 1005 } 1006 1007 /* select feature based on control block settings */ 1008 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); 1009 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); 1010 1011 /* Filter index */ 1012 UINT8_TO_STREAM(p, filt_index); 1013 1014 /* set PCF selection */ 1015 UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE); 1016 /* set logic condition as OR as default */ 1017 UINT8_TO_STREAM(p, BTM_BLE_PF_LOGIC_OR); 1018 1019 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 1020 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN), 1021 param, 1022 btm_ble_scan_pf_cmpl_cback)) 1023 != BTM_NO_RESOURCES) 1024 { 1025 if (p_target) 1026 memcpy(&btm_ble_adv_filt_cb.cur_filter_target, p_target, sizeof(tBLE_BD_ADDR)); 1027 else 1028 memset(&btm_ble_adv_filt_cb.cur_filter_target, 0, sizeof(tBLE_BD_ADDR)); 1029 } 1030 return st; 1031 } 1032 1033 /******************************************************************************* 1034 ** 1035 ** Function BTM_BleAdvFilterParamSetup 1036 ** 1037 ** Description This function is called to setup the adv data payload filter 1038 ** condition. 1039 ** 1040 ** Parameters action - Type of action to be performed 1041 ** filt_index - Filter index 1042 ** p_filt_params - Filter parameters 1043 ** p_target - Target device 1044 ** p_cmpl_back - Callback pointer 1045 ** ref_value - reference value 1046 ** 1047 ** Returns void 1048 ** 1049 *******************************************************************************/ 1050 tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, tBTM_BLE_PF_FILT_INDEX filt_index, 1051 tBTM_BLE_PF_FILT_PARAMS *p_filt_params, 1052 tBLE_BD_ADDR *p_target, tBTM_BLE_PF_PARAM_CBACK *p_cmpl_cback, 1053 tBTM_BLE_REF_VALUE ref_value) 1054 { 1055 tBTM_STATUS st = BTM_WRONG_MODE; 1056 tBTM_BLE_PF_COUNT *p_bda_filter = NULL; 1057 UINT8 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN + 1058 BTM_BLE_ADV_FILT_TRACK_NUM; 1059 UINT8 param[len], *p; 1060 1061 if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) 1062 return st; 1063 1064 p = param; 1065 memset(param, 0, len); 1066 BTM_TRACE_EVENT (" BTM_BleAdvFilterParamSetup"); 1067 1068 if (BTM_BLE_SCAN_COND_ADD == action) 1069 { 1070 p_bda_filter = btm_ble_find_addr_filter_counter(p_target); 1071 if (NULL == p_bda_filter) 1072 { 1073 BTM_TRACE_ERROR("BD Address not found!"); 1074 return st; 1075 } 1076 1077 BTM_TRACE_DEBUG("BTM_BleAdvFilterParamSetup : Feat mask:%d", p_filt_params->feat_seln); 1078 /* select feature based on control block settings */ 1079 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); 1080 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); 1081 1082 /* Filter index */ 1083 UINT8_TO_STREAM(p, filt_index); 1084 1085 /* set PCF selection */ 1086 UINT16_TO_STREAM(p, p_filt_params->feat_seln); 1087 /* set logic type */ 1088 UINT16_TO_STREAM(p, p_filt_params->logic_type); 1089 /* set logic condition */ 1090 UINT8_TO_STREAM(p, p_filt_params->filt_logic_type); 1091 /* set RSSI high threshold */ 1092 UINT8_TO_STREAM(p, p_filt_params->rssi_high_thres); 1093 /* set delivery mode */ 1094 UINT8_TO_STREAM(p, p_filt_params->dely_mode); 1095 1096 if (0x01 == p_filt_params->dely_mode) 1097 { 1098 /* set onfound timeout */ 1099 UINT16_TO_STREAM(p, p_filt_params->found_timeout); 1100 /* set onfound timeout count*/ 1101 UINT8_TO_STREAM(p, p_filt_params->found_timeout_cnt); 1102 /* set RSSI low threshold */ 1103 UINT8_TO_STREAM(p, p_filt_params->rssi_low_thres); 1104 /* set onlost timeout */ 1105 UINT16_TO_STREAM(p, p_filt_params->lost_timeout); 1106 /* set num_of_track_entries for firmware greater than L-release version */ 1107 if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) 1108 UINT16_TO_STREAM(p, p_filt_params->num_of_tracking_entries); 1109 } 1110 1111 if (cmn_ble_vsc_cb.version_supported == BTM_VSC_CHIP_CAPABILITY_L_VERSION) 1112 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN; 1113 else 1114 len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_ADV_FILT_FEAT_SELN_LEN + 1115 BTM_BLE_ADV_FILT_TRACK_NUM; 1116 1117 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 1118 (UINT8)len, 1119 param, 1120 btm_ble_scan_pf_cmpl_cback)) 1121 == BTM_NO_RESOURCES) 1122 { 1123 return st; 1124 } 1125 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, 1126 ref_value, NULL, p_cmpl_cback); 1127 } 1128 else 1129 if (BTM_BLE_SCAN_COND_DELETE == action) 1130 { 1131 /* select feature based on control block settings */ 1132 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); 1133 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_DELETE); 1134 /* Filter index */ 1135 UINT8_TO_STREAM(p, filt_index); 1136 1137 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 1138 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH), 1139 param, 1140 btm_ble_scan_pf_cmpl_cback)) 1141 == BTM_NO_RESOURCES) 1142 { 1143 return st; 1144 } 1145 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, 1146 ref_value, NULL, p_cmpl_cback); 1147 } 1148 else 1149 if (BTM_BLE_SCAN_COND_CLEAR == action) 1150 { 1151 /* Deallocate all filters here */ 1152 btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL); 1153 1154 /* select feature based on control block settings */ 1155 UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); 1156 UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); 1157 1158 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 1159 (UINT8)(BTM_BLE_ADV_FILT_META_HDR_LENGTH-1), 1160 param, 1161 btm_ble_scan_pf_cmpl_cback)) 1162 == BTM_NO_RESOURCES) 1163 { 1164 return st; 1165 } 1166 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_ADV_PARAM, 1167 ref_value, NULL, p_cmpl_cback); 1168 } 1169 1170 return st; 1171 } 1172 1173 /******************************************************************************* 1174 ** 1175 ** Function BTM_BleEnableDisableFilterFeature 1176 ** 1177 ** Description This function is called to enable / disable the APCF feature 1178 ** 1179 ** Parameters enable the generic scan condition. 1180 ** enable: enable or disable the filter condition 1181 ** p_stat_cback - Status callback pointer 1182 ** ref_value - Ref value 1183 ** Returns void 1184 ** 1185 *******************************************************************************/ 1186 tBTM_STATUS BTM_BleEnableDisableFilterFeature(UINT8 enable, 1187 tBTM_BLE_PF_STATUS_CBACK *p_stat_cback, 1188 tBTM_BLE_REF_VALUE ref_value) 1189 { 1190 UINT8 param[20], *p; 1191 tBTM_STATUS st = BTM_WRONG_MODE; 1192 1193 if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) 1194 return st; 1195 1196 p = param; 1197 memset(param, 0, 20); 1198 1199 /* enable the content filter in controller */ 1200 p = param; 1201 UINT8_TO_STREAM(p, BTM_BLE_META_PF_ENABLE); 1202 /* enable adv data payload filtering */ 1203 UINT8_TO_STREAM(p, enable); 1204 1205 if ((st = BTM_VendorSpecificCommand (HCI_BLE_ADV_FILTER_OCF, 1206 BTM_BLE_PCF_ENABLE_LEN, param, 1207 btm_ble_scan_pf_cmpl_cback)) == BTM_CMD_STARTED) 1208 { 1209 btm_ble_adv_filt_cb.p_filt_stat_cback = p_stat_cback; 1210 btm_ble_advfilt_enq_op_q(enable, BTM_BLE_META_PF_ENABLE, BTM_BLE_FILT_ENABLE_DISABLE, 1211 ref_value, NULL, NULL); 1212 } 1213 return st; 1214 } 1215 1216 /******************************************************************************* 1217 ** 1218 ** Function BTM_BleCfgFilterCondition 1219 ** 1220 ** Description This function is called to configure the adv data payload filter 1221 ** condition. 1222 ** 1223 ** Parameters action: to read/write/clear 1224 ** cond_type: filter condition type. 1225 ** filt_index - Filter index 1226 ** p_cond: filter condition parameter 1227 ** p_cmpl_cback - Config callback pointer 1228 ** ref_value - Reference value 1229 ** 1230 ** Returns void 1231 ** 1232 *******************************************************************************/ 1233 tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, 1234 tBTM_BLE_PF_COND_TYPE cond_type, 1235 tBTM_BLE_PF_FILT_INDEX filt_index, 1236 tBTM_BLE_PF_COND_PARAM *p_cond, 1237 tBTM_BLE_PF_CFG_CBACK *p_cmpl_cback, 1238 tBTM_BLE_REF_VALUE ref_value) 1239 { 1240 tBTM_STATUS st = BTM_ILLEGAL_VALUE; 1241 UINT8 ocf = 0; 1242 BTM_TRACE_EVENT (" BTM_BleCfgFilterCondition action:%d, cond_type:%d, index:%d", action, 1243 cond_type, filt_index); 1244 1245 if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) 1246 return st; 1247 1248 switch (cond_type) 1249 { 1250 /* write service data filter */ 1251 case BTM_BLE_PF_SRVC_DATA_PATTERN: 1252 /* write manufacturer data filter */ 1253 case BTM_BLE_PF_MANU_DATA: 1254 st = btm_ble_update_pf_manu_data(action, filt_index, p_cond, cond_type, 0, ref_value); 1255 break; 1256 1257 /* write local name filter */ 1258 case BTM_BLE_PF_LOCAL_NAME: 1259 st = btm_ble_update_pf_local_name(action, filt_index, p_cond); 1260 break; 1261 1262 /* filter on advertiser address */ 1263 case BTM_BLE_PF_ADDR_FILTER: 1264 st = btm_ble_update_addr_filter(action, filt_index, p_cond); 1265 break; 1266 1267 /* filter on service/solicitated UUID */ 1268 case BTM_BLE_PF_SRVC_UUID: 1269 case BTM_BLE_PF_SRVC_SOL_UUID: 1270 st = btm_ble_update_uuid_filter(action, filt_index, cond_type, p_cond, 0, ref_value); 1271 break; 1272 1273 case BTM_BLE_PF_SRVC_DATA: 1274 st = btm_ble_update_srvc_data_change(action, filt_index, p_cond); 1275 break; 1276 1277 case BTM_BLE_PF_TYPE_ALL: /* only used to clear filter */ 1278 st = btm_ble_clear_scan_pf_filter(action, filt_index, p_cond, p_cmpl_cback, 1279 0, ref_value); 1280 break; 1281 1282 default: 1283 BTM_TRACE_WARNING("condition type [%d] not supported currently.", cond_type); 1284 break; 1285 } 1286 1287 if(BTM_CMD_STARTED == st && cond_type != BTM_BLE_PF_TYPE_ALL) 1288 { 1289 ocf = btm_ble_condtype_to_ocf(cond_type); 1290 btm_ble_advfilt_enq_op_q(action, ocf, BTM_BLE_FILT_CFG, ref_value, p_cmpl_cback, NULL); 1291 } 1292 else 1293 if(BTM_CMD_STARTED == st && BTM_BLE_PF_TYPE_ALL == cond_type) 1294 { 1295 btm_ble_advfilt_enq_op_q(action, BTM_BLE_META_PF_FEAT_SEL, BTM_BLE_FILT_CFG, 1296 ref_value, p_cmpl_cback, NULL); 1297 } 1298 return st; 1299 } 1300 1301 /******************************************************************************* 1302 ** 1303 ** Function btm_ble_adv_filter_init 1304 ** 1305 ** Description This function initializes the adv filter control block 1306 ** 1307 ** Parameters 1308 ** 1309 ** Returns status 1310 ** 1311 *******************************************************************************/ 1312 void btm_ble_adv_filter_init(void) 1313 { 1314 memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB)); 1315 if (BTM_SUCCESS != btm_ble_obtain_vsc_details()) 1316 return; 1317 1318 if (cmn_ble_vsc_cb.max_filter > 0) 1319 { 1320 btm_ble_adv_filt_cb.p_addr_filter_count = 1321 (tBTM_BLE_PF_COUNT*)osi_malloc(sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter); 1322 } 1323 } 1324 1325 /******************************************************************************* 1326 ** 1327 ** Function btm_ble_adv_filter_cleanup 1328 ** 1329 ** Description This function de-initializes the adv filter control block 1330 ** 1331 ** Parameters 1332 ** 1333 ** Returns status 1334 ** 1335 *******************************************************************************/ 1336 void btm_ble_adv_filter_cleanup(void) 1337 { 1338 osi_free_and_reset((void **)&btm_ble_adv_filt_cb.p_addr_filter_count); 1339 } 1340 1341 #endif 1342