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