Home | History | Annotate | Download | only in dm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-2014 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file contains the action functions for device manager state
     22  *  machine.
     23  *
     24  ******************************************************************************/
     25 
     26 #define LOG_TAG "bt_bta_dm"
     27 
     28 #include <assert.h>
     29 #include <string.h>
     30 
     31 #include "bt_target.h"
     32 #include "bt_types.h"
     33 #include "bta_api.h"
     34 #include "bta_dm_co.h"
     35 #include "bta_dm_int.h"
     36 #include "bta_sys.h"
     37 #include "btm_api.h"
     38 #include "btm_int.h"
     39 #include "btu.h"
     40 #include "gap_api.h"    /* For GAP_BleReadPeerPrefConnParams */
     41 #include "bt_common.h"
     42 #include "l2c_api.h"
     43 #include "osi/include/log.h"
     44 #include "osi/include/osi.h"
     45 #include "sdp_api.h"
     46 #include "utl.h"
     47 
     48 #if (GAP_INCLUDED == TRUE)
     49 #include "gap_api.h"
     50 #endif
     51 
     52 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
     53 static void bta_dm_inq_cmpl_cb (void * p_result);
     54 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name);
     55 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name);
     56 static void bta_dm_find_services ( BD_ADDR bd_addr);
     57 static void bta_dm_discover_next_device(void);
     58 static void bta_dm_sdp_callback (UINT16 sdp_status);
     59 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator);
     60 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, BOOLEAN min_16_digit);
     61 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, LINK_KEY key, UINT8 key_type);
     62 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result);
     63 static void bta_dm_local_name_cback(BD_ADDR bd_addr);
     64 static BOOLEAN bta_dm_check_av(UINT16 event);
     65 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
     66 
     67 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
     68 
     69 /* Extended Inquiry Response */
     70 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
     71 
     72 static void bta_dm_set_eir (char *local_name);
     73 
     74 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS  *p_result,
     75                                         tBTA_SERVICE_MASK *p_services_to_search,
     76                                         tBTA_SERVICE_MASK *p_services_found);
     77 
     78 static void bta_dm_search_timer_cback(void *data);
     79 static void bta_dm_disable_conn_down_timer_cback(void *data);
     80 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
     81 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch);
     82 static char *bta_dm_get_remname(void);
     83 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
     84 
     85 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport);
     86 static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
     87 
     88 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
     89 static void bta_dm_disable_search_and_disc(void);
     90 
     91 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     92     #if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE))
     93 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data);
     94     #endif
     95 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key);
     96     #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
     97 static void bta_dm_gattc_register(void);
     98 static void btm_dm_start_gatt_discovery(BD_ADDR bd_addr);
     99 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
    100 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
    101 extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
    102     #endif
    103 
    104 #if BLE_VND_INCLUDED == TRUE
    105 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
    106 #endif
    107 
    108 #ifndef BTA_DM_BLE_ADV_CHNL_MAP
    109 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
    110 #endif
    111 #endif
    112 
    113 /* Disable timer interval (in milliseconds) */
    114 #ifndef BTA_DM_DISABLE_TIMER_MS
    115 #define BTA_DM_DISABLE_TIMER_MS 5000
    116 #endif
    117 
    118 /* Disable timer retrial interval (in milliseconds) */
    119 #ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS
    120 #define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500
    121 #endif
    122 
    123 /* Disable connection down timer (in milliseconds) */
    124 #ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS
    125 #define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000
    126 #endif
    127 
    128 /* Switch delay timer (in milliseconds) */
    129 #ifndef BTA_DM_SWITCH_DELAY_TIMER_MS
    130 #define BTA_DM_SWITCH_DELAY_TIMER_MS 500
    131 #endif
    132 
    133 static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr);
    134 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
    135 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
    136 static void bta_dm_observe_cmpl_cb(void * p_result);
    137 static void bta_dm_delay_role_switch_cback(void *data);
    138 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128);
    139 static void bta_dm_disable_timer_cback(void *data);
    140 
    141 
    142 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] =
    143 {
    144     UUID_SERVCLASS_PNP_INFORMATION,         /* Reserved */
    145     UUID_SERVCLASS_SERIAL_PORT,             /* BTA_SPP_SERVICE_ID */
    146     UUID_SERVCLASS_DIALUP_NETWORKING,       /* BTA_DUN_SERVICE_ID */
    147     UUID_SERVCLASS_AUDIO_SOURCE,            /* BTA_A2DP_SOURCE_SERVICE_ID */
    148     UUID_SERVCLASS_LAN_ACCESS_USING_PPP,    /* BTA_LAP_SERVICE_ID */
    149     UUID_SERVCLASS_HEADSET,                 /* BTA_HSP_HS_SERVICE_ID */
    150     UUID_SERVCLASS_HF_HANDSFREE,            /* BTA_HFP_HS_SERVICE_ID */
    151     UUID_SERVCLASS_OBEX_OBJECT_PUSH,        /* BTA_OPP_SERVICE_ID */
    152     UUID_SERVCLASS_OBEX_FILE_TRANSFER,      /* BTA_FTP_SERVICE_ID */
    153     UUID_SERVCLASS_CORDLESS_TELEPHONY,      /* BTA_CTP_SERVICE_ID */
    154     UUID_SERVCLASS_INTERCOM,                /* BTA_ICP_SERVICE_ID */
    155     UUID_SERVCLASS_IRMC_SYNC,               /* BTA_SYNC_SERVICE_ID */
    156     UUID_SERVCLASS_DIRECT_PRINTING,         /* BTA_BPP_SERVICE_ID */
    157     UUID_SERVCLASS_IMAGING_RESPONDER,       /* BTA_BIP_SERVICE_ID */
    158     UUID_SERVCLASS_PANU,                    /* BTA_PANU_SERVICE_ID */
    159     UUID_SERVCLASS_NAP,                     /* BTA_NAP_SERVICE_ID */
    160     UUID_SERVCLASS_GN,                      /* BTA_GN_SERVICE_ID */
    161     UUID_SERVCLASS_SAP,                     /* BTA_SAP_SERVICE_ID */
    162     UUID_SERVCLASS_AUDIO_SINK,              /* BTA_A2DP_SERVICE_ID */
    163     UUID_SERVCLASS_AV_REMOTE_CONTROL,       /* BTA_AVRCP_SERVICE_ID */
    164     UUID_SERVCLASS_HUMAN_INTERFACE,         /* BTA_HID_SERVICE_ID */
    165     UUID_SERVCLASS_VIDEO_SINK,              /* BTA_VDP_SERVICE_ID */
    166     UUID_SERVCLASS_PBAP_PSE,                /* BTA_PBAP_SERVICE_ID */
    167     UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,   /* BTA_HSP_SERVICE_ID */
    168     UUID_SERVCLASS_AG_HANDSFREE,            /* BTA_HFP_SERVICE_ID */
    169     UUID_SERVCLASS_MESSAGE_ACCESS,          /* BTA_MAP_SERVICE_ID */
    170     UUID_SERVCLASS_MESSAGE_NOTIFICATION,    /* BTA_MN_SERVICE_ID */
    171     UUID_SERVCLASS_HDP_PROFILE,             /* BTA_HDP_SERVICE_ID */
    172     UUID_SERVCLASS_PBAP_PCE                 /* BTA_PCE_SERVICE_ID */
    173 #if BLE_INCLUDED && BTA_GATT_INCLUDED
    174     ,UUID_PROTOCOL_ATT                       /* BTA_GATT_SERVICE_ID */
    175 #endif
    176 };
    177 
    178 /*
    179  * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should be matching with
    180  *        the value BTA_MAX_SERVICE_ID in bta_api.h
    181  *
    182  *        i.e., If you add new Service ID for BTA, the correct security ID of the new service
    183  *              from Security service definitions (btm_api.h) should be added to this lookup table.
    184  */
    185 const UINT32 bta_service_id_to_btm_srv_id_lkup_tbl [BTA_MAX_SERVICE_ID] =
    186 {
    187     0,                                      /* Reserved */
    188     BTM_SEC_SERVICE_SERIAL_PORT,            /* BTA_SPP_SERVICE_ID */
    189     BTM_SEC_SERVICE_DUN,                    /* BTA_DUN_SERVICE_ID */
    190     BTM_SEC_SERVICE_AVDTP,                  /* BTA_AUDIO_SOURCE_SERVICE_ID */
    191     BTM_SEC_SERVICE_LAN_ACCESS,             /* BTA_LAP_SERVICE_ID */
    192     BTM_SEC_SERVICE_HEADSET_AG,             /* BTA_HSP_SERVICE_ID */
    193     BTM_SEC_SERVICE_AG_HANDSFREE,           /* BTA_HFP_SERVICE_ID */
    194     BTM_SEC_SERVICE_OBEX,                   /* BTA_OPP_SERVICE_ID */
    195     BTM_SEC_SERVICE_OBEX_FTP,               /* BTA_FTP_SERVICE_ID */
    196     BTM_SEC_SERVICE_CORDLESS,               /* BTA_CTP_SERVICE_ID */
    197     BTM_SEC_SERVICE_INTERCOM,               /* BTA_ICP_SERVICE_ID */
    198     BTM_SEC_SERVICE_IRMC_SYNC,              /* BTA_SYNC_SERVICE_ID */
    199     BTM_SEC_SERVICE_BPP_JOB,                /* BTA_BPP_SERVICE_ID */
    200     BTM_SEC_SERVICE_BIP,                    /* BTA_BIP_SERVICE_ID */
    201     BTM_SEC_SERVICE_BNEP_PANU,              /* BTA_PANU_SERVICE_ID */
    202     BTM_SEC_SERVICE_BNEP_NAP,               /* BTA_NAP_SERVICE_ID */
    203     BTM_SEC_SERVICE_BNEP_GN,                /* BTA_GN_SERVICE_ID */
    204     BTM_SEC_SERVICE_SAP,                    /* BTA_SAP_SERVICE_ID */
    205     BTM_SEC_SERVICE_AVDTP,                  /* BTA_A2DP_SERVICE_ID */
    206     BTM_SEC_SERVICE_AVCTP,                  /* BTA_AVRCP_SERVICE_ID */
    207     BTM_SEC_SERVICE_HIDH_SEC_CTRL,          /* BTA_HID_SERVICE_ID */
    208     BTM_SEC_SERVICE_AVDTP,                  /* BTA_VDP_SERVICE_ID */
    209     BTM_SEC_SERVICE_PBAP,                   /* BTA_PBAP_SERVICE_ID */
    210     BTM_SEC_SERVICE_HEADSET,                /* BTA_HSP_HS_SERVICE_ID */
    211     BTM_SEC_SERVICE_HF_HANDSFREE,           /* BTA_HFP_HS_SERVICE_ID */
    212     BTM_SEC_SERVICE_MAP,                    /* BTA_MAP_SERVICE_ID */
    213     BTM_SEC_SERVICE_MAP,                    /* BTA_MN_SERVICE_ID */
    214     BTM_SEC_SERVICE_HDP_SNK,                /* BTA_HDP_SERVICE_ID */
    215     BTM_SEC_SERVICE_PBAP                    /* BTA_PCE_SERVICE_ID */
    216 #if BLE_INCLUDED && BTA_GATT_INCLUDED
    217     ,BTM_SEC_SERVICE_ATT                    /* BTA_GATT_SERVICE_ID */
    218 #endif
    219 
    220 };
    221 
    222 /* bta security callback */
    223 const tBTM_APPL_INFO bta_security =
    224 {
    225     &bta_dm_authorize_cback,
    226     &bta_dm_pin_cback,
    227     &bta_dm_new_link_key_cback,
    228     &bta_dm_authentication_complete_cback,
    229     &bta_dm_bond_cancel_complete_cback,
    230 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
    231     &bta_dm_sp_cback
    232 #else
    233     NULL
    234 #endif
    235 #if BLE_INCLUDED == TRUE
    236 #if SMP_INCLUDED == TRUE
    237     ,&bta_dm_ble_smp_cback
    238 #endif
    239     ,&bta_dm_ble_id_key_cback
    240 #endif
    241 
    242 };
    243 
    244 #define MAX_DISC_RAW_DATA_BUF       (4096)
    245 UINT8 g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
    246 
    247 extern DEV_CLASS local_device_default_class;
    248 extern fixed_queue_t *btu_bta_alarm_queue;
    249 
    250 /*******************************************************************************
    251 **
    252 ** Function         bta_dm_enable
    253 **
    254 ** Description      Initialises the BT device manager
    255 **
    256 **
    257 ** Returns          void
    258 **
    259 *******************************************************************************/
    260 void bta_dm_enable(tBTA_DM_MSG *p_data)
    261 {
    262     tBTA_DM_ENABLE enable_event;
    263 
    264     /* if already in use, return an error */
    265     if( bta_dm_cb.is_bta_dm_active == TRUE  )
    266     {
    267         APPL_TRACE_WARNING("%s Device already started by another application", __func__);
    268         memset(&enable_event, 0, sizeof(tBTA_DM_ENABLE));
    269         enable_event.status = BTA_FAILURE;
    270         if (p_data->enable.p_sec_cback != NULL)
    271             p_data->enable.p_sec_cback(BTA_DM_ENABLE_EVT, (tBTA_DM_SEC *)&enable_event);
    272         return;
    273     }
    274 
    275     /* first, register our callback to SYS HW manager */
    276     bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
    277 
    278     /* make sure security callback is saved - if no callback, do not erase the previous one,
    279     it could be an error recovery mechanism */
    280     if( p_data->enable.p_sec_cback != NULL  )
    281     bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback;
    282     /* notify BTA DM is now active */
    283     bta_dm_cb.is_bta_dm_active = TRUE;
    284 
    285     /* send a message to BTA SYS */
    286     tBTA_SYS_HW_MSG *sys_enable_event =
    287         (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
    288     sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;
    289     sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
    290 
    291     bta_sys_sendmsg(sys_enable_event);
    292 }
    293 
    294 /*******************************************************************************
    295 **
    296 ** Function         bta_dm_init_cb
    297 **
    298 ** Description      Initializes or re-initializes the bta_dm_cb control block
    299 **
    300 **
    301 ** Returns          void
    302 **
    303 *******************************************************************************/
    304 void bta_dm_init_cb(void)
    305 {
    306     /*
    307      * TODO: Should alarm_free() the bta_dm_cb timers during graceful
    308      * shutdown.
    309      */
    310     alarm_free(bta_dm_cb.disable_timer);
    311     alarm_free(bta_dm_cb.switch_delay_timer);
    312     for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
    313         for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
    314             alarm_free(bta_dm_cb.pm_timer[i].timer[j]);
    315         }
    316     }
    317     memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
    318     bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer");
    319     bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer");
    320     for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
    321         for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
    322             bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer");
    323         }
    324     }
    325 }
    326 
    327 /*******************************************************************************
    328 **
    329 ** Function         bta_dm_sys_hw_cback
    330 **
    331 ** Description     callback register to SYS to get HW status updates
    332 **
    333 **
    334 ** Returns          void
    335 **
    336 *******************************************************************************/
    337 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
    338 {
    339     DEV_CLASS   dev_class;
    340     tBTA_DM_SEC_CBACK           *temp_cback;
    341 #if BLE_INCLUDED == TRUE
    342     UINT8                   key_mask = 0;
    343     BT_OCTET16              er;
    344     tBTA_BLE_LOCAL_ID_KEYS  id_key;
    345 #endif
    346 
    347     APPL_TRACE_DEBUG("%s with event: %i", __func__, status);
    348 
    349     /* On H/W error evt, report to the registered DM application callback */
    350     if (status == BTA_SYS_HW_ERROR_EVT) {
    351           if( bta_dm_cb.p_sec_cback != NULL )
    352                 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL);
    353           return;
    354     }
    355 
    356     if( status == BTA_SYS_HW_OFF_EVT )
    357     {
    358         if( bta_dm_cb.p_sec_cback != NULL )
    359             bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
    360 
    361         /* reinitialize the control block */
    362         bta_dm_init_cb();
    363 
    364         /* unregister from SYS */
    365         bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
    366         /* notify BTA DM is now unactive */
    367         bta_dm_cb.is_bta_dm_active = FALSE;
    368     }
    369     else
    370     if( status == BTA_SYS_HW_ON_EVT )
    371     {
    372         /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
    373         * We need to revisit when this platform has more than one BLuetooth H/W chip */
    374         //bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH);
    375 
    376         /* save security callback */
    377         temp_cback = bta_dm_cb.p_sec_cback;
    378         /* make sure the control block is properly initialized */
    379         bta_dm_init_cb();
    380         /* and retrieve the callback */
    381         bta_dm_cb.p_sec_cback=temp_cback;
    382         bta_dm_cb.is_bta_dm_active = TRUE;
    383 
    384         /* hw is ready, go on with BTA DM initialization */
    385         alarm_free(bta_dm_search_cb.search_timer);
    386         alarm_free(bta_dm_search_cb.gatt_close_timer);
    387         memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
    388         /*
    389          * TODO: Should alarm_free() the bta_dm_search_cb timers during
    390          * graceful shutdown.
    391          */
    392         bta_dm_search_cb.search_timer =
    393           alarm_new("bta_dm_search.search_timer");
    394         bta_dm_search_cb.gatt_close_timer =
    395           alarm_new("bta_dm_search.gatt_close_timer");
    396 
    397         memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
    398         memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
    399 
    400         memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
    401         BTM_SetDeviceClass (dev_class);
    402 
    403 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
    404         /* load BLE local information: ID keys, ER if available */
    405         bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);
    406 
    407         if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER)
    408         {
    409             BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS *)&er);
    410         }
    411         if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID)
    412         {
    413             BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
    414         }
    415 #if (defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
    416         bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
    417 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    418 #endif  // (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
    419 
    420         BTM_SecRegister((tBTM_APPL_INFO*)&bta_security);
    421         BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
    422         BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
    423         bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
    424         BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
    425         BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK|BTM_BL_ROLE_CHG_MASK);
    426 
    427 #if BLE_VND_INCLUDED == TRUE
    428         BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
    429 #endif
    430 
    431         /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr
    432            from the control block and invoking the callback which was sending the DM_ENABLE_EVT.
    433            But then we have a few HCI commands being invoked above which were still in progress
    434            when the ENABLE_EVT was sent. So modified this to fetch the local name which forces
    435            the DM_ENABLE_EVT to be sent only after all the init steps are complete */
    436         BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback);
    437 
    438         bta_sys_rm_register((tBTA_SYS_CONN_CBACK*)bta_dm_rm_cback);
    439 
    440         /* initialize bluetooth low power manager */
    441         bta_dm_init_pm();
    442 
    443         bta_sys_policy_register((tBTA_SYS_CONN_CBACK*)bta_dm_policy_cback);
    444 
    445 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
    446         bta_dm_gattc_register();
    447 #endif
    448 
    449     }
    450     else
    451         APPL_TRACE_DEBUG(" --- ignored event");
    452 
    453 }
    454 
    455 
    456 /*******************************************************************************
    457 **
    458 ** Function         bta_dm_disable
    459 **
    460 ** Description      Disables the BT device manager
    461 **
    462 **
    463 ** Returns          void
    464 **
    465 *******************************************************************************/
    466 void bta_dm_disable (tBTA_DM_MSG *p_data)
    467 {
    468     UNUSED(p_data);
    469 
    470     /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
    471     L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR);
    472     L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_LE);
    473 
    474     /* disable all active subsystems */
    475     bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
    476 
    477     BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
    478     BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0);
    479 
    480     bta_dm_disable_pm();
    481     bta_dm_disable_search_and_disc();
    482     bta_dm_cb.disabling = TRUE;
    483 
    484 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
    485     BTM_BleClearBgConnDev();
    486 #endif
    487 
    488     if(BTM_GetNumAclLinks()==0)
    489     {
    490 #if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
    491         /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
    492          * BTA_DISABLE_DELAY milliseconds
    493          */
    494         APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms",
    495                             __FUNCTION__, BTA_DISABLE_DELAY);
    496         alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY,
    497                            bta_dm_disable_conn_down_timer_cback, NULL,
    498                            btu_bta_alarm_queue);
    499 #else
    500         bta_dm_disable_conn_down_timer_cback(NULL);
    501 #endif
    502     }
    503     else
    504     {
    505         alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS,
    506                            bta_dm_disable_timer_cback, UINT_TO_PTR(0),
    507                            btu_bta_alarm_queue);
    508     }
    509 }
    510 
    511 /*******************************************************************************
    512 **
    513 ** Function         bta_dm_disable_timer_cback
    514 **
    515 ** Description      Called if the disable timer expires
    516 **                  Used to close ACL connections which are still active
    517 **
    518 **
    519 **
    520 ** Returns          void
    521 **
    522 *******************************************************************************/
    523 static void bta_dm_disable_timer_cback(void *data)
    524 {
    525     UINT8 i;
    526     tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
    527     BOOLEAN trigger_disc = FALSE;
    528     uint32_t param = PTR_TO_UINT(data);
    529 
    530     APPL_TRACE_EVENT("%s trial %u", __func__, param);
    531 
    532     if (BTM_GetNumAclLinks() && (param == 0))
    533     {
    534         for(i=0; i<bta_dm_cb.device_list.count; i++)
    535         {
    536 #if (BLE_INCLUDED == TRUE)
    537             transport = bta_dm_cb.device_list.peer_device[i].transport;
    538 #endif
    539             btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
    540             trigger_disc = TRUE;
    541         }
    542 
    543         /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need
    544             to be sent out to avoid jave layer disable timeout */
    545         if (trigger_disc)
    546         {
    547             alarm_set_on_queue(bta_dm_cb.disable_timer,
    548                                BTA_DM_DISABLE_TIMER_RETRIAL_MS,
    549                                bta_dm_disable_timer_cback, UINT_TO_PTR(1),
    550                                btu_bta_alarm_queue);
    551         }
    552     }
    553     else
    554     {
    555         bta_dm_cb.disabling = FALSE;
    556 
    557         bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
    558         bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
    559     }
    560 }
    561 
    562 
    563 
    564 
    565 /*******************************************************************************
    566 **
    567 ** Function         bta_dm_set_dev_name
    568 **
    569 ** Description      Sets local device name
    570 **
    571 **
    572 ** Returns          void
    573 **
    574 *******************************************************************************/
    575 void bta_dm_set_dev_name (tBTA_DM_MSG *p_data)
    576 {
    577 
    578     BTM_SetLocalDeviceName((char*)p_data->set_name.name);
    579     bta_dm_set_eir ((char*)p_data->set_name.name);
    580 }
    581 
    582 /*******************************************************************************
    583 **
    584 ** Function         bta_dm_set_visibility
    585 **
    586 ** Description      Sets discoverability, connectability and pairability
    587 **
    588 **
    589 ** Returns          void
    590 **
    591 *******************************************************************************/
    592 void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
    593 {
    594     UINT16 window, interval;
    595 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    596     UINT16 le_disc_mode = BTM_BleReadDiscoverability();
    597     UINT16 le_conn_mode = BTM_BleReadConnectability();
    598 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    599     UINT16 disc_mode = BTM_ReadDiscoverability(&window, &interval);
    600     UINT16 conn_mode = BTM_ReadConnectability(&window, &interval);
    601 
    602     /* set modes for Discoverability and connectability if not ignore */
    603     if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE))
    604     {
    605 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    606         if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
    607             p_data->set_visibility.disc_mode =
    608                 ((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode);
    609 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    610         if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
    611             p_data->set_visibility.disc_mode =
    612                 ((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode);
    613 
    614         BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
    615                                 bta_dm_cb.inquiry_scan_window,
    616                                 bta_dm_cb.inquiry_scan_interval);
    617     }
    618 
    619     if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE))
    620     {
    621 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    622         if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
    623             p_data->set_visibility.conn_mode =
    624                 ((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode);
    625 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    626         if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
    627             p_data->set_visibility.conn_mode =
    628                 ((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode);
    629 
    630         BTM_SetConnectability(p_data->set_visibility.conn_mode,
    631                                 bta_dm_cb.page_scan_window,
    632                                 bta_dm_cb.page_scan_interval);
    633     }
    634 
    635     /* Send False or True if not ignore */
    636     if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE )
    637     {
    638 
    639         if (p_data->set_visibility.pair_mode == BTA_DM_NON_PAIRABLE)
    640             bta_dm_cb.disable_pair_mode = TRUE;
    641         else
    642             bta_dm_cb.disable_pair_mode = FALSE;
    643 
    644     }
    645 
    646     /* Send False or True if not ignore */
    647     if (p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE)
    648     {
    649 
    650         if (p_data->set_visibility.conn_paired_only == BTA_DM_CONN_ALL)
    651             bta_dm_cb.conn_paired_only = FALSE;
    652         else
    653             bta_dm_cb.conn_paired_only = TRUE;
    654 
    655     }
    656 
    657     /* Change mode if either mode is not ignore */
    658     if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE)
    659         BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)),bta_dm_cb.conn_paired_only);
    660 
    661 }
    662 
    663 /*******************************************************************************
    664 **
    665 ** Function         bta_dm_process_remove_device
    666 **
    667 ** Description      Removes device, Disconnects ACL link if required.
    668 ****
    669 *******************************************************************************/
    670 void bta_dm_process_remove_device(BD_ADDR bd_addr)
    671 {
    672 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
    673      /* need to remove all pending background connection before unpair */
    674      BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
    675 #endif
    676 
    677      BTM_SecDeleteDevice(bd_addr);
    678 
    679 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
    680       /* remove all cached GATT information */
    681       BTA_GATTC_Refresh(bd_addr);
    682 #endif
    683 
    684       if (bta_dm_cb.p_sec_cback)
    685       {
    686          tBTA_DM_SEC sec_event;
    687          bdcpy(sec_event.link_down.bd_addr, bd_addr);
    688          /* No connection, set status to success (acl disc code not valid) */
    689          sec_event.link_down.status = HCI_SUCCESS;
    690          bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
    691       }
    692 }
    693 
    694 /*******************************************************************************
    695 **
    696 ** Function         bta_dm_remove_device
    697 **
    698 ** Description      Removes device, disconnects ACL link if required.
    699 ****
    700 *******************************************************************************/
    701 void bta_dm_remove_device(tBTA_DM_MSG *p_data)
    702 {
    703     tBTA_DM_API_REMOVE_DEVICE *p_dev = &p_data->remove_dev;
    704     BOOLEAN continue_delete_other_dev = FALSE;
    705     if (p_dev == NULL)
    706         return;
    707 
    708     BD_ADDR other_address;
    709     bdcpy(other_address, p_dev->bd_addr);
    710 
    711     /* If ACL exists for the device in the remove_bond message*/
    712     BOOLEAN continue_delete_dev = FALSE;
    713     UINT8 other_transport = BT_TRANSPORT_INVALID;
    714 
    715     if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
    716         BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR))
    717     {
    718         APPL_TRACE_DEBUG("%s: ACL Up count  %d", __func__, bta_dm_cb.device_list.count);
    719         continue_delete_dev = FALSE;
    720 
    721         /* Take the link down first, and mark the device for removal when disconnected */
    722         for(int i=0; i < bta_dm_cb.device_list.count; i++)
    723         {
    724             if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr))
    725             {
    726                 UINT8 transport = BT_TRANSPORT_BR_EDR;
    727 
    728 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    729                 transport = bta_dm_cb.device_list.peer_device[i].transport;
    730 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    731                 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
    732                 btm_remove_acl(p_dev->bd_addr, transport);
    733 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    734                 APPL_TRACE_DEBUG("%s:transport = %d", __func__,
    735                                   bta_dm_cb.device_list.peer_device[i].transport);
    736 
    737                 /* save the other transport to check if device is connected on other_transport */
    738                 if(bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE)
    739                    other_transport = BT_TRANSPORT_BR_EDR;
    740                 else
    741                    other_transport = BT_TRANSPORT_LE;
    742 #endif  // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    743 
    744                 break;
    745             }
    746         }
    747     }
    748     else
    749     {
    750         continue_delete_dev = TRUE;
    751     }
    752 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
    753     // If it is DUMO device and device is paired as different address, unpair that device
    754     // if different address
    755     if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
    756       (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
    757        BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE))))
    758     {
    759         continue_delete_other_dev = FALSE;
    760         /* Take the link down first, and mark the device for removal when disconnected */
    761         for(int i=0; i < bta_dm_cb.device_list.count; i++)
    762         {
    763             if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address))
    764             {
    765                 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
    766                 btm_remove_acl(other_address,bta_dm_cb.device_list.peer_device[i].transport);
    767                 break;
    768             }
    769         }
    770     }
    771     else
    772     {
    773         APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
    774         continue_delete_other_dev = TRUE;
    775     }
    776 #endif
    777     /* Delete the device mentioned in the msg */
    778     if (continue_delete_dev)
    779         bta_dm_process_remove_device(p_dev->bd_addr);
    780 
    781     /* Delete the other paired device too */
    782     BD_ADDR dummy_bda = {0};
    783     if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0))
    784         bta_dm_process_remove_device(other_address);
    785 }
    786 
    787 /*******************************************************************************
    788 **
    789 ** Function         bta_dm_add_device
    790 **
    791 ** Description      This function adds a Link Key to an security database entry.
    792 **                  It is normally called during host startup to restore all required information
    793 **                  stored in the NVRAM.
    794 ****
    795 *******************************************************************************/
    796 void bta_dm_add_device (tBTA_DM_MSG *p_data)
    797 {
    798     tBTA_DM_API_ADD_DEVICE *p_dev = &p_data->add_dev;
    799     UINT8   *p_dc = NULL;
    800     UINT8   *p_lc = NULL;
    801     UINT32  trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
    802     UINT8   index = 0;
    803     UINT8   btm_mask_index = 0;
    804 
    805     memset (trusted_services_mask, 0, sizeof(trusted_services_mask));
    806 
    807     /* If not all zeros, the device class has been specified */
    808     if (p_dev->dc_known)
    809         p_dc = (UINT8 *)p_dev->dc;
    810 
    811     if (p_dev->link_key_known)
    812         p_lc = (UINT8 *)p_dev->link_key;
    813 
    814     if (p_dev->is_trusted)
    815     {
    816         /* covert BTA service mask to BTM mask */
    817         while (p_dev->tm && (index < BTA_MAX_SERVICE_ID))
    818         {
    819             if (p_dev->tm & (UINT32)(1<<index))
    820             {
    821 
    822                 btm_mask_index =  bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS;
    823                 trusted_services_mask[btm_mask_index] |= (UINT32)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - (UINT32)(btm_mask_index * 32)));
    824 
    825                 p_dev->tm &= (UINT32)(~(1<<index));
    826 
    827             }
    828             index++;
    829         }
    830     }
    831 
    832     if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
    833                            trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap,
    834                            p_dev->pin_length))
    835     {
    836         APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
    837                 (p_dev->bd_addr[0]<<24)+(p_dev->bd_addr[1]<<16)+(p_dev->bd_addr[2]<<8)+p_dev->bd_addr[3],
    838                 (p_dev->bd_addr[4]<<8)+p_dev->bd_addr[5]);
    839     }
    840 }
    841 
    842 /*******************************************************************************
    843 **
    844 ** Function         bta_dm_close_acl
    845 **
    846 ** Description      This function forces to close the connection to a remote device
    847 **                  and optionaly remove the device from security database if
    848 **                  required.
    849 ****
    850 *******************************************************************************/
    851 void bta_dm_close_acl(tBTA_DM_MSG *p_data)
    852 {
    853     tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
    854     UINT8   index;
    855 
    856     APPL_TRACE_DEBUG("bta_dm_close_acl");
    857 
    858     if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport))
    859     {
    860         for (index = 0; index < bta_dm_cb.device_list.count; index ++)
    861         {
    862             if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr))
    863                 break;
    864             }
    865         if (index != bta_dm_cb.device_list.count)
    866         {
    867             if (p_remove_acl->remove_dev)
    868                 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
    869         }
    870         else
    871         {
    872             APPL_TRACE_ERROR("unknown device, remove ACL failed");
    873         }
    874         /* Disconnect the ACL link */
    875         btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport);
    876     }
    877     /* if to remove the device from security database ? do it now */
    878     else if (p_remove_acl->remove_dev)
    879     {
    880         if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr))
    881         {
    882             APPL_TRACE_ERROR("delete device from security database failed.");
    883         }
    884 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
    885         /* need to remove all pending background connection if any */
    886         BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
    887         /* remove all cached GATT information */
    888         BTA_GATTC_Refresh(p_remove_acl->bd_addr);
    889 #endif
    890     }
    891     /* otherwise, no action needed */
    892 
    893 }
    894 
    895 /*******************************************************************************
    896 **
    897 ** Function         bta_dm_remove_all_acl
    898 **
    899 ** Description      This function forces to close all the ACL links specified by link type
    900 ****
    901 *******************************************************************************/
    902 void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data)
    903 {
    904     const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type;
    905     tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
    906 
    907     APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
    908 
    909     for (UINT8 i=0; i < bta_dm_cb.device_list.count; i++)
    910     {
    911         BD_ADDR addr = {0};
    912         bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
    913 #if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
    914         transport = bta_dm_cb.device_list.peer_device[i].transport;
    915 #endif
    916         if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
    917             ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) ||
    918             ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR)))
    919         {
    920             /* Disconnect the ACL link */
    921             btm_remove_acl(addr, transport);
    922         }
    923     }
    924 }
    925 
    926 
    927 /*******************************************************************************
    928 **
    929 ** Function         bta_dm_bond
    930 **
    931 ** Description      Bonds with peer device
    932 **
    933 **
    934 ** Returns          void
    935 **
    936 *******************************************************************************/
    937 void bta_dm_bond (tBTA_DM_MSG *p_data)
    938 {
    939     tBTM_STATUS status;
    940     tBTA_DM_SEC sec_event;
    941     char        *p_name;
    942 
    943     if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN)
    944         status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
    945     else
    946         status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
    947 
    948 
    949     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
    950     {
    951 
    952         memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
    953         bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
    954         p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
    955         if (p_name != NULL)
    956         {
    957             memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
    958             sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
    959         }
    960 
    961 /*      taken care of by memset [above]
    962         sec_event.auth_cmpl.key_present = FALSE;
    963         sec_event.auth_cmpl.success = FALSE;
    964 */
    965         sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
    966         if (status == BTM_SUCCESS)
    967         {
    968             sec_event.auth_cmpl.success = TRUE;
    969         }
    970         else
    971         {
    972             /* delete this device entry from Sec Dev DB */
    973             bta_dm_remove_sec_dev_entry(p_data->bond.bd_addr);
    974         }
    975         bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
    976     }
    977 
    978 }
    979 
    980 /*******************************************************************************
    981 **
    982 ** Function         bta_dm_bond_cancel
    983 **
    984 ** Description      Cancels bonding with a peer device
    985 **
    986 **
    987 ** Returns          void
    988 **
    989 *******************************************************************************/
    990 void bta_dm_bond_cancel (tBTA_DM_MSG *p_data)
    991 {
    992     tBTM_STATUS status;
    993     tBTA_DM_SEC sec_event;
    994 
    995     APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
    996     status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr );
    997 
    998     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS))
    999     {
   1000         sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
   1001 
   1002         bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
   1003     }
   1004 
   1005 }
   1006 
   1007 /*******************************************************************************
   1008 **
   1009 ** Function         bta_dm_pin_reply
   1010 **
   1011 ** Description      Send the pin_reply to a request from BTM
   1012 **
   1013 **
   1014 ** Returns          void
   1015 **
   1016 *******************************************************************************/
   1017 void bta_dm_pin_reply (tBTA_DM_MSG *p_data)
   1018 {
   1019     UINT32  trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
   1020     UINT32  * current_trusted_mask;
   1021 
   1022     current_trusted_mask = BTM_ReadTrustedMask(p_data->pin_reply.bd_addr);
   1023 
   1024     if(current_trusted_mask)
   1025     {
   1026         memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask));
   1027     }
   1028     else
   1029     {
   1030         memset(trusted_mask, 0, sizeof(trusted_mask));
   1031     }
   1032 
   1033     if(p_data->pin_reply.accept)
   1034     {
   1035 
   1036         BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_SUCCESS, p_data->pin_reply.pin_len, p_data->pin_reply.p_pin, trusted_mask );
   1037     }
   1038     else
   1039     {
   1040         BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask );
   1041     }
   1042 
   1043 }
   1044 
   1045 /*******************************************************************************
   1046 **
   1047 ** Function         bta_dm_policy_cback
   1048 **
   1049 ** Description      process the link policy changes
   1050 **
   1051 ** Returns          void
   1052 **
   1053 *******************************************************************************/
   1054 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
   1055 {
   1056     tBTA_DM_PEER_DEVICE *p_dev = NULL;
   1057     UINT16  policy = app_id;
   1058     UINT32  mask = (UINT32)(1 << id);
   1059 
   1060     if(peer_addr)
   1061         p_dev = bta_dm_find_peer_device(peer_addr);
   1062 
   1063     APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x",
   1064         status, policy);
   1065     switch(status)
   1066     {
   1067     case BTA_SYS_PLCY_SET:
   1068         if(!p_dev)
   1069             return;
   1070         /* restore the default link policy */
   1071         p_dev->link_policy |= policy;
   1072         BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
   1073         break;
   1074 
   1075     case BTA_SYS_PLCY_CLR:
   1076         if(!p_dev)
   1077             return;
   1078         /* clear the policy from the default link policy */
   1079         p_dev->link_policy &= (~policy);
   1080         BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
   1081 
   1082         if(policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE))
   1083         {
   1084             /* if clearing sniff/park, wake the link */
   1085             bta_dm_pm_active(p_dev->peer_bdaddr);
   1086         }
   1087         break;
   1088 
   1089     case BTA_SYS_PLCY_DEF_SET:
   1090         /* want to restore/set the role switch policy */
   1091         bta_dm_cb.role_policy_mask &= ~mask;
   1092         if(0 == bta_dm_cb.role_policy_mask)
   1093         {
   1094             /* if nobody wants to insist on the role */
   1095             bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
   1096             BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
   1097         }
   1098         break;
   1099 
   1100     case BTA_SYS_PLCY_DEF_CLR:
   1101         /* want to remove the role switch policy */
   1102         bta_dm_cb.role_policy_mask |= mask;
   1103         bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
   1104         BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
   1105         break;
   1106     }
   1107 }
   1108 
   1109 /*******************************************************************************
   1110 **
   1111 ** Function         bta_dm_confirm
   1112 **
   1113 ** Description      Send the user confirm request reply in response to a
   1114 **                  request from BTM
   1115 **
   1116 ** Returns          void
   1117 **
   1118 *******************************************************************************/
   1119 void bta_dm_confirm(tBTA_DM_MSG *p_data)
   1120 {
   1121     tBTM_STATUS res = BTM_NOT_AUTHORIZED;
   1122 
   1123     if(p_data->confirm.accept == TRUE)
   1124         res = BTM_SUCCESS;
   1125     BTM_ConfirmReqReply(res, p_data->confirm.bd_addr);
   1126 }
   1127 
   1128 /*******************************************************************************
   1129 **
   1130 ** Function         bta_dm_loc_oob
   1131 **
   1132 ** Description      Retrieve the OOB data from the local LM
   1133 **
   1134 ** Returns          void
   1135 **
   1136 *******************************************************************************/
   1137 void bta_dm_loc_oob(tBTA_DM_MSG *p_data)
   1138 {
   1139     UNUSED(p_data);
   1140     BTM_ReadLocalOobData();
   1141 }
   1142 
   1143 /*******************************************************************************
   1144 **
   1145 ** Function         bta_dm_ci_io_req_act
   1146 **
   1147 ** Description      respond to the IO capabilities request from BTM
   1148 **
   1149 ** Returns          void
   1150 **
   1151 *******************************************************************************/
   1152 void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data)
   1153 {
   1154     tBTM_AUTH_REQ   auth_req = BTM_AUTH_AP_NO;
   1155     if(p_data->ci_io_req.auth_req)
   1156         auth_req = BTM_AUTH_AP_YES;
   1157     BTM_IoCapRsp(p_data->ci_io_req.bd_addr, p_data->ci_io_req.io_cap,
   1158         p_data->ci_io_req.oob_data, auth_req);
   1159 }
   1160 
   1161 /*******************************************************************************
   1162 **
   1163 ** Function         bta_dm_ci_rmt_oob_act
   1164 **
   1165 ** Description      respond to the OOB data request for the remote device from BTM
   1166 **
   1167 **
   1168 ** Returns          void
   1169 **
   1170 *******************************************************************************/
   1171 void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data)
   1172 {
   1173     tBTM_STATUS res = BTM_NOT_AUTHORIZED;
   1174 
   1175     if(p_data->ci_rmt_oob.accept == TRUE)
   1176         res = BTM_SUCCESS;
   1177     BTM_RemoteOobDataReply(res, p_data->ci_rmt_oob.bd_addr,
   1178         p_data->ci_rmt_oob.c, p_data->ci_rmt_oob.r );
   1179 }
   1180 
   1181 /*******************************************************************************
   1182 **
   1183 ** Function         bta_dm_search_start
   1184 **
   1185 ** Description      Starts an inquiry
   1186 **
   1187 **
   1188 ** Returns          void
   1189 **
   1190 *******************************************************************************/
   1191 void bta_dm_search_start (tBTA_DM_MSG *p_data)
   1192 {
   1193     tBTM_INQUIRY_CMPL result;
   1194 
   1195 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
   1196     size_t len = sizeof(tBT_UUID) * p_data->search.num_uuid;
   1197     bta_dm_gattc_register();
   1198 #endif
   1199 
   1200     APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter);
   1201 
   1202     if (p_bta_dm_cfg->avoid_scatter &&
   1203         (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT))
   1204     {
   1205         memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH));
   1206         return;
   1207     }
   1208 
   1209     BTM_ClearInqDb(NULL);
   1210     /* save search params */
   1211     bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
   1212     bta_dm_search_cb.services = p_data->search.services;
   1213 
   1214 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
   1215     osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
   1216 
   1217     if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 &&
   1218          p_data->search.p_uuid != NULL) {
   1219         bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len);
   1220         memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len);
   1221     }
   1222 #endif
   1223     result.status = BTM_StartInquiry(   (tBTM_INQ_PARMS*)&p_data->search.inq_params,
   1224                         bta_dm_inq_results_cb,
   1225                         (tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb);
   1226 
   1227     APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
   1228     if (result.status != BTM_CMD_STARTED)
   1229     {
   1230         result.num_resp = 0;
   1231         bta_dm_inq_cmpl_cb ((void *)&result);
   1232     }
   1233 }
   1234 
   1235 /*******************************************************************************
   1236 **
   1237 ** Function         bta_dm_search_cancel
   1238 **
   1239 ** Description      Cancels an ongoing search for devices
   1240 **
   1241 **
   1242 ** Returns          void
   1243 **
   1244 *******************************************************************************/
   1245 void bta_dm_search_cancel (tBTA_DM_MSG *p_data)
   1246 {
   1247     UNUSED(p_data);
   1248     tBTA_DM_MSG *p_msg;
   1249 
   1250     if (BTM_IsInquiryActive())
   1251     {
   1252         if (BTM_CancelInquiry() == BTM_SUCCESS)
   1253         {
   1254             bta_dm_search_cancel_notify(NULL);
   1255             p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1256             p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1257             p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   1258             bta_sys_sendmsg(p_msg);
   1259         } else {
   1260             /* flag a search cancel is pending */
   1261             bta_dm_search_cb.cancel_pending = TRUE;
   1262         }
   1263     }
   1264     /* If no Service Search going on then issue cancel remote name in case it is active */
   1265     else if (!bta_dm_search_cb.name_discover_done)
   1266     {
   1267         BTM_CancelRemoteDeviceName();
   1268 
   1269         p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1270         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1271         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   1272         bta_sys_sendmsg(p_msg);
   1273     } else {
   1274         p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1275         p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
   1276         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   1277         bta_sys_sendmsg(p_msg);
   1278     }
   1279 
   1280 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1281     if (bta_dm_search_cb.gatt_disc_active)
   1282     {
   1283         bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
   1284     }
   1285 #endif
   1286 }
   1287 
   1288 /*******************************************************************************
   1289 **
   1290 ** Function         bta_dm_discover
   1291 **
   1292 ** Description      Discovers services on a remote device
   1293 **
   1294 **
   1295 ** Returns          void
   1296 **
   1297 *******************************************************************************/
   1298 void bta_dm_discover (tBTA_DM_MSG *p_data)
   1299 {
   1300 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1301     size_t len = sizeof(tBT_UUID) * p_data->discover.num_uuid;
   1302 #endif
   1303     APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__,
   1304                       p_data->discover.services, p_data->discover.sdp_search);
   1305 
   1306     /* save the search condition */
   1307     bta_dm_search_cb.services = p_data->discover.services;
   1308 
   1309 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1310     bta_dm_gattc_register();
   1311     osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
   1312     if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 &&
   1313         p_data->discover.p_uuid != NULL) {
   1314         bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len);
   1315         memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->discover.p_uuid, len);
   1316     }
   1317     bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
   1318 #endif
   1319 
   1320     bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
   1321     bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
   1322     bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
   1323     bta_dm_search_cb.service_index = 0;
   1324     bta_dm_search_cb.services_found = 0;
   1325     bta_dm_search_cb.peer_name[0] = 0;
   1326     bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
   1327     bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
   1328     bta_dm_search_cb.transport = p_data->discover.transport;
   1329 
   1330     bta_dm_search_cb.name_discover_done = FALSE;
   1331     memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
   1332     bta_dm_discover_device(p_data->discover.bd_addr);
   1333 }
   1334 
   1335 /*******************************************************************************
   1336 **
   1337 ** Function         bta_dm_di_disc_cmpl
   1338 **
   1339 ** Description      Sends event to application when DI discovery complete
   1340 **
   1341 ** Returns          void
   1342 **
   1343 *******************************************************************************/
   1344 void bta_dm_di_disc_cmpl(tBTA_DM_MSG *p_data)
   1345 {
   1346     tBTA_DM_DI_DISC_CMPL    di_disc;
   1347 
   1348     memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
   1349     bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
   1350 
   1351     if((p_data->hdr.offset == SDP_SUCCESS)
   1352         || (p_data->hdr.offset == SDP_DB_FULL))
   1353     {
   1354         di_disc.num_record  = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db);
   1355     }
   1356     else
   1357         di_disc.result      = BTA_FAILURE;
   1358 
   1359     bta_dm_di_cb.p_di_db = NULL;
   1360     bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, (tBTA_DM_SEARCH *) &di_disc);
   1361 }
   1362 
   1363 /*******************************************************************************
   1364 **
   1365 ** Function         bta_dm_di_disc_callback
   1366 **
   1367 ** Description      This function queries a remote device for DI information.
   1368 **
   1369 **
   1370 ** Returns          void
   1371 **
   1372 *******************************************************************************/
   1373 static void bta_dm_di_disc_callback(UINT16 result)
   1374 {
   1375     tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1376 
   1377     p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1378     p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
   1379     p_msg->hdr.offset = result;
   1380 
   1381     bta_sys_sendmsg(p_msg);
   1382 }
   1383 
   1384 /*******************************************************************************
   1385 **
   1386 ** Function         bta_dm_disable_search_and_disc
   1387 **
   1388 ** Description      Cancels an ongoing search or discovery for devices in case of
   1389 **                  a Bluetooth disable
   1390 **
   1391 **
   1392 ** Returns          void
   1393 **
   1394 *******************************************************************************/
   1395 static void bta_dm_disable_search_and_disc (void)
   1396 {
   1397     tBTA_DM_DI_DISC_CMPL    di_disc;
   1398 
   1399     if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
   1400         bta_dm_search_cancel(NULL);
   1401 
   1402     if (bta_dm_di_cb.p_di_db != NULL)
   1403     {
   1404         memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
   1405         bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
   1406         di_disc.result      = BTA_FAILURE;
   1407 
   1408         bta_dm_di_cb.p_di_db = NULL;
   1409         bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL);
   1410     }
   1411 }
   1412 
   1413 /*******************************************************************************
   1414 **
   1415 ** Function         bta_dm_di_disc
   1416 **
   1417 ** Description      This function queries a remote device for DI information.
   1418 **
   1419 **
   1420 ** Returns          void
   1421 **
   1422 *******************************************************************************/
   1423 void bta_dm_di_disc (tBTA_DM_MSG *p_data)
   1424 {
   1425     UINT16  result = BTA_FAILURE;
   1426 
   1427     bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
   1428     bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr);
   1429     bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
   1430 
   1431     bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE);
   1432     if (SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db,
   1433                        p_data->di_disc.len,
   1434                        bta_dm_di_disc_callback) == SDP_SUCCESS) {
   1435         result = BTA_SUCCESS;
   1436     }
   1437 
   1438     if (result == BTA_FAILURE) {
   1439         tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1440 
   1441         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1442         p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
   1443         p_data->hdr.offset = result;
   1444         bta_sys_sendmsg(p_msg);
   1445     }
   1446 }
   1447 
   1448 /*******************************************************************************
   1449 **
   1450 ** Function         bta_dm_read_remote_device_name
   1451 **
   1452 ** Description      Initiate to get remote device name
   1453 **
   1454 ** Returns          TRUE if started to get remote name
   1455 **
   1456 *******************************************************************************/
   1457 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport)
   1458 {
   1459     tBTM_STATUS  btm_status;
   1460 
   1461     APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
   1462 
   1463     bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
   1464     bta_dm_search_cb.peer_name[0] = 0;
   1465 
   1466     btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
   1467                                            (tBTM_CMPL_CB *) bta_dm_remname_cback,
   1468                                            transport);
   1469 
   1470     if ( btm_status == BTM_CMD_STARTED )
   1471     {
   1472         APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
   1473 
   1474         return (TRUE);
   1475     }
   1476     else if ( btm_status == BTM_BUSY )
   1477     {
   1478         APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
   1479 
   1480         /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */
   1481         /* adding callback to get notified that current reading remore name done */
   1482         BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
   1483 
   1484         return (TRUE);
   1485     }
   1486     else
   1487     {
   1488         APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
   1489 
   1490         return (FALSE);
   1491     }
   1492 }
   1493 
   1494 /*******************************************************************************
   1495 **
   1496 ** Function         bta_dm_inq_cmpl
   1497 **
   1498 ** Description      Process the inquiry complete event from BTM
   1499 **
   1500 ** Returns          void
   1501 **
   1502 *******************************************************************************/
   1503 void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data)
   1504 {
   1505     tBTA_DM_SEARCH  data;
   1506 
   1507     APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
   1508 
   1509     data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
   1510     bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
   1511 
   1512     if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL)
   1513     {
   1514         /* start name and service discovery from the first device on inquiry result */
   1515         bta_dm_search_cb.name_discover_done = FALSE;
   1516         bta_dm_search_cb.peer_name[0]       = 0;
   1517         bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
   1518     } else {
   1519         tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1520 
   1521         /* no devices, search complete */
   1522         bta_dm_search_cb.services = 0;
   1523 
   1524         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1525         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   1526         bta_sys_sendmsg(p_msg);
   1527     }
   1528 }
   1529 
   1530 /*******************************************************************************
   1531 **
   1532 ** Function         bta_dm_rmt_name
   1533 **
   1534 ** Description      Process the remote name result from BTM
   1535 **
   1536 ** Returns          void
   1537 **
   1538 *******************************************************************************/
   1539 void bta_dm_rmt_name (tBTA_DM_MSG *p_data)
   1540 {
   1541     APPL_TRACE_DEBUG("bta_dm_rmt_name");
   1542 
   1543     if( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info)
   1544     {
   1545         bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = TRUE;
   1546     }
   1547 
   1548     bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
   1549 }
   1550 
   1551 /*******************************************************************************
   1552 **
   1553 ** Function         bta_dm_disc_rmt_name
   1554 **
   1555 ** Description      Process the remote name result from BTM when application
   1556 **                  wants to find the name for a bdaddr
   1557 **
   1558 ** Returns          void
   1559 **
   1560 *******************************************************************************/
   1561 void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data)
   1562 {
   1563     tBTM_INQ_INFO *p_btm_inq_info;
   1564 
   1565     APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
   1566 
   1567     p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr);
   1568     if( p_btm_inq_info )
   1569     {
   1570         if( p_data->rem_name.result.disc_res.bd_name[0] )
   1571         {
   1572             p_btm_inq_info->appl_knows_rem_name = TRUE;
   1573         }
   1574     }
   1575 
   1576     bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
   1577 }
   1578 
   1579 /*******************************************************************************
   1580 **
   1581 ** Function         bta_dm_sdp_result
   1582 **
   1583 ** Description      Process the discovery result from sdp
   1584 **
   1585 ** Returns          void
   1586 **
   1587 *******************************************************************************/
   1588 void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
   1589 {
   1590 
   1591     tSDP_DISC_REC   *p_sdp_rec = NULL;
   1592     tBTA_DM_MSG     *p_msg;
   1593     BOOLEAN          scn_found = FALSE;
   1594     UINT16           service = 0xFFFF;
   1595     tSDP_PROTOCOL_ELEM  pe;
   1596 
   1597 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1598     tBT_UUID           *p_uuid = bta_dm_search_cb.p_srvc_uuid;
   1599     tBTA_DM_SEARCH      result;
   1600     tBT_UUID            service_uuid;
   1601 #endif
   1602 
   1603     UINT32 num_uuids = 0;
   1604     UINT8  uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
   1605 
   1606     if((p_data->sdp_event.sdp_result == SDP_SUCCESS)
   1607         || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
   1608         || (p_data->sdp_event.sdp_result == SDP_DB_FULL))
   1609     {
   1610         APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
   1611         do
   1612         {
   1613 
   1614             p_sdp_rec = NULL;
   1615             if( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID+1) )
   1616             {
   1617                 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
   1618 
   1619                 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe))
   1620                 {
   1621                     bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
   1622                     scn_found = TRUE;
   1623                 }
   1624             }
   1625             else
   1626             {
   1627                 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
   1628                 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
   1629             }
   1630 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1631             /* finished with BR/EDR services, now we check the result for GATT based service UUID */
   1632             if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID)
   1633             {
   1634                 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL)
   1635                 {
   1636                     p_uuid +=  (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
   1637                     /* only support 16 bits UUID for now */
   1638                     service = p_uuid->uu.uuid16;
   1639 
   1640                 }
   1641                 /* all GATT based services */
   1642                 do
   1643                 {
   1644                     /* find a service record, report it */
   1645                     p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
   1646                                                 0, p_sdp_rec);
   1647                     if (p_sdp_rec)
   1648                     {
   1649                         if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid))
   1650                         {
   1651                             /* send result back to app now, one by one */
   1652                             bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
   1653                             strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
   1654                             result.disc_ble_res.service.len = service_uuid.len;
   1655                             result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
   1656 
   1657                             bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
   1658                         }
   1659                     }
   1660 
   1661                     if (bta_dm_search_cb.uuid_to_search > 0)
   1662                         break;
   1663 
   1664                 } while (p_sdp_rec);
   1665             }
   1666             else
   1667 #endif
   1668             {
   1669                 /* SDP_DB_FULL means some records with the
   1670                    required attributes were received */
   1671                 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
   1672                         bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
   1673                         (p_sdp_rec != NULL))
   1674                 {
   1675                     if (service != UUID_SERVCLASS_PNP_INFORMATION)
   1676                     {
   1677                         UINT16 tmp_svc = 0xFFFF;
   1678                         bta_dm_search_cb.services_found |=
   1679                             (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index-1));
   1680                         tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
   1681                         /* Add to the list of UUIDs */
   1682                         sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
   1683                         num_uuids++;
   1684                     }
   1685                 }
   1686             }
   1687 
   1688             if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
   1689                 bta_dm_search_cb.services_to_search == 0)
   1690             {
   1691 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1692                 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
   1693                     bta_dm_search_cb.uuid_to_search > 0)
   1694                     bta_dm_search_cb.uuid_to_search --;
   1695 
   1696                 if (bta_dm_search_cb.uuid_to_search == 0 ||
   1697                     bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
   1698 #endif
   1699                     bta_dm_search_cb.service_index++;
   1700             }
   1701             else /* regular one service per search or PNP search */
   1702                 break;
   1703 
   1704         } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
   1705 
   1706         APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
   1707                          bta_dm_search_cb.services_found);
   1708 
   1709         /* Collect the 128-bit services here and put them into the list */
   1710         if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK)
   1711         {
   1712             p_sdp_rec = NULL;
   1713             do
   1714             {
   1715                 tBT_UUID temp_uuid;
   1716                 /* find a service record, report it */
   1717                 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
   1718                 if (p_sdp_rec)
   1719                 {
   1720                     if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid))
   1721                     {
   1722                         memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
   1723                         num_uuids++;
   1724                     }
   1725                 }
   1726             } while (p_sdp_rec);
   1727         }
   1728         /* if there are more services to search for */
   1729         if(bta_dm_search_cb.services_to_search)
   1730         {
   1731             /* Free up the p_sdp_db before checking the next one */
   1732             bta_dm_free_sdp_db(NULL);
   1733             bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
   1734         }
   1735         else
   1736         {
   1737             /* callbacks */
   1738             /* start next bd_addr if necessary */
   1739 
   1740             BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
   1741 
   1742             p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1743             p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
   1744             p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
   1745             p_msg->disc_result.result.disc_res.p_raw_data = NULL;
   1746             p_msg->disc_result.result.disc_res.raw_data_size = 0;
   1747             p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
   1748             p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
   1749             if (num_uuids > 0) {
   1750                 p_msg->disc_result.result.disc_res.p_uuid_list =
   1751                     (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
   1752                 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list,
   1753                        uuid_list, num_uuids * MAX_UUID_SIZE);
   1754             }
   1755             // Copy the raw_data to the discovery result structure
   1756             if (bta_dm_search_cb.p_sdp_db != NULL &&
   1757                 bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
   1758                 bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
   1759                 APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x",
   1760                                  __func__,
   1761                                  bta_dm_search_cb.p_sdp_db->raw_used,
   1762                                  bta_dm_search_cb.p_sdp_db->raw_data);
   1763 
   1764                 p_msg->disc_result.result.disc_res.p_raw_data =
   1765                     osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
   1766                 memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
   1767                        bta_dm_search_cb.p_sdp_db->raw_data,
   1768                        bta_dm_search_cb.p_sdp_db->raw_used);
   1769 
   1770                 p_msg->disc_result.result.disc_res.raw_data_size =
   1771                     bta_dm_search_cb.p_sdp_db->raw_used;
   1772 
   1773                 bta_dm_search_cb.p_sdp_db->raw_data = NULL;     //no need to free this - it is a global assigned.
   1774                 bta_dm_search_cb.p_sdp_db->raw_used = 0;
   1775                 bta_dm_search_cb.p_sdp_db->raw_size = 0;
   1776             } else {
   1777                 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!",
   1778                                  __func__);
   1779             }
   1780             /* Done with p_sdp_db. Free it */
   1781             bta_dm_free_sdp_db(NULL);
   1782             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
   1783 
   1784             // Piggy back the SCN over result field
   1785             if (scn_found) {
   1786                 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
   1787                 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
   1788 
   1789                 APPL_TRACE_EVENT(" Piggy back the SCN over result field  SCN=%d", bta_dm_search_cb.peer_scn);
   1790 
   1791             }
   1792             bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
   1793                   bta_dm_search_cb.peer_bdaddr);
   1794             strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
   1795                       bta_dm_get_remname(), BD_NAME_LEN);
   1796 
   1797             bta_sys_sendmsg(p_msg);
   1798         }
   1799     } else {
   1800         /* conn failed. No need for timer */
   1801         if(p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
   1802            || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR)
   1803             bta_dm_search_cb.wait_disc = FALSE;
   1804 
   1805         /* not able to connect go to next device */
   1806         if (bta_dm_search_cb.p_sdp_db)
   1807             osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
   1808 
   1809         BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
   1810 
   1811         p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1812         p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
   1813         p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
   1814         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
   1815         bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
   1816               bta_dm_search_cb.peer_bdaddr);
   1817         strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
   1818                 bta_dm_get_remname(), BD_NAME_LEN);
   1819 
   1820         bta_sys_sendmsg(p_msg);
   1821     }
   1822 }
   1823 
   1824 /*******************************************************************************
   1825 **
   1826 ** Function         bta_dm_search_cmpl
   1827 **
   1828 ** Description      Sends event to application
   1829 **
   1830 ** Returns          void
   1831 **
   1832 *******************************************************************************/
   1833 void bta_dm_search_cmpl(tBTA_DM_MSG *p_data)
   1834 {
   1835     APPL_TRACE_EVENT("%s", __func__);
   1836 
   1837 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
   1838     osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
   1839 #endif
   1840 
   1841     if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT)
   1842         bta_dm_di_disc_cmpl(p_data);
   1843     else
   1844         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
   1845 }
   1846 
   1847 /*******************************************************************************
   1848 **
   1849 ** Function         bta_dm_disc_result
   1850 **
   1851 ** Description      Service discovery result when discovering services on a device
   1852 **
   1853 ** Returns          void
   1854 **
   1855 *******************************************************************************/
   1856 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
   1857 {
   1858     APPL_TRACE_EVENT("%s", __func__);
   1859 
   1860 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   1861     /* if any BR/EDR service discovery has been done, report the event */
   1862     if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
   1863 #endif
   1864     bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
   1865 
   1866     tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   1867 
   1868     /* send a message to change state */
   1869     p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   1870     p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   1871     bta_sys_sendmsg(p_msg);
   1872 }
   1873 
   1874 /*******************************************************************************
   1875 **
   1876 ** Function         bta_dm_search_result
   1877 **
   1878 ** Description      Service discovery result while searching for devices
   1879 **
   1880 ** Returns          void
   1881 **
   1882 *******************************************************************************/
   1883 void bta_dm_search_result (tBTA_DM_MSG *p_data)
   1884 {
   1885     APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
   1886                        bta_dm_search_cb.services,
   1887                        p_data->disc_result.result.disc_res.services);
   1888 
   1889     /* call back if application wants name discovery or found services that application is searching */
   1890     if (( !bta_dm_search_cb.services )
   1891       ||(( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services )))
   1892     {
   1893         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
   1894     }
   1895 
   1896     /* if searching did not initiate to create link */
   1897     if(!bta_dm_search_cb.wait_disc )
   1898     {
   1899         /* if service searching is done with EIR, don't search next device */
   1900         if( bta_dm_search_cb.p_btm_inq_info )
   1901         bta_dm_discover_next_device();
   1902     }
   1903     else
   1904     {
   1905         /* wait until link is disconnected or timeout */
   1906         bta_dm_search_cb.sdp_results = TRUE;
   1907         alarm_set_on_queue(bta_dm_search_cb.search_timer,
   1908                            1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1),
   1909                            bta_dm_search_timer_cback, NULL,
   1910                            btu_bta_alarm_queue);
   1911     }
   1912 }
   1913 
   1914 /*******************************************************************************
   1915 **
   1916 ** Function         bta_dm_search_timer_cback
   1917 **
   1918 ** Description      Called when ACL disconnect time is over
   1919 **
   1920 **
   1921 ** Returns          void
   1922 **
   1923 *******************************************************************************/
   1924 static void bta_dm_search_timer_cback(UNUSED_ATTR void *data)
   1925 {
   1926     APPL_TRACE_EVENT("%s", __func__);
   1927     bta_dm_search_cb.wait_disc = FALSE;
   1928 
   1929     /* proceed with next device */
   1930     bta_dm_discover_next_device();
   1931 
   1932 }
   1933 
   1934 
   1935 /*******************************************************************************
   1936 **
   1937 ** Function         bta_dm_free_sdp_db
   1938 **
   1939 ** Description      Frees SDP data base
   1940 **
   1941 ** Returns          void
   1942 **
   1943 *******************************************************************************/
   1944 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
   1945 {
   1946     UNUSED(p_data);
   1947     osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
   1948 }
   1949 
   1950 /*******************************************************************************
   1951 **
   1952 ** Function         bta_dm_queue_search
   1953 **
   1954 ** Description      Queues search command while search is being cancelled
   1955 **
   1956 ** Returns          void
   1957 **
   1958 *******************************************************************************/
   1959 void bta_dm_queue_search(tBTA_DM_MSG *p_data)
   1960 {
   1961     osi_free(bta_dm_search_cb.p_search_queue);
   1962     bta_dm_search_cb.p_search_queue =
   1963       (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
   1964     memcpy(bta_dm_search_cb.p_search_queue, p_data,
   1965            sizeof(tBTA_DM_API_SEARCH));
   1966 }
   1967 
   1968 /*******************************************************************************
   1969 **
   1970 ** Function         bta_dm_queue_disc
   1971 **
   1972 ** Description      Queues discovery command while search is being cancelled
   1973 **
   1974 ** Returns          void
   1975 **
   1976 *******************************************************************************/
   1977 void bta_dm_queue_disc(tBTA_DM_MSG *p_data)
   1978 {
   1979     osi_free(bta_dm_search_cb.p_search_queue);
   1980     bta_dm_search_cb.p_search_queue =
   1981         (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
   1982     memcpy(bta_dm_search_cb.p_search_queue, p_data,
   1983            sizeof(tBTA_DM_API_DISCOVER));
   1984 }
   1985 
   1986 /*******************************************************************************
   1987 **
   1988 ** Function         bta_dm_search_clear_queue
   1989 **
   1990 ** Description      Clears the queue if API search cancel is called
   1991 **
   1992 ** Returns          void
   1993 **
   1994 *******************************************************************************/
   1995 void bta_dm_search_clear_queue(tBTA_DM_MSG *p_data)
   1996 {
   1997     UNUSED(p_data);
   1998     osi_free_and_reset((void **)&bta_dm_search_cb.p_search_queue);
   1999 }
   2000 
   2001 /*******************************************************************************
   2002 **
   2003 ** Function         bta_dm_search_cancel_cmpl
   2004 **
   2005 ** Description      Search cancel is complete
   2006 **
   2007 ** Returns          void
   2008 **
   2009 *******************************************************************************/
   2010 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
   2011 {
   2012     UNUSED(p_data);
   2013     if(bta_dm_search_cb.p_search_queue)
   2014     {
   2015         bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
   2016         bta_dm_search_cb.p_search_queue = NULL;
   2017     }
   2018 
   2019 }
   2020 
   2021 /*******************************************************************************
   2022 **
   2023 ** Function         bta_dm_search_cancel_transac_cmpl
   2024 **
   2025 ** Description      Current Service Discovery or remote name procedure is
   2026 **                  completed after search cancellation
   2027 **
   2028 ** Returns          void
   2029 **
   2030 *******************************************************************************/
   2031 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
   2032 {
   2033     UNUSED(p_data);
   2034 
   2035     osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
   2036     bta_dm_search_cancel_notify(NULL);
   2037 }
   2038 
   2039 
   2040 /*******************************************************************************
   2041 **
   2042 ** Function         bta_dm_search_cancel_notify
   2043 **
   2044 ** Description      Notify application that search has been cancelled
   2045 **
   2046 ** Returns          void
   2047 **
   2048 *******************************************************************************/
   2049 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
   2050 {
   2051     UNUSED(p_data);
   2052     if (bta_dm_search_cb.p_search_cback)
   2053     {
   2054         bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
   2055     }
   2056     if (!bta_dm_search_cb.name_discover_done)
   2057     {
   2058         BTM_CancelRemoteDeviceName();
   2059     }
   2060 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE)
   2061     if (bta_dm_search_cb.gatt_disc_active)
   2062     {
   2063         bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
   2064     }
   2065 #endif
   2066 
   2067 }
   2068 
   2069 /*******************************************************************************
   2070 **
   2071 ** Function         bta_dm_find_services
   2072 **
   2073 ** Description      Starts discovery on a device
   2074 **
   2075 ** Returns          void
   2076 **
   2077 *******************************************************************************/
   2078 static void bta_dm_find_services ( BD_ADDR bd_addr)
   2079 {
   2080 
   2081     tSDP_UUID    uuid;
   2082 
   2083     memset(&uuid, 0, sizeof(tSDP_UUID));
   2084 
   2085     while(bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID)
   2086     {
   2087         if( bta_dm_search_cb.services_to_search
   2088             & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)))
   2089         {
   2090             bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE);
   2091             APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
   2092             /* try to search all services by search based on L2CAP UUID */
   2093             if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
   2094                 LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__,
   2095                          bta_dm_search_cb.services_to_search);
   2096                 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
   2097                     uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
   2098                     bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
   2099                 } else {
   2100                     uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
   2101                     bta_dm_search_cb.services_to_search = 0;
   2102                 }
   2103             } else {
   2104 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   2105                 /* for LE only profile */
   2106                 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) {
   2107                     if (bta_dm_search_cb.uuid_to_search > 0 &&
   2108                         bta_dm_search_cb.p_srvc_uuid) {
   2109                         memcpy(&uuid,
   2110                                (const void *)(bta_dm_search_cb.p_srvc_uuid +
   2111                                               bta_dm_search_cb.num_uuid -
   2112                                               bta_dm_search_cb.uuid_to_search),
   2113                                sizeof(tBT_UUID));
   2114 
   2115                         bta_dm_search_cb.uuid_to_search--;
   2116                     } else {
   2117                         uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
   2118                     }
   2119 
   2120                     /* last one? clear the BLE service bit if all discovery has been done */
   2121                     if (bta_dm_search_cb.uuid_to_search == 0)
   2122                       bta_dm_search_cb.services_to_search &=
   2123                         (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
   2124 
   2125                 } else
   2126 #endif
   2127                 {
   2128                     /* remove the service from services to be searched  */
   2129                     bta_dm_search_cb.services_to_search &=
   2130                         (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
   2131                     uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
   2132                 }
   2133             }
   2134 
   2135             if (uuid.len == 0)
   2136                 uuid.len = LEN_UUID_16;
   2137 
   2138             if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) {
   2139                 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
   2140             }
   2141 
   2142             LOG_INFO(LOG_TAG, "%s search UUID = %04x", __func__,
   2143                      uuid.uu.uuid16);
   2144             SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE,
   2145                                 1, &uuid, 0, NULL);
   2146 
   2147             memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
   2148             bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
   2149 
   2150             bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
   2151 
   2152             if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
   2153               /*
   2154                * If discovery is not successful with this device, then
   2155                * proceed with the next one.
   2156                */
   2157               osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
   2158               bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
   2159 
   2160             } else {
   2161 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   2162                 if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
   2163                      bta_dm_search_cb.uuid_to_search == 0) ||
   2164                     bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
   2165 #endif
   2166                     bta_dm_search_cb.service_index++;
   2167                 return;
   2168             }
   2169         }
   2170 
   2171         bta_dm_search_cb.service_index++;
   2172     }
   2173 
   2174     /* no more services to be discovered */
   2175     if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
   2176         tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   2177         p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
   2178         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
   2179         bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
   2180         strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
   2181                 bta_dm_get_remname(), BD_NAME_LEN);
   2182 
   2183         bta_sys_sendmsg(p_msg);
   2184     }
   2185 }
   2186 
   2187 /*******************************************************************************
   2188 **
   2189 ** Function         bta_dm_discover_next_device
   2190 **
   2191 ** Description      Starts discovery on the next device in Inquiry data base
   2192 **
   2193 ** Returns          void
   2194 **
   2195 *******************************************************************************/
   2196 static void bta_dm_discover_next_device(void)
   2197 {
   2198     APPL_TRACE_DEBUG("bta_dm_discover_next_device");
   2199 
   2200     /* searching next device on inquiry result */
   2201     if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
   2202         bta_dm_search_cb.name_discover_done = FALSE;
   2203         bta_dm_search_cb.peer_name[0]       = 0;
   2204         bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
   2205     } else {
   2206         tBTA_DM_MSG *p_msg =
   2207             (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   2208 
   2209         /* no devices, search complete */
   2210         bta_dm_search_cb.services = 0;
   2211 
   2212         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   2213         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   2214 
   2215         bta_sys_sendmsg(p_msg);
   2216     }
   2217 }
   2218 
   2219 /*******************************************************************************
   2220 **
   2221 ** Function         bta_dm_discover_device
   2222 **
   2223 ** Description      Starts name and service discovery on the device
   2224 **
   2225 ** Returns          void
   2226 **
   2227 *******************************************************************************/
   2228 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
   2229 {
   2230     tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
   2231 
   2232 #if BLE_INCLUDED == TRUE
   2233     if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN)
   2234     {
   2235         tBT_DEVICE_TYPE dev_type;
   2236         tBLE_ADDR_TYPE  addr_type;
   2237 
   2238         BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
   2239         if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM)
   2240             transport = BT_TRANSPORT_LE;
   2241     } else {
   2242         transport = bta_dm_search_cb.transport;
   2243     }
   2244 #endif
   2245 
   2246     /* Reset transport state for next discovery */
   2247     bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
   2248 
   2249     APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
   2250                         remote_bd_addr[0],remote_bd_addr[1],
   2251                         remote_bd_addr[2],remote_bd_addr[3],
   2252                         remote_bd_addr[4],remote_bd_addr[5]);
   2253 
   2254     bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
   2255 
   2256     APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
   2257                         __func__,
   2258                         bta_dm_search_cb.name_discover_done,
   2259                         bta_dm_search_cb.p_btm_inq_info,
   2260                         bta_dm_search_cb.state,
   2261                         transport);
   2262 
   2263     if (bta_dm_search_cb.p_btm_inq_info)
   2264     {
   2265         APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
   2266                             bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
   2267     }
   2268 #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
   2269     if((bta_dm_search_cb.p_btm_inq_info)
   2270        && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
   2271        && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE))
   2272     {
   2273         /* Do not perform RNR for LE devices at inquiry complete*/
   2274         bta_dm_search_cb.name_discover_done = TRUE;
   2275     }
   2276 #endif
   2277     /* if name discovery is not done and application needs remote name */
   2278     if ((!bta_dm_search_cb.name_discover_done)
   2279        && (( bta_dm_search_cb.p_btm_inq_info == NULL )
   2280             ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name))))
   2281     {
   2282         if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE)
   2283             return;
   2284 
   2285         /* starting name discovery failed */
   2286         bta_dm_search_cb.name_discover_done = TRUE;
   2287     }
   2288 
   2289     /* if application wants to discover service */
   2290     if ( bta_dm_search_cb.services )
   2291     {
   2292         /* initialize variables */
   2293         bta_dm_search_cb.service_index      = 0;
   2294         bta_dm_search_cb.services_found     = 0;
   2295         bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
   2296 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   2297         bta_dm_search_cb.uuid_to_search     = bta_dm_search_cb.num_uuid;
   2298 #endif
   2299         if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
   2300             bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
   2301             &&(bta_dm_search_cb.sdp_search == FALSE))
   2302         {
   2303             /* check if EIR provides the information of supported services */
   2304             bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
   2305                                         &bta_dm_search_cb.services_to_search,
   2306                                         &bta_dm_search_cb.services_found );
   2307         }
   2308 
   2309         /* if seaching with EIR is not completed */
   2310         if(bta_dm_search_cb.services_to_search)
   2311         {
   2312             /* check whether connection already exists to the device
   2313                if connection exists, we don't have to wait for ACL
   2314                link to go down to start search on next device */
   2315             if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
   2316                 bta_dm_search_cb.wait_disc = FALSE;
   2317             else
   2318                 bta_dm_search_cb.wait_disc = TRUE;
   2319 
   2320 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
   2321             if ( bta_dm_search_cb.p_btm_inq_info )
   2322             {
   2323                 APPL_TRACE_DEBUG("%s p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x",
   2324                                     __func__,
   2325                                     bta_dm_search_cb.p_btm_inq_info,
   2326                                     bta_dm_search_cb.p_btm_inq_info->results.device_type,
   2327                                     bta_dm_search_cb.services_to_search);
   2328             }
   2329 
   2330             if (transport == BT_TRANSPORT_LE)
   2331             {
   2332                 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK)
   2333                 {
   2334                     //set the raw data buffer here
   2335                     memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
   2336                     bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
   2337 
   2338                     bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
   2339                     bta_dm_search_cb.ble_raw_used = 0;
   2340 
   2341                     /* start GATT for service discovery */
   2342                     btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
   2343                     return;
   2344                 }
   2345             }
   2346             else
   2347 #endif
   2348             {
   2349                 bta_dm_search_cb.sdp_results = FALSE;
   2350                 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
   2351                 return;
   2352             }
   2353         }
   2354     }
   2355 
   2356     /* name discovery and service discovery are done for this device */
   2357     tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   2358     p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
   2359     /* initialize the data structure - includes p_raw_data and raw_data_size */
   2360     memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
   2361     p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
   2362     p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
   2363     bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
   2364     strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
   2365             (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN);
   2366 
   2367     bta_sys_sendmsg(p_msg);
   2368 }
   2369 
   2370 /*******************************************************************************
   2371 **
   2372 ** Function         bta_dm_sdp_callback
   2373 **
   2374 ** Description      Callback from sdp with discovery status
   2375 **
   2376 ** Returns          void
   2377 **
   2378 *******************************************************************************/
   2379 static void bta_dm_sdp_callback (UINT16 sdp_status)
   2380 {
   2381 
   2382     tBTA_DM_SDP_RESULT *p_msg =
   2383         (tBTA_DM_SDP_RESULT *)osi_malloc(sizeof(tBTA_DM_SDP_RESULT));
   2384 
   2385     p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
   2386     p_msg->sdp_result = sdp_status;
   2387 
   2388     bta_sys_sendmsg(p_msg);
   2389 }
   2390 
   2391 /*******************************************************************************
   2392 **
   2393 ** Function         bta_dm_inq_results_cb
   2394 **
   2395 ** Description      Inquiry results callback from BTM
   2396 **
   2397 ** Returns          void
   2398 **
   2399 *******************************************************************************/
   2400 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
   2401 {
   2402 
   2403     tBTA_DM_SEARCH     result;
   2404     tBTM_INQ_INFO      *p_inq_info;
   2405     UINT16             service_class;
   2406 
   2407     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
   2408     memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
   2409     BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
   2410     result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER)?TRUE:FALSE;
   2411     result.inq_res.rssi = p_inq->rssi;
   2412 
   2413 #if (BLE_INCLUDED == TRUE)
   2414     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
   2415     result.inq_res.inq_result_type  = p_inq->inq_result_type;
   2416     result.inq_res.device_type      = p_inq->device_type;
   2417     result.inq_res.flag             = p_inq->flag;
   2418 #endif
   2419 
   2420     /* application will parse EIR to find out remote device name */
   2421     result.inq_res.p_eir = p_eir;
   2422 
   2423     if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
   2424     {
   2425         /* initialize remt_name_not_required to FALSE so that we get the name by default */
   2426         result.inq_res.remt_name_not_required = FALSE;
   2427 
   2428     }
   2429 
   2430     if(bta_dm_search_cb.p_search_cback)
   2431         bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
   2432 
   2433     if(p_inq_info)
   2434     {
   2435         /* application indicates if it knows the remote name, inside the callback
   2436          copy that to the inquiry data base*/
   2437         if(result.inq_res.remt_name_not_required)
   2438             p_inq_info->appl_knows_rem_name = TRUE;
   2439 
   2440     }
   2441 
   2442 
   2443 }
   2444 
   2445 
   2446 /*******************************************************************************
   2447 **
   2448 ** Function         bta_dm_inq_cmpl_cb
   2449 **
   2450 ** Description      Inquiry complete callback from BTM
   2451 **
   2452 ** Returns          void
   2453 **
   2454 *******************************************************************************/
   2455 static void bta_dm_inq_cmpl_cb (void * p_result)
   2456 {
   2457     tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   2458 
   2459     APPL_TRACE_DEBUG("%s", __func__);
   2460 
   2461     if (bta_dm_search_cb.cancel_pending == FALSE) {
   2462         p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
   2463         p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
   2464     } else {
   2465         bta_dm_search_cb.cancel_pending = FALSE;
   2466         bta_dm_search_cancel_notify(NULL);
   2467         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
   2468         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
   2469     }
   2470 
   2471     bta_sys_sendmsg(p_msg);
   2472 }
   2473 
   2474 /*******************************************************************************
   2475 **
   2476 ** Function         bta_dm_service_search_remname_cback
   2477 **
   2478 ** Description      Remote name call back from BTM during service discovery
   2479 **
   2480 ** Returns          void
   2481 **
   2482 *******************************************************************************/
   2483 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
   2484 {
   2485     tBTM_REMOTE_DEV_NAME    rem_name;
   2486     tBTM_STATUS             btm_status;
   2487     UNUSED(dc);
   2488 
   2489     APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
   2490 
   2491     /* if this is what we are looking for */
   2492     if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr))
   2493     {
   2494         rem_name.length = strlen((char*)bd_name);
   2495         if (rem_name.length > (BD_NAME_LEN-1))
   2496         {
   2497             rem_name.length = (BD_NAME_LEN-1);
   2498             rem_name.remote_bd_name[(BD_NAME_LEN-1)] = 0;
   2499         }
   2500         strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN);
   2501         rem_name.status = BTM_SUCCESS;
   2502 
   2503         bta_dm_remname_cback(&rem_name);
   2504     }
   2505     else
   2506     {
   2507         /* get name of device */
   2508         btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
   2509                                                 (tBTM_CMPL_CB *) bta_dm_remname_cback,
   2510                                                 BT_TRANSPORT_BR_EDR);
   2511         if ( btm_status == BTM_BUSY )
   2512         {
   2513             /* wait for next chance(notification of remote name discovery done) */
   2514             APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
   2515         }
   2516         else if ( btm_status != BTM_CMD_STARTED )
   2517         {
   2518             /* if failed to start getting remote name then continue */
   2519             APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
   2520 
   2521             rem_name.length = 0;
   2522             rem_name.remote_bd_name[0] = 0;
   2523             rem_name.status = btm_status;
   2524             bta_dm_remname_cback(&rem_name);
   2525         }
   2526     }
   2527 }
   2528 
   2529 
   2530 /*******************************************************************************
   2531 **
   2532 ** Function         bta_dm_remname_cback
   2533 **
   2534 ** Description      Remote name complete call back from BTM
   2535 **
   2536 ** Returns          void
   2537 **
   2538 *******************************************************************************/
   2539 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
   2540 {
   2541     APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
   2542                       p_remote_name->remote_bd_name);
   2543 
   2544     /* remote name discovery is done but it could be failed */
   2545     bta_dm_search_cb.name_discover_done = TRUE;
   2546     strlcpy((char*)bta_dm_search_cb.peer_name,
   2547             (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
   2548 
   2549     BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
   2550 
   2551 #if BLE_INCLUDED == TRUE
   2552     if (bta_dm_search_cb.transport == BT_TRANSPORT_LE )
   2553     {
   2554         GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
   2555     }
   2556 #endif
   2557 
   2558     tBTA_DM_REM_NAME *p_msg =
   2559         (tBTA_DM_REM_NAME *)osi_malloc(sizeof(tBTA_DM_REM_NAME));
   2560     bdcpy(p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
   2561     strlcpy((char*)p_msg->result.disc_res.bd_name,
   2562             (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
   2563     p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
   2564 
   2565     bta_sys_sendmsg(p_msg);
   2566 }
   2567 
   2568 /*******************************************************************************
   2569 **
   2570 ** Function         bta_dm_authorize_cback
   2571 **
   2572 ** Description      cback requesting authorization
   2573 **
   2574 ** Returns          void
   2575 **
   2576 *******************************************************************************/
   2577 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
   2578                                      UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
   2579 {
   2580     tBTA_DM_SEC sec_event;
   2581     UINT8       index = 1;
   2582     UNUSED(service_name);
   2583     UNUSED(is_originator);
   2584 
   2585     bdcpy(sec_event.authorize.bd_addr, bd_addr);
   2586     memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
   2587     strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN);
   2588 
   2589 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
   2590     sec_event.authorize.service = service_id;
   2591 #endif
   2592 
   2593     while(index < BTA_MAX_SERVICE_ID)
   2594     {
   2595         /* get the BTA service id corresponding to BTM id */
   2596         if(bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id)
   2597         {
   2598             sec_event.authorize.service = index;
   2599             break;
   2600         }
   2601         index++;
   2602     }
   2603 
   2604 
   2605     /* if supported service callback otherwise not authorized */
   2606     if(bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
   2607 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
   2608         /* pass through JV service ID */
   2609         || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
   2610 #endif
   2611         ))
   2612     {
   2613         bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
   2614         return BTM_CMD_STARTED;
   2615     }
   2616     else
   2617     {
   2618         return BTM_NOT_AUTHORIZED;
   2619     }
   2620 }
   2621 
   2622 
   2623 
   2624 
   2625 
   2626 /*******************************************************************************
   2627 **
   2628 ** Function         bta_dm_pinname_cback
   2629 **
   2630 ** Description      Callback requesting pin_key
   2631 **
   2632 ** Returns          void
   2633 **
   2634 *******************************************************************************/
   2635 static void bta_dm_pinname_cback (void *p_data)
   2636 {
   2637     tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
   2638     tBTA_DM_SEC           sec_event;
   2639     UINT32                bytes_to_copy;
   2640     tBTA_DM_SEC_EVT       event = bta_dm_cb.pin_evt;
   2641 
   2642     if (BTA_DM_SP_CFM_REQ_EVT == event)
   2643     {
   2644         /* Retrieved saved device class and bd_addr */
   2645         bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
   2646         BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
   2647 
   2648         if (p_result && p_result->status == BTM_SUCCESS)
   2649         {
   2650             bytes_to_copy = (p_result->length < (BD_NAME_LEN-1))
   2651             ? p_result->length : (BD_NAME_LEN-1);
   2652             memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
   2653             sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0;
   2654         }
   2655         else    /* No name found */
   2656             sec_event.cfm_req.bd_name[0] = 0;
   2657 
   2658         sec_event.key_notif.passkey    = bta_dm_cb.num_val; /* get PIN code numeric number */
   2659 
   2660         /* 1 additional event data fields for this event */
   2661         sec_event.cfm_req.just_works = bta_dm_cb.just_works;
   2662     }
   2663     else
   2664     {
   2665         /* Retrieved saved device class and bd_addr */
   2666         bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
   2667         BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
   2668 
   2669         if (p_result && p_result->status == BTM_SUCCESS)
   2670         {
   2671             bytes_to_copy = (p_result->length < (BD_NAME_LEN-1))
   2672             ? p_result->length : (BD_NAME_LEN-1);
   2673             memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
   2674             sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0;
   2675         }
   2676         else    /* No name found */
   2677             sec_event.pin_req.bd_name[0] = 0;
   2678 
   2679         event = bta_dm_cb.pin_evt;
   2680         sec_event.key_notif.passkey    = bta_dm_cb.num_val; /* get PIN code numeric number */
   2681     }
   2682 
   2683     if( bta_dm_cb.p_sec_cback )
   2684         bta_dm_cb.p_sec_cback(event, &sec_event);
   2685 }
   2686 
   2687 /*******************************************************************************
   2688 **
   2689 ** Function         bta_dm_pin_cback
   2690 **
   2691 ** Description      Callback requesting pin_key
   2692 **
   2693 ** Returns          void
   2694 **
   2695 *******************************************************************************/
   2696 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
   2697         BOOLEAN min_16_digit)
   2698 {
   2699     tBTA_DM_SEC sec_event;
   2700 
   2701     if (!bta_dm_cb.p_sec_cback)
   2702         return BTM_NOT_AUTHORIZED;
   2703 
   2704     /* If the device name is not known, save bdaddr and devclass and initiate a name request */
   2705     if (bd_name[0] == 0)
   2706     {
   2707         bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
   2708         bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
   2709         BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
   2710         if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
   2711             return BTM_CMD_STARTED;
   2712 
   2713         APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
   2714     }
   2715 
   2716     bdcpy(sec_event.pin_req.bd_addr, bd_addr);
   2717     BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
   2718     strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN);
   2719     sec_event.pin_req.min_16_digit = min_16_digit;
   2720 
   2721     bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
   2722     return BTM_CMD_STARTED;
   2723 }
   2724 
   2725 /*******************************************************************************
   2726 **
   2727 ** Function         bta_dm_new_link_key_cback
   2728 **
   2729 ** Description      Callback from BTM to notify new link key
   2730 **
   2731 ** Returns          void
   2732 **
   2733 *******************************************************************************/
   2734 static UINT8  bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
   2735                                         BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
   2736 {
   2737     tBTA_DM_SEC sec_event;
   2738     tBTA_DM_AUTH_CMPL *p_auth_cmpl;
   2739     UINT8             event;
   2740     UNUSED(dev_class);
   2741 
   2742     memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
   2743 
   2744     /* Not AMP Key type */
   2745     if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB)
   2746     {
   2747         event = BTA_DM_AUTH_CMPL_EVT;
   2748         p_auth_cmpl = &sec_event.auth_cmpl;
   2749 
   2750         bdcpy(p_auth_cmpl->bd_addr, bd_addr);
   2751 
   2752         memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN-1));
   2753         p_auth_cmpl->bd_name[BD_NAME_LEN-1] = 0;
   2754 
   2755         p_auth_cmpl->key_present = TRUE;
   2756         p_auth_cmpl->key_type = key_type;
   2757         p_auth_cmpl->success = TRUE;
   2758 
   2759         memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
   2760         sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
   2761 
   2762 #if BLE_INCLUDED == TRUE
   2763         // Report the BR link key based on the BR/EDR address and type
   2764         BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
   2765 #endif
   2766         if(bta_dm_cb.p_sec_cback)
   2767             bta_dm_cb.p_sec_cback(event, &sec_event);
   2768 
   2769         // Setting remove_dev_pending flag to FALSE, where it will avoid deleting the
   2770         // security device record when the ACL connection link goes down in case of
   2771         // reconnection.
   2772         if (bta_dm_cb.device_list.count)
   2773             bta_dm_reset_sec_dev_pending(p_auth_cmpl->bd_addr);
   2774     }
   2775     else
   2776     {
   2777         APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
   2778     }
   2779 
   2780     return BTM_CMD_STARTED;
   2781 }
   2782 
   2783 
   2784 /*******************************************************************************
   2785 **
   2786 ** Function         bta_dm_authentication_complete_cback
   2787 **
   2788 ** Description      Authentication complete callback from BTM
   2789 **
   2790 ** Returns          void
   2791 **
   2792 *******************************************************************************/
   2793 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result)
   2794 {
   2795     tBTA_DM_SEC sec_event;
   2796     UNUSED(dev_class);
   2797 
   2798     if(result != BTM_SUCCESS)
   2799     {
   2800         memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
   2801         bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
   2802 
   2803         memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN-1));
   2804         sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
   2805 
   2806 #if BLE_INCLUDED == TRUE
   2807         // Report the BR link key based on the BR/EDR address and type
   2808         BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
   2809 #endif
   2810         sec_event.auth_cmpl.fail_reason = (UINT8)result;
   2811 
   2812         if(bta_dm_cb.p_sec_cback)
   2813             bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
   2814 
   2815         bta_dm_remove_sec_dev_entry(bd_addr);
   2816     }
   2817 
   2818     return BTM_SUCCESS;
   2819 }
   2820 
   2821 /*******************************************************************************
   2822 **
   2823 ** Function         bta_dm_sp_cback
   2824 **
   2825 ** Description      simple pairing callback from BTM
   2826 **
   2827 ** Returns          void
   2828 **
   2829 *******************************************************************************/
   2830 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
   2831 {
   2832     tBTM_STATUS status = BTM_CMD_STARTED;
   2833     tBTA_DM_SEC sec_event;
   2834     tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
   2835 
   2836     APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
   2837     if (!bta_dm_cb.p_sec_cback)
   2838         return BTM_NOT_AUTHORIZED;
   2839 
   2840     /* TODO_SP */
   2841     switch(event)
   2842     {
   2843     case BTM_SP_IO_REQ_EVT:
   2844 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
   2845         /* translate auth_req */
   2846         bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
   2847             &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
   2848 #endif
   2849         APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
   2850         break;
   2851     case BTM_SP_IO_RSP_EVT:
   2852 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
   2853         bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
   2854                          p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
   2855 #endif
   2856         break;
   2857 
   2858     case BTM_SP_CFM_REQ_EVT:
   2859         pin_evt = BTA_DM_SP_CFM_REQ_EVT;
   2860         bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
   2861         sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
   2862         sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
   2863         sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
   2864         sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
   2865 
   2866         /* continue to next case */
   2867 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
   2868     /* Passkey entry mode, mobile device with output capability is very
   2869         unlikely to receive key request, so skip this event */
   2870     /*case BTM_SP_KEY_REQ_EVT: */
   2871     case BTM_SP_KEY_NOTIF_EVT:
   2872 #endif
   2873         if(BTM_SP_CFM_REQ_EVT == event)
   2874         {
   2875           /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
   2876              call remote name request using values from cfm_req */
   2877           if(p_data->cfm_req.bd_name[0] == 0)
   2878           {
   2879               bta_dm_cb.pin_evt = pin_evt;
   2880               bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
   2881               BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
   2882               if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
   2883                          BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
   2884                   return BTM_CMD_STARTED;
   2885               APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
   2886           }
   2887           else
   2888           {
   2889               /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
   2890                  copy these values into key_notif from cfm_req */
   2891               bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
   2892               BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
   2893               strlcpy((char*)sec_event.key_notif.bd_name,
   2894                       (char*)p_data->cfm_req.bd_name, BD_NAME_LEN);
   2895            }
   2896         }
   2897 
   2898         bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
   2899         if (BTM_SP_KEY_NOTIF_EVT == event)
   2900         {
   2901             /* If the device name is not known, save bdaddr and devclass
   2902                and initiate a name request with values from key_notif */
   2903             if(p_data->key_notif.bd_name[0] == 0)
   2904             {
   2905                 bta_dm_cb.pin_evt = pin_evt;
   2906                 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
   2907                 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
   2908                 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
   2909                          BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
   2910                 return BTM_CMD_STARTED;
   2911                 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
   2912             }
   2913             else
   2914             {
   2915                 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
   2916                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
   2917                 strlcpy((char*)sec_event.key_notif.bd_name,
   2918                         (char*)p_data->key_notif.bd_name, BD_NAME_LEN);
   2919                 sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
   2920             }
   2921         }
   2922 
   2923         bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
   2924 
   2925         break;
   2926 
   2927     case BTM_SP_LOC_OOB_EVT:
   2928         bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
   2929             p_data->loc_oob.c, p_data->loc_oob.r);
   2930         break;
   2931 
   2932     case BTM_SP_RMT_OOB_EVT:
   2933         /* If the device name is not known, save bdaddr and devclass and initiate a name request */
   2934         if (p_data->rmt_oob.bd_name[0] == 0)
   2935         {
   2936              bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
   2937              bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
   2938              BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
   2939              if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
   2940                       BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
   2941              return BTM_CMD_STARTED;
   2942              APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
   2943         }
   2944 
   2945         bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
   2946         BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
   2947         strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name, BD_NAME_LEN);
   2948 
   2949         bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
   2950 
   2951         bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
   2952         break;
   2953 
   2954     case BTM_SP_COMPLT_EVT:
   2955         /* do not report this event - handled by link_key_callback or auth_complete_callback */
   2956         break;
   2957 
   2958     case BTM_SP_KEYPRESS_EVT:
   2959         memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
   2960         bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
   2961         break;
   2962 
   2963     case BTM_SP_UPGRADE_EVT:
   2964         bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
   2965         break;
   2966 
   2967     default:
   2968         status = BTM_NOT_AUTHORIZED;
   2969         break;
   2970     }
   2971     APPL_TRACE_EVENT("dm status: %d", status);
   2972     return status;
   2973 }
   2974 
   2975 /*******************************************************************************
   2976 **
   2977 ** Function         bta_dm_local_name_cback
   2978 **
   2979 ** Description      Callback from btm after local name is read
   2980 **
   2981 **
   2982 ** Returns          void
   2983 **
   2984 *******************************************************************************/
   2985 static void bta_dm_local_name_cback(UINT8 *p_name)
   2986 {
   2987     tBTA_DM_SEC sec_event;
   2988     UNUSED(p_name);
   2989 
   2990     sec_event.enable.status = BTA_SUCCESS;
   2991 
   2992     if(bta_dm_cb.p_sec_cback)
   2993         bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
   2994 
   2995 }
   2996 
   2997 /*******************************************************************************
   2998 **
   2999 ** Function         bta_dm_bl_change_cback
   3000 **
   3001 ** Description      Callback from btm when acl connection goes up or down
   3002 **
   3003 **
   3004 ** Returns          void
   3005 **
   3006 *******************************************************************************/
   3007 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
   3008 {
   3009     tBTA_DM_ACL_CHANGE *p_msg =
   3010         (tBTA_DM_ACL_CHANGE *)osi_malloc(sizeof(tBTA_DM_ACL_CHANGE));
   3011 
   3012     p_msg->event = p_data->event;
   3013     p_msg->is_new = FALSE;
   3014 
   3015     switch (p_msg->event) {
   3016     case BTM_BL_CONN_EVT:
   3017         p_msg->is_new = TRUE;
   3018         bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
   3019 #if BLE_INCLUDED == TRUE
   3020         p_msg->transport = p_data->conn.transport;
   3021         p_msg->handle = p_data->conn.handle;
   3022 #endif
   3023         break;
   3024     case BTM_BL_DISCN_EVT:
   3025         bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
   3026 #if BLE_INCLUDED == TRUE
   3027         p_msg->transport = p_data->discn.transport;
   3028         p_msg->handle = p_data->discn.handle;
   3029 #endif
   3030         break;
   3031     case BTM_BL_UPDATE_EVT:
   3032         p_msg->busy_level = p_data->update.busy_level;
   3033         p_msg->busy_level_flags = p_data->update.busy_level_flags;
   3034         break;
   3035     case BTM_BL_ROLE_CHG_EVT:
   3036         p_msg->new_role = p_data->role_chg.new_role;
   3037         p_msg->hci_status = p_data->role_chg.hci_status;
   3038         bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
   3039         break;
   3040     case BTM_BL_COLLISION_EVT:
   3041         bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
   3042         break;
   3043     }
   3044 
   3045     p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
   3046     bta_sys_sendmsg(p_msg);
   3047 }
   3048 
   3049 /*******************************************************************************
   3050 **
   3051 ** Function         bta_dm_rs_cback
   3052 **
   3053 ** Description      Receives the role switch complete event
   3054 **
   3055 ** Returns
   3056 **
   3057 *******************************************************************************/
   3058 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
   3059 {
   3060     UNUSED(p1);
   3061     APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
   3062     if(bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT)
   3063     {
   3064         bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
   3065         bta_dm_cb.rs_event = 0;
   3066         bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
   3067     }
   3068 }
   3069 
   3070 /*******************************************************************************
   3071 **
   3072 ** Function         bta_dm_check_av
   3073 **
   3074 ** Description      This function checks if AV is active
   3075 **                  if yes, make sure the AV link is master
   3076 **
   3077 ** Returns          BOOLEAN - TRUE, if switch is in progress
   3078 **
   3079 *******************************************************************************/
   3080 static BOOLEAN bta_dm_check_av(UINT16 event)
   3081 {
   3082     BOOLEAN avoid_roleswitch = FALSE;
   3083     BOOLEAN switching = FALSE;
   3084     UINT8 i;
   3085     tBTA_DM_PEER_DEVICE *p_dev;
   3086 
   3087 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
   3088 
   3089     /* avoid role switch upon inquiry if a2dp is actively streaming as it
   3090        introduces an audioglitch due to FW scheduling delays (unavoidable) */
   3091     if (event == BTA_DM_API_SEARCH_EVT)
   3092     {
   3093         avoid_roleswitch = TRUE;
   3094     }
   3095 #endif
   3096 
   3097     APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
   3098     if(bta_dm_cb.cur_av_count)
   3099     {
   3100         for(i=0; i<bta_dm_cb.device_list.count; i++)
   3101         {
   3102             p_dev = &bta_dm_cb.device_list.peer_device[i];
   3103             APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
   3104                                 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
   3105             if((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
   3106                (avoid_roleswitch == FALSE))
   3107             {
   3108                 /* make master and take away the role switch policy */
   3109                 if(BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback))
   3110                 {
   3111                     /* the role switch command is actually sent */
   3112                     bta_dm_cb.rs_event = event;
   3113                     switching = TRUE;
   3114                 }
   3115                 /* else either already master or can not switch for some reasons */
   3116                 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
   3117                 break;
   3118             }
   3119         }
   3120     }
   3121     return switching;
   3122 }
   3123 
   3124 /*******************************************************************************
   3125 **
   3126 ** Function         bta_dm_acl_change
   3127 **
   3128 ** Description      Process BTA_DM_ACL_CHANGE_EVT
   3129 **
   3130 **
   3131 ** Returns          void
   3132 **
   3133 *******************************************************************************/
   3134 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
   3135 {
   3136 
   3137     UINT8 i;
   3138     UINT8 *p;
   3139     tBTA_DM_SEC conn;
   3140     BOOLEAN is_new = p_data->acl_change.is_new;
   3141     BD_ADDR_PTR     p_bda = p_data->acl_change.bd_addr;
   3142     BOOLEAN         need_policy_change = FALSE;
   3143     BOOLEAN         issue_unpair_cb = FALSE;
   3144 
   3145     tBTA_DM_PEER_DEVICE *p_dev;
   3146     memset(&conn, 0, sizeof(tBTA_DM_SEC));
   3147 
   3148     switch(p_data->acl_change.event)
   3149     {
   3150     case BTM_BL_UPDATE_EVT:     /* busy level update */
   3151         if( bta_dm_cb.p_sec_cback )
   3152         {
   3153             conn.busy_level.level = p_data->acl_change.busy_level;
   3154             conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
   3155             bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
   3156         }
   3157         return;
   3158 
   3159     case BTM_BL_ROLE_CHG_EVT:   /* role change event */
   3160         p_dev = bta_dm_find_peer_device(p_bda);
   3161         if(p_dev)
   3162         {
   3163             APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
   3164                 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
   3165             if(p_dev->info & BTA_DM_DI_AV_ACTIVE)
   3166             {
   3167                 /* there's AV activity on this link */
   3168                 if(p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
   3169                     && p_data->acl_change.hci_status == HCI_SUCCESS)
   3170                 {
   3171                     /* more than one connections and the AV connection is role switched to slave
   3172                      * switch it back to master and remove the switch policy */
   3173                     BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
   3174                     need_policy_change = TRUE;
   3175                 }
   3176                 else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER))
   3177                 {
   3178                     /* if the link updated to be master include AV activities, remove the switch policy */
   3179                     need_policy_change = TRUE;
   3180                 }
   3181 
   3182                 if(need_policy_change)
   3183                 {
   3184                     bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
   3185                 }
   3186             }
   3187             else
   3188             {
   3189                 /* there's AV no activity on this link and role switch happened
   3190                  * check if AV is active
   3191                  * if so, make sure the AV link is master */
   3192                 bta_dm_check_av(0);
   3193             }
   3194             bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
   3195             bdcpy(conn.role_chg.bd_addr, p_bda);
   3196             conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
   3197             if( bta_dm_cb.p_sec_cback )
   3198                 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
   3199         }
   3200         return;
   3201     }
   3202 
   3203     /* Collision report from Stack: Notify profiles */
   3204     if (p_data->acl_change.event == BTM_BL_COLLISION_EVT)
   3205     {
   3206         bta_sys_notify_collision (p_bda);
   3207         return;
   3208     }
   3209 
   3210     if(is_new)
   3211     {
   3212         for(i=0; i<bta_dm_cb.device_list.count; i++)
   3213         {
   3214             if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
   3215 #if BLE_INCLUDED == TRUE
   3216                  && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
   3217 #endif
   3218                  )
   3219                 break;
   3220 
   3221         }
   3222 
   3223         if(i == bta_dm_cb.device_list.count)
   3224         {
   3225             if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE)
   3226             {
   3227                 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
   3228                 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
   3229                 bta_dm_cb.device_list.count++;
   3230 #if BLE_INCLUDED == TRUE
   3231                 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
   3232                 if (p_data->acl_change.transport == BT_TRANSPORT_LE)
   3233                     bta_dm_cb.device_list.le_count++;
   3234 #endif
   3235             } else {
   3236                 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
   3237                 return;
   3238             }
   3239         }
   3240 
   3241         bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
   3242         bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
   3243         bdcpy(conn.link_up.bd_addr, p_bda);
   3244         bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
   3245 #if BLE_INCLUDED == TRUE
   3246         conn.link_up.link_type = p_data->acl_change.transport;
   3247         bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
   3248 #endif
   3249 
   3250         if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
   3251             ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
   3252         {
   3253             /* both local and remote devices support SSR */
   3254             bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
   3255         }
   3256         APPL_TRACE_WARNING("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
   3257 
   3258         if (bta_dm_cb.p_sec_cback)
   3259             bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
   3260     } else {
   3261         for(i=0; i<bta_dm_cb.device_list.count; i++)
   3262         {
   3263             if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
   3264 #if BLE_INCLUDED == TRUE
   3265                  ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
   3266 #endif
   3267                )
   3268                 continue;
   3269 
   3270             if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
   3271             {
   3272                 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
   3273                     issue_unpair_cb = TRUE;
   3274 
   3275                 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ",__FUNCTION__, issue_unpair_cb);
   3276             }
   3277 
   3278             conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
   3279 
   3280             for(; i<bta_dm_cb.device_list.count ; i++)
   3281             {
   3282                 memcpy(&bta_dm_cb.device_list.peer_device[i], &bta_dm_cb.device_list.peer_device[i+1], sizeof(bta_dm_cb.device_list.peer_device[i]));
   3283             }
   3284             break;
   3285         }
   3286         if(bta_dm_cb.device_list.count)
   3287             bta_dm_cb.device_list.count--;
   3288 #if BLE_INCLUDED == TRUE
   3289         if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
   3290              (bta_dm_cb.device_list.le_count))
   3291             bta_dm_cb.device_list.le_count--;
   3292         conn.link_down.link_type = p_data->acl_change.transport;
   3293 #endif
   3294 
   3295         if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda))
   3296         {
   3297             bta_dm_search_cb.wait_disc = FALSE;
   3298 
   3299             if(bta_dm_search_cb.sdp_results)
   3300             {
   3301                 APPL_TRACE_EVENT(" timer stopped  ");
   3302                 alarm_cancel(bta_dm_search_cb.search_timer);
   3303                 bta_dm_discover_next_device();
   3304             }
   3305 
   3306         }
   3307 
   3308         if(bta_dm_cb.disabling)
   3309         {
   3310             if(!BTM_GetNumAclLinks())
   3311             {
   3312                 /*
   3313                  * Start a timer to make sure that the profiles
   3314                  * get the disconnect event.
   3315                  */
   3316                 alarm_set_on_queue(bta_dm_cb.disable_timer,
   3317                                    BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
   3318                                    bta_dm_disable_conn_down_timer_cback, NULL,
   3319                                    btu_bta_alarm_queue);
   3320             }
   3321         }
   3322         if (conn.link_down.is_removed)
   3323         {
   3324             BTM_SecDeleteDevice(p_bda);
   3325 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
   3326             /* need to remove all pending background connection */
   3327             BTA_GATTC_CancelOpen(0, p_bda, FALSE);
   3328             /* remove all cached GATT information */
   3329             BTA_GATTC_Refresh(p_bda);
   3330 #endif
   3331          }
   3332 
   3333         bdcpy(conn.link_down.bd_addr, p_bda);
   3334         conn.link_down.status = (UINT8) btm_get_acl_disc_reason_code();
   3335         if( bta_dm_cb.p_sec_cback )
   3336         {
   3337             bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
   3338             if( issue_unpair_cb )
   3339                 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
   3340         }
   3341     }
   3342 
   3343     bta_dm_adjust_roles(TRUE);
   3344 }
   3345 
   3346 /*******************************************************************************
   3347 **
   3348 ** Function         bta_dm_disable_conn_down_timer_cback
   3349 **
   3350 ** Description      Sends disable event to application
   3351 **
   3352 **
   3353 ** Returns          void
   3354 **
   3355 *******************************************************************************/
   3356 static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void *data)
   3357 {
   3358     tBTA_SYS_HW_MSG *sys_enable_event =
   3359         (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
   3360 
   3361     /* disable the power managment module */
   3362     bta_dm_disable_pm();
   3363 
   3364     /* register our callback to SYS HW manager */
   3365     bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
   3366 
   3367     /* send a message to BTA SYS */
   3368     sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
   3369     sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
   3370     bta_sys_sendmsg(sys_enable_event);
   3371 
   3372     bta_dm_cb.disabling = FALSE;
   3373 }
   3374 
   3375 /*******************************************************************************
   3376 **
   3377 ** Function         bta_dm_rm_cback
   3378 **
   3379 ** Description      Role management callback from sys
   3380 **
   3381 **
   3382 ** Returns          void
   3383 **
   3384 *******************************************************************************/
   3385 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
   3386 {
   3387     UINT8 j;
   3388     tBTA_PREF_ROLES role;
   3389     tBTA_DM_PEER_DEVICE *p_dev;
   3390 
   3391     p_dev = bta_dm_find_peer_device(peer_addr);
   3392     if( status == BTA_SYS_CONN_OPEN)
   3393     {
   3394         if(p_dev)
   3395         {
   3396             /* Do not set to connected if we are in the middle of unpairing. When AV stream is
   3397              * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
   3398              * But this should not be done if we are in the middle of unpairing.
   3399              */
   3400             if (p_dev->conn_state != BTA_DM_UNPAIRING)
   3401                 p_dev->conn_state = BTA_DM_CONNECTED;
   3402 
   3403             for(j=1; j<= p_bta_dm_rm_cfg[0].app_id; j++)
   3404             {
   3405                 if(((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
   3406                     && (p_bta_dm_rm_cfg[j].id == id))
   3407                 {
   3408                     role = p_bta_dm_rm_cfg[j].cfg;
   3409 
   3410                     if(role > p_dev->pref_role )
   3411                         p_dev->pref_role = role;
   3412                     break;
   3413                 }
   3414             }
   3415         }
   3416     }
   3417 
   3418     if((BTA_ID_AV == id)||(BTA_ID_AVK ==id))
   3419     {
   3420         if( status == BTA_SYS_CONN_BUSY)
   3421         {
   3422             if(p_dev)
   3423                 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
   3424             /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
   3425             if(BTA_ID_AV == id)
   3426                 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
   3427         }
   3428         else if( status == BTA_SYS_CONN_IDLE)
   3429         {
   3430             if(p_dev)
   3431                 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
   3432 
   3433             /* get cur_av_count from connected services */
   3434             if(BTA_ID_AV == id)
   3435                 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
   3436         }
   3437         APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
   3438     }
   3439 
   3440     /* Don't adjust roles for each busy/idle state transition to avoid
   3441        excessive switch requests when individual profile busy/idle status
   3442        changes */
   3443     if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE))
   3444         bta_dm_adjust_roles(FALSE);
   3445 }
   3446 
   3447 /*******************************************************************************
   3448 **
   3449 ** Function         bta_dm_delay_role_switch_cback
   3450 **
   3451 ** Description      Callback from btm to delay a role switch
   3452 **
   3453 ** Returns          void
   3454 **
   3455 *******************************************************************************/
   3456 static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void *data)
   3457 {
   3458     APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__);
   3459     bta_dm_adjust_roles(FALSE);
   3460 }
   3461 
   3462 /*******************************************************************************
   3463 **
   3464 ** Function         bta_dm_reset_sec_dev_pending
   3465 **
   3466 ** Description      Setting the remove device pending status to FALSE from
   3467 **                  security device DB, when the link key notification
   3468 **                  event comes.
   3469 **
   3470 ** Returns          void
   3471 **
   3472 *******************************************************************************/
   3473 static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr)
   3474 {
   3475     for (size_t i = 0; i < bta_dm_cb.device_list.count; i++)
   3476     {
   3477         if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, remote_bd_addr) == 0)
   3478         {
   3479             bta_dm_cb.device_list.peer_device[i].remove_dev_pending = FALSE;
   3480             return;
   3481         }
   3482     }
   3483 }
   3484 
   3485 /*******************************************************************************
   3486 **
   3487 ** Function         bta_dm_remove_sec_dev_entry
   3488 **
   3489 ** Description      Removes device entry from Security device DB if ACL connection with
   3490 **                  remtoe device does not exist, else schedule for dev entry removal upon
   3491                      ACL close
   3492 **
   3493 ** Returns          void
   3494 **
   3495 *******************************************************************************/
   3496 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
   3497 {
   3498     if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
   3499          BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
   3500     {
   3501         APPL_TRACE_DEBUG("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
   3502                             __func__);
   3503         BTM_SecClearSecurityFlags (remote_bd_addr);
   3504         for (int i = 0; i < bta_dm_cb.device_list.count; i++)
   3505         {
   3506             if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, remote_bd_addr))
   3507             {
   3508                 bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
   3509                 break;
   3510             }
   3511         }
   3512     }
   3513     else
   3514     {
   3515         BTM_SecDeleteDevice (remote_bd_addr);
   3516 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
   3517         /* need to remove all pending background connection */
   3518         BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
   3519         /* remove all cached GATT information */
   3520         BTA_GATTC_Refresh(remote_bd_addr);
   3521 #endif
   3522     }
   3523 }
   3524 
   3525 
   3526 /*******************************************************************************
   3527 **
   3528 ** Function         bta_dm_adjust_roles
   3529 **
   3530 ** Description      Adjust roles
   3531 **
   3532 **
   3533 ** Returns          void
   3534 **
   3535 *******************************************************************************/
   3536 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
   3537 {
   3538 
   3539     UINT8 i;
   3540     BOOLEAN set_master_role = FALSE;
   3541 #if BLE_INCLUDED == TRUE
   3542     UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
   3543 #else
   3544     UINT8 br_count = bta_dm_cb.device_list.count;
   3545 #endif
   3546     if (br_count)
   3547     {
   3548 
   3549         /* the configuration is no scatternet
   3550          * or AV connection exists and there are more than one ACL link */
   3551         if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
   3552              (bta_dm_cb.cur_av_count && br_count > 1) )
   3553         {
   3554 
   3555             L2CA_SetDesireRole (HCI_ROLE_MASTER);
   3556             set_master_role = TRUE;
   3557 
   3558         }
   3559 
   3560         for(i=0; i<bta_dm_cb.device_list.count; i++)
   3561         {
   3562             if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
   3563 #if BLE_INCLUDED == TRUE
   3564                 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
   3565 #endif
   3566                 )
   3567             {
   3568                 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
   3569                     && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
   3570                 {
   3571                     L2CA_SetDesireRole (HCI_ROLE_MASTER);
   3572                     set_master_role = TRUE;
   3573                 }
   3574 
   3575                 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
   3576                     || (br_count > 1))
   3577                 {
   3578 
   3579                 /* Initiating immediate role switch with certain remote devices
   3580                   has caused issues due to role  switch colliding with link encryption setup and
   3581                   causing encryption (and in turn the link) to fail .  These device . Firmware
   3582                   versions are stored in a blacklist and role switch with these devices are
   3583                   delayed to avoid the collision with link encryption setup */
   3584 
   3585                     if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
   3586                             delay_role_switch == FALSE)
   3587                     {
   3588                         BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
   3589                                         HCI_ROLE_MASTER, NULL);
   3590                     }
   3591                     else
   3592                     {
   3593                         alarm_set_on_queue(bta_dm_cb.switch_delay_timer,
   3594                                            BTA_DM_SWITCH_DELAY_TIMER_MS,
   3595                                            bta_dm_delay_role_switch_cback,
   3596                                            NULL, btu_bta_alarm_queue);
   3597                     }
   3598                 }
   3599             }
   3600         }
   3601 
   3602 
   3603         if(!set_master_role)
   3604         {
   3605 
   3606             L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
   3607 
   3608         }
   3609 
   3610     }
   3611     else
   3612     {
   3613         L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
   3614     }
   3615 
   3616 
   3617 }
   3618 
   3619 /*******************************************************************************
   3620 **
   3621 ** Function         bta_dm_get_remname
   3622 **
   3623 ** Description      Returns a pointer to the remote name stored in the DM control
   3624 **                  block if it exists, or from the BTM memory.
   3625 **
   3626 ** Returns          char * - Pointer to the remote device name
   3627 *******************************************************************************/
   3628 static char *bta_dm_get_remname(void)
   3629 {
   3630     char *p_name = (char *)bta_dm_search_cb.peer_name;
   3631     char *p_temp;
   3632 
   3633     /* If the name isn't already stored, try retrieving from BTM */
   3634     if (*p_name == '\0')
   3635         if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL)
   3636             p_name = p_temp;
   3637 
   3638     return p_name;
   3639 }
   3640 
   3641 /*******************************************************************************
   3642 **
   3643 ** Function         bta_dm_bond_cancel_complete_cback
   3644 **
   3645 ** Description      Authentication complete callback from BTM
   3646 **
   3647 ** Returns          void
   3648 **
   3649 *******************************************************************************/
   3650 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
   3651 {
   3652 
   3653     tBTA_DM_SEC sec_event;
   3654 
   3655     if (result == BTM_SUCCESS)
   3656         sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
   3657     else
   3658         sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
   3659 
   3660     if(bta_dm_cb.p_sec_cback)
   3661     {
   3662         bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
   3663     }
   3664 }
   3665 
   3666 /*******************************************************************************
   3667 **
   3668 ** Function         find_utf8_char_boundary
   3669 **
   3670 ** Description      This function checks a UTF8 string |utf8str| starting at
   3671 **                  |offset|, moving backwards and returns the offset of the
   3672 **                  next valid UTF8 character boundary found.
   3673 **
   3674 ** Returns          Offset of UTF8 character boundary
   3675 **
   3676 *******************************************************************************/
   3677 static size_t find_utf8_char_boundary(const char *utf8str, size_t offset)
   3678 {
   3679     assert(utf8str);
   3680     assert(offset > 0);
   3681 
   3682     while (--offset)
   3683     {
   3684         uint8_t ch = (uint8_t)utf8str[offset];
   3685         if ((ch & 0x80) == 0x00) // ASCII
   3686             return offset + 1;
   3687         if ((ch & 0xC0) == 0xC0) // Multi-byte sequence start
   3688             return offset;
   3689     }
   3690 
   3691     return 0;
   3692 }
   3693 
   3694 /*******************************************************************************
   3695 **
   3696 ** Function         bta_dm_set_eir
   3697 **
   3698 ** Description      This function creates EIR tagged data and writes it to controller.
   3699 **
   3700 ** Returns          None
   3701 **
   3702 *******************************************************************************/
   3703 static void bta_dm_set_eir (char *local_name)
   3704 {
   3705     UINT8    *p;
   3706     UINT8    *p_length;
   3707 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
   3708     UINT8    *p_type;
   3709     UINT8    max_num_uuid;
   3710 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
   3711     UINT8    custom_uuid_idx;
   3712 #endif  // BTA_EIR_SERVER_NUM_CUSTOM_UUID
   3713 #endif  // BTA_EIR_CANNED_UUID_LIST
   3714 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
   3715     UINT8    free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
   3716 #else  // BTM_EIR_DEFAULT_FEC_REQUIRED
   3717     UINT8    free_eir_length = HCI_DM5_PACKET_SIZE;
   3718 #endif  // BTM_EIR_DEFAULT_FEC_REQUIRED
   3719     UINT8    num_uuid;
   3720     UINT8    data_type;
   3721     UINT8    local_name_len;
   3722 
   3723     /* wait until complete to disable */
   3724     if (alarm_is_scheduled(bta_dm_cb.disable_timer))
   3725         return;
   3726 
   3727 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
   3728     /* if local name is not provided, get it from controller */
   3729     if( local_name == NULL )
   3730     {
   3731         if( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS )
   3732         {
   3733             APPL_TRACE_ERROR("Fail to read local device name for EIR");
   3734         }
   3735     }
   3736 #endif  // BTA_EIR_CANNED_UUID_LIST
   3737 
   3738     /* Allocate a buffer to hold HCI command */
   3739     BT_HDR *p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE);
   3740     p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
   3741 
   3742     memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
   3743 
   3744     APPL_TRACE_DEBUG("BTA is generating EIR");
   3745 
   3746     if( local_name )
   3747         local_name_len = strlen( local_name );
   3748     else
   3749         local_name_len = 0;
   3750 
   3751     data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
   3752     /* if local name is longer than minimum length of shortened name */
   3753     /* check whether it needs to be shortened or not */
   3754     if( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len )
   3755     {
   3756         /* get number of UUID 16-bit list */
   3757 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
   3758         num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len/LEN_UUID_16;
   3759 #else  // BTA_EIR_CANNED_UUID_LIST
   3760         max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
   3761         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
   3762                                                  max_num_uuid, &num_uuid );
   3763         p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
   3764 #endif  // BTA_EIR_CANNED_UUID_LIST
   3765 
   3766         /* if UUID doesn't fit remaing space, shorten local name */
   3767         if (local_name_len > (free_eir_length - 4 - num_uuid*LEN_UUID_16))
   3768         {
   3769             local_name_len = find_utf8_char_boundary(local_name,
   3770                 p_bta_dm_eir_cfg->bta_dm_eir_min_name_len);
   3771             APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__, local_name_len);
   3772             data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
   3773         } else {
   3774             data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
   3775         }
   3776     }
   3777 
   3778     UINT8_TO_STREAM(p, local_name_len + 1);
   3779     UINT8_TO_STREAM(p, data_type);
   3780 
   3781     if (local_name != NULL)
   3782     {
   3783         memcpy(p, local_name, local_name_len);
   3784         p += local_name_len;
   3785     }
   3786     free_eir_length -= local_name_len + 2;
   3787 
   3788 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
   3789     /* if UUID list is provided as static data in configuration */
   3790     if(( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
   3791         &&(p_bta_dm_eir_cfg->bta_dm_eir_uuid16))
   3792     {
   3793         if( free_eir_length > LEN_UUID_16 + 2)
   3794         {
   3795             free_eir_length -= 2;
   3796 
   3797             if( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len)
   3798             {
   3799                 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
   3800                 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
   3801             }
   3802             else /* not enough room for all UUIDs */
   3803             {
   3804                 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
   3805                 num_uuid = free_eir_length / LEN_UUID_16;
   3806                 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
   3807             }
   3808             UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
   3809             UINT8_TO_STREAM(p, data_type);
   3810             memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
   3811             p += num_uuid * LEN_UUID_16;
   3812             free_eir_length -= num_uuid * LEN_UUID_16;
   3813         }
   3814     }
   3815 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
   3816     /* if UUID list is dynamic */
   3817     if ( free_eir_length >= 2)
   3818     {
   3819         p_length = p++;
   3820         p_type   = p++;
   3821         num_uuid = 0;
   3822 
   3823         max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
   3824         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
   3825 
   3826         if( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE )
   3827         {
   3828             APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
   3829         }
   3830 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
   3831         else
   3832         {
   3833             for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
   3834             {
   3835                 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16)
   3836                 {
   3837                     if ( num_uuid < max_num_uuid )
   3838                     {
   3839                         UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
   3840                         num_uuid++;
   3841                     }
   3842                     else
   3843                     {
   3844                         data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
   3845                         APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
   3846                         break;
   3847                     }
   3848                 }
   3849             }
   3850         }
   3851 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
   3852 
   3853         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
   3854         UINT8_TO_STREAM(p_type, data_type);
   3855         free_eir_length -= num_uuid * LEN_UUID_16 + 2;
   3856     }
   3857 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
   3858 
   3859 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
   3860     /* Adding 32-bit UUID list */
   3861     if ( free_eir_length >= 2)
   3862     {
   3863         p_length = p++;
   3864         p_type   = p++;
   3865         num_uuid = 0;
   3866         data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
   3867 
   3868         max_num_uuid = (free_eir_length - 2)/LEN_UUID_32;
   3869 
   3870         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
   3871         {
   3872             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32)
   3873             {
   3874                 if ( num_uuid < max_num_uuid )
   3875                 {
   3876                     UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
   3877                     num_uuid++;
   3878                 }
   3879                 else
   3880                 {
   3881                     data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
   3882                     APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
   3883                     break;
   3884                 }
   3885             }
   3886         }
   3887 
   3888         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
   3889         UINT8_TO_STREAM(p_type, data_type);
   3890         free_eir_length -= num_uuid * LEN_UUID_32 + 2;
   3891     }
   3892 
   3893     /* Adding 128-bit UUID list */
   3894     if ( free_eir_length >= 2)
   3895     {
   3896         p_length = p++;
   3897         p_type   = p++;
   3898         num_uuid = 0;
   3899         data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
   3900 
   3901         max_num_uuid = (free_eir_length - 2)/LEN_UUID_128;
   3902 
   3903         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
   3904         {
   3905             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128)
   3906             {
   3907                 if ( num_uuid < max_num_uuid )
   3908                 {
   3909                     ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
   3910                     num_uuid++;
   3911                 }
   3912                 else
   3913                 {
   3914                     data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
   3915                     APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
   3916                     break;
   3917                 }
   3918             }
   3919         }
   3920 
   3921         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
   3922         UINT8_TO_STREAM(p_type, data_type);
   3923         free_eir_length -= num_uuid * LEN_UUID_128 + 2;
   3924     }
   3925 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
   3926 
   3927     /* if Flags are provided in configuration */
   3928     if(( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
   3929      &&( p_bta_dm_eir_cfg->bta_dm_eir_flags )
   3930      &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 ))
   3931     {
   3932         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
   3933         UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
   3934         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
   3935                p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
   3936         p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
   3937         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
   3938     }
   3939 
   3940     /* if Manufacturer Specific are provided in configuration */
   3941     if(( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
   3942      &&( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
   3943      &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 ))
   3944     {
   3945         p_length = p;
   3946 
   3947         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
   3948         UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
   3949         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
   3950                p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
   3951         p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
   3952         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
   3953 
   3954     }
   3955     else
   3956     {
   3957         p_length = NULL;
   3958     }
   3959 
   3960     /* if Inquiry Tx Resp Power compiled */
   3961     if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
   3962         (free_eir_length >= 3))
   3963     {
   3964         UINT8_TO_STREAM(p, 2);      /* Length field */
   3965         UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
   3966         UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
   3967         free_eir_length -= 3;
   3968     }
   3969 
   3970     if( free_eir_length )
   3971         UINT8_TO_STREAM(p, 0); /* terminator of significant part */
   3972 
   3973     BTM_WriteEIR( p_buf );
   3974 
   3975 }
   3976 
   3977 /*******************************************************************************
   3978 **
   3979 ** Function         bta_dm_eir_search_services
   3980 **
   3981 ** Description      This function searches services in received EIR
   3982 **
   3983 ** Returns          None
   3984 **
   3985 *******************************************************************************/
   3986 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS  *p_result,
   3987                                         tBTA_SERVICE_MASK *p_services_to_search,
   3988                                         tBTA_SERVICE_MASK *p_services_found)
   3989 {
   3990     tBTA_SERVICE_MASK       service_index = 0;
   3991     tBTM_EIR_SEARCH_RESULT  result;
   3992 
   3993     APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
   3994                         p_result->remote_bd_addr[0],p_result->remote_bd_addr[1],
   3995                         p_result->remote_bd_addr[2],p_result->remote_bd_addr[3],
   3996                         p_result->remote_bd_addr[4],p_result->remote_bd_addr[5]);
   3997 
   3998     APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
   3999 
   4000 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
   4001     /* always do GATT based service discovery by SDP instead of from EIR    */
   4002     /* if GATT based service is also to be put in EIR, need to modify this  */
   4003     while (service_index < (BTA_MAX_SERVICE_ID - 1))
   4004 #else
   4005     while(service_index < BTA_MAX_SERVICE_ID)
   4006 #endif
   4007     {
   4008         if( *p_services_to_search
   4009            & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)))
   4010         {
   4011             result = BTM_HasInquiryEirService( p_result,
   4012                                                bta_service_id_to_uuid_lkup_tbl[service_index] );
   4013 
   4014             /* Searching for HSP v1.2 only device */
   4015             if ((result != BTM_EIR_FOUND) &&
   4016                 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET))
   4017             {
   4018                 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
   4019             }
   4020 
   4021             if( result == BTM_EIR_FOUND )
   4022             {
   4023                 /* If Plug and Play service record, need to check to see if Broadcom stack */
   4024                 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
   4025                 if( bta_service_id_to_uuid_lkup_tbl[service_index]
   4026                     != UUID_SERVCLASS_PNP_INFORMATION )
   4027                 {
   4028 
   4029                     *p_services_found |=
   4030                        (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
   4031                     /* remove the service from services to be searched  */
   4032                     *p_services_to_search &=
   4033                        (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
   4034                 }
   4035             }
   4036             else if( result == BTM_EIR_NOT_FOUND )
   4037             {
   4038                 /* remove the service from services to be searched  */
   4039                 *p_services_to_search &=
   4040                        (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
   4041             }
   4042         }
   4043 
   4044         service_index++;
   4045     }
   4046 
   4047     APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
   4048                         *p_services_to_search, *p_services_found);
   4049 }
   4050 
   4051 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
   4052 /*******************************************************************************
   4053 **
   4054 ** Function         bta_dm_eir_update_uuid
   4055 **
   4056 ** Description      This function adds or removes service UUID in EIR database.
   4057 **
   4058 ** Returns          None
   4059 **
   4060 *******************************************************************************/
   4061 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
   4062 {
   4063     /* if this UUID is not advertised in EIR */
   4064     if( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 ))
   4065         return;
   4066 
   4067     if( adding )
   4068     {
   4069         APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
   4070 
   4071         BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
   4072     }
   4073     else
   4074     {
   4075         APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
   4076 
   4077         BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
   4078     }
   4079 
   4080     bta_dm_set_eir (NULL);
   4081 
   4082     APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
   4083                        bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
   4084 }
   4085 #endif
   4086 
   4087 /*******************************************************************************
   4088 **
   4089 ** Function         bta_dm_enable_test_mode
   4090 **
   4091 ** Description      enable test mode
   4092 **
   4093 **
   4094 ** Returns          void
   4095 **
   4096 *******************************************************************************/
   4097 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
   4098 {
   4099     UNUSED(p_data);
   4100     BTM_EnableTestMode();
   4101 }
   4102 
   4103 /*******************************************************************************
   4104 **
   4105 ** Function         bta_dm_disable_test_mode
   4106 **
   4107 ** Description      disable test mode
   4108 **
   4109 **
   4110 ** Returns          void
   4111 **
   4112 *******************************************************************************/
   4113 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
   4114 {
   4115     UNUSED(p_data);
   4116     BTM_DeviceReset(NULL);
   4117 }
   4118 
   4119 /*******************************************************************************
   4120 **
   4121 ** Function         bta_dm_execute_callback
   4122 **
   4123 ** Description      Just execute a generic call back in the context of the BTU/BTA tack
   4124 **
   4125 **
   4126 ** Returns          void
   4127 **
   4128 *******************************************************************************/
   4129 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
   4130 {
   4131     /* sanity check */
   4132     if(p_data->exec_cback.p_exec_cback == NULL)
   4133     {
   4134         return;
   4135     }
   4136 
   4137     p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
   4138 }
   4139 
   4140 /*******************************************************************************
   4141 **
   4142 ** Function         bta_dm_encrypt_cback
   4143 **
   4144 ** Description      link encryption complete callback.
   4145 **
   4146 ** Returns         None
   4147 **
   4148 *******************************************************************************/
   4149 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
   4150 {
   4151     tBTA_STATUS   bta_status = BTA_SUCCESS;
   4152     tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
   4153     UINT8   i ;
   4154     UNUSED(p_ref_data);
   4155 
   4156     for (i=0; i<bta_dm_cb.device_list.count; i++)
   4157     {
   4158         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
   4159             bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
   4160             break;
   4161     }
   4162 
   4163     if (i < bta_dm_cb.device_list.count)
   4164     {
   4165         p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
   4166         bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
   4167     }
   4168 
   4169     switch (result)
   4170     {
   4171         case BTM_SUCCESS:
   4172             break;
   4173         case BTM_WRONG_MODE:
   4174             bta_status = BTA_WRONG_MODE;
   4175             break;
   4176         case BTM_NO_RESOURCES:
   4177             bta_status = BTA_NO_RESOURCES;
   4178             break;
   4179         case BTM_BUSY:
   4180             bta_status = BTA_BUSY;
   4181             break;
   4182         default:
   4183             bta_status = BTA_FAILURE;
   4184             break;
   4185     }
   4186 
   4187     APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
   4188 
   4189     if (p_callback)
   4190     {
   4191         (*p_callback)(bd_addr, transport, bta_status);
   4192     }
   4193 }
   4194 
   4195 /*******************************************************************************
   4196 **
   4197 ** Function         bta_dm_set_encryption
   4198 **
   4199 ** Description      This function to encrypt the link
   4200 **
   4201 ** Returns          None
   4202 **
   4203 *******************************************************************************/
   4204 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
   4205 {
   4206     UINT8 i ;
   4207 
   4208     APPL_TRACE_DEBUG("bta_dm_set_encryption"); //todo
   4209     if (!p_data->set_encryption.p_callback)
   4210     {
   4211         APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
   4212         return;
   4213     }
   4214     for (i=0; i<bta_dm_cb.device_list.count; i++)
   4215     {
   4216         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
   4217             bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
   4218             break;
   4219     }
   4220     if (i < bta_dm_cb.device_list.count)
   4221     {
   4222         if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
   4223         {
   4224             APPL_TRACE_ERROR("earlier enc was not done for same device");
   4225             (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
   4226                                              p_data->set_encryption.transport,
   4227                                              BTA_BUSY);
   4228             return;
   4229         }
   4230 
   4231         if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
   4232                               bta_dm_encrypt_cback, NULL, p_data->set_encryption.sec_act)
   4233                               == BTM_CMD_STARTED)
   4234         {
   4235             bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
   4236         }
   4237     }
   4238 }
   4239 
   4240 #if (BLE_INCLUDED == TRUE)
   4241 /*******************************************************************************
   4242 **
   4243 ** Function         bta_dm_observe_results_cb
   4244 **
   4245 ** Description      Callback for BLE Observe result
   4246 **
   4247 **
   4248 ** Returns          void
   4249 **
   4250 *******************************************************************************/
   4251 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
   4252 {
   4253 ;
   4254     tBTA_DM_SEARCH     result;
   4255     tBTM_INQ_INFO      *p_inq_info;
   4256     APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
   4257 
   4258     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
   4259     result.inq_res.rssi = p_inq->rssi;
   4260     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
   4261     result.inq_res.inq_result_type  = p_inq->inq_result_type;
   4262     result.inq_res.device_type      = p_inq->device_type;
   4263     result.inq_res.flag             = p_inq->flag;
   4264 
   4265     /* application will parse EIR to find out remote device name */
   4266     result.inq_res.p_eir = p_eir;
   4267 
   4268     if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
   4269     {
   4270         /* initialize remt_name_not_required to FALSE so that we get the name by default */
   4271         result.inq_res.remt_name_not_required = FALSE;
   4272     }
   4273 
   4274     if(bta_dm_search_cb.p_scan_cback)
   4275         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
   4276 
   4277     if(p_inq_info)
   4278     {
   4279         /* application indicates if it knows the remote name, inside the callback
   4280          copy that to the inquiry data base*/
   4281         if(result.inq_res.remt_name_not_required)
   4282             p_inq_info->appl_knows_rem_name = TRUE;
   4283     }
   4284 }
   4285 
   4286 /*******************************************************************************
   4287 **
   4288 ** Function         bta_dm_observe_cmpl_cb
   4289 **
   4290 ** Description      Callback for BLE Observe complete
   4291 **
   4292 **
   4293 ** Returns          void
   4294 **
   4295 *******************************************************************************/
   4296 static void bta_dm_observe_cmpl_cb (void * p_result)
   4297 {
   4298     tBTA_DM_SEARCH  data;
   4299 
   4300     APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
   4301 
   4302     data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
   4303     if (bta_dm_search_cb.p_scan_cback)
   4304     {
   4305         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
   4306     }
   4307 }
   4308 
   4309 #if (SMP_INCLUDED == TRUE)
   4310 /*******************************************************************************
   4311 **
   4312 ** Function         bta_dm_ble_smp_cback
   4313 **
   4314 ** Description      Callback for BLE SMP
   4315 **
   4316 **
   4317 ** Returns          void
   4318 **
   4319 *******************************************************************************/
   4320 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
   4321 {
   4322     tBTM_STATUS status = BTM_SUCCESS;
   4323     tBTA_DM_SEC sec_event;
   4324     char *p_name = NULL;
   4325 
   4326     if (!bta_dm_cb.p_sec_cback)
   4327         return BTM_NOT_AUTHORIZED;
   4328 
   4329     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
   4330     switch (event)
   4331     {
   4332         case BTM_LE_IO_REQ_EVT:
   4333 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
   4334 
   4335             bta_dm_co_ble_io_req(bda,
   4336                                  &p_data->io_req.io_cap,
   4337                                  &p_data->io_req.oob_data,
   4338                                  &p_data->io_req.auth_req,
   4339                                  &p_data->io_req.max_key_size,
   4340                                  &p_data->io_req.init_keys,
   4341                                  &p_data->io_req.resp_keys);
   4342 #endif
   4343             APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
   4344 
   4345             break;
   4346 
   4347         case BTM_LE_SEC_REQUEST_EVT:
   4348             bdcpy(sec_event.ble_req.bd_addr, bda);
   4349             p_name = BTM_SecReadDevName(bda);
   4350             if (p_name != NULL)
   4351                 strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
   4352             else
   4353                 sec_event.ble_req.bd_name[0] = 0;
   4354             bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
   4355             break;
   4356 
   4357         case BTM_LE_KEY_NOTIF_EVT:
   4358             bdcpy(sec_event.key_notif.bd_addr, bda);
   4359             p_name = BTM_SecReadDevName(bda);
   4360             if (p_name != NULL)
   4361                 strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
   4362             else
   4363                 sec_event.key_notif.bd_name[0] = 0;
   4364             sec_event.key_notif.passkey = p_data->key_notif;
   4365             bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
   4366             break;
   4367 
   4368         case BTM_LE_KEY_REQ_EVT:
   4369             bdcpy(sec_event.ble_req.bd_addr, bda);
   4370             bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
   4371             break;
   4372 
   4373         case BTM_LE_OOB_REQ_EVT:
   4374             bdcpy(sec_event.ble_req.bd_addr, bda);
   4375             bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
   4376             break;
   4377 
   4378         case BTM_LE_NC_REQ_EVT:
   4379             bdcpy(sec_event.key_notif.bd_addr, bda);
   4380             strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
   4381             sec_event.key_notif.passkey = p_data->key_notif;
   4382             bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
   4383             break;
   4384 
   4385         case BTM_LE_KEY_EVT:
   4386             bdcpy(sec_event.ble_key.bd_addr, bda);
   4387             sec_event.ble_key.key_type = p_data->key.key_type;
   4388             sec_event.ble_key.p_key_value = p_data->key.p_key_value;
   4389             bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
   4390             break;
   4391 
   4392         case BTM_LE_COMPLT_EVT:
   4393             bdcpy(sec_event.auth_cmpl.bd_addr, bda);
   4394 #if BLE_INCLUDED == TRUE
   4395             BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
   4396 #endif
   4397             p_name = BTM_SecReadDevName(bda);
   4398             if (p_name != NULL)
   4399                 strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
   4400             else
   4401                 sec_event.auth_cmpl.bd_name[0] = 0;
   4402 
   4403             if (p_data->complt.reason != 0)
   4404             {
   4405                 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
   4406                 /* delete this device entry from Sec Dev DB */
   4407                 bta_dm_remove_sec_dev_entry (bda);
   4408             }
   4409             else
   4410             {
   4411                 sec_event.auth_cmpl.success = TRUE;
   4412                 if (!p_data->complt.smp_over_br)
   4413                     GATT_ConfigServiceChangeCCC(bda, TRUE, BT_TRANSPORT_LE);
   4414             }
   4415 
   4416             if (bta_dm_cb.p_sec_cback)
   4417             {
   4418                 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
   4419                 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
   4420             }
   4421             break;
   4422 
   4423         default:
   4424             status = BTM_NOT_AUTHORIZED;
   4425             break;
   4426     }
   4427     return status;
   4428 }
   4429 #endif  /* SMP_INCLUDED == TRUE */
   4430 
   4431 /*******************************************************************************
   4432 **
   4433 ** Function         bta_dm_ble_id_key_cback
   4434 **
   4435 ** Description      Callback for BLE local ID keys
   4436 **
   4437 **
   4438 ** Returns          void
   4439 **
   4440 *******************************************************************************/
   4441 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
   4442 {
   4443     UINT8   evt;
   4444     tBTA_DM_SEC dm_key;
   4445 
   4446     switch (key_type)
   4447     {
   4448         case BTM_BLE_KEY_TYPE_ID:
   4449         case BTM_BLE_KEY_TYPE_ER:
   4450             if (bta_dm_cb.p_sec_cback)
   4451             {
   4452                 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
   4453 
   4454                 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT :\
   4455                       BTA_DM_BLE_LOCAL_ER_EVT;
   4456                 bta_dm_cb.p_sec_cback(evt, &dm_key);
   4457             }
   4458             break;
   4459 
   4460         default:
   4461             APPL_TRACE_DEBUG("Unknown key type %d", key_type);
   4462             break;
   4463     }
   4464     return;
   4465 
   4466 }
   4467 
   4468 /*******************************************************************************
   4469 **
   4470 ** Function         bta_dm_add_blekey
   4471 **
   4472 ** Description      This function adds an BLE Key to an security database entry.
   4473 **                  This function shall only be called AFTER BTA_DmAddBleDevice has been called.
   4474 **                  It is normally called during host startup to restore all required information
   4475 **                  stored in the NVRAM.
   4476 **
   4477 ** Parameters:
   4478 **
   4479 *******************************************************************************/
   4480 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
   4481 {
   4482     if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
   4483                            (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
   4484                            p_data->add_ble_key.key_type))
   4485     {
   4486         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
   4487                            (p_data->add_ble_key.bd_addr[0]<<24)+(p_data->add_ble_key.bd_addr[1]<<16)+\
   4488                            (p_data->add_ble_key.bd_addr[2]<<8)+p_data->add_ble_key.bd_addr[3],
   4489                            (p_data->add_ble_key.bd_addr[4]<<8)+p_data->add_ble_key.bd_addr[5]);
   4490     }
   4491 }
   4492 
   4493 /*******************************************************************************
   4494 **
   4495 ** Function         bta_dm_add_ble_device
   4496 **
   4497 ** Description      This function adds an BLE device to an security database entry.
   4498 **                  It is normally called during host startup to restore all required information
   4499 **                  stored in the NVRAM.
   4500 **
   4501 ** Parameters:
   4502 **
   4503 *******************************************************************************/
   4504 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
   4505 {
   4506     if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
   4507                               p_data->add_ble_device.dev_type  ,
   4508                               p_data->add_ble_device.addr_type))
   4509     {
   4510         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
   4511                            (p_data->add_ble_device.bd_addr[0]<<24)+(p_data->add_ble_device.bd_addr[1]<<16)+ \
   4512                            (p_data->add_ble_device.bd_addr[2]<<8)+p_data->add_ble_device.bd_addr[3],
   4513                            (p_data->add_ble_device.bd_addr[4]<<8)+p_data->add_ble_device.bd_addr[5]);
   4514     }
   4515 }
   4516 
   4517 /*******************************************************************************
   4518 **
   4519 ** Function         bta_dm_add_ble_device
   4520 **
   4521 ** Description      This function adds an BLE device to an security database entry.
   4522 **                  It is normally called during host startup to restore all required information
   4523 **                  stored in the NVRAM.
   4524 **
   4525 ** Parameters:
   4526 **
   4527 *******************************************************************************/
   4528 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
   4529 {
   4530     if (p_data->pin_reply.accept)
   4531     {
   4532         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
   4533     }
   4534     else
   4535     {
   4536         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
   4537     }
   4538 
   4539 }
   4540 
   4541 /*******************************************************************************
   4542 **
   4543 ** Function         bta_dm_ble_confirm_reply
   4544 **
   4545 ** Description      This is response to SM numeric comparison request submitted
   4546 **                  to application.
   4547 **
   4548 ** Parameters:
   4549 **
   4550 *******************************************************************************/
   4551 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
   4552 {
   4553     if (p_data->confirm.accept)
   4554     {
   4555         BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
   4556     }
   4557     else
   4558     {
   4559         BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
   4560     }
   4561 }
   4562 
   4563 /*******************************************************************************
   4564 **
   4565 ** Function         bta_dm_security_grant
   4566 **
   4567 ** Description      This function grant SMP security request access.
   4568 **
   4569 ** Parameters:
   4570 **
   4571 *******************************************************************************/
   4572 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
   4573 {
   4574     BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
   4575 }
   4576 
   4577 /*******************************************************************************
   4578 **
   4579 ** Function         bta_dm_ble_set_bg_conn_type
   4580 **
   4581 ** Description      This function set the BLE background connection type
   4582 **
   4583 ** Parameters:
   4584 **
   4585 *******************************************************************************/
   4586 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
   4587 {
   4588     BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
   4589                          p_data->ble_set_bd_conn_type.p_select_cback);
   4590 }
   4591 
   4592 /*******************************************************************************
   4593 **
   4594 ** Function         bta_dm_ble_set_conn_params
   4595 **
   4596 ** Description      This function set the preferred connection parameters.
   4597 **
   4598 ** Parameters:
   4599 **
   4600 *******************************************************************************/
   4601 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
   4602 {
   4603     BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
   4604                              p_data->ble_set_conn_params.conn_int_min,
   4605                              p_data->ble_set_conn_params.conn_int_max,
   4606                              p_data->ble_set_conn_params.slave_latency,
   4607                              p_data->ble_set_conn_params.supervision_tout);
   4608 }
   4609 
   4610 /*******************************************************************************
   4611 **
   4612 ** Function         bta_dm_ble_set_conn_scan_params
   4613 **
   4614 ** Description      This function sets BLE scan parameters.
   4615 **
   4616 ** Parameters:
   4617 **
   4618 *******************************************************************************/
   4619 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
   4620 {
   4621     BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
   4622                          p_data->ble_set_scan_params.scan_int,
   4623                          p_data->ble_set_scan_params.scan_window,
   4624                          p_data->ble_set_scan_params.scan_mode,
   4625                          p_data->ble_set_scan_params.scan_param_setup_cback);
   4626 }
   4627 
   4628 /*******************************************************************************
   4629 **
   4630 ** Function         bta_dm_ble_set_conn_scan_params
   4631 **
   4632 ** Description      This function set the preferred connection scan parameters.
   4633 **
   4634 ** Parameters:
   4635 **
   4636 *******************************************************************************/
   4637 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
   4638 {
   4639     BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
   4640                              p_data->ble_set_conn_scan_params.scan_window);
   4641 }
   4642 /*******************************************************************************
   4643 **
   4644 ** Function         bta_dm_ble_update_conn_params
   4645 **
   4646 ** Description      This function update LE connection parameters.
   4647 **
   4648 ** Parameters:
   4649 **
   4650 *******************************************************************************/
   4651 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
   4652 {
   4653     if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
   4654                                  p_data->ble_update_conn_params.min_int,
   4655                                  p_data->ble_update_conn_params.max_int,
   4656                                  p_data->ble_update_conn_params.latency,
   4657                                  p_data->ble_update_conn_params.timeout))
   4658     {
   4659         APPL_TRACE_ERROR("Update connection parameters failed!");
   4660     }
   4661 }
   4662 
   4663 #if BLE_PRIVACY_SPT == TRUE
   4664 /*******************************************************************************
   4665 **
   4666 ** Function         bta_dm_ble_config_local_privacy
   4667 **
   4668 ** Description      This function set the local device LE privacy settings.
   4669 **
   4670 ** Parameters:
   4671 **
   4672 *******************************************************************************/
   4673 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
   4674 {
   4675     BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
   4676 }
   4677 #endif
   4678 
   4679 /*******************************************************************************
   4680 **
   4681 ** Function         bta_dm_ble_observe
   4682 **
   4683 ** Description      This function set the preferred connection scan parameters.
   4684 **
   4685 ** Parameters:
   4686 **
   4687 *******************************************************************************/
   4688 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
   4689 {
   4690     tBTM_STATUS status;
   4691     if (p_data->ble_observe.start)
   4692     {
   4693         /*Save the  callback to be called when a scan results are available */
   4694         bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
   4695         if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
   4696                             bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_CMD_STARTED)
   4697         {
   4698             tBTA_DM_SEARCH  data;
   4699             APPL_TRACE_WARNING(" %s BTM_BleObserve  failed. status %d",__FUNCTION__,status);
   4700             data.inq_cmpl.num_resps = 0;
   4701             if (bta_dm_search_cb.p_scan_cback)
   4702             {
   4703                 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
   4704             }
   4705         }
   4706     }
   4707     else
   4708     {
   4709         bta_dm_search_cb.p_scan_cback = NULL;
   4710         BTM_BleObserve(FALSE, 0, NULL,NULL );
   4711     }
   4712 }
   4713 /*******************************************************************************
   4714 **
   4715 ** Function         bta_dm_ble_set_adv_params
   4716 **
   4717 ** Description      This function set the adv parameters.
   4718 **
   4719 ** Parameters:
   4720 **
   4721 *******************************************************************************/
   4722 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
   4723 {
   4724     BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
   4725                         p_data->ble_set_adv_params.adv_int_max,
   4726                         p_data->ble_set_adv_params.p_dir_bda,
   4727                         BTA_DM_BLE_ADV_CHNL_MAP);
   4728 }
   4729 
   4730 /*******************************************************************************
   4731 **
   4732 ** Function         bta_dm_ble_set_adv_config
   4733 **
   4734 ** Description      This function set the customized ADV data configuration
   4735 **
   4736 ** Parameters:
   4737 **
   4738 *******************************************************************************/
   4739 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
   4740 {
   4741     tBTA_STATUS status = BTA_FAILURE;
   4742 
   4743     if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
   4744                         (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
   4745     {
   4746         status = BTA_SUCCESS;
   4747     }
   4748 
   4749     if (p_data->ble_set_adv_data.p_adv_data_cback)
   4750         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
   4751 }
   4752 
   4753 /*******************************************************************************
   4754 **
   4755 ** Function         bta_dm_ble_set_scan_rsp
   4756 **
   4757 ** Description      This function set the customized ADV scan resp. configuration
   4758 **
   4759 ** Parameters:
   4760 **
   4761 *******************************************************************************/
   4762 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
   4763 {
   4764     tBTA_STATUS status = BTA_FAILURE;
   4765 
   4766     if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
   4767                         (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
   4768     {
   4769         status = BTA_SUCCESS;
   4770     }
   4771 
   4772     if (p_data->ble_set_adv_data.p_adv_data_cback)
   4773         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
   4774 }
   4775 
   4776 /*******************************************************************************
   4777 **
   4778 ** Function         bta_dm_ble_set_data_length
   4779 **
   4780 ** Description      This function set the maximum transmission packet size
   4781 **
   4782 ** Parameters
   4783 **
   4784 *******************************************************************************/
   4785 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
   4786 {
   4787     if (BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
   4788                         p_data->ble_set_data_length.tx_data_length) != BTM_SUCCESS)
   4789     {
   4790         APPL_TRACE_ERROR("%s failed", __FUNCTION__);
   4791     }
   4792 }
   4793 
   4794 /*******************************************************************************
   4795 **
   4796 ** Function         bta_dm_ble_broadcast
   4797 **
   4798 ** Description      Starts or stops LE broadcasts
   4799 **
   4800 ** Parameters:
   4801 **
   4802 *******************************************************************************/
   4803 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
   4804 {
   4805     BTM_BleBroadcast(p_data->ble_observe.start);
   4806 }
   4807 
   4808 /*******************************************************************************
   4809 **
   4810 ** Function         bta_dm_ble_multi_adv_enb
   4811 **
   4812 ** Description      This function enables a single advertising instance
   4813 **
   4814 ** Parameters:
   4815 **
   4816 *******************************************************************************/
   4817 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
   4818 {
   4819     tBTM_STATUS btm_status = 0;
   4820 
   4821     bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
   4822     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref)
   4823     {
   4824         btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*)
   4825                                             p_data->ble_multi_adv_enb.p_params,
   4826                                             p_data->ble_multi_adv_enb.p_cback,
   4827                                             p_data->ble_multi_adv_enb.p_ref);
   4828     }
   4829 
   4830     if(BTM_CMD_STARTED != btm_status)
   4831     {
   4832         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
   4833                                     p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
   4834     }
   4835 }
   4836 /*******************************************************************************
   4837 **
   4838 ** Function         bta_dm_ble_multi_adv_param_upd
   4839 **
   4840 ** Description      This function updates multiple advertising instance parameters
   4841 **
   4842 ** Parameters:
   4843 **
   4844 *******************************************************************************/
   4845 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
   4846 {
   4847     tBTM_STATUS btm_status = 0;
   4848     void *p_ref = NULL;
   4849 
   4850     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
   4851         && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount())
   4852     {
   4853         btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
   4854                          (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params);
   4855     }
   4856 
   4857     if(BTM_CMD_STARTED != btm_status)
   4858     {
   4859        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
   4860        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
   4861                                    p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
   4862     }
   4863 }
   4864 /*******************************************************************************
   4865 **
   4866 ** Function         bta_dm_ble_multi_adv_data
   4867 **
   4868 ** Description      This function write multiple advertising instance adv data
   4869 **                  or scan response data
   4870 **
   4871 ** Parameters:
   4872 **
   4873 *******************************************************************************/
   4874 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
   4875 {
   4876     tBTM_STATUS btm_status = 0;
   4877     void *p_ref = NULL;
   4878 
   4879     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
   4880         && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount())
   4881     {
   4882         btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
   4883                         p_data->ble_multi_adv_data.is_scan_rsp,
   4884                         p_data->ble_multi_adv_data.data_mask,
   4885                         (tBTM_BLE_ADV_DATA*)&p_data->ble_multi_adv_data.data);
   4886     }
   4887 
   4888     if(BTM_CMD_STARTED != btm_status)
   4889     {
   4890        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
   4891        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
   4892                                    p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
   4893     }
   4894 
   4895 }
   4896 /*******************************************************************************
   4897 **
   4898 ** Function         btm_dm_ble_multi_adv_disable
   4899 **
   4900 ** Description      This function disable a single adv instance
   4901 **
   4902 ** Parameters:
   4903 **
   4904 *******************************************************************************/
   4905 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
   4906 {
   4907     tBTM_STATUS btm_status = 0;
   4908     void *p_ref = NULL;
   4909 
   4910     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
   4911         && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount())
   4912     {
   4913         btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
   4914     }
   4915 
   4916     if(BTM_CMD_STARTED != btm_status)
   4917     {
   4918        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
   4919        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
   4920                                    p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
   4921     }
   4922 }
   4923 
   4924 /*******************************************************************************
   4925 **
   4926 ** Function         bta_dm_ble_setup_storage
   4927 **
   4928 ** Description      This function configures up the storage parameters for ADV batch scanning
   4929 **
   4930 ** Parameters:
   4931 **
   4932 *******************************************************************************/
   4933 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
   4934 {
   4935     tBTM_STATUS btm_status = 0;
   4936     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
   4937 
   4938     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
   4939 
   4940     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
   4941     {
   4942         btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
   4943                                              p_data->ble_set_storage.batch_scan_trunc_max,
   4944                                              p_data->ble_set_storage.batch_scan_notify_threshold,
   4945                                              p_data->ble_set_storage.p_setup_cback,
   4946                                              p_data->ble_set_storage.p_thres_cback,
   4947                                              p_data->ble_set_storage.p_read_rep_cback,
   4948                                              p_data->ble_set_storage.ref_value);
   4949     }
   4950 
   4951     if(BTM_CMD_STARTED != btm_status)
   4952        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
   4953                              btm_status);
   4954 }
   4955 
   4956 /*******************************************************************************
   4957 **
   4958 ** Function         bta_dm_ble_enable_batch_scan
   4959 **
   4960 ** Description      This function sets up the parameters and enables batch scan
   4961 **
   4962 ** Parameters:
   4963 **
   4964 *******************************************************************************/
   4965 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
   4966 {
   4967     tBTM_STATUS btm_status = 0;
   4968     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
   4969 
   4970     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
   4971 
   4972     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
   4973     {
   4974         btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
   4975                                             p_data->ble_enable_scan.scan_int,
   4976                                             p_data->ble_enable_scan.scan_window,
   4977                                             p_data->ble_enable_scan.discard_rule,
   4978                                             p_data->ble_enable_scan.addr_type,
   4979                                             p_data->ble_enable_scan.ref_value);
   4980     }
   4981 
   4982     if(BTM_CMD_STARTED != btm_status)
   4983        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
   4984                              btm_status);
   4985 }
   4986 
   4987 /*******************************************************************************
   4988 **
   4989 ** Function         bta_dm_ble_disable_batch_scan
   4990 **
   4991 ** Description      This function disables the batch scan
   4992 **
   4993 ** Parameters:
   4994 **
   4995 *******************************************************************************/
   4996 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
   4997 {
   4998     UNUSED(p_data);
   4999     tBTM_STATUS btm_status = 0;
   5000     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
   5001 
   5002     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
   5003 
   5004     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
   5005     {
   5006         btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
   5007     }
   5008 
   5009     if(BTM_CMD_STARTED != btm_status)
   5010        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
   5011                              btm_status);
   5012 }
   5013 
   5014 /*******************************************************************************
   5015 **
   5016 ** Function         bta_dm_ble_read_scan_reports
   5017 **
   5018 ** Description      This function reads the batch scan reports
   5019 **
   5020 ** Parameters:
   5021 **
   5022 *******************************************************************************/
   5023 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
   5024 {
   5025     tBTM_STATUS btm_status = 0;
   5026     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
   5027 
   5028     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
   5029 
   5030     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
   5031     {
   5032         btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
   5033                                             p_data->ble_read_reports.ref_value);
   5034     }
   5035 
   5036     if(BTM_CMD_STARTED != btm_status)
   5037        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
   5038                              btm_status);
   5039 }
   5040 
   5041 /*******************************************************************************
   5042 **
   5043 ** Function         bta_dm_ble_track_advertiser
   5044 **
   5045 ** Description      This function tracks the specific advertiser
   5046 **
   5047 ** Parameters:
   5048 **
   5049 *******************************************************************************/
   5050 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
   5051 {
   5052     tBTM_STATUS btm_status = 0;
   5053     BD_ADDR bda;
   5054     memset(&bda, 0 , sizeof(BD_ADDR));
   5055     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
   5056     tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
   5057 
   5058     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
   5059 
   5060     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
   5061     {
   5062         btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
   5063                                             p_data->ble_track_advert.p_track_adv_cback,
   5064                                             p_data->ble_track_advert.ref_value);
   5065     }
   5066 
   5067     if(BTM_CMD_STARTED != btm_status)
   5068     {
   5069         memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
   5070         track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
   5071         track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
   5072         p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
   5073     }
   5074 }
   5075 
   5076 /*******************************************************************************
   5077 **
   5078 ** Function         bta_ble_scan_setup_cb
   5079 **
   5080 ** Description      Handle the setup callback from BTM layer and forward it to app layer
   5081 **
   5082 ** Parameters:
   5083 **
   5084 *******************************************************************************/
   5085 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
   5086                                   tBTM_STATUS status)
   5087 {
   5088     tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
   5089 
   5090     APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
   5091                       ref_value, status);
   5092 
   5093     switch(evt)
   5094     {
   5095         case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
   5096            bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
   5097            break;
   5098         case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
   5099            bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
   5100            break;
   5101         case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
   5102             bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
   5103             break;
   5104         case BTM_BLE_BATCH_SCAN_PARAM_EVT:
   5105             bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
   5106             break;
   5107         default:
   5108             break;
   5109     }
   5110 
   5111     if(NULL != bta_dm_cb.p_setup_cback)
   5112        bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
   5113 }
   5114 
   5115 
   5116 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
   5117 /*******************************************************************************
   5118 **
   5119 ** Function         bta_ble_scan_pf_cmpl
   5120 **
   5121 ** Description      ADV payload filtering operation complete callback
   5122 **
   5123 **
   5124 ** Returns         TRUE if handled, otherwise FALSE.
   5125 **
   5126 *******************************************************************************/
   5127 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
   5128                                  tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
   5129                                  tBTM_BLE_REF_VALUE ref_value)
   5130 {
   5131     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
   5132 
   5133     APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
   5134 
   5135     if(bta_dm_cb.p_scan_filt_cfg_cback)
   5136        bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
   5137 }
   5138 
   5139 /*******************************************************************************
   5140 **
   5141 ** Function         bta_dm_cfg_filter_cond
   5142 **
   5143 ** Description      This function configure adv payload filtering condition
   5144 **
   5145 ** Parameters:
   5146 **
   5147 *******************************************************************************/
   5148 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
   5149 {
   5150     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
   5151     tBTA_STATUS status = BTA_FAILURE;
   5152 
   5153     tBTM_BLE_VSC_CB cmn_vsc_cb;
   5154 
   5155     APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
   5156     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
   5157     if(0 != cmn_vsc_cb.filter_support)
   5158     {
   5159         if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
   5160                             p_data->ble_cfg_filter_cond.cond_type,
   5161                             (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
   5162                             (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
   5163                             bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
   5164                 == BTM_CMD_STARTED)
   5165         {
   5166             bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
   5167             return;
   5168         }
   5169     }
   5170 
   5171     if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
   5172         p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
   5173                                             p_data->ble_cfg_filter_cond.cond_type, 0, status,
   5174                                             p_data->ble_cfg_filter_cond.ref_value);
   5175     return;
   5176 }
   5177 
   5178 /*******************************************************************************
   5179 **
   5180 ** Function         bta_dm_enable_scan_filter
   5181 **
   5182 ** Description      This function enable/disable adv payload filtering condition
   5183 **
   5184 ** Parameters:
   5185 **
   5186 *******************************************************************************/
   5187 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
   5188 {
   5189     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
   5190     tBTA_STATUS status = BTA_FAILURE;
   5191 
   5192     tBTM_BLE_VSC_CB cmn_vsc_cb;
   5193     APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
   5194     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
   5195 
   5196     if(0 != cmn_vsc_cb.filter_support)
   5197     {
   5198         if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
   5199                    p_data->ble_enable_scan_filt.p_filt_status_cback,
   5200                    (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED)
   5201         bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
   5202         return;
   5203     }
   5204 
   5205     if (p_data->ble_enable_scan_filt.p_filt_status_cback)
   5206         p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
   5207                                             p_data->ble_enable_scan_filt.ref_value, status);
   5208 
   5209 }
   5210 
   5211 /*******************************************************************************
   5212 **
   5213 ** Function         bta_dm_scan_filter_param_setup
   5214 **
   5215 ** Description      This function sets up scan filter params
   5216 **
   5217 ** Parameters:
   5218 **
   5219 *******************************************************************************/
   5220 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
   5221 {
   5222     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
   5223     tBTA_STATUS status = BTA_FAILURE;
   5224 
   5225     tBTM_BLE_VSC_CB cmn_vsc_cb;
   5226 
   5227     APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
   5228     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
   5229     if(0 != cmn_vsc_cb.filter_support)
   5230     {
   5231         if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
   5232                    p_data->ble_scan_filt_param_setup.filt_index,
   5233                   (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
   5234                    p_data->ble_scan_filt_param_setup.p_target,
   5235                    p_data->ble_scan_filt_param_setup.p_filt_param_cback,
   5236                    p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED)
   5237         {
   5238             bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
   5239             return;
   5240         }
   5241     }
   5242 
   5243     if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
   5244         p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
   5245                                         p_data->ble_scan_filt_param_setup.ref_value, status);
   5246 
   5247     return;
   5248 }
   5249 #endif
   5250 
   5251 /*******************************************************************************
   5252 **
   5253 ** Function         bta_ble_enable_scan_cmpl
   5254 **
   5255 ** Description      ADV payload filtering enable / disable complete callback
   5256 **
   5257 **
   5258 ** Returns          None
   5259 **
   5260 *******************************************************************************/
   5261 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
   5262                                         tBTM_BLE_RX_TIME_MS rx_time,
   5263                                         tBTM_BLE_IDLE_TIME_MS idle_time,
   5264                                         tBTM_BLE_ENERGY_USED  energy_used,
   5265                                         tBTM_STATUS status)
   5266 {
   5267     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
   5268     tBTA_DM_CONTRL_STATE ctrl_state = 0;
   5269 
   5270     if (BTA_SUCCESS == st)
   5271        ctrl_state = bta_dm_pm_obtain_controller_state();
   5272 
   5273     if (bta_dm_cb.p_energy_info_cback)
   5274         bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
   5275 }
   5276 
   5277 /*******************************************************************************
   5278 **
   5279 ** Function         bta_dm_ble_get_energy_info
   5280 **
   5281 ** Description      This function obtains the energy info
   5282 **
   5283 ** Parameters:
   5284 **
   5285 *******************************************************************************/
   5286 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
   5287 {
   5288     tBTM_STATUS btm_status = 0;
   5289 
   5290     bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
   5291     btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
   5292     if (BTM_CMD_STARTED != btm_status)
   5293         bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
   5294 }
   5295 
   5296 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
   5297 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
   5298 #define BTA_DM_GATT_CLOSE_DELAY_TOUT    1000
   5299 #endif
   5300 
   5301 /*******************************************************************************
   5302 **
   5303 ** Function         bta_dm_gattc_register
   5304 **
   5305 ** Description      Register with GATTC in DM if BLE is needed.
   5306 **
   5307 **
   5308 ** Returns          void
   5309 **
   5310 *******************************************************************************/
   5311 static void bta_dm_gattc_register(void)
   5312 {
   5313     tBT_UUID                app_uuid = {LEN_UUID_128,{0}};
   5314 
   5315     if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF)
   5316     {
   5317         memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
   5318         BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
   5319     }
   5320 }
   5321 
   5322 /*******************************************************************************
   5323 **
   5324 ** Function         btm_dm_start_disc_gatt_services
   5325 **
   5326 ** Description      This function starts a GATT service search request.
   5327 **
   5328 ** Parameters:
   5329 **
   5330 *******************************************************************************/
   5331 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
   5332 {
   5333     tBT_UUID    *p_uuid = bta_dm_search_cb.p_srvc_uuid +
   5334                           bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
   5335 
   5336     p_uuid = bta_dm_search_cb.p_srvc_uuid +
   5337              bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
   5338 
   5339     /* always search for all services */
   5340     BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
   5341 }
   5342 
   5343 /*******************************************************************************
   5344 **
   5345 ** Function         bta_dm_gatt_disc_result
   5346 **
   5347 ** Description      This function process the GATT service search result.
   5348 **
   5349 ** Parameters:
   5350 **
   5351 *******************************************************************************/
   5352 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
   5353 {
   5354     tBTA_DM_SEARCH   result;
   5355 
   5356     /*
   5357         * This logic will not work for gatt case.  We are checking against the bluetooth profiles here
   5358         * just copy the GATTID in raw data field and send it across.
   5359         */
   5360 
   5361 
   5362     if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size )
   5363     {
   5364         APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x",
   5365             service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);
   5366 
   5367         if(bta_dm_search_cb.p_ble_rawdata)
   5368         {
   5369             memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
   5370                    sizeof(service_id) );
   5371 
   5372             bta_dm_search_cb.ble_raw_used += sizeof(service_id);
   5373         }
   5374         else
   5375         {
   5376             APPL_TRACE_ERROR("p_ble_rawdata is NULL");
   5377         }
   5378 
   5379     }
   5380     else
   5381     {
   5382         APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__,bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
   5383     }
   5384 
   5385     LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
   5386     if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
   5387     {
   5388 
   5389         /* send result back to app now, one by one */
   5390         bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
   5391         strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
   5392         memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
   5393 
   5394         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
   5395     }
   5396 }
   5397 
   5398 /*******************************************************************************
   5399 **
   5400 ** Function         bta_dm_gatt_disc_complete
   5401 **
   5402 ** Description      This function process the GATT service search complete.
   5403 **
   5404 ** Parameters:
   5405 **
   5406 *******************************************************************************/
   5407 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
   5408 {
   5409     APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id);
   5410 
   5411     if (bta_dm_search_cb.uuid_to_search > 0)
   5412         bta_dm_search_cb.uuid_to_search --;
   5413 
   5414     if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
   5415         btm_dm_start_disc_gatt_services(conn_id);
   5416     } else {
   5417         tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
   5418 
   5419         bta_dm_search_cb.uuid_to_search = 0;
   5420 
   5421         /* no more services to be discovered */
   5422         p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
   5423         p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS :BTA_FAILURE;
   5424         APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__,
   5425                          bta_dm_search_cb.services_found);
   5426         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
   5427         p_msg->disc_result.result.disc_res.num_uuids = 0;
   5428         p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
   5429         bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
   5430               bta_dm_search_cb.peer_bdaddr);
   5431         strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
   5432                 bta_dm_get_remname(), BD_NAME_LEN);
   5433 
   5434         p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
   5435         if (bta_dm_search_cb.ble_raw_used > 0) {
   5436             p_msg->disc_result.result.disc_res.p_raw_data =
   5437                 osi_malloc(bta_dm_search_cb.ble_raw_used);
   5438 
   5439             memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
   5440                    bta_dm_search_cb.p_ble_rawdata,
   5441                    bta_dm_search_cb.ble_raw_used);
   5442 
   5443             p_msg->disc_result.result.disc_res.raw_data_size =
   5444                 bta_dm_search_cb.ble_raw_used;
   5445         } else {
   5446             p_msg->disc_result.result.disc_res.p_raw_data = NULL;
   5447             bta_dm_search_cb.p_ble_rawdata = 0;
   5448         }
   5449 
   5450         bta_sys_sendmsg(p_msg);
   5451 
   5452         if (conn_id != BTA_GATT_INVALID_CONN_ID)
   5453         {
   5454             /* start a GATT channel close delay timer */
   5455             bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
   5456                                 BTA_DM_GATT_CLOSE_DELAY_TOUT,
   5457                                 BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
   5458             bdcpy(bta_dm_search_cb.pending_close_bda,
   5459                   bta_dm_search_cb.peer_bdaddr);
   5460         }
   5461         bta_dm_search_cb.gatt_disc_active = FALSE;
   5462     }
   5463 }
   5464 
   5465 /*******************************************************************************
   5466 **
   5467 ** Function         bta_dm_close_gatt_conn
   5468 **
   5469 ** Description      This function close the GATT connection after delay timeout.
   5470 **
   5471 ** Parameters:
   5472 **
   5473 *******************************************************************************/
   5474 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
   5475 {
   5476     UNUSED(p_data);
   5477 
   5478     if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
   5479         BTA_GATTC_Close(bta_dm_search_cb.conn_id);
   5480 
   5481     memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
   5482     bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
   5483 }
   5484 /*******************************************************************************
   5485 **
   5486 ** Function         btm_dm_start_gatt_discovery
   5487 **
   5488 ** Description      This is GATT initiate the service search by open a GATT connection
   5489 **                  first.
   5490 **
   5491 ** Parameters:
   5492 **
   5493 *******************************************************************************/
   5494 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
   5495 {
   5496     bta_dm_search_cb.gatt_disc_active = TRUE;
   5497 
   5498     /* connection is already open */
   5499     if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
   5500         bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
   5501     {
   5502         memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
   5503         alarm_cancel(bta_dm_search_cb.gatt_close_timer);
   5504         btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
   5505     }
   5506     else
   5507         BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
   5508 }
   5509 
   5510 /*******************************************************************************
   5511 **
   5512 ** Function         bta_dm_cancel_gatt_discovery
   5513 **
   5514 ** Description      This is GATT cancel the GATT service search.
   5515 **
   5516 ** Parameters:
   5517 **
   5518 *******************************************************************************/
   5519 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
   5520 {
   5521     if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID)
   5522     {
   5523         BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
   5524     }
   5525 
   5526     bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
   5527 }
   5528 
   5529 /*******************************************************************************
   5530 **
   5531 ** Function         bta_dm_proc_open_evt
   5532 **
   5533 ** Description      process BTA_GATTC_OPEN_EVT in DM.
   5534 **
   5535 ** Parameters:
   5536 **
   5537 *******************************************************************************/
   5538 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
   5539 {
   5540     UINT8           *p1;
   5541     UINT8           *p2;
   5542 
   5543     p1 = bta_dm_search_cb.peer_bdaddr;
   5544     p2 = p_data->remote_bda;
   5545 
   5546     APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
   5547                       bta_dm_search_cb.state,
   5548                       ((p1[0])<<24)+((p1[1])<<16)+((p1[2])<<8)+(p1[3]),
   5549                       ((p1[4])<<8)+ p1[5],
   5550                       ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]),
   5551                       ((p2[4])<<8)+ p2[5]);
   5552 
   5553     APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
   5554                       p_data->conn_id,
   5555                       p_data->client_if,
   5556                       p_data->status);
   5557 
   5558     bta_dm_search_cb.conn_id = p_data->conn_id;
   5559 
   5560     if (p_data->status == BTA_GATT_OK)
   5561     {
   5562         btm_dm_start_disc_gatt_services(p_data->conn_id);
   5563     }
   5564     else
   5565     {
   5566         bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
   5567     }
   5568 }
   5569 
   5570 /*******************************************************************************
   5571 **
   5572 ** Function         bta_dm_gattc_callback
   5573 **
   5574 ** Description      This is GATT client callback function used in DM.
   5575 **
   5576 ** Parameters:
   5577 **
   5578 *******************************************************************************/
   5579 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
   5580 {
   5581     APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
   5582 
   5583     switch (event)
   5584     {
   5585         case BTA_GATTC_REG_EVT:
   5586             APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d",  p_data->reg_oper.client_if);
   5587             if (p_data->reg_oper.status == BTA_GATT_OK)
   5588                 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
   5589             else
   5590                 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
   5591             break;
   5592 
   5593         case BTA_GATTC_OPEN_EVT:
   5594             bta_dm_proc_open_evt(&p_data->open);
   5595             break;
   5596 
   5597         case BTA_GATTC_SEARCH_RES_EVT:
   5598             bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
   5599             break;
   5600 
   5601         case BTA_GATTC_SEARCH_CMPL_EVT:
   5602             if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
   5603                 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
   5604             break;
   5605 
   5606         case BTA_GATTC_CLOSE_EVT:
   5607             APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
   5608             /* in case of disconnect before search is completed */
   5609             if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
   5610                  (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
   5611                  !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN))
   5612             {
   5613                 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID,  (tBTA_GATT_STATUS) BTA_GATT_ERROR);
   5614             }
   5615             break;
   5616 
   5617         default:
   5618             break;
   5619     }
   5620 }
   5621 
   5622 #endif /* BTA_GATT_INCLUDED */
   5623 
   5624 #if BLE_VND_INCLUDED == TRUE
   5625 /*******************************************************************************
   5626 **
   5627 ** Function         bta_dm_ctrl_features_rd_cmpl_cback
   5628 **
   5629 ** Description      callback to handle controller feature read complete
   5630 **
   5631 ** Parameters:
   5632 **
   5633 *******************************************************************************/
   5634 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
   5635 {
   5636     APPL_TRACE_DEBUG("%s  status = %d ", __FUNCTION__, result);
   5637     if (result == BTM_SUCCESS)
   5638     {
   5639         if(bta_dm_cb.p_sec_cback)
   5640             bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
   5641     }
   5642     else
   5643     {
   5644         APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result);
   5645     }
   5646 
   5647 }
   5648 #endif /* BLE_VND_INCLUDED */
   5649 
   5650 #endif  /* BLE_INCLUDED */
   5651