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