Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2008-2012 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 /******************************************************************************
     20  *
     21  *  This file contains functions for BLE GAP.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <string.h>
     26 #include <stdio.h>
     27 #include <stddef.h>
     28 
     29 #include "bt_types.h"
     30 #include "btu.h"
     31 #include "btm_int.h"
     32 #include "hcimsgs.h"
     33 #if (GAP_INCLUDED == TRUE)
     34 #include "gap_api.h"
     35 #endif
     36 
     37 #if (BLE_INCLUDED == TRUE)
     38 #define BTM_BLE_NAME_SHORT                  0x01
     39 #define BTM_BLE_NAME_CMPL                   0x02
     40 
     41 #define BTM_BLE_FILTER_TARGET_UNKNOWN       0xff
     42 #define BTM_BLE_POLICY_UNKNOWN              0xff
     43 
     44 #define BLE_RESOLVE_ADDR_MSB                 0x40   /*  most significant bit, bit7, bit6 is 01 to be resolvable random */
     45 #define BLE_RESOLVE_ADDR_MASK                0xc0   /* bit 6, and bit7 */
     46 #define BTM_BLE_IS_RESOLVE_BDA(x)           ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
     47 
     48 #define BTM_EXT_BLE_RMT_NAME_TIMEOUT        30
     49 static tBLE_BD_ADDR le_bda_any ={BLE_ADDR_PUBLIC, {0x00,0x00,0x00,0x00,0x00,0x00}};
     50 
     51 
     52 #define BTM_BLE_VALID_CONN_DIRECT(x) (memcmp(&le_bda_any, x, sizeof(tBLE_BD_ADDR)) != 0)
     53 
     54 /*******************************************************************************
     55 **  Local functions
     56 *******************************************************************************/
     57 static void btm_ble_update_adv_flag(UINT8 flag);
     58 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p);
     59 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data);
     60 
     61 
     62 
     63 
     64 
     65 
     66 
     67 
     68 /*******************************************************************************
     69 **
     70 ** Function         BTM_BleReset
     71 **
     72 ** Description      This function is called to reset ULP controller.
     73 **
     74 ** Parameters       None.
     75 **
     76 ** Returns          void
     77 **
     78 *******************************************************************************/
     79 void BTM_BleReset(void)
     80 {
     81     btsnd_hcic_ble_reset();
     82 }
     83 
     84 /*******************************************************************************
     85 **
     86 ** Function         BTM_BleObserve
     87 **
     88 ** Description      This procedure keep the device listening for advertising
     89 **                  events from a broadcast device.
     90 **
     91 ** Parameters       start: start or stop observe.
     92 **                  white_list: use white list in observer mode or not.
     93 **
     94 ** Returns          void
     95 **
     96 *******************************************************************************/
     97 tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration,
     98                            tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
     99 {
    100     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
    101     tBTM_STATUS     status = BTM_NO_RESOURCES;
    102 
    103     BTM_TRACE_EVENT0 ("BTM_BleObserve ");
    104 
    105     if (start)
    106     {
    107         if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
    108             return BTM_BUSY;
    109 
    110         btm_cb.btm_inq_vars.p_inq_results_cb = p_results_cb;
    111         btm_cb.btm_inq_vars.p_inq_cmpl_cb = p_cmpl_cb;
    112 
    113         /* allow config scanning type */
    114         if (btsnd_hcic_ble_set_scan_params ((UINT8)((p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type),
    115                                             (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
    116                                             (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
    117                                             BLE_ADDR_PUBLIC,
    118                                             BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */
    119         {
    120             /* start scan, disable duplicate filtering */
    121             if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
    122             {
    123                 status = BTM_SUCCESS;
    124                 p_inq->proc_mode = BTM_BLE_OBSERVE;
    125                 btm_cb.btm_inq_vars.inq_active = TRUE;
    126 
    127                 if (duration != 0)
    128                 {
    129                     /* start inquiry timer */
    130                     btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
    131                 }
    132             }
    133         }
    134     }
    135     else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
    136     {
    137         btm_ble_stop_scan();
    138     }
    139 
    140     return status;
    141 }
    142 
    143 /*******************************************************************************
    144 **
    145 ** Function         BTM_BleBroadcast
    146 **
    147 ** Description      This function is to start or stop broadcasting.
    148 **
    149 ** Parameters       start: start or stop broadcasting.
    150 **
    151 ** Returns          status.
    152 **
    153 *******************************************************************************/
    154 tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
    155 {
    156     tBTM_STATUS status = BTM_NO_RESOURCES;
    157     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    158     UINT8 evt_type = p_cb->scan_rsp ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
    159 
    160 #ifdef  BTM_BLE_PC_ADV_TEST_MODE
    161     if (BTM_BLE_PC_ADV_TEST_MODE)
    162     {
    163         evt_type = p_cb->scan_rsp ? BTM_BLE_CONNECT_EVT: BTM_BLE_NON_CONNECT_EVT;
    164     }
    165 #endif
    166 
    167     if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE)
    168     {
    169         /* update adv params */
    170         if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
    171                                               (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
    172                                               evt_type,
    173                                               p_cb->own_addr_type,
    174                                               p_cb->direct_bda.type, p_cb->direct_bda.bda,
    175                                               p_cb->adv_chnl_map,
    176                                               p_cb->afp))
    177 
    178             status = BTM_NO_RESOURCES;
    179         else
    180             p_cb->evt_type = evt_type;
    181 
    182         if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE))
    183         {
    184             p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
    185 
    186             status = BTM_SUCCESS;
    187         }
    188     }
    189     else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
    190     {
    191         if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
    192         {
    193             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
    194 
    195             status = BTM_SUCCESS;
    196         }
    197     }
    198     else
    199     {
    200         status = BTM_WRONG_MODE;
    201         BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode",
    202             (start ? "Start" : "Stop"), (start ? "alerady" :"not"));
    203     }
    204 
    205     return status;
    206 }
    207 
    208 
    209 
    210 
    211 
    212 
    213 
    214 /*******************************************************************************
    215 **
    216 ** Function         BTM_RegisterScanReqEvt
    217 **
    218 ** Description      This function is called to register a scan request callback
    219 **                  on the advertiser.
    220 **
    221 ** Parameters       p_scan_req_cback: scan request callback.  If NULL, remove the
    222 **                                    registration.
    223 **
    224 ** Returns          void
    225 **
    226 *******************************************************************************/
    227 void BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK   *p_scan_req_cback)
    228 {
    229 #ifdef BTM_BLE_PC_ADV_TEST_MODE // For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include
    230     if (BTM_BLE_PC_ADV_TEST_MODE)   // For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode
    231     {
    232         tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
    233         p_cb->p_scan_req_cback = p_scan_req_cback;
    234     }
    235 #endif
    236 }
    237 /*******************************************************************************
    238 **
    239 ** Function         BTM_BleConfigPrivacy
    240 **
    241 ** Description      This function is called to enable or disable the privacy in
    242 **                  the local device.
    243 **
    244 ** Parameters       enable: TRUE to enable it; FALSE to disable it.
    245 **
    246 ** Returns          void
    247 **
    248 *******************************************************************************/
    249 void BTM_BleConfigPrivacy(BOOLEAN enable)
    250 {
    251     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
    252     BTM_TRACE_EVENT0 (" BTM_BleConfigPrivacy");
    253     p_cb->privacy = enable;
    254 }
    255 
    256 /*******************************************************************************
    257 **
    258 ** Function         BTM_BleSetBgConnType
    259 **
    260 ** Description      This function is called to set BLE connectable mode for a
    261 **                  peripheral device.
    262 **
    263 ** Parameters       bg_conn_type: it can be auto connection, or selective connection.
    264 **                  p_select_cback: callback function when selective connection procedure
    265 **                              is being used.
    266 **
    267 ** Returns          void
    268 **
    269 *******************************************************************************/
    270 BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE   bg_conn_type,
    271                              tBTM_BLE_SEL_CBACK   *p_select_cback)
    272 {
    273     BOOLEAN started = TRUE;
    274 
    275     BTM_TRACE_EVENT0 ("BTM_BleSetBgConnType ");
    276 
    277     if (btm_cb.ble_ctr_cb.bg_conn_type != bg_conn_type)
    278     {
    279         switch (bg_conn_type)
    280         {
    281             case BTM_BLE_CONN_AUTO:
    282                 btm_ble_start_auto_conn(TRUE);
    283                 break;
    284 
    285             case BTM_BLE_CONN_SELECTIVE:
    286                 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
    287                 {
    288                     btm_ble_start_auto_conn(FALSE);
    289                 }
    290                 started = btm_ble_start_select_conn(TRUE, p_select_cback);
    291                 break;
    292 
    293             case BTM_BLE_CONN_NONE:
    294                 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
    295                 {
    296                     btm_ble_start_auto_conn(FALSE);
    297                 }
    298                 else if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
    299                 {
    300                     btm_ble_start_select_conn(FALSE, NULL);
    301                 }
    302                 started = TRUE;
    303                 break;
    304 
    305             default:
    306                 BTM_TRACE_ERROR1("invalid bg connection type : %d ", bg_conn_type);
    307                 started = FALSE;
    308                 break;
    309         }
    310 
    311         if (started)
    312             btm_cb.ble_ctr_cb.bg_conn_type = bg_conn_type;
    313     }
    314     return started;
    315 }
    316 
    317 /*******************************************************************************
    318 **
    319 ** Function         BTM_BleUpdateBgConnDev
    320 **
    321 ** Description      This function is called to add or remove a device into/from
    322 **                  background connection procedure. The background connection
    323 *                   procedure is decided by the background connection type, it can be
    324 *                   auto connection, or selective connection.
    325 **
    326 ** Parameters       add_remove: TRUE to add; FALSE to remove.
    327 **                  remote_bda: device address to add/remove.
    328 **
    329 ** Returns          void
    330 **
    331 *******************************************************************************/
    332 BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR   remote_bda)
    333 {
    334     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
    335     tBTM_BLE_SEL_CBACK   *p_select_cback;
    336     BOOLEAN ret = TRUE;
    337 
    338     BTM_TRACE_EVENT0 (" BTM_BleUpdateBgConnDev");
    339 
    340     /* if auto connection is active */
    341     if (p_cb->bg_conn_state == BLE_BG_CONN_ACTIVE)
    342     {
    343         if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)
    344         {
    345             /* terminate auto connection first */
    346             ret = btm_ble_start_auto_conn(FALSE);
    347         }
    348         else if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE)
    349         {
    350             p_select_cback = btm_cb.ble_ctr_cb.p_select_cback;
    351             ret = btm_ble_start_select_conn(FALSE, NULL);
    352         }
    353     }
    354     if (ret)
    355     {
    356         /* update white list */
    357         ret = btm_update_bg_conn_list(add_remove, remote_bda);
    358         btm_update_dev_to_white_list(add_remove, remote_bda, BLE_ADDR_PUBLIC);
    359     }
    360 
    361     if (ret && p_cb->bg_conn_state == BLE_BG_CONN_IDLE)
    362     {
    363         if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)
    364         {
    365             /* restart auto connection */
    366             btm_ble_start_auto_conn(TRUE);
    367         }
    368         else if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE)
    369         {
    370             p_select_cback = btm_cb.ble_ctr_cb.p_select_cback;
    371             btm_ble_start_select_conn(TRUE, p_select_cback);
    372         }
    373     }
    374     return ret;
    375 }
    376 
    377 /*******************************************************************************
    378 **
    379 ** Function         BTM_BleSetConnMode
    380 **
    381 ** Description      This function is called to set BLE connectable mode for a
    382 **                  peripheral device.
    383 **
    384 ** Parameters       directed: is directed connectable mode, or non-directed.
    385 **                  p_dir_bda: connectable direct initiator's LE device address
    386 **
    387 ** Returns          void
    388 **
    389 *******************************************************************************/
    390 tBTM_STATUS BTM_BleSetConnMode(BOOLEAN directed, tBLE_BD_ADDR *p_dir_bda)
    391 {
    392     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    393     tBTM_STATUS status = BTM_SUCCESS;
    394     BD_ADDR     reconn_bda;
    395 
    396     BTM_TRACE_EVENT0 ("BTM_BleSetConnMode ");
    397 
    398     memcpy(&p_cb->direct_bda, &le_bda_any, sizeof(tBLE_BD_ADDR));
    399     p_cb->own_addr_type = BLE_ADDR_PUBLIC;
    400 
    401     if (directed)
    402     {
    403         if (p_dir_bda)
    404         {
    405             memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
    406 
    407             if (btm_cb.ble_ctr_cb.privacy /* && GAP privacy ad reconnect addr exist */)
    408             {
    409                 /* write reconnect address to controller*/
    410                 btsnd_hcic_ble_set_random_addr(reconn_bda);
    411             }
    412             /* else use static address or publich address */
    413 
    414         }
    415         else
    416             status = BTM_ILLEGAL_VALUE;
    417     }
    418     else /* undirected connecatable */
    419     {
    420         if (btm_cb.ble_ctr_cb.privacy /* GAP privacy flag enabled */)
    421         {
    422             /* generate resolvable private address */
    423             btm_gen_resolvable_private_addr();
    424         } /* else use publich address */
    425 
    426     }
    427     return status;
    428 }
    429 
    430 /*******************************************************************************
    431 **
    432 ** Function         BTM_BleSetAdvParams
    433 **
    434 ** Description      This function is called to set advertising parameters.
    435 **
    436 ** Parameters       adv_int_min: minimum advertising interval
    437 **                  adv_int_max: maximum advertising interval
    438 **                  p_dir_bda: connectable direct initiator's LE device address
    439 **                  chnl_map: advertising channel map.
    440 **
    441 ** Returns          void
    442 **
    443 *******************************************************************************/
    444 tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max,
    445                                 tBLE_BD_ADDR *p_dir_bda,
    446                                 tBTM_BLE_ADV_CHNL_MAP chnl_map)
    447 {
    448     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    449     tBTM_STATUS status = BTM_SUCCESS;
    450 
    451     BTM_TRACE_EVENT0 ("BTM_BleSetAdvParams");
    452 
    453     if (!BTM_BLE_VALID_PRAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
    454         !BTM_BLE_VALID_PRAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX))
    455     {
    456         return BTM_ILLEGAL_VALUE;
    457     }
    458 
    459     p_cb->adv_interval_min = adv_int_min;
    460     p_cb->adv_interval_max = adv_int_max;
    461     p_cb->adv_chnl_map = chnl_map;
    462 
    463     if (p_dir_bda)
    464     {
    465         memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
    466     }
    467     else
    468         memcpy(&p_cb->direct_bda, &le_bda_any, sizeof(tBLE_BD_ADDR));
    469 
    470     if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
    471     {
    472         BTM_TRACE_EVENT0 ("update params for an active adv");
    473 
    474         if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE)
    475         {
    476             if (BTM_BLE_VALID_CONN_DIRECT(&p_cb->direct_bda))
    477                 p_cb->evt_type = BTM_BLE_CONNECT_DIR_EVT;
    478             else
    479                 p_cb->evt_type = BTM_BLE_CONNECT_EVT;
    480 
    481             BTM_TRACE_DEBUG1(" evt_type = %d", p_cb->evt_type);
    482         }
    483 
    484         if (!btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
    485             status = BTM_NO_RESOURCES;
    486         else
    487         /* update adv params */
    488         if (!btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
    489                                               p_cb->adv_interval_max,
    490                                               p_cb->evt_type,
    491                                               p_cb->own_addr_type,
    492                                               p_cb->direct_bda.type,
    493                                               p_cb->direct_bda.bda,
    494                                               p_cb->adv_chnl_map,
    495                                               p_cb->afp))
    496 
    497             status = BTM_NO_RESOURCES;
    498 
    499         else if (!btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE))
    500         {
    501             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
    502 
    503             status = BTM_NO_RESOURCES;
    504         }
    505 
    506     }
    507 
    508     return status;
    509 }
    510 
    511 /*******************************************************************************
    512 **
    513 ** Function         BTM_BleReadAdvParams
    514 **
    515 ** Description      This function is called to set advertising parameters.
    516 **
    517 ** Parameters       adv_int_min: minimum advertising interval
    518 **                  adv_int_max: maximum advertising interval
    519 **                  p_dir_bda: connectable direct initiator's LE device address
    520 **                  chnl_map: advertising channel map.
    521 **
    522 ** Returns          void
    523 **
    524 *******************************************************************************/
    525 void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max,
    526                            tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map)
    527 {
    528     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    529 
    530     BTM_TRACE_EVENT0 ("BTM_BleReadAdvParams ");
    531 
    532     *adv_int_min = p_cb->adv_interval_min;
    533     *adv_int_max = p_cb->adv_interval_max;
    534     *p_chnl_map = p_cb->adv_chnl_map;
    535 
    536     if (p_dir_bda != NULL)
    537     {
    538         memcpy(p_dir_bda, &p_cb->direct_bda, sizeof(tBLE_BD_ADDR));
    539     }
    540 }
    541 
    542 
    543 /*******************************************************************************
    544 **
    545 ** Function         BTM_BleSetScanParams
    546 **
    547 ** Description      This function is called to set Scan parameters.
    548 **
    549 ** Parameters       adv_int_min: minimum advertising interval
    550 **                  adv_int_max: maximum advertising interval
    551 **                  p_dir_bda: connectable direct initiator's LE device address
    552 **                  chnl_map: advertising channel map.
    553 **                  scan_type: active scan or passive scan
    554 **
    555 ** Returns          void
    556 **
    557 *******************************************************************************/
    558 void BTM_BleSetScanParams(UINT16 scan_interval, UINT16 scan_window, tBTM_BLE_SCAN_MODE scan_mode)
    559 {
    560     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    561 
    562     BTM_TRACE_EVENT0 (" BTM_BleSetScanParams");
    563 
    564     if (BTM_BLE_VALID_PRAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
    565         BTM_BLE_VALID_PRAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) &&
    566         (scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS))
    567     {
    568         p_cb->scan_type     = scan_mode;
    569 
    570         if (BTM_BLE_CONN_PARAM_UNDEF != scan_interval)
    571             p_cb->scan_interval = scan_interval;
    572 
    573         if (BTM_BLE_CONN_PARAM_UNDEF != scan_window)
    574             p_cb->scan_window   = scan_window;
    575     }
    576     else
    577     {
    578         BTM_TRACE_ERROR2("Illegal params: scan_interval = %d scan_window = %d",
    579                         scan_interval, scan_window);
    580     }
    581 
    582 }
    583 
    584 /*******************************************************************************
    585 **
    586 ** Function         BTM_BleWriteScanRsp
    587 **
    588 ** Description      This function is called to write LE scan response.
    589 **
    590 ** Parameters:      p_scan_rsp: scan response information.
    591 **
    592 ** Returns          void
    593 **
    594 *******************************************************************************/
    595 tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data)
    596 {
    597     tBTM_STATUS     status = BTM_NO_RESOURCES;
    598     UINT8   rsp_data[BTM_BLE_AD_DATA_LEN],
    599             *p = rsp_data;
    600 
    601     BTM_TRACE_EVENT0 (" BTM_BleWriteScanRsp");
    602     memset(rsp_data, 0, BTM_BLE_AD_DATA_LEN);
    603     btm_ble_build_adv_data(&data_mask, &p, p_data);
    604 
    605     if (btsnd_hcic_ble_set_scan_rsp_data((UINT8)(p - rsp_data), rsp_data))
    606     {
    607         status = BTM_SUCCESS;
    608 
    609         if (p_data != NULL)
    610             btm_cb.ble_ctr_cb.inq_var.scan_rsp = TRUE;
    611         else
    612             btm_cb.ble_ctr_cb.inq_var.scan_rsp = FALSE;
    613     }
    614     else
    615         status = BTM_ILLEGAL_VALUE;
    616 
    617     return status;
    618 }
    619 
    620 /*******************************************************************************
    621 **
    622 ** Function         BTM_BleWriteAdvData
    623 **
    624 ** Description      This function is called to write advertising data.
    625 **
    626 ** Parameters:       None.
    627 **
    628 ** Returns          void
    629 **
    630 *******************************************************************************/
    631 tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data)
    632 {
    633     tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
    634     UINT8  *p;
    635     UINT16   mask = data_mask;
    636 
    637     memset(p_cb_data, 0, sizeof(tBTM_BLE_LOCAL_ADV_DATA));
    638     p = p_cb_data->ad_data;
    639     p_cb_data->data_mask = data_mask;
    640 
    641     BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData ");
    642     p_cb_data->p_flags = btm_ble_build_adv_data(&mask, &p, p_data);
    643 
    644     p_cb_data->p_pad = p;
    645 
    646     if (data_mask != 0)
    647     {
    648         BTM_TRACE_ERROR0("Partial data write into ADV");
    649     }
    650 
    651     p_cb_data->data_mask &= ~mask;
    652 
    653     if (btsnd_hcic_ble_set_adv_data((UINT8)(p_cb_data->p_pad - p_cb_data->ad_data),
    654                                     p_cb_data->ad_data))
    655         return BTM_SUCCESS;
    656     else
    657         return BTM_NO_RESOURCES;
    658 
    659 }
    660 
    661 /*******************************************************************************
    662 **
    663 ** Function         BTM_CheckAdvData
    664 **
    665 ** Description      This function is called to get ADV data for a specific type.
    666 **
    667 ** Parameters       p_adv - pointer of ADV data
    668 **                  type   - finding ADV data type
    669 **                  p_length - return the length of ADV data not including type
    670 **
    671 ** Returns          pointer of ADV data
    672 **
    673 *******************************************************************************/
    674 UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length)
    675 {
    676     UINT8 *p = p_adv;
    677     UINT8 length;
    678     UINT8 adv_type;
    679     BTM_TRACE_API1("BTM_CheckAdvData type=0x%02X", type);
    680 
    681     STREAM_TO_UINT8(length, p);
    682 
    683     while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX))
    684     {
    685         STREAM_TO_UINT8(adv_type, p);
    686 
    687         if ( adv_type == type )
    688         {
    689             /* length doesn't include itself */
    690             *p_length = length - 1; /* minus the length of type */
    691             return p;
    692         }
    693         p += length - 1; /* skip the length of data */
    694         STREAM_TO_UINT8(length, p);
    695     }
    696 
    697     *p_length = 0;
    698     return NULL;
    699 }
    700 
    701 /*******************************************************************************
    702 **
    703 ** Function         btm_ble_build_adv_data
    704 **
    705 ** Description      This function is called build the adv data and rsp data.
    706 *******************************************************************************/
    707 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data)
    708 {
    709     UINT16 data_mask = *p_data_mask;
    710     UINT8   *p = *p_dst,
    711     *p_flag = NULL;
    712     UINT16  len = BTM_BLE_AD_DATA_LEN, cp_len = 0;
    713     UINT8   i = 0;
    714     tBTM_BLE_ATTR           *p_attr;
    715     tBTM_BLE_PROP_ELEM      *p_elem;
    716 
    717     BTM_TRACE_EVENT0 (" btm_ble_build_adv_data");
    718 
    719     /* build the adv data structure and build the data string */
    720     if (data_mask)
    721     {
    722         /* flags */
    723         if (data_mask & BTM_BLE_AD_BIT_FLAGS)
    724         {
    725             *p++ = 2;
    726             *p++ = BTM_BLE_AD_TYPE_FLAG;
    727             p_flag = p;
    728             if (p_data)
    729                 *p++ = p_data->flag;
    730             else
    731                 *p++ = 0;
    732 
    733             len -= 3;
    734 
    735             data_mask &= ~BTM_BLE_AD_BIT_FLAGS;
    736         }
    737         /* device name */
    738         if (len > 2 && data_mask & BTM_BLE_AD_BIT_DEV_NAME)
    739         {
    740             if (strlen(btm_cb.cfg.bd_name) > (UINT16)(len - 2))
    741             {
    742                 *p++ = len - 2 + 1;
    743                 *p++ = BTM_BLE_AD_TYPE_NAME_SHORT;
    744                 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, len - 2);
    745             }
    746             else
    747             {
    748                 cp_len = (UINT16)strlen(btm_cb.cfg.bd_name);
    749                 *p++ = cp_len + 1;
    750                 *p++ = BTM_BLE_AD_TYPE_NAME_CMPL;
    751                 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, cp_len);
    752             }
    753 
    754             len -= (cp_len + 2);
    755             data_mask &= ~BTM_BLE_AD_BIT_DEV_NAME;
    756         }
    757         /* manufacturer data */
    758         if (len > 2 && data_mask & BTM_BLE_AD_BIT_MANU &&
    759             p_data && p_data->manu.len != 0 && p_data->manu.p_val)
    760         {
    761             if (p_data->manu.len > (len - 2))
    762                 cp_len = len - 2;
    763             else
    764                 cp_len = p_data->manu.len;
    765 
    766             *p++ = cp_len + 1;
    767             *p++ = BTM_BLE_AD_TYPE_MANU;
    768             ARRAY_TO_STREAM(p, p_data->manu.p_val, cp_len);
    769 
    770             len -= (cp_len + 2);
    771             data_mask &= ~BTM_BLE_AD_BIT_MANU;
    772         }
    773         /* TX power */
    774         if (len > 2 && data_mask & BTM_BLE_AD_BIT_TX_PWR)
    775         {
    776             *p++ = 2;
    777             *p++ = BTM_BLE_AD_TYPE_TX_PWR;
    778             *p++ = btm_cb.ble_ctr_cb.inq_var.tx_power;
    779             len -= 3;
    780 
    781             data_mask &= ~BTM_BLE_AD_BIT_TX_PWR;
    782         }
    783         /* services */
    784         if (len > 2 && data_mask & BTM_BLE_AD_BIT_SERVICE &&
    785             p_data && p_data->services.num_service != 0 &&
    786             p_data->services.p_uuid)
    787         {
    788             if (p_data->services.num_service * 2 > (len - 2))
    789             {
    790                 cp_len = (len - 2)/2;
    791                 *p ++ = 1 + cp_len * 2;
    792                 *p++ = BTM_BLE_AD_TYPE_SRV_PART;
    793             }
    794             else
    795             {
    796                 cp_len = p_data->services.num_service;
    797                 *p++ = 1 + cp_len * 2;
    798                 *p++ = BTM_BLE_AD_TYPE_SRV_CMPL;
    799             }
    800             for (i = 0; i < cp_len; i ++)
    801             {
    802                 UINT16_TO_STREAM(p, *(p_data->services.p_uuid + i));
    803             }
    804 
    805             len -= (cp_len * 2 + 2);
    806             data_mask &= ~BTM_BLE_AD_BIT_SERVICE;
    807         }
    808         if (len >= 6 && data_mask & BTM_BLE_AD_BIT_INT_RANGE &&
    809             p_data)
    810         {
    811             *p++ = 5;
    812             *p++ = BTM_BLE_AD_TYPE_INT_RANGE;
    813             UINT16_TO_STREAM(p, p_data->int_range.low);
    814             UINT16_TO_STREAM(p, p_data->int_range.hi);
    815             len -= 6;
    816             data_mask &= ~BTM_BLE_AD_BIT_INT_RANGE;
    817         }
    818         if (data_mask & BTM_BLE_AD_BIT_ATTR && p_data && p_data->attr.num_attr != 0)
    819         {
    820             for (i = 0; i < p_data->attr.num_attr ; i ++)
    821             {
    822                 p_attr = p_data->attr.attr_list + i;
    823 
    824                 if (len >= (2 + 2 + p_attr->data_len))/* len byte(1) + ATTR type(1) + Uuid len(2) + value length */
    825                 {
    826                     *p ++ = p_attr->data_len + 2 + 1; /* Uuid len + value length */
    827                     *p ++ = BTM_BLE_AD_TYPE_ATTR;
    828                     UINT16_TO_STREAM(p, p_attr->uuid);
    829                     ARRAY_TO_STREAM(p, p_attr->p_data, p_attr->data_len);
    830 
    831                     len -= (4 + p_attr->data_len);
    832                 }
    833                 else
    834                     break;
    835             }
    836             if (i == p_data->attr.num_attr)
    837                 data_mask &= ~BTM_BLE_AD_BIT_ATTR;
    838         }
    839         if (data_mask & BTM_BLE_AD_BIT_PROPRIETARY && p_data && p_data->p_proprietary)
    840         {
    841             for (i = 0; i < p_data->p_proprietary->num_elem ; i ++)
    842             {
    843                 p_elem = p_data->p_proprietary->p_elem  + i;
    844 
    845                 if (len >= (2 + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2) + value length */
    846                 {
    847                     *p ++ = p_elem->len + 1; /* Uuid len + value length */
    848                     *p ++ = p_elem->adv_type;
    849                     ARRAY_TO_STREAM(p, p_elem->p_val, p_elem->len);
    850 
    851                     len -= (2 + p_elem->len);
    852                 }
    853                 else
    854                 {
    855                     BTM_TRACE_WARNING0("data exceed max adv packet length");
    856                     break;
    857                 }
    858             }
    859             data_mask &= ~BTM_BLE_AD_BIT_PROPRIETARY;
    860         }
    861     }
    862 
    863     *p_data_mask = data_mask;
    864     *p_dst = p;
    865 
    866     return p_flag;
    867 }
    868 
    869 /*******************************************************************************
    870 **
    871 ** Function         btm_ble_set_discoverability
    872 **
    873 ** Description      This function is called to set BLE discoverable mode.
    874 **
    875 ** Parameters:      mode: discoverability mode.
    876 **
    877 ** Returns          void
    878 **
    879 *******************************************************************************/
    880 tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
    881 {
    882     tBTM_BLE_INQ_CB     *p_cb = &btm_cb.ble_ctr_cb.inq_var;
    883     UINT16              mode = (combined_mode &  BTM_BLE_DISCOVERABLE_MASK);
    884     UINT8               flag = 0;
    885     UINT8               new_mode = BTM_BLE_ADV_ENABLE;
    886     UINT8               evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \
    887                                    ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\
    888                                    : BTM_BLE_CONNECT_EVT;
    889     tBTM_STATUS         status = BTM_SUCCESS;
    890 
    891     BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
    892 
    893     /*** Check mode parameter ***/
    894     if (mode > BTM_BLE_MAX_DISCOVERABLE)
    895         return(BTM_ILLEGAL_VALUE);
    896 
    897     p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK);
    898     p_cb->discoverable_mode = mode;
    899 
    900     if (!p_cb->br_edr_supported_flag)
    901     {
    902         flag = BTM_BLE_BREDR_NOT_SPT;
    903         BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag);
    904     }
    905 
    906     BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag);
    907 
    908     if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE)
    909     {
    910         BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE ");
    911         /* write ADV data with limited disc flag */
    912         if (mode == BTM_BLE_LIMITED_DISCOVERABLE)
    913             flag |= BTM_BLE_LIMIT_DISC_FLAG ;
    914         else
    915             flag |= BTM_BLE_GEN_DISC_FLAG;
    916     }
    917     else  /* non-discoverable */
    918     {
    919         BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE ");
    920 
    921         if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE)
    922         {
    923             p_cb->br_edr_supported_flag = 0;
    924 
    925             BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp ");
    926             if (!p_cb->scan_rsp )
    927 	            new_mode = BTM_BLE_ADV_DISABLE;
    928         }
    929         else
    930         {
    931             if (BTM_BLE_VALID_CONN_DIRECT(&p_cb->direct_bda))
    932             {
    933                 BTM_TRACE_DEBUG0("evt_type = BTM_BLE_CONNECT_DIR_EVT");
    934                 evt_type = BTM_BLE_CONNECT_DIR_EVT;
    935             }
    936             else
    937             {
    938                 BTM_TRACE_DEBUG0(" evt_type = BTM_BLE_CONNECT_EVT");
    939                 evt_type = BTM_BLE_CONNECT_EVT;
    940             }
    941         }
    942     }
    943     btm_ble_update_adv_flag(flag);
    944 
    945     /* update adv params if start advertising */
    946     BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type);
    947     if (new_mode == BTM_BLE_ADV_ENABLE && evt_type != p_cb->evt_type)
    948     {
    949         if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
    950         {
    951             BTM_TRACE_EVENT0 ("Set Adv disable");
    952             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
    953             btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE);
    954         }
    955 
    956         /* update adv params */
    957         if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
    958                                               (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
    959                                               evt_type,
    960                                               p_cb->own_addr_type,
    961                                               p_cb->direct_bda.type, p_cb->direct_bda.bda,
    962                                               p_cb->adv_chnl_map,
    963                                               p_cb->afp))
    964 
    965             status = BTM_NO_RESOURCES;
    966         else
    967             p_cb->evt_type = evt_type;
    968 
    969     }
    970     if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode)
    971     {
    972         /* update advertising mode */
    973         if (!btsnd_hcic_ble_set_adv_enable (new_mode))
    974             status = BTM_NO_RESOURCES;
    975         else
    976             p_cb->adv_mode = new_mode;
    977     }
    978 
    979     /* set up stop advertising timer */
    980     if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE)
    981     {
    982         BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT);
    983         /* start Tgap(lim_timeout) */
    984         btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC,
    985                          BTM_BLE_GAP_LIM_TOUT);
    986     }
    987     return status;
    988 }
    989 
    990 /*******************************************************************************
    991 **
    992 ** Function         btm_ble_set_connectability
    993 **
    994 ** Description      This function is called to set BLE connectability mode.
    995 **
    996 ** Parameters:      mode: connectability mode.
    997 **
    998 ** Returns          void
    999 **
   1000 *******************************************************************************/
   1001 tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
   1002 {
   1003     tBTM_BLE_INQ_CB         *p_cb = &btm_cb.ble_ctr_cb.inq_var;
   1004     UINT16                  mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK);
   1005     UINT8                   cur_flag = 0;
   1006     UINT8                   cur_br_edr_not_sup_flag;
   1007     UINT8                   new_flag;
   1008     UINT8                   new_mode = BTM_BLE_ADV_ENABLE;
   1009     UINT8                   evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
   1010     tBTM_STATUS             status = BTM_SUCCESS;
   1011 
   1012     BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
   1013 
   1014     /*** Check mode parameter ***/
   1015     if (mode > BTM_BLE_MAX_CONNECTABLE)
   1016         return(BTM_ILLEGAL_VALUE);
   1017     if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags)
   1018         cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ;
   1019     cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT));
   1020 
   1021     p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4);
   1022     if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag)
   1023     {
   1024         new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT));
   1025         BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag,  cur_flag);
   1026         btm_ble_update_adv_flag(new_flag);
   1027     }
   1028     p_cb->connectable_mode = mode;
   1029 
   1030     if (mode == BTM_BLE_NON_CONNECTABLE)
   1031     {
   1032         if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
   1033         {
   1034             p_cb->br_edr_supported_flag = 0;
   1035             BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp");
   1036             if(!p_cb->scan_rsp)
   1037 	            new_mode = BTM_BLE_ADV_DISABLE;
   1038         }
   1039     }
   1040     else /* connectable */
   1041     {
   1042         BTM_TRACE_DEBUG2("btm_ble_set_connectability: mode = %04x discoverable_mode= %02x", mode, p_cb->discoverable_mode);
   1043 
   1044         if (BTM_BLE_VALID_CONN_DIRECT(&p_cb->direct_bda))
   1045         {
   1046             BTM_TRACE_DEBUG0("evt_type = BTM_BLE_CONNECT_DIR_EVT");
   1047             evt_type = BTM_BLE_CONNECT_DIR_EVT;
   1048         }
   1049         else
   1050         {
   1051             BTM_TRACE_DEBUG0(" evt_type = BTM_BLE_CONNECT_EVT");
   1052             evt_type = BTM_BLE_CONNECT_EVT;
   1053         }
   1054     }
   1055 
   1056     /* update adv params if needed */
   1057     if (p_cb->evt_type != evt_type && new_mode == BTM_BLE_ADV_ENABLE)
   1058     {
   1059         if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
   1060         {
   1061             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
   1062             btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE);
   1063         }
   1064 
   1065         if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
   1066                                               (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
   1067                                               evt_type,
   1068                                               p_cb->own_addr_type,
   1069                                               p_cb->direct_bda.type,
   1070                                               p_cb->direct_bda.bda,
   1071                                               p_cb->adv_chnl_map,
   1072                                               p_cb->afp))
   1073             status = BTM_NO_RESOURCES;
   1074         else
   1075             p_cb->evt_type = evt_type;
   1076     }
   1077     /* update advertising mode */
   1078     if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode)
   1079     {
   1080         if (btsnd_hcic_ble_set_adv_enable (new_mode))
   1081         {
   1082             status = BTM_SUCCESS;
   1083 
   1084             p_cb->adv_mode = new_mode;
   1085         }
   1086     }
   1087 
   1088     return status;
   1089 }
   1090 
   1091 /*******************************************************************************
   1092 **
   1093 ** Function         btm_ble_start_inquiry
   1094 **
   1095 ** Description      This function is called to start BLE inquiry procedure.
   1096 **                  If the duration is zero, the periodic inquiry mode is cancelled.
   1097 **
   1098 ** Parameters:      mode - GENERAL or LIMITED inquiry
   1099 **                  p_inq_params - pointer to the BLE inquiry parameter.
   1100 **                  p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS)
   1101 **                  p_cmpl_cb - callback indicating the end of an inquiry
   1102 **
   1103 **
   1104 **
   1105 ** Returns          BTM_CMD_STARTED if successfully started
   1106 **                  BTM_ILLEGAL_VALUE if a bad parameter is detected
   1107 **                  BTM_NO_RESOURCES if could not allocate a message buffer
   1108 **                  BTM_SUCCESS - if cancelling the periodic inquiry
   1109 **                  BTM_BUSY - if an inquiry is already active
   1110 **                  BTM_WRONG_MODE if the device is not up.
   1111 **
   1112 *******************************************************************************/
   1113 tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8   duration)
   1114 {
   1115     tBTM_STATUS status = BTM_NO_RESOURCES;
   1116     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
   1117 
   1118     BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active);
   1119 
   1120     if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
   1121     {
   1122         BTM_TRACE_ERROR0("LE scan is active, can not start inquiry");
   1123         return(BTM_BUSY);
   1124     }
   1125 
   1126     btm_update_scanner_filter_policy(SP_ADV_ALL);
   1127 
   1128     /* start scan, already enable duplicate filtering */
   1129     if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
   1130     {
   1131         status = BTM_SUCCESS;
   1132         p_inq->proc_mode = mode;
   1133 
   1134         if (duration != 0)
   1135         {
   1136             /* start inquiry timer */
   1137             btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
   1138         }
   1139     }
   1140 
   1141     return status;
   1142 }
   1143 
   1144 /*******************************************************************************
   1145 **
   1146 ** Function         btm_ble_read_remote_name_cmpl
   1147 **
   1148 ** Description      This function is called when BLE remote name is received.
   1149 **
   1150 ** Returns          void
   1151 **
   1152 *******************************************************************************/
   1153 void btm_ble_read_remote_name_cmpl(BOOLEAN status, BD_ADDR bda, UINT16 length, char *p_name)
   1154 {
   1155     UINT8   hci_status = HCI_SUCCESS;
   1156     BD_NAME bd_name;
   1157 
   1158     memset(bd_name, 0, BD_NAME_LEN);
   1159     memcpy((UINT8*)bd_name, p_name, length);
   1160 
   1161     if ((!status) || (length==0))
   1162     {
   1163         hci_status = HCI_ERR_HOST_TIMEOUT;
   1164     }
   1165 
   1166     btm_process_remote_name(bda, bd_name, length, hci_status);
   1167     btm_sec_rmt_name_request_complete (bda, (UINT8 *)p_name, hci_status);
   1168 }
   1169 
   1170 /*******************************************************************************
   1171 **
   1172 ** Function         btm_ble_read_remote_name
   1173 **
   1174 ** Description      This function read remote LE device name using GATT read
   1175 **                  procedure.
   1176 **
   1177 ** Parameters:       None.
   1178 **
   1179 ** Returns          void
   1180 **
   1181 *******************************************************************************/
   1182 tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb)
   1183 {
   1184     tBTM_INQUIRY_VAR_ST      *p_inq = &btm_cb.btm_inq_vars;
   1185 
   1186     if (p_cur &&
   1187         p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_ADV &&
   1188         p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_DIR_ADV)
   1189     {
   1190         BTM_TRACE_DEBUG0("name request to non-connectable device failed.");
   1191         return BTM_ERR_PROCESSING;
   1192     }
   1193 
   1194     /* read remote device name using GATT procedure */
   1195     if (p_inq->remname_active)
   1196         return BTM_BUSY;
   1197 
   1198     if (!GAP_BleReadPeerDevName(remote_bda, btm_ble_read_remote_name_cmpl))
   1199         return BTM_BUSY;
   1200 
   1201     p_inq->p_remname_cmpl_cb = p_cb;
   1202     p_inq->remname_active = TRUE;
   1203 
   1204     memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
   1205 
   1206     btu_start_timer (&p_inq->rmt_name_timer_ent,
   1207                      BTU_TTYPE_BTM_RMT_NAME,
   1208                      BTM_EXT_BLE_RMT_NAME_TIMEOUT);
   1209 
   1210     return BTM_CMD_STARTED;
   1211 }
   1212 
   1213 /*******************************************************************************
   1214 **
   1215 ** Function         btm_ble_cancel_remote_name
   1216 **
   1217 ** Description      This function cancel read remote LE device name.
   1218 **
   1219 ** Parameters:       None.
   1220 **
   1221 ** Returns          void
   1222 **
   1223 *******************************************************************************/
   1224 BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda)
   1225 {
   1226     tBTM_INQUIRY_VAR_ST      *p_inq = &btm_cb.btm_inq_vars;
   1227     BOOLEAN     status;
   1228 
   1229     status = GAP_BleCancelReadPeerDevName(remote_bda);
   1230 
   1231     p_inq->remname_active = FALSE;
   1232     memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
   1233     btu_stop_timer(&p_inq->rmt_name_timer_ent);
   1234 
   1235     return status;
   1236 }
   1237 
   1238 /*******************************************************************************
   1239 **
   1240 ** Function         btm_ble_update_adv_flag
   1241 **
   1242 ** Description      This function update the limited discoverable flag in the adv
   1243 **                  data.
   1244 **
   1245 ** Parameters:       None.
   1246 **
   1247 ** Returns          void
   1248 **
   1249 *******************************************************************************/
   1250 static void btm_ble_update_adv_flag(UINT8 flag)
   1251 {
   1252     tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
   1253     UINT8   *p;
   1254 
   1255     BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag new=0x%x", flag);
   1256 
   1257     if (p_adv_data->p_flags != NULL)
   1258     {
   1259         BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag old=0x%x",   *p_adv_data->p_flags);
   1260         *p_adv_data->p_flags = flag;
   1261     }
   1262     else /* no FLAGS in ADV data*/
   1263     {
   1264         p = (p_adv_data->p_pad == NULL) ? p_adv_data->ad_data : p_adv_data->p_pad;
   1265         /* need 3 bytes space to stuff in the flags, if not */
   1266         /* erase all written data, just for flags */
   1267         if ((BTM_BLE_AD_DATA_LEN - (p - p_adv_data->ad_data)) < 3)
   1268         {
   1269             p = p_adv_data->p_pad = p_adv_data->ad_data;
   1270             memset(p_adv_data->ad_data, 0, BTM_BLE_AD_DATA_LEN);
   1271         }
   1272 
   1273         *p++ = 2;
   1274         *p++ = BTM_BLE_AD_TYPE_FLAG;
   1275         p_adv_data->p_flags = p;
   1276         *p++ = flag;
   1277         p_adv_data->p_pad = p;
   1278     }
   1279 
   1280     if (btsnd_hcic_ble_set_adv_data((UINT8)(p_adv_data->p_pad - p_adv_data->ad_data),
   1281                                     p_adv_data->ad_data))
   1282         p_adv_data->data_mask |= BTM_BLE_AD_BIT_FLAGS;
   1283 
   1284 }
   1285 
   1286 #if 0
   1287 /*******************************************************************************
   1288 **
   1289 ** Function         btm_ble_parse_adv_data
   1290 **
   1291 ** Description      This function parse the adv data into a structure.
   1292 **
   1293 ** Returns          pointer to entry, or NULL if not found
   1294 **
   1295 *******************************************************************************/
   1296 static void btm_ble_parse_adv_data(tBTM_INQ_INFO *p_info, UINT8 *p_data,
   1297                                    UINT8 len, tBTM_BLE_INQ_DATA *p_adv_data, UINT8 *p_buf)
   1298 {
   1299     UINT8   *p_cur = p_data;
   1300     UINT8   ad_len, ad_type, ad_flag;
   1301     tBTM_BLE_ATTR   *p_attr;
   1302 
   1303     BTM_TRACE_EVENT0 (" btm_ble_parse_adv_data");
   1304 
   1305     while (len > 0)
   1306     {
   1307         BTM_TRACE_DEBUG1("btm_ble_parse_adv_data: len = %d", len);
   1308         if ((ad_len = *p_cur ++) == 0)
   1309             break;
   1310 
   1311         ad_type = *p_cur ++;
   1312 
   1313         BTM_TRACE_DEBUG2("     ad_type = %02x ad_len = %d", ad_type, ad_len);
   1314 
   1315         switch (ad_type)
   1316         {
   1317             case BTM_BLE_AD_TYPE_NAME_SHORT:
   1318 
   1319             case BTM_BLE_AD_TYPE_NAME_CMPL:
   1320                 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_DEV_NAME;
   1321                 if (p_info)
   1322                 {
   1323                     p_info->remote_name_type =(ad_type == BTM_BLE_AD_TYPE_NAME_SHORT) ?
   1324                                               BTM_BLE_NAME_SHORT: BTM_BLE_NAME_CMPL;
   1325                     memcpy(p_info->remote_name, p_cur, ad_len -1);
   1326                     p_info->remote_name[ad_len] = 0;
   1327                     p_adv_data->p_remote_name = p_info->remote_name;
   1328                     p_info->remote_name_len = p_adv_data->remote_name_len = ad_len - 1;
   1329                     BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_NAME name = %s",p_adv_data->p_remote_name);
   1330                 }
   1331                 p_cur += (ad_len -1);
   1332 
   1333                 break;
   1334 
   1335             case BTM_BLE_AD_TYPE_FLAG:
   1336                 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_FLAGS;
   1337                 ad_flag = *p_cur ++;
   1338                 p_adv_data->flag = (UINT8)(ad_flag & BTM_BLE_ADV_FLAG_MASK) ;
   1339                 BTM_TRACE_DEBUG3("BTM_BLE_AD_TYPE_FLAG flag = %s | %s | %s",
   1340                                  (p_adv_data->flag & BTM_BLE_LIMIT_DISC_FLAG)? "LE_LIMIT_DISC" : "",
   1341                                  (p_adv_data->flag & BTM_BLE_GEN_DISC_FLAG)? "LE_GENERAL_DISC" : "",
   1342                                  (p_adv_data->flag & BTM_BLE_BREDR_NOT_SPT)? "LE Only device" : "");
   1343                 break;
   1344 
   1345             case BTM_BLE_AD_TYPE_TX_PWR:
   1346                 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_TX_PWR;
   1347                 p_adv_data->tx_power_level = (INT8)*p_cur ++;
   1348                 BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_TX_PWR tx_level = %d", p_adv_data->tx_power_level);
   1349                 break;
   1350 
   1351             case BTM_BLE_AD_TYPE_ATTR:
   1352                 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_ATTR;
   1353                 p_attr = &p_adv_data->attr_data.attr_list[p_adv_data->attr_data.num_attr];
   1354                 p_attr->uuid = *p_cur ++;
   1355 
   1356                 if (ad_len > 3)
   1357                 {
   1358                     p_attr->data_len = ad_len - 3;
   1359                     p_attr->p_data = p_buf;
   1360                     memcpy(p_attr->p_data, p_cur, p_attr->data_len);
   1361                     p_buf += p_attr->data_len;
   1362                 }
   1363 
   1364                 p_adv_data->attr_data.num_attr ++;
   1365                 BTM_TRACE_DEBUG2("BTM_BLE_AD_TYPE_ATTR[%d] uuid = 0x%04x",p_adv_data->attr_data.num_attr, p_attr->uuid);
   1366                 break;
   1367 
   1368             case BTM_BLE_AD_TYPE_MANU:
   1369 
   1370             case BTM_BLE_AD_TYPE_SRV_CMPL:
   1371             case BTM_BLE_AD_TYPE_SRV_PART:
   1372                 p_adv_data->ad_mask |= ad_type;
   1373                 /* need allocate memory to store UUID list */
   1374                 p_adv_data->service.num_service = (ad_len - 1)/2;
   1375                 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service);
   1376 
   1377             default:
   1378                 p_cur += (ad_len - 1);
   1379                 break;
   1380         }
   1381         len -= (ad_len + 1);
   1382     }
   1383 }
   1384 #endif
   1385 
   1386 /*******************************************************************************
   1387 **
   1388 ** Function         btm_ble_cache_adv_data
   1389 **
   1390 ** Description      Update advertising cache data.
   1391 **
   1392 ** Returns          void
   1393 **
   1394 *******************************************************************************/
   1395 void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, UINT8 evt_type)
   1396 {
   1397     tBTM_BLE_INQ_CB     *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
   1398     UINT8 *p_cache;
   1399     UINT8 length;
   1400 
   1401     /* cache adv report/scan response data */
   1402     if (evt_type != BTM_BLE_SCAN_RSP_EVT)
   1403     {
   1404         p_le_inq_cb->adv_len = 0;
   1405         memset(p_le_inq_cb->adv_data_cache, 0, BTM_BLE_CACHE_ADV_DATA_MAX);
   1406     }
   1407 
   1408     if (data_len > 0)
   1409     {
   1410         p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len];
   1411         STREAM_TO_UINT8(length, p);
   1412         while ( length && ((p_le_inq_cb->adv_len + length + 1) <= BTM_BLE_CACHE_ADV_DATA_MAX))
   1413         {
   1414             /* copy from the length byte & data into cache */
   1415             memcpy(p_cache, p-1, length+1);
   1416             /* advance the cache pointer past data */
   1417             p_cache += length+1;
   1418             /* increment cache length */
   1419             p_le_inq_cb->adv_len += length+1;
   1420             /* skip the length of data */
   1421             p += length;
   1422             STREAM_TO_UINT8(length, p);
   1423         }
   1424     }
   1425 
   1426     /* parse service UUID from adv packet and save it in inq db eir_uuid */
   1427     /* TODO */
   1428 }
   1429 /*******************************************************************************
   1430 **
   1431 ** Function         btm_ble_is_discoverable
   1432 **
   1433 ** Description      check ADV flag to make sure device is discoverable and match
   1434 **                  the search condition
   1435 **
   1436 ** Parameters
   1437 **
   1438 ** Returns          void
   1439 **
   1440 *******************************************************************************/
   1441 BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
   1442 {
   1443     BOOLEAN             is_discoverable = FALSE;
   1444     UINT8               *p_flag, flag = 0;
   1445     UINT8                data_len;
   1446     tBTM_INQ_PARMS      *p_cond = &btm_cb.btm_inq_vars.inqparms;
   1447 
   1448     STREAM_TO_UINT8    (data_len, p);
   1449 
   1450     /* for observer, always "discoverable */
   1451     if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE ||
   1452         (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN &&
   1453         btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE))
   1454         return TRUE;
   1455 
   1456     /* does not match filter condition */
   1457     if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR &&
   1458         memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0)
   1459     {
   1460         BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition");
   1461         return FALSE;
   1462     }
   1463 
   1464     /* scan response does not include the flag */
   1465     if (evt_type == BTM_BLE_SCAN_RSP_EVT)
   1466         return FALSE;
   1467 
   1468     if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
   1469     {
   1470         BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len);
   1471         return FALSE;
   1472     }
   1473 
   1474     if (data_len != 0)
   1475     {
   1476         if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
   1477         {
   1478             flag = * p_flag;
   1479 
   1480             if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) &&
   1481                 (flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0)
   1482             {
   1483                 BTM_TRACE_DEBUG0("Find Generable Discoverable device");
   1484                 is_discoverable = TRUE;
   1485             }
   1486 
   1487             else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY &&
   1488                      (flag & BTM_BLE_LIMIT_DISC_FLAG) != 0)
   1489             {
   1490                 BTM_TRACE_DEBUG0("Find limited discoverable device");
   1491                 is_discoverable = TRUE;
   1492             }
   1493 
   1494         }
   1495     }
   1496 
   1497     if (!is_discoverable)
   1498     {
   1499         BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag);
   1500     }
   1501 
   1502     return is_discoverable;
   1503 }
   1504 /*******************************************************************************
   1505 **
   1506 ** Function         btm_ble_update_inq_result
   1507 **
   1508 ** Description      Update adv packet information into inquiry result.
   1509 **
   1510 ** Parameters
   1511 **
   1512 ** Returns          void
   1513 **
   1514 *******************************************************************************/
   1515 BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
   1516 {
   1517     BOOLEAN             to_report = TRUE;
   1518     tBTM_INQ_RESULTS     *p_cur = &p_i->inq_info.results;
   1519     UINT8               len;
   1520     UINT8               *p_flag;
   1521     tBTM_INQUIRY_VAR_ST  *p_inq = &btm_cb.btm_inq_vars;
   1522     UINT8                data_len, rssi;
   1523     tBTM_BLE_INQ_CB     *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
   1524     UINT8 *p1;
   1525 
   1526     STREAM_TO_UINT8    (data_len, p);
   1527 
   1528     if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
   1529     {
   1530         BTM_TRACE_WARNING1("EIR data too long %d. discard", data_len);
   1531         return FALSE;
   1532     }
   1533     btm_ble_cache_adv_data(p_cur, data_len, p, evt_type);
   1534 
   1535     p1 = (p + data_len);
   1536     STREAM_TO_UINT8 (rssi, p1);
   1537 
   1538     /* Save the info */
   1539     p_cur->inq_result_type = BTM_INQ_RESULT_BLE;
   1540     p_cur->ble_addr_type    = addr_type;
   1541     p_cur->rssi = rssi;
   1542 
   1543     /* active scan, always wait until get scan_rsp to report the result */
   1544     if ((btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI &&
   1545          (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_DISCOVER_EVT)))
   1546     {
   1547         p_i->scan_rsp = FALSE;
   1548         to_report = FALSE;
   1549     }
   1550     else
   1551         p_i->scan_rsp = TRUE;
   1552 
   1553     if (p_i->inq_count != p_inq->inq_counter)
   1554         p_cur->device_type = BT_DEVICE_TYPE_BLE;
   1555     else
   1556         p_cur->device_type |= BT_DEVICE_TYPE_BLE;
   1557 
   1558     if (evt_type != BTM_BLE_SCAN_RSP_EVT)
   1559         p_cur->ble_evt_type     = evt_type;
   1560 
   1561     p_i->inq_count = p_inq->inq_counter;   /* Mark entry for current inquiry */
   1562 
   1563     if (p_le_inq_cb->adv_len != 0)
   1564     {
   1565         if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL)
   1566             p_cur->flag = * p_flag;
   1567     }
   1568 
   1569     /* if BR/EDR not supported is not set, assume is a DUMO device */
   1570     if ((p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0)
   1571     {
   1572         BTM_TRACE_ERROR0("BR/EDR NOT support bit not set, treat as DUMO");
   1573         p_cur->device_type |= BT_DEVICE_TYPE_DUMO;
   1574     }
   1575     else
   1576     {
   1577         BTM_TRACE_DEBUG0("BR/EDR NOT SUPPORT bit set, LE only device");
   1578     }
   1579 
   1580     return to_report;
   1581 
   1582 }
   1583 
   1584 /*******************************************************************************
   1585 **
   1586 ** Function         btm_send_sel_conn_callback
   1587 **
   1588 ** Description      send selection connection request callback.
   1589 **
   1590 ** Parameters
   1591 **
   1592 ** Returns          void
   1593 **
   1594 *******************************************************************************/
   1595 void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_data, UINT8 addr_type)
   1596 {
   1597     UINT8   data_len, len;
   1598     UINT8   *p_dev_name, remname[31] = {0};
   1599 
   1600     if (btm_cb.ble_ctr_cb.p_select_cback == NULL ||
   1601         /* non-connectable device */
   1602         (evt_type != BTM_BLE_EVT_CONN_ADV && evt_type != BTM_BLE_EVT_CONN_DIR_ADV))
   1603         return;
   1604 
   1605     STREAM_TO_UINT8    (data_len, p_data);
   1606 
   1607     /* get the device name if exist in ADV data */
   1608     if (data_len != 0)
   1609     {
   1610         p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len);
   1611 
   1612         if (p_dev_name == NULL)
   1613             p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len);
   1614 
   1615         if (p_dev_name)
   1616             memcpy(remname, p_dev_name, len);
   1617     }
   1618     /* allow connection */
   1619     if ((* btm_cb.ble_ctr_cb.p_select_cback)(remote_bda, remname))
   1620     {
   1621         /* terminate selective connection, initiate connection */
   1622         btm_ble_initiate_select_conn(remote_bda);
   1623     }
   1624 }
   1625 
   1626 /*******************************************************************************
   1627 **
   1628 ** Function         btm_ble_resolve_random_addr_cmpl
   1629 **
   1630 ** Description      resolve random address complete callback.
   1631 **
   1632 ** Returns          void
   1633 **
   1634 *******************************************************************************/
   1635 static void btm_ble_resolve_random_addr_cmpl(void * p_rec, void *p)
   1636 {
   1637     tBTM_SEC_DEV_REC    *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
   1638     UINT8       addr_type = BLE_ADDR_RANDOM;
   1639     BD_ADDR     bda;
   1640     UINT8       *pp = (UINT8 *)p + 1;
   1641     UINT8           evt_type;
   1642 
   1643     BTM_TRACE_EVENT0 ("btm_ble_resolve_random_addr_cmpl ");
   1644 
   1645     STREAM_TO_UINT8    (evt_type, pp);
   1646     STREAM_TO_UINT8    (addr_type, pp);
   1647     STREAM_TO_BDADDR   (bda, pp);
   1648 
   1649     if (match_rec)
   1650     {
   1651         BTM_TRACE_ERROR0("Random match");
   1652         memcpy(match_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN);
   1653         memcpy(bda, match_rec->bd_addr, BD_ADDR_LEN);
   1654     }
   1655     else
   1656     {
   1657         BTM_TRACE_ERROR0("Random unmatch");
   1658     }
   1659 
   1660     btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, pp);
   1661 
   1662     return;
   1663 }
   1664 
   1665 /*******************************************************************************
   1666 **
   1667 ** Function         btm_ble_process_adv_pkt
   1668 **
   1669 ** Description      This function is called when adv packet report events are
   1670 **                  received from the device. It updates the inquiry database.
   1671 **                  If the inquiry database is full, the oldest entry is discarded.
   1672 **
   1673 ** Parameters
   1674 **
   1675 ** Returns          void
   1676 **
   1677 *******************************************************************************/
   1678 void btm_ble_process_adv_pkt (UINT8 *p_data)
   1679 {
   1680     BD_ADDR             bda;
   1681     UINT8               evt_type = 0, *p = p_data;
   1682     UINT8               addr_type = 0;
   1683 
   1684     BTM_TRACE_EVENT0 ("btm_ble_process_adv_pkt ");
   1685 
   1686     /* always get one device at a time */
   1687     p ++;
   1688 
   1689     /* Extract inquiry results */
   1690     STREAM_TO_UINT8    (evt_type, p);
   1691     STREAM_TO_UINT8    (addr_type, p);
   1692     STREAM_TO_BDADDR   (bda, p);
   1693 
   1694 #ifdef BTM_BLE_PC_ADV_TEST_MODE // For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include
   1695     if (BTM_BLE_PC_ADV_TEST_MODE)   // For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode
   1696     {
   1697         if (btm_cb.ble_ctr_cb.p_scan_req_cback)
   1698             (*btm_cb.ble_ctr_cb.p_scan_req_cback)(bda, addr_type, evt_type);
   1699     }
   1700 #endif
   1701 
   1702     /* Only process the results if the inquiry is still active */
   1703     if (!btm_cb.btm_inq_vars.inq_active &&
   1704         (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE ||
   1705          /* or selective auto connection is active */
   1706          btm_cb.ble_ctr_cb.p_select_cback == NULL))
   1707         return;
   1708 
   1709 
   1710 #if SMP_INCLUDED == TRUE
   1711     if (addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bda))
   1712     {
   1713         btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_cmpl, p_data);
   1714     }
   1715     else
   1716 #endif
   1717         btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p);
   1718 }
   1719 
   1720 /*******************************************************************************
   1721 **
   1722 ** Function         btm_ble_process_adv_pkt_cont
   1723 **
   1724 ** Description      This function is called after random address resolution is
   1725 **                  done, and proceed to process adv packet.
   1726 **
   1727 ** Parameters
   1728 **
   1729 ** Returns          void
   1730 **
   1731 *******************************************************************************/
   1732 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
   1733 {
   1734     tINQ_DB_ENT          *p_i;
   1735     BOOLEAN              to_report = FALSE;
   1736     tBTM_INQUIRY_VAR_ST  *p_inq = &btm_cb.btm_inq_vars;
   1737     tBTM_INQ_RESULTS_CB  *p_inq_results_cb = p_inq->p_inq_results_cb;
   1738     tBTM_BLE_INQ_CB      *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
   1739 
   1740     p_i = btm_inq_db_find (bda);
   1741 
   1742     /* Check if this address has already been processed for this inquiry */
   1743     if (btm_inq_find_bdaddr(bda))
   1744     {
   1745         /* never been report as an LE device */
   1746         if ((p_i &&
   1747             (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) ||
   1748               /* scan repsonse to be updated */
   1749               (!p_i->scan_rsp)))
   1750             ||
   1751             btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE)
   1752         {
   1753             BTM_TRACE_DEBUG0("update new BLE information ");
   1754             to_report = TRUE;
   1755         }
   1756         else
   1757         {
   1758             BTM_TRACE_DEBUG0("LE in le_bd_db already");
   1759             /* if yes, skip it */
   1760             return; /* assumption: one result per event */
   1761         }
   1762     }
   1763     else /* not been processed int his round */
   1764     {
   1765         BTM_TRACE_DEBUG0("new LE BD_ADDR");
   1766         to_report = TRUE;
   1767     }
   1768 
   1769     /* If existing entry, use that, else get  a new one (possibly reusing the oldest) */
   1770     if (p_i == NULL)
   1771     {
   1772         if (btm_ble_is_discoverable(bda, evt_type, p))
   1773         {
   1774             if ((p_i = btm_inq_db_new (bda)) != NULL)
   1775             {
   1776                 p_inq->inq_cmpl_info.num_resp++;
   1777                 BTM_TRACE_DEBUG0("adv pkt process:  new record is added into inq db");
   1778                 to_report = TRUE;
   1779             }
   1780             else
   1781                 return;
   1782         }
   1783         else
   1784         {
   1785             BTM_TRACE_ERROR0("discard adv pkt");
   1786             return;
   1787         }
   1788     }
   1789     else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */
   1790     {
   1791         p_inq->inq_cmpl_info.num_resp++;
   1792     }
   1793 
   1794     /* update the LE device information in inquiry database */
   1795     if (to_report)
   1796     {
   1797         to_report = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
   1798     }
   1799 
   1800 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
   1801     /* If the number of responses found and limited, issue a cancel inquiry */
   1802     if (p_inq->inqparms.max_resps &&
   1803         p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps)
   1804     {
   1805         /* new device */
   1806         if (p_i == NULL ||
   1807             (/* assume a DUMO device, BR/EDR inquiry is always active */
   1808              p_i && p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && p_i->scan_rsp))
   1809         {
   1810             BTM_TRACE_WARNING0("INQ RES: Extra Response Received...cancelling inquiry..");
   1811 
   1812             if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) )
   1813                 btsnd_hcic_inq_cancel();
   1814 
   1815             /* stop LE scan now */
   1816             btm_ble_stop_scan();
   1817 
   1818 #if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE
   1819             btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
   1820 #endif
   1821         }
   1822     }
   1823 #endif
   1824 
   1825     /* background connection in selective connection mode */
   1826     if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
   1827     {
   1828         btm_send_sel_conn_callback(bda, evt_type, p, addr_type);
   1829     }
   1830     else if (p_inq_results_cb && to_report)
   1831     {
   1832         BTM_TRACE_DEBUG0("BTMINQ LE: Found devices, send callback btm_inqrslt_cb");
   1833 
   1834         if (p_inq->inq_active)
   1835             (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
   1836     }
   1837 }
   1838 
   1839 /*******************************************************************************
   1840 **
   1841 ** Function         btm_ble_stop_scan
   1842 **
   1843 ** Description      Stop the BLE scan.
   1844 **
   1845 ** Returns          void
   1846 **
   1847 *******************************************************************************/
   1848 void btm_ble_stop_scan(void)
   1849 {
   1850     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
   1851     tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
   1852 
   1853     BTM_TRACE_EVENT0 ("btm_ble_stop_scan ");
   1854 
   1855     btu_stop_timer (&p_cb->inq_timer_ent);
   1856 
   1857     /* Clear the inquiry callback if set */
   1858     p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE;
   1859     p_cb->proc_mode = BTM_BLE_INQUIRY_NONE;
   1860 
   1861     /* stop discovery now */
   1862     btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
   1863 
   1864     /* If we have a callback registered for inquiry complete, call it */
   1865     BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d",
   1866                       p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
   1867 
   1868     btm_update_scanner_filter_policy(SP_ADV_ALL);
   1869 
   1870     btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK));
   1871 
   1872 }
   1873 
   1874 /*******************************************************************************
   1875 **
   1876 ** Function         btm_ble_stop_adv
   1877 **
   1878 ** Description      Stop the BLE advertising.
   1879 **
   1880 ** Returns          void
   1881 **
   1882 *******************************************************************************/
   1883 void btm_ble_stop_adv(void)
   1884 {
   1885     BTM_TRACE_EVENT0 (" btm_ble_stop_adv");
   1886 
   1887     if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
   1888     {
   1889         btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
   1890     }
   1891 }
   1892 
   1893 /*******************************************************************************
   1894 **
   1895 ** Function         btm_ble_timeout
   1896 **
   1897 ** Description      Called when BTM BLE inquiry timer expires
   1898 **
   1899 ** Returns          void
   1900 **
   1901 *******************************************************************************/
   1902 void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
   1903 {
   1904     BTM_TRACE_EVENT0 ("btm_ble_timeout");
   1905 
   1906     switch (p_tle->event)
   1907     {
   1908         case BTU_TTYPE_BLE_INQUIRY:
   1909             btm_ble_stop_scan();
   1910             break;
   1911 
   1912         case BTU_TTYPE_BLE_GAP_LIM_DISC:
   1913             /* lim_timeout expiried, limited discovery should exit now */
   1914             btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG);
   1915 
   1916             btm_ble_stop_adv();
   1917             break;
   1918 
   1919         case BTU_TTYPE_BLE_RANDOM_ADDR:
   1920             if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_ENABLE &&
   1921                 btm_cb.ble_ctr_cb.inq_var.own_addr_type == BLE_ADDR_RANDOM)
   1922             {
   1923                 /* refresh the random addr */
   1924                 btm_gen_resolvable_private_addr();
   1925             }
   1926             break;
   1927 
   1928     }
   1929 }
   1930 
   1931 /*******************************************************************************
   1932 **
   1933 ** Function         btm_ble_connected
   1934 **
   1935 ** Description      This function is when a LE connection to the peer device is
   1936 **                  establsihed
   1937 **
   1938 ** Returns          void
   1939 **
   1940 *******************************************************************************/
   1941 void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role)
   1942 {
   1943     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
   1944     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
   1945 
   1946     BTM_TRACE_EVENT0 ("btm_ble_connected");
   1947 
   1948     /* Commenting out trace due to obf/compilation problems.
   1949     */
   1950 #if (BT_USE_TRACES == TRUE)
   1951     if (p_dev_rec)
   1952     {
   1953         BTM_TRACE_EVENT4 ("Security Manager: btm_sec_connected :  handle:%d  enc_mode:%d  bda:%x RName:%s",
   1954                           handle,  enc_mode,
   1955                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
   1956                           p_dev_rec->sec_bd_name);
   1957 
   1958         BTM_TRACE_DEBUG1 ("btm_ble_connected sec_flags=0x%x",p_dev_rec->sec_flags);
   1959     }
   1960     else
   1961     {
   1962         BTM_TRACE_EVENT3 ("Security Manager: btm_sec_connected:   handle:%d  enc_mode:%d  bda:%x ",
   1963                           handle,  enc_mode,
   1964                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
   1965     }
   1966 #endif
   1967 
   1968     if (!p_dev_rec)
   1969     {
   1970         /* There is no device record for new connection.  Allocate one */
   1971         p_dev_rec = btm_sec_alloc_dev (bda);
   1972     }
   1973     else    /* Update the timestamp for this device */
   1974     {
   1975         p_dev_rec->timestamp = btm_cb.dev_rec_count++;
   1976     }
   1977 
   1978     p_dev_rec->device_type = BT_DEVICE_TYPE_BLE;
   1979     p_dev_rec->hci_handle = handle;
   1980     if (role == HCI_ROLE_MASTER)
   1981         p_dev_rec->role_master = TRUE;
   1982 
   1983     p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
   1984 
   1985     return;
   1986 }
   1987 
   1988 /*******************************************************************************
   1989 **
   1990 ** Function         btm_ble_read_remote_features_complete
   1991 **
   1992 ** Description      This function is called when the command complete message
   1993 **                  is received from the HCI for the read LE remote feature supported
   1994 **                  complete event.
   1995 **
   1996 ** Returns          void
   1997 **
   1998 *******************************************************************************/
   1999 void btm_ble_read_remote_features_complete(UINT8 *p)
   2000 {
   2001     tACL_CONN        *p_acl_cb = &btm_cb.acl_db[0];
   2002     UINT8             size;
   2003     UINT16            handle;
   2004     int               xx, yy;
   2005     tBTM_SEC_DEV_REC *p_dev_rec;
   2006 
   2007     BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete ");
   2008 
   2009     STREAM_TO_UINT16  (handle, p);
   2010     STREAM_TO_UINT8  (size, p);
   2011 
   2012     /* Look up the connection by handle and copy features */
   2013     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++)
   2014     {
   2015         if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle))
   2016         {
   2017             for (yy = 0; yy < BD_FEATURES_LEN; yy++)
   2018                 STREAM_TO_UINT8 (p_acl_cb->features[yy], p);
   2019 
   2020             p_dev_rec = btm_find_dev_by_handle (handle);
   2021             if (!p_dev_rec)
   2022             {
   2023                 /* Get a new device; might be doing dedicated bonding */
   2024                 p_dev_rec = btm_find_or_alloc_dev (p_acl_cb->remote_addr);
   2025             }
   2026 
   2027             memcpy (p_dev_rec->features, p_acl_cb->features, BD_FEATURES_LEN);
   2028             break;
   2029         }
   2030     }
   2031 }
   2032 
   2033 /*******************************************************************************
   2034 **
   2035 ** Function         btm_ble_write_adv_enable_complete
   2036 **
   2037 ** Description      This function process the write adv enable command complete.
   2038 **
   2039 ** Returns          void
   2040 **
   2041 *******************************************************************************/
   2042 void btm_ble_write_adv_enable_complete(UINT8 * p)
   2043 {
   2044     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
   2045 
   2046     /* if write adv enable/disbale not succeed */
   2047     if (*p != HCI_SUCCESS)
   2048     {
   2049         /* toggle back the adv mode */
   2050         p_cb->adv_mode = !p_cb->adv_mode;
   2051     }
   2052 }
   2053 /*******************************************************************************
   2054 **
   2055 ** Function         btm_ble_init
   2056 **
   2057 ** Description      Initialize the control block variable values.
   2058 **
   2059 ** Returns          void
   2060 **
   2061 *******************************************************************************/
   2062 void btm_ble_init (void)
   2063 {
   2064     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
   2065 
   2066     BTM_TRACE_EVENT0 ("btm_ble_init ");
   2067 
   2068     memset(p_cb, 0, sizeof(tBTM_BLE_CB));
   2069 
   2070     p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
   2071     p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
   2072     p_cb->inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
   2073     p_cb->inq_var.afp = BTM_BLE_DEFAULT_AFP;
   2074     p_cb->inq_var.sfp = BTM_BLE_DEFAULT_SFP;
   2075     p_cb->inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE;
   2076     p_cb->inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE;
   2077 
   2078     /* for background connection, reset connection params to be undefined */
   2079     p_cb->scan_int = p_cb->scan_win = BTM_BLE_CONN_PARAM_UNDEF;
   2080 
   2081     p_cb->inq_var.evt_type = BTM_BLE_UNKNOWN_EVT;
   2082 }
   2083 
   2084 #endif  /* BLE_INCLUDED */
   2085