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 #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