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