OSDN Git Service

Merge BT 4.1 features
authorGanesh Ganapathi Batta <ganeshg@broadcom.com>
Wed, 16 Apr 2014 23:50:09 +0000 (16:50 -0700)
committerGanesh Ganapathi Batta <ganeshg@broadcom.com>
Wed, 30 Apr 2014 17:30:47 +0000 (10:30 -0700)
The features include:
- LE Peripheral Mode
- Link Layer topology (LE Central & Peripheral Concurrency)
- Dual Mode Topology (Ability to choose LE transport when connecting with
other Dual Mode devices)
- Fast advertising Interval
- Limited Discovery Time Changes
- GAP Authentication and Lost Bond
- Dual Mode Addressing
- Common Profile and Service Error Code
- 32 bit UUIDs

Change-Id: Ic6701da4cf6aaa390ff2c8816b43157f36b7fb42

92 files changed:
bta/dm/bta_dm_act.c
bta/dm/bta_dm_api.c
bta/dm/bta_dm_int.h
bta/dm/bta_dm_main.c
bta/gatt/bta_gattc_act.c
bta/gatt/bta_gattc_api.c
bta/gatt/bta_gattc_cache.c
bta/gatt/bta_gattc_int.h
bta/gatt/bta_gattc_main.c
bta/gatt/bta_gattc_utils.c
bta/gatt/bta_gatts_act.c
bta/gatt/bta_gatts_api.c
bta/gatt/bta_gatts_int.h
bta/hh/bta_hh_le.c
bta/include/bta_api.h
bta/include/bta_gatt_api.h
bta/jv/bta_jv_act.c
bta/jv/bta_jv_api.c
btif/include/btif_storage.h
btif/src/bluetooth.c
btif/src/btif_dm.c
btif/src/btif_gatt_client.c
btif/src/btif_gatt_server.c
btif/src/btif_gatt_test.c
btif/src/btif_gatt_util.c
btif/src/btif_storage.c
hci/src/utils.c
include/bt_target.h
main/bte_main.c
stack/avdt/avdt_l2c.c
stack/bnep/bnep_int.h
stack/bnep/bnep_utils.c
stack/btm/btm_acl.c
stack/btm/btm_ble.c
stack/btm/btm_ble_bgconn.c
stack/btm/btm_ble_gap.c
stack/btm/btm_ble_int.h
stack/btm/btm_dev.c
stack/btm/btm_devctl.c
stack/btm/btm_inq.c
stack/btm/btm_int.h
stack/btm/btm_pm.c
stack/btm/btm_sco.c
stack/btm/btm_sec.c
stack/btu/btu_hcif.c
stack/btu/btu_task.c
stack/gap/gap_api.c
stack/gap/gap_ble.c
stack/gap/gap_conn.c
stack/gap/gap_utils.c
stack/gatt/att_protocol.c
stack/gatt/gatt_api.c
stack/gatt/gatt_attr.c
stack/gatt/gatt_auth.c
stack/gatt/gatt_cl.c
stack/gatt/gatt_db.c
stack/gatt/gatt_int.h
stack/gatt/gatt_main.c
stack/gatt/gatt_sr.c
stack/gatt/gatt_utils.c
stack/hcic/hciblecmds.c
stack/hid/hidh_conn.c
stack/include/bt_types.h
stack/include/btm_api.h
stack/include/btm_ble_api.h
stack/include/btu.h
stack/include/gap_api.h
stack/include/gatt_api.h
stack/include/hcidefs.h
stack/include/hcimsgs.h
stack/include/l2c_api.h
stack/include/smp_api.h
stack/include/uipc_msg.h
stack/l2cap/l2c_api.c
stack/l2cap/l2c_ble.c
stack/l2cap/l2c_fcr.c
stack/l2cap/l2c_int.h
stack/l2cap/l2c_link.c
stack/l2cap/l2c_main.c
stack/l2cap/l2c_ucd.c
stack/l2cap/l2c_utils.c
stack/mcap/mca_l2c.c
stack/rfcomm/rfc_int.h
stack/rfcomm/rfc_utils.c
stack/smp/aes.c
stack/smp/smp_act.c
stack/smp/smp_int.h
stack/smp/smp_l2c.c
stack/smp/smp_main.c
stack/smp/smp_utils.c
stack/srvc/srvc_dis.c
stack/srvc/srvc_eng.c

index 86a7db2..3a9ddde 100644 (file)
@@ -89,7 +89,7 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch);
 static char *bta_dm_get_remname(void);
 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
 
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr);
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport);
 static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
 
 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
@@ -516,6 +516,8 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
 {
     UNUSED(p_tle);
     UINT8 i;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+
 
     APPL_TRACE_EVENT0(" bta_dm_disable_timer_cback  ");
 
@@ -523,8 +525,10 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
-
+#if (BLE_INCLUDED == TRUE)
+            transport = bta_dm_cb.device_list.peer_device[i].transport;
+#endif
+            btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
         }
 
     }
@@ -688,22 +692,25 @@ void bta_dm_remove_device (tBTA_DM_MSG *p_data)
     BTA_GATTC_CancelOpen(0, p_dev->bd_addr, FALSE);
 #endif
 
-    if (BTM_IsAclConnectionUp(p_dev->bd_addr))
+    if ( BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR))
     {
+           APPL_TRACE_DEBUG2("%s: ACL Up count  %d", __FUNCTION__,bta_dm_cb.device_list.count);
         /* Take the link down first, and mark the device for removal when disconnected */
-        btm_remove_acl( p_dev->bd_addr) ;
 
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
             if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr))
-            break;
-        }
-
-        if(i < bta_dm_cb.device_list.count)
-        {
-            bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+            {
+                bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
+                btm_remove_acl( p_dev->bd_addr,bta_dm_cb.device_list.peer_device[i].transport);
+                APPL_TRACE_DEBUG2("%s:transport = %d", __FUNCTION__,
+                                   bta_dm_cb.device_list.peer_device[i].transport);
+                break;
+            }
         }
     }
+
     else    /* Ok to remove the device in application layer */
     {
         BTM_SecDeleteDevice(p_dev->bd_addr);
@@ -789,15 +796,23 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data)
 {
     tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
     UINT8   index;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
 
     APPL_TRACE_DEBUG0("bta_dm_close_acl");
 
-    if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr))
+    if ( BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(p_remove_acl->bd_addr, BT_TRANSPORT_BR_EDR))
+
     {
         for (index = 0; index < bta_dm_cb.device_list.count; index ++)
         {
             if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr))
+            {
+#if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
+                transport = bta_dm_cb.device_list.peer_device[index].transport;
+#endif
                 break;
+            }
         }
         if (index != bta_dm_cb.device_list.count)
         {
@@ -809,7 +824,7 @@ void bta_dm_close_acl(tBTA_DM_MSG *p_data)
             APPL_TRACE_ERROR0("unknown device, remove ACL failed");
         }
         /* Disconnect the ACL link */
-        btm_remove_acl(p_remove_acl->bd_addr);
+        btm_remove_acl(p_remove_acl->bd_addr, transport);
     }
     /* if to remove the device from security database ? do it now */
     else if (p_remove_acl->remove_dev)
@@ -844,7 +859,11 @@ void bta_dm_bond (tBTA_DM_MSG *p_data)
     tBTA_DM_SEC sec_event;
     char        *p_name;
 
-    status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+    if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN)
+        status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
+    else
+        status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
+
 
     if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
     {
@@ -1334,6 +1353,7 @@ void bta_dm_discover (tBTA_DM_MSG *p_data)
     bta_dm_search_cb.peer_name[0] = 0;
     bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
     bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
+    bta_dm_search_cb.transport = p_data->discover.transport;
 
     bta_dm_search_cb.name_discover_done = FALSE;
     memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
@@ -1501,7 +1521,7 @@ void bta_dm_di_disc (tBTA_DM_MSG *p_data)
 ** Returns          TRUE if started to get remote name
 **
 *******************************************************************************/
-static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr)
+static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport)
 {
     tBTM_STATUS  btm_status;
 
@@ -1511,7 +1531,8 @@ static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr)
     bta_dm_search_cb.peer_name[0] = 0;
 
     btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
-                                           (tBTM_CMPL_CB *) bta_dm_remname_cback);
+                                           (tBTM_CMPL_CB *) bta_dm_remname_cback,
+                                           transport);
 
     if ( btm_status == BTM_CMD_STARTED )
     {
@@ -2383,6 +2404,21 @@ static void bta_dm_discover_next_device(void)
 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
 {
     tBTA_DM_MSG * p_msg;
+    tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
+#if BLE_INCLUDED == TRUE
+        tBT_DEVICE_TYPE dev_type;
+        tBLE_ADDR_TYPE  addr_type;
+
+    if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN)
+    {
+        BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
+        if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM )
+            transport = BT_TRANSPORT_LE;
+    }
+    else
+        transport = bta_dm_search_cb.transport;
+#endif
+
 
     APPL_TRACE_DEBUG6("bta_dm_discover_device, BDA:0x%02X%02X%02X%02X%02X%02X",
                         remote_bd_addr[0],remote_bd_addr[1],
@@ -2407,7 +2443,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
        && (( bta_dm_search_cb.p_btm_inq_info == NULL )
             ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name))))
     {
-        if( bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr) == TRUE )
+            if(bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE)
         {
             return;
         }
@@ -2446,7 +2482,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
             /* check whether connection already exists to the device
                if connection exists, we don't have to wait for ACL
                link to go down to start search on next device */
-            if(BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr))
+            if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
                 bta_dm_search_cb.wait_disc = FALSE;
             else
                 bta_dm_search_cb.wait_disc = TRUE;
@@ -2460,8 +2496,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
                                     bta_dm_search_cb.services_to_search
                                     );
             }
-            if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
-            /*
+            if (transport == BT_TRANSPORT_LE)            /*
             if ( bta_dm_search_cb.p_btm_inq_info != NULL &&
                  bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE &&
                  (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK))*/
@@ -2559,7 +2594,7 @@ static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
     result.inq_res.inq_result_type  = p_inq->inq_result_type;
     result.inq_res.device_type      = p_inq->device_type;
-
+    result.inq_res.flag             = p_inq->flag;
 #endif
 
     /* application will parse EIR to find out remote device name */
@@ -2649,7 +2684,8 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc,
     {
         /* get name of device */
         btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
-                                                (tBTM_CMPL_CB *) bta_dm_remname_cback);
+                                                (tBTM_CMPL_CB *) bta_dm_remname_cback,
+                                                BT_TRANSPORT_BR_EDR);
         if ( btm_status == BTM_BUSY )
         {
             /* wait for next chance(notification of remote name discovery done) */
@@ -2691,9 +2727,12 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
     bta_dm_search_cb.peer_name[BD_NAME_LEN]=0;
 
     BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+
 #if BLE_INCLUDED == TRUE
-    if (BTM_UseLeLink(bta_dm_search_cb.peer_bdaddr))
-        GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+    if (bta_dm_search_cb.transport == BT_TRANSPORT_LE )
+    {
+       GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
+    }
 #endif
     if ((p_msg = (tBTA_DM_REM_NAME *) GKI_getbuf(sizeof(tBTA_DM_REM_NAME))) != NULL)
     {
@@ -2856,7 +2895,7 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
         bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
         bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
         BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
-        if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
+        if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
             return BTM_CMD_STARTED;
 
         APPL_TRACE_WARNING0(" bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
@@ -3044,22 +3083,56 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
     /*case BTM_SP_KEY_REQ_EVT: */
     case BTM_SP_KEY_NOTIF_EVT:
 #endif
+        if(BTM_SP_CFM_REQ_EVT == event)
+        {
+          /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+             call remote name request using values from cfm_req */
+          if(p_data->cfm_req.bd_name[0] == 0)
+          {
+              bta_dm_cb.pin_evt = pin_evt;
+              bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
+              BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
+              if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
+                         BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+                  return BTM_CMD_STARTED;
+              APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+          }
+          else
+          {
+              /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
+                 copy these values into key_notif from cfm_req */
+              bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
+              BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
+              BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+                   (char*)p_data->cfm_req.bd_name, (BD_NAME_LEN-1));
+              sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+           }
+        }
+
         bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
-        /* If the device name is not known, save bdaddr and devclass and initiate a name request */
-        if (p_data->key_notif.bd_name[0] == 0)
+        if (BTM_SP_KEY_NOTIF_EVT == event)
         {
-            bta_dm_cb.pin_evt = pin_evt;
-            bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
-            BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
-            if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
+            /* If the device name is not known, save bdaddr and devclass
+               and initiate a name request with values from key_notif */
+            if(p_data->key_notif.bd_name[0] == 0)
+            {
+                bta_dm_cb.pin_evt = pin_evt;
+                bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
+                BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
+                if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
+                         BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                 return BTM_CMD_STARTED;
-
-            APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+                APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+            }
+            else
+            {
+                bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
+                BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
+                BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME),
+                    (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
+                sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
+            }
         }
-        bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
-        BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
-            BCM_STRNCPY_S((char*)sec_event.key_notif.bd_name, sizeof(BD_NAME), (char*)p_data->key_notif.bd_name, (BD_NAME_LEN-1));
-            sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
 
         bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
 
@@ -3075,17 +3148,18 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
         /* If the device name is not known, save bdaddr and devclass and initiate a name request */
         if (p_data->rmt_oob.bd_name[0] == 0)
         {
-            bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
-            bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
-            BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
-            if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback)) == BTM_CMD_STARTED)
-                return BTM_CMD_STARTED;
+             bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
+             bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
+             BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
+             if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
+                      BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
+             return BTM_CMD_STARTED;
+             APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
+         }
 
-            APPL_TRACE_WARNING0(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
-        }
-        bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
-        BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
-            BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
+         bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
+         BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
+         BCM_STRNCPY_S((char*)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char*)p_data->rmt_oob.bd_name, (BD_NAME_LEN-1));
             sec_event.rmt_oob.bd_name[BD_NAME_LEN-1] = 0;
 
         bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
@@ -3227,9 +3301,17 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
         case BTM_BL_CONN_EVT:
             p_msg->is_new = TRUE;
             bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+#if BLE_INCLUDED == TRUE
+            p_msg->transport = p_data->conn.transport;
+            p_msg->handle = p_data->conn.handle;
+#endif
             break;
         case BTM_BL_DISCN_EVT:
             bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
+#if BLE_INCLUDED == TRUE
+            p_msg->transport = p_data->discn.transport;
+            p_msg->handle = p_data->discn.handle;
+#endif
             break;
         case BTM_BL_UPDATE_EVT:
             p_msg->busy_level = p_data->update.busy_level;
@@ -3240,9 +3322,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
             p_msg->hci_status = p_data->role_chg.hci_status;
             bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
             break;
-            case BTM_BL_COLLISION_EVT:
-                bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
-                break;;
+        case BTM_BL_COLLISION_EVT:
+            bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
+            break;
         }
 
         p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
@@ -3264,7 +3346,8 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
 **
 *******************************************************************************/
 static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn,
-                                     UINT8 *features, BOOLEAN is_new)
+                                     UINT8 *features, BOOLEAN is_new,UINT16 handle,
+                                     tBT_TRANSPORT transport)
 {
 
     tBTA_DM_ACL_CHANGE * p_msg;
@@ -3273,7 +3356,10 @@ static void bta_dm_acl_change_cback (BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bd
     {
         bdcpy (p_msg->bd_addr, p_bda);
         p_msg->is_new = is_new;
-
+#if BLE_INCLUDED == TRUE
+        p_msg->handle   = handle;
+        p_msg->transport = transport;
+#endif
         /* This is collision case */
         if (features != NULL)
         {
@@ -3386,6 +3472,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
 
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
     tBTA_DM_PEER_DEVICE *p_dev;
+    memset(&conn, 0, sizeof(tBTA_DM_SEC));
 
     switch(p_data->acl_change.event)
     {
@@ -3437,7 +3524,7 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
             bdcpy(conn.role_chg.bd_addr, p_bda);
             conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
             if( bta_dm_cb.p_sec_cback )
-                bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn);
+                bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
         }
         return;
     }
@@ -3454,7 +3541,11 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+            if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+                 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
+#endif
+                 )
                 break;
 
         }
@@ -3464,14 +3555,24 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
             bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
             bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
             bta_dm_cb.device_list.count++;
+#if BLE_INCLUDED == TRUE
+            bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
+            if (p_data->acl_change.transport == BT_TRANSPORT_LE)
+                bta_dm_cb.device_list.le_count++;
+#endif
         }
 
         bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
         bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
         bdcpy(conn.link_up.bd_addr, p_bda);
         bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
-        if( ((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
-            ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) )
+#if BLE_INCLUDED == TRUE
+        conn.link_up.link_type = p_data->acl_change.transport;
+        bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
+#endif
+
+        if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
+            ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
         {
             /* both local and remote devices support SSR */
             bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
@@ -3485,17 +3586,23 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
     {
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda))
+            if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
+#if BLE_INCLUDED == TRUE
+                 ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
+#endif
+               )
                 continue;
 
             if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
             {
-                BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
+                if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
+                {
 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
-                /* remove all cached GATT information */
-                BTA_GATTC_Refresh(p_bda);
+                    /* remove all cached GATT information */
+                    BTA_GATTC_Refresh(p_bda);
 #endif
-                issue_unpair_cb = TRUE;
+                    issue_unpair_cb = TRUE;
+                }
             }
 
             conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
@@ -3508,6 +3615,12 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
         }
         if(bta_dm_cb.device_list.count)
             bta_dm_cb.device_list.count--;
+#if BLE_INCLUDED == TRUE
+        if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
+             (bta_dm_cb.device_list.le_count))
+            bta_dm_cb.device_list.le_count--;
+        conn.link_down.link_type = p_data->acl_change.transport;
+#endif
 
         if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda))
         {
@@ -3785,7 +3898,8 @@ static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
 {
     UINT16 index = 0;
-    if (BTM_IsAclConnectionUp(remote_bd_addr))
+    if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
+         BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
     {
          APPL_TRACE_DEBUG1("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
                             __FUNCTION__);
@@ -3831,14 +3945,18 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
 
     UINT8 i;
     BOOLEAN set_master_role = FALSE;
-
-    if(bta_dm_cb.device_list.count)
+#if BLE_INCLUDED == TRUE
+    UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
+#else
+    UINT8 br_count = bta_dm_cb.device_list.count;
+#endif
+    if (br_count)
     {
 
         /* the configuration is no scatternet
          * or AV connection exists and there are more than one ACL link */
-        if( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
-            (bta_dm_cb.cur_av_count && bta_dm_cb.device_list.count > 1) )
+        if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
+             (bta_dm_cb.cur_av_count && br_count > 1) )
         {
 
             L2CA_SetDesireRole (HCI_ROLE_MASTER);
@@ -3848,7 +3966,11 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
 
         for(i=0; i<bta_dm_cb.device_list.count; i++)
         {
-            if(bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
+#if BLE_INCLUDED == TRUE
+                && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
+#endif
+                )
             {
                 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
                     && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
@@ -3858,7 +3980,7 @@ static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
                 }
 
                 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
-                    || (bta_dm_cb.device_list.count > 1))
+                    || (br_count > 1))
                 {
 
                 /* Initiating immediate role switch with certain remote devices
@@ -4508,13 +4630,26 @@ void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
 ** Returns         None
 **
 *******************************************************************************/
-void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
 {
     tBTA_STATUS   bta_status = BTA_SUCCESS;
-    tBTA_DM_ENCRYPT_CBACK *p_callback = bta_dm_cb.p_encrypt_cback;
+    tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
+    UINT8   i ;
     UNUSED(p_ref_data);
 
-    bta_dm_cb.p_encrypt_cback = NULL;
+    for (i=0; i<bta_dm_cb.device_list.count; i++)
+    {
+        if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
+            bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            break;
+    }
+
+    if (i < bta_dm_cb.device_list.count)
+    {
+        p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
+        bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
+    }
+
     switch (result)
     {
         case BTM_SUCCESS:
@@ -4537,7 +4672,7 @@ void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
 
     if (p_callback)
     {
-        (*p_callback)(bd_addr, bta_status);
+        (*p_callback)(bd_addr, transport, bta_status);
     }
 }
 /*******************************************************************************
@@ -4551,6 +4686,7 @@ void bta_dm_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
 *******************************************************************************/
 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
 {
+    UINT8 i ;
 
     APPL_TRACE_DEBUG0("bta_dm_set_encryption"); //todo
     if (!p_data->set_encryption.p_callback)
@@ -4559,16 +4695,35 @@ void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
         return;
     }
 
-    if (bta_dm_cb.p_encrypt_cback)
+    for (i=0; i<bta_dm_cb.device_list.count; i++)
     {
-        (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr, BTA_BUSY);
-        return;
+        if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
+            bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
+            break;
     }
+    if (i < bta_dm_cb.device_list.count)
+    {
+        if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
+        {
+            APPL_TRACE_ERROR0("earlier enc was not done for same device");
+            (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
+                p_data->set_encryption.transport, BTA_BUSY);
+            return;
+        }
 
-
-    bta_dm_cb.p_encrypt_cback = p_data->set_encryption.p_callback;
-    bta_dm_cb.sec_act         = p_data->set_encryption.sec_act;
-    BTM_SetEncryption(p_data->set_encryption.bd_addr, bta_dm_encrypt_cback, &bta_dm_cb.sec_act);
+        if (BTM_SetEncryption(p_data->set_encryption.bd_addr,
+                              p_data->set_encryption.transport,
+                              bta_dm_encrypt_cback,
+                              &p_data->set_encryption.sec_act)
+                              == BTM_CMD_STARTED)
+        {
+            bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
+        }
+    }
+    else
+    {
+        APPL_TRACE_ERROR1(" %s Device not found/not connected", __FUNCTION__);
+    }
 }
 
 /*******************************************************************************
@@ -4991,7 +5146,42 @@ void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data)
     BTM_BleSetConnScanParams(p_data->ble_set_scan_params.scan_int,
                              p_data->ble_set_scan_params.scan_window);
 }
+/*******************************************************************************
+**
+** Function         bta_dm_ble_update_conn_params
+**
+** Description      This function update LE connection parameters.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
+{
+    if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
+                                 p_data->ble_update_conn_params.min_int,
+                                 p_data-> ble_update_conn_params.max_int,
+                                 p_data->ble_update_conn_params.latency,
+                                 p_data->ble_update_conn_params.timeout))
+    {
+        APPL_TRACE_ERROR0("Update connection parameters failed!");
+    }
+}
 
+#if BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function         bta_dm_ble_config_local_privacy
+**
+** Description      This function set the local device LE privacy settings.
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
+{
+    BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
+}
+#endif
 
 /*******************************************************************************
 **
@@ -5310,7 +5500,7 @@ void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
         btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
     }
     else
-        BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE);
+        BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
 }
 
 /*******************************************************************************
index 7db7f7b..89e2cce 100644 (file)
@@ -526,12 +526,29 @@ BOOLEAN BTA_DmIsMaster(BD_ADDR bd_addr)
 *******************************************************************************/
 void BTA_DmBond(BD_ADDR bd_addr)
 {
+    BTA_DmBondByTransport (bd_addr, BTA_TRANSPORT_UNKNOWN);
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmBondByTransports
+**
+** Description      This function initiates a bonding procedure with a peer
+**                  device
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport)
+{
     tBTA_DM_API_BOND    *p_msg;
 
     if ((p_msg = (tBTA_DM_API_BOND *) GKI_getbuf(sizeof(tBTA_DM_API_BOND))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BOND_EVT;
         bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->transport = transport;
         bta_sys_sendmsg(p_msg);
     }
 
@@ -1487,6 +1504,9 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
     }
 #endif
 }
+/*******************************************************************************
+**                      BLE ADV data management API
+********************************************************************************/
 
 #if BLE_INCLUDED == TRUE
 /*******************************************************************************
@@ -1507,7 +1527,7 @@ void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv
     if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
-               p_msg->data_mask = data_mask;
+        p_msg->data_mask = data_mask;
         p_msg->p_adv_cfg = p_adv_cfg;
 
         bta_sys_sendmsg(p_msg);
@@ -1532,7 +1552,7 @@ BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_AD
     if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
     {
         p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
-               p_msg->data_mask = data_mask;
+        p_msg->data_mask = data_mask;
         p_msg->p_adv_cfg = p_adv_cfg;
 
         bta_sys_sendmsg(p_msg);
@@ -1599,28 +1619,24 @@ void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_BLE_SEL_
     }
 #endif
 }
+
 /*******************************************************************************
 **
-** Function         BTA_DmDiscoverExt
-**
-** Description      This function does service discovery for services of a
-**                  peer device. When services.num_uuid is 0, it indicates all
-**                  GATT based services are to be searched; other wise a list of
-**                  UUID of interested services should be provided through
-**                  p_services->p_uuid.
-**
+** Function         bta_dm_discover_send_msg
 **
+** Description      This function send discover message to BTA task.
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
-                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search)
+static void bta_dm_discover_send_msg(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+                    tBTA_TRANSPORT transport)
 {
-#if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     tBTA_DM_API_DISCOVER    *p_msg;
-    UINT16  len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + sizeof(tBT_UUID) * p_services->num_uuid) :
-                    sizeof(tBTA_DM_API_DISCOVER);
+    UINT16  len = p_services ? (sizeof(tBTA_DM_API_DISCOVER) + 
+                                sizeof(tBT_UUID) * p_services->num_uuid) :
+                                sizeof(tBTA_DM_API_DISCOVER);
 
     if ((p_msg = (tBTA_DM_API_DISCOVER *) GKI_getbuf(len)) != NULL)
     {
@@ -1630,6 +1646,7 @@ void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
         bdcpy(p_msg->bd_addr, bd_addr);
         p_msg->p_cback = p_cback;
         p_msg->sdp_search = sdp_search;
+        p_msg->transport    = transport;
 
         if (p_services != NULL)
         {
@@ -1645,12 +1662,60 @@ void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
 
         bta_sys_sendmsg(p_msg);
     }
-#else
-    UNUSED(bd_addr);
-    UNUSED(p_services);
-    UNUSED(p_cback);
-    UNUSED(sdp_search);
-#endif
+}
+
+/*******************************************************************************
+**
+** Function         BTA_DmDiscoverByTransport
+**
+** Description      This function does service discovery on particular transport
+**                  for services of a
+**                  peer device. When services.num_uuid is 0, it indicates all
+**                  GATT based services are to be searched; otherwise a list of
+**                  UUID of interested services should be provided through
+**                  p_services->p_uuid.
+**
+** Parameters       bd_addr: Bluetooth address of remote device
+**                  p_services :bit mask of the list of services to be discovered
+**                  p_cback : Callback on which result will be received
+**                  sdp_search: if TRUE SDP search will be initiated, else services present in
+**                                     EIR structure of remote device will be returned.
+**                  transport : Physical transport BR/EDR or LE
+** Returns          void
+**
+*******************************************************************************/
+
+void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+                    tBTA_TRANSPORT transport)
+{
+    bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, transport);
+}
+
+
+/*******************************************************************************
+**
+** Function         BTA_DmDiscoverExt
+**
+** Description      This function does service discovery for services of a
+**                  peer device. When services.num_uuid is 0, it indicates all
+**                  GATT based services are to be searched; other wise a list of
+**                  UUID of interested services should be provided through
+**                  p_services->p_uuid.
+**
+** Parameters       bd_addr: Bluetooth address of remote device
+**                  p_services :bit mask of the list of services to be discovered
+**                  p_cback : Callback on which result will be received
+**                  sdp_search: if TRUE SDP search will be initiated, else services present in
+**                                     EIR structure of remote device will be returned.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                    tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search)
+{
+    bta_dm_discover_send_msg(bd_addr, p_services, p_cback, sdp_search, BTA_TRANSPORT_UNKNOWN);
 
 }
 
@@ -1751,6 +1816,43 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable)
 
 /*******************************************************************************
 **
+** Function         BTA_DmBleUpdateConnectionParams
+**
+** Description      Update connection parameters, can only be used when connection is up.
+**
+** Parameters:      bd_addr   - BD address of the peer
+**                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
+**                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
+**                  latency   -     slave latency [0 ~ 500]
+**                  timeout   -     supervision timeout [0x000a ~ 0xc80]
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
+                                    UINT16 latency, UINT16 timeout)
+{
+#if BLE_INCLUDED == TRUE
+    tBTA_DM_API_UPDATE_CONN_PARAM *p_msg;
+
+    if ((p_msg = (tBTA_DM_API_UPDATE_CONN_PARAM *) GKI_getbuf(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM))) != NULL)
+    {
+        memset (p_msg, 0, sizeof(tBTA_DM_API_UPDATE_CONN_PARAM));
+
+        p_msg->hdr.event = BTA_DM_API_UPDATE_CONN_PARAM_EVT;
+        bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->min_int   = min_int;
+        p_msg->max_int   = max_int;
+        p_msg->latency   = latency;
+        p_msg->timeout   = timeout;
+
+        bta_sys_sendmsg(p_msg);
+    }
+#endif
+}
+
+/*******************************************************************************
+**
 ** Function         BTA_DmSetEncryption
 **
 ** Description      This function is called to ensure that connection is
@@ -1759,6 +1861,7 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable)
 **                  bring up unencrypted links, then later encrypt them.
 **
 ** Parameters:      bd_addr       - Address of the peer device
+**                  transport     - transport of the link to be encruypted
 **                  p_callback    - Pointer to callback function to indicat the
 **                                  link encryption status
 **                  sec_act       - This is the security action to indicate
@@ -1770,7 +1873,7 @@ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable)
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
+void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_DM_ENCRYPT_CBACK *p_callback,
                             tBTA_DM_BLE_SEC_ACT sec_act)
 {
     tBTA_DM_API_SET_ENCRYPTION   *p_msg;
@@ -1783,6 +1886,7 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
         p_msg->hdr.event = BTA_DM_API_SET_ENCRYPTION_EVT;
 
         memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
+        p_msg->transport    = transport;
         p_msg->p_callback      = p_callback;
         p_msg->sec_act         = sec_act;
 
@@ -1803,7 +1907,7 @@ void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev)
+void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport)
 {
     tBTA_DM_API_REMOVE_ACL   *p_msg;
 
@@ -1817,6 +1921,7 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev)
 
         memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
         p_msg->remove_dev      = remove_dev;
+        p_msg->transport       = transport;
 
         bta_sys_sendmsg(p_msg);
     }
index 784d49e..03cb45f 100644 (file)
@@ -99,6 +99,7 @@ enum
     BTA_DM_API_BLE_CONN_PARAM_EVT,
     BTA_DM_API_BLE_SCAN_PARAM_EVT,
     BTA_DM_API_BLE_OBSERVE_EVT,
+    BTA_DM_API_UPDATE_CONN_PARAM_EVT,
     BTA_DM_API_BLE_ADV_PARAM_EVT,
     BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
     BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
@@ -214,6 +215,7 @@ typedef struct
     tBTA_SERVICE_MASK services;
     tBTA_DM_SEARCH_CBACK * p_cback;
     BOOLEAN         sdp_search;
+    tBTA_TRANSPORT  transport;
 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
     UINT8           num_uuid;
     tBT_UUID        *p_uuid;
@@ -236,6 +238,7 @@ typedef struct
 {
     BT_HDR      hdr;
     BD_ADDR bd_addr;
+    tBTA_TRANSPORT transport;
 } tBTA_DM_API_BOND;
 
 /* data type for BTA_DM_API_BOND_CANCEL_EVT */
@@ -243,6 +246,7 @@ typedef struct
 {
     BT_HDR          hdr;
     BD_ADDR         bd_addr;
+    tBTA_TRANSPORT  transport;
 } tBTA_DM_API_BOND_CANCEL;
 
 /* data type for BTA_DM_API_PIN_REPLY_EVT */
@@ -370,6 +374,10 @@ typedef struct
     UINT8           new_role;
     BD_ADDR         bd_addr;
     UINT8           hci_status;
+#if BLE_INCLUDED == TRUE
+    UINT16          handle;
+    tBT_TRANSPORT   transport;
+#endif
 } tBTA_DM_ACL_CHANGE;
 
 /* data type for BTA_DM_PM_BTM_STATUS_EVT */
@@ -429,6 +437,7 @@ typedef struct
 typedef struct
 {
     BT_HDR                    hdr;
+    tBTA_TRANSPORT            transport;
     tBTA_DM_ENCRYPT_CBACK     *p_callback;
     tBTA_DM_BLE_SEC_ACT       sec_act;
     BD_ADDR                   bd_addr;
@@ -568,7 +577,18 @@ typedef struct
     BT_HDR      hdr;
     BD_ADDR     bd_addr;
     BOOLEAN     remove_dev;
+    tBTA_TRANSPORT transport;
+
 }tBTA_DM_API_REMOVE_ACL;
+typedef struct
+{
+    BT_HDR      hdr;
+    BD_ADDR     bd_addr;
+    UINT16      min_int;
+    UINT16      max_int;
+    UINT16      latency;
+    UINT16      timeout;
+}tBTA_DM_API_UPDATE_CONN_PARAM;
 
 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
 typedef struct
@@ -668,6 +688,7 @@ typedef union
     tBTA_DM_API_ENABLE_SCAN_FILTER      ble_enable_scan_filter;
     tBTA_DM_API_CFG_FILTER_COND         ble_cfg_filter_cond;
 #endif
+    tBTA_DM_API_UPDATE_CONN_PARAM       ble_update_conn_params;
 #endif
 
     tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment;
@@ -707,13 +728,15 @@ typedef struct
     tBTA_PREF_ROLES             pref_role;
     BOOLEAN                     in_use;
     tBTA_DM_DEV_INFO            info;
+    tBTA_DM_ENCRYPT_CBACK      *p_encrypt_cback;
 #if (BTM_SSR_INCLUDED == TRUE)
     tBTM_PM_STATUS              prev_low;   /* previous low power mode used */
 #endif
     tBTA_DM_PM_ACTTION          pm_mode_attempted;
     tBTA_DM_PM_ACTTION          pm_mode_failed;
     BOOLEAN                     remove_dev_pending;
-
+    UINT16                      conn_handle;
+    tBT_TRANSPORT               transport;
 } tBTA_DM_PEER_DEVICE;
 
 
@@ -724,7 +747,9 @@ typedef struct
 {
     tBTA_DM_PEER_DEVICE    peer_device[BTA_DM_NUM_PEER_DEVICE];
     UINT8                  count;
-
+#if BLE_INCLUDED == TRUE
+    UINT8                  le_count;
+#endif
 } tBTA_DM_ACTIVE_LINK;
 
 
@@ -805,8 +830,6 @@ typedef struct
 
 #endif
 
-    tBTA_DM_ENCRYPT_CBACK      *p_encrypt_cback;
-    tBTA_DM_BLE_SEC_ACT         sec_act;
     TIMER_LIST_ENT              switch_delay_timer;
 
 } tBTA_DM_CB;
@@ -837,7 +860,7 @@ typedef struct
     tSDP_UUID              uuid;
     UINT8                  peer_scn;
     BOOLEAN                sdp_search;
-
+    tBTA_TRANSPORT         transport;
 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
     tBTA_DM_SEARCH_CBACK * p_scan_cback;
 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
@@ -1024,6 +1047,7 @@ extern void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
 extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
@@ -1068,6 +1092,10 @@ extern void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data);
 extern void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data);
 extern tBTA_DM_PEER_DEVICE * bta_dm_find_peer_device(BD_ADDR peer_addr);
 
+#if BLE_PRIVACY_SPT == TRUE
+extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data);
+#endif
+
 extern void bta_dm_pm_active(BD_ADDR peer_addr);
 
 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )
index 74f4d82..8f8c750 100644 (file)
@@ -96,6 +96,10 @@ const tBTA_DM_ACTION bta_dm_action[] =
     bta_dm_ble_set_conn_params,      /* BTA_DM_API_BLE_CONN_PARAM_EVT */
     bta_dm_ble_set_scan_params,      /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
     bta_dm_ble_observe,
+    bta_dm_ble_update_conn_params,   /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
+#if BLE_PRIVACY_SPT == TRUE
+    bta_dm_ble_config_local_privacy,   /* BTA_DM_API_LOCAL_PRIVACY_EVT */
+#endif
     bta_dm_ble_set_adv_params,     /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
     bta_dm_ble_set_adv_config,     /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
     bta_dm_ble_set_scan_rsp,       /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
index f980c0b..1b3261b 100644 (file)
@@ -45,7 +45,8 @@
 **  Constants
 *****************************************************************************/
 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
-                                 BOOLEAN connected, tGATT_DISCONN_REASON reason);
+                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                 tBT_TRANSPORT transport);
 
 static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
                                   tGATT_CL_COMPLETE *p_data);
@@ -339,7 +340,8 @@ void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
         if (p_msg->api_conn.is_direct)
         {
             if ((p_clcb = bta_gattc_find_alloc_clcb(p_msg->api_conn.client_if,
-                                                    p_msg->api_conn.remote_bda)) != NULL)
+                                                    p_msg->api_conn.remote_bda,
+                                                    p_msg->api_conn.transport)) != NULL)
             {
                 bta_gattc_sm_execute(p_clcb, event, p_msg);
             }
@@ -351,7 +353,7 @@ void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
                                           BTA_GATT_NO_RESOURCES,
                                           p_msg->api_conn.remote_bda,
                                           BTA_GATT_INVALID_CONN_ID,
-                                          0);
+                                          p_msg->api_conn.transport, 0);
             }
         }
         else
@@ -385,7 +387,8 @@ void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p
     if (p_msg->api_cancel_conn.is_direct)
     {
         if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->api_cancel_conn.client_if,
-                                                 p_msg->api_cancel_conn.remote_bda)) != NULL)
+                                                 p_msg->api_cancel_conn.remote_bda,
+                                                 BTA_GATT_TRANSPORT_LE)) != NULL)
         {
             bta_gattc_sm_execute(p_clcb, event, p_msg);
         }
@@ -476,6 +479,7 @@ void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
                               BTA_GATT_OK,
                               p_clcb->bda,
                               p_clcb->bta_conn_id,
+                              p_clcb->transport,
                               0);
 }
 /*******************************************************************************
@@ -495,8 +499,8 @@ void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
                               BTA_GATT_ERROR,
                               p_clcb->bda,
                               p_clcb->bta_conn_id,
+                              p_clcb->transport,
                               0);
-
     /* open failure, remove clcb */
     bta_gattc_clcb_dealloc(p_clcb);
 }
@@ -515,7 +519,8 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     tBTA_GATTC_DATA gattc_data;
 
     /* open/hold a connection */
-    if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda, TRUE))
+    if (!GATT_Connect(p_clcb->p_rcb->client_if, p_data->api_conn.remote_bda,
+                      TRUE, p_data->api_conn.transport))
     {
         APPL_TRACE_ERROR0("Connection open failure");
 
@@ -526,7 +531,8 @@ void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
         /* a connected remote device */
         if (GATT_GetConnIdIfConnected(p_clcb->p_rcb->client_if,
                                       p_data->api_conn.remote_bda,
-                                      &p_clcb->bta_conn_id))
+                                      &p_clcb->bta_conn_id,
+                                      p_data->api_conn.transport))
         {
             gattc_data.int_conn.hdr.layer_specific = p_clcb->bta_conn_id;
 
@@ -553,8 +559,8 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg
 
     if (bta_gattc_mark_bg_conn(p_data->client_if, p_data->remote_bda, TRUE, FALSE))
     {
-        /* alwaya call open to hold a connection */
-        if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE))
+        /* always call open to hold a connection */
+        if (!GATT_Connect(p_data->client_if, p_data->remote_bda, FALSE, p_data->transport))
         {
             status = BTA_GATT_ERROR;
             APPL_TRACE_ERROR0("bta_gattc_init_bk_conn failed");
@@ -566,9 +572,11 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg
             /* if is a connected remote device */
             if (GATT_GetConnIdIfConnected(p_data->client_if,
                                           p_data->remote_bda,
-                                          &conn_id))
+                                          &conn_id,
+                                          p_data->transport))
             {
-                if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda)) != NULL)
+                if ((p_clcb = bta_gattc_find_alloc_clcb(p_data->client_if, p_data->remote_bda,
+                    BTA_GATT_TRANSPORT_LE)) != NULL)
                 {
                     gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
 
@@ -583,7 +591,8 @@ void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg
     /* open failure, report OPEN_EVT */
     if (status != BTA_GATT_OK)
     {
-        bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda, BTA_GATT_INVALID_CONN_ID, 0);
+        bta_gattc_send_open_cback(p_clreg, status, p_data->remote_bda,
+        BTA_GATT_INVALID_CONN_ID, BTA_GATT_TRANSPORT_LE, 0);
     }
 }
 /*******************************************************************************
@@ -687,7 +696,9 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     {
         APPL_TRACE_DEBUG1("bta_gattc_conn conn_id=%d",p_data->hdr.layer_specific);
         p_clcb->bta_conn_id  = p_data->int_conn.hdr.layer_specific;
-        GATT_GetConnectionInfor(p_data->int_conn.hdr.layer_specific, &gatt_if, p_clcb->bda);
+
+        GATT_GetConnectionInfor(p_data->hdr.layer_specific,
+                                &gatt_if, p_clcb->bda, &p_clcb->transport);
     }
 
         p_clcb->p_srcb->connected = TRUE;
@@ -721,14 +732,16 @@ void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 
         if (p_clcb->p_rcb)
         {
-            /* there is no RM for GATT */
-            if (!BTM_IsBleLink(p_clcb->bda))
-                bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-            bta_gattc_send_open_cback(p_clcb->p_rcb,
-                                      BTA_GATT_OK,
-                                      p_clcb->bda,
-                                      p_clcb->bta_conn_id,
-                                      p_clcb->p_srcb->mtu);
+        /* there is no RM for GATT */
+        if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+            bta_sys_conn_open(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+
+        bta_gattc_send_open_cback(p_clcb->p_rcb,
+                                  BTA_GATT_OK,
+                                  p_clcb->bda,
+                                  p_clcb->bta_conn_id,
+                                  p_clcb->transport,
+                                  p_clcb->p_srcb->mtu);
         }
     }
 /*******************************************************************************
@@ -780,7 +793,7 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     cb_data.close.status    = p_clcb->status;
     bdcpy(cb_data.close.remote_bda, p_clcb->bda);
 
-    if (!BTM_IsBleLink(p_clcb->bda))
+    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
         bta_sys_conn_close( BTA_ID_GATTC ,BTA_ALL_APP_ID, p_clcb->bda);
 
     bta_gattc_clcb_dealloc(p_clcb);
@@ -948,12 +961,16 @@ void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
             p_clcb->p_srcb->update_count = 0;
             p_clcb->p_srcb->state = BTA_GATTC_SERV_DISC_ACT;
 
+            if (p_clcb->transport == BTA_TRANSPORT_LE)
+                L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, FALSE);
+
             /* set all srcb related clcb into discovery ST */
             bta_gattc_set_discover_st(p_clcb->p_srcb);
 
             if ((p_clcb->status = bta_gattc_init_cache(p_clcb->p_srcb)) == BTA_GATT_OK)
             {
-                p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id, p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
+                p_clcb->status = bta_gattc_discover_pri_service(p_clcb->bta_conn_id,
+                                                               p_clcb->p_srcb, GATT_DISC_SRVC_ALL);
             }
             if (p_clcb->status != BTA_GATT_OK)
             {
@@ -993,7 +1010,8 @@ void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
     APPL_TRACE_DEBUG1("bta_gattc_disc_cmpl conn_id=%d",p_clcb->bta_conn_id);
 
 #if BLE_INCLUDED == TRUE
-    L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
+    if(p_clcb->transport == BTA_TRANSPORT_LE)
+        L2CA_EnableUpdateBleConnParams(p_clcb->p_srcb->server_bda, TRUE);
 #endif
     p_clcb->p_srcb->state = BTA_GATTC_SERV_IDLE;
 
@@ -1255,11 +1273,14 @@ void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
         {
             APPL_TRACE_ERROR1("bta_gattc_confirm to handle [0x%04x] failed", handle);
         }
-        /* if over BR_EDR, inform PM for mode change */
-        else if (!BTM_IsBleLink(p_clcb->bda))
+        else
         {
-            bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
-            bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+            /* if over BR_EDR, inform PM for mode change */
+            if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
+            {
+                bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+                bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
+            }
         }
     }
 }
@@ -1292,7 +1313,8 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
                                 &cb_data.read.descr_type) == FALSE)
         {
             cb_data.read.status = BTA_GATT_INTERNAL_ERROR;
-            APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x", p_data->p_cmpl->att_value.handle);
+            APPL_TRACE_ERROR1("can not map to GATT ID. handle = 0x%04x",
+                                p_data->p_cmpl->att_value.handle);
         }
         else
         {
@@ -1308,10 +1330,12 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
         cb_data.read.srvc_id = p_clcb->p_q_cmd->api_read.srvc_id;
         cb_data.read.char_id = p_clcb->p_q_cmd->api_read.char_id;
         if (p_clcb->p_q_cmd->api_read.p_descr_type)
-            memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type, sizeof(tBTA_GATT_ID));
+            memcpy(&cb_data.read.descr_type, p_clcb->p_q_cmd->api_read.p_descr_type,
+                   sizeof(tBTA_GATT_ID));
     }
 
-    event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ? BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
+    event = (p_clcb->p_q_cmd->api_read.p_descr_type == NULL) ?
+                    BTA_GATTC_READ_CHAR_EVT: BTA_GATTC_READ_DESCR_EVT;
     cb_data.read.conn_id = p_clcb->bta_conn_id;
 
     utl_freebuf((void **)&p_clcb->p_q_cmd);
@@ -1345,10 +1369,13 @@ void bta_gattc_write_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data)
     }
     else
     {
-        memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id, sizeof(tBTA_GATT_SRVC_ID));
-        memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id, sizeof(tBTA_GATT_ID));
+        memcpy(&cb_data.write.srvc_id, &p_clcb->p_q_cmd->api_write.srvc_id,
+                sizeof(tBTA_GATT_SRVC_ID));
+        memcpy(&cb_data.write.char_id, &p_clcb->p_q_cmd->api_write.char_id,
+                sizeof(tBTA_GATT_ID));
         if (p_clcb->p_q_cmd->api_write.p_descr_type)
-            memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type, sizeof(tBTA_GATT_ID));
+            memcpy(&cb_data.write.descr_type, p_clcb->p_q_cmd->api_write.p_descr_type,
+                   sizeof(tBTA_GATT_ID));
     }
 
     if (p_clcb->p_q_cmd->api_write.hdr.event == BTA_GATTC_API_WRITE_EVT &&
@@ -1629,7 +1656,8 @@ void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
          p_data->ci_load.status == BTA_GATT_MORE) &&
         p_data->ci_load.num_attr > 0)
     {
-        bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr, p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
+        bta_gattc_rebuild_cache(p_clcb->p_srcb, p_data->ci_load.num_attr,
+                                p_data->ci_load.attr, p_clcb->p_srcb->attr_index);
 
         if (p_data->ci_load.status == BTA_GATT_OK)
         {
@@ -1741,7 +1769,8 @@ static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg)
 **
 *******************************************************************************/
 static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
-                                 BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                 BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                 tBT_TRANSPORT transport)
 {
     tBTA_GATTC_DATA *p_buf;
 
@@ -1752,11 +1781,13 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
     {
         memset(p_buf, 0, sizeof(tBTA_GATTC_DATA));
 
-        p_buf->int_conn.hdr.event            = connected ? BTA_GATTC_INT_CONN_EVT: BTA_GATTC_INT_DISCONN_EVT;
+        p_buf->int_conn.hdr.event            = connected ? BTA_GATTC_INT_CONN_EVT:
+                                                           BTA_GATTC_INT_DISCONN_EVT;
         p_buf->int_conn.hdr.layer_specific   = conn_id;
         p_buf->int_conn.client_if            = gattc_if;
         p_buf->int_conn.role                 = L2CA_GetBleConnRole(bda);
         p_buf->int_conn.reason               = reason;
+        p_buf->int_conn.transport            = transport;
         bdcpy(p_buf->int_conn.remote_bda, bda);
 
                 bta_sys_sendmsg(p_buf);
@@ -1777,7 +1808,7 @@ static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda)
     tBTA_GATTC_DATA *p_buf;
     tBTA_GATTC_CLCB *p_clcb = NULL;
 
-    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda)) == NULL)
+    if ((p_clcb = bta_gattc_find_clcb_by_cif(gattc_if, bda, BTA_GATT_TRANSPORT_LE)) == NULL)
     {
         return;
     }
@@ -1973,8 +2004,9 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
     tBTA_GATTC_NOTIFY   notify;
     BD_ADDR             remote_bda;
     tBTA_GATTC_IF       gatt_if;
+    tBTA_TRANSPORT transport;
 
-    if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+    if (!GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
     {
         APPL_TRACE_ERROR0("indication/notif for unknown app");
         return;
@@ -2008,9 +2040,10 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
                 /* connection not open yet */
                 if (p_clcb == NULL)
                 {
-                    if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda)) != NULL)
+                    if ((p_clcb = bta_gattc_clcb_alloc(gatt_if, remote_bda, transport)) != NULL)
                     {
                         p_clcb->bta_conn_id = conn_id;
+                        p_clcb->transport   = transport;
 
                         bta_gattc_sm_execute(p_clcb, BTA_GATTC_INT_CONN_EVT, NULL);
                     }
@@ -2033,7 +2066,8 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL
     }
     else
     {
-        APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.", handle);
+        APPL_TRACE_ERROR1("Indi/Notif for Unknown handle[0x%04x], can not find in local cache.",
+                          handle);
     }
 }
 /*******************************************************************************
@@ -2068,9 +2102,8 @@ static void  bta_gattc_cmpl_cback(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
         return;
     }
 
-
-/* if over BR_EDR, inform PM for mode change */
-    if (!BTM_IsBleLink(p_clcb->bda))
+    /* if over BR_EDR, inform PM for mode change */
+    if (p_clcb->transport == BTA_TRANSPORT_BR_EDR)
     {
         bta_sys_busy(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
         bta_sys_idle(BTA_ID_GATTC, BTA_ALL_APP_ID, p_clcb->bda);
@@ -2112,14 +2145,14 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda)
     UINT16              conn_id;
 
     /* should always get the connection ID */
-    if (GATT_GetConnIdIfConnected(cif, remote_bda,&conn_id) == FALSE)
+    if (GATT_GetConnIdIfConnected(cif, remote_bda, &conn_id, BTA_GATT_TRANSPORT_LE) == FALSE)
     {
         APPL_TRACE_ERROR0("bta_gattc_init_clcb_conn ERROR: not a connected device");
         return;
     }
 
     /* initaite a new connection here */
-    if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda)) != NULL)
+    if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL)
     {
         gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id;
 
@@ -2153,7 +2186,7 @@ void bta_gattc_process_listen_all(UINT8 cif)
     {
         if (p_conn->in_use )
         {
-            if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda) == NULL)
+            if (bta_gattc_find_clcb_by_cif(cif, p_conn->remote_bda, BTA_GATT_TRANSPORT_LE) == NULL)
             {
                 bta_gattc_init_clcb_conn(cif, p_conn->remote_bda);
             }
@@ -2212,7 +2245,9 @@ void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
 
                     /* if is a connected remote device */
                     if (L2CA_GetBleConnRole(p_msg->api_listen.remote_bda) == HCI_ROLE_SLAVE &&
-                        bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if, p_msg->api_listen.remote_bda) == NULL)
+                        bta_gattc_find_clcb_by_cif(p_msg->api_listen.client_if,
+                                                   p_msg->api_listen.remote_bda,
+                                                   BTA_GATT_TRANSPORT_LE) == NULL)
                     {
 
                         bta_gattc_init_clcb_conn(p_msg->api_listen.client_if,
@@ -2223,7 +2258,8 @@ void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg)
                 else
                 {
                     APPL_TRACE_ERROR0("Listen For All now");
-                    /* go through all connected device and send callback for all connected slave connection */
+                    /* go through all connected device and send
+                    callback for all connected slave connection */
                     bta_gattc_process_listen_all(p_msg->api_listen.client_if);
                 }
             }
index 0bc87ec..bfbaf63 100644 (file)
@@ -143,11 +143,13 @@ void BTA_GATTC_AppDeregister(tBTA_GATTC_IF client_if)
 ** Parameters       client_if: server interface.
 **                  remote_bda: remote device BD address.
 **                  is_direct: direct connection or background auto connection
+**                  transport: Transport to be used for GATT connection (BREDR/LE)
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                    BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport)
 {
     tBTA_GATTC_API_OPEN  *p_buf;
 
@@ -157,6 +159,7 @@ void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_dire
 
         p_buf->client_if = client_if;
         p_buf->is_direct = is_direct;
+        p_buf->transport = transport;
         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
 
 
index 3d603c3..64147e2 100644 (file)
@@ -460,12 +460,21 @@ void bta_gattc_get_disc_range(tBTA_GATTC_SERV *p_srvc_cb, UINT16 *p_s_hdl, UINT1
 ** Returns          status of the operation.
 **
 *******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+                                                    UINT8 disc_type)
 {
-    if (BTM_IsBleLink(p_server_cb->server_bda))
-        return bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
-    else
-        return bta_gattc_sdp_service_disc(conn_id, p_server_cb);
+    tBTA_GATTC_CLCB     *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
+    tBTA_GATT_STATUS    status =  BTA_GATT_ERROR;
+
+    if (p_clcb)
+    {
+        if (p_clcb->transport == BTA_TRANSPORT_LE)
+            status = bta_gattc_discover_procedure(conn_id, p_server_cb, disc_type);
+        else
+            status = bta_gattc_sdp_service_disc(conn_id, p_server_cb);
+    }
+
+    return status;
 }
 /*******************************************************************************
 **
@@ -476,7 +485,8 @@ tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV
 ** Returns          status of the operation.
 **
 *******************************************************************************/
-tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type)
+tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb,
+                                                   UINT8 disc_type)
 {
     tGATT_DISC_PARAM param;
     BOOLEAN is_service = TRUE;
@@ -844,7 +854,7 @@ void bta_gattc_sdp_callback (UINT16 sdp_status)
                                         service_uuid.uu.uuid16, start_handle, end_handle);
 #endif
 
-                        if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle) &&
+                        if (GATT_HANDLE_IS_VALID(start_handle) && GATT_HANDLE_IS_VALID(end_handle)&&
                             p_srvc_cb != NULL)
                         {
                             /* discover services result, add services into a service list */
@@ -856,7 +866,8 @@ void bta_gattc_sdp_callback (UINT16 sdp_status)
                         }
                         else
                         {
-                            APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d", start_handle, end_handle);
+                            APPL_TRACE_ERROR2("invalid start_handle = %d end_handle = %d",
+                                                start_handle, end_handle);
                         }
                 }
 
@@ -904,9 +915,11 @@ static tBTA_GATT_STATUS bta_gattc_sdp_service_disc(UINT16 conn_id, tBTA_GATTC_SE
         attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
         attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
 
-        SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1, &uuid, num_attrs, attr_list);
+        SDP_InitDiscoveryDb (bta_gattc_cb.p_sdp_db, BTA_GATT_SDP_DB_SIZE, 1,
+                             &uuid, num_attrs, attr_list);
 
-        if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda, bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
+        if(!SDP_ServiceSearchAttributeRequest (p_server_cb->server_bda,
+                                              bta_gattc_cb.p_sdp_db, &bta_gattc_sdp_callback))
         {
             GKI_freebuf(bta_gattc_cb.p_sdp_db);
             bta_gattc_cb.p_sdp_db = NULL;
@@ -990,7 +1003,8 @@ void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_
                 break;
 
             case GATT_DISC_CHAR_DSCPT:
-                bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0, BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
+                bta_gattc_add_attr_to_cache(p_srvc_cb, p_data->handle, &p_data->type, 0,
+                                            BTA_GATTC_ATTR_TYPE_CHAR_DESCR);
                 break;
         }
     }
@@ -1073,7 +1087,8 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service
             {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
                 APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
-                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+                                    p_attr->inst_id, p_attr->attr_type);
 #endif
                 bta_gattc_pack_attr_uuid(p_attr, &attr_uuid);
 
@@ -1120,7 +1135,7 @@ UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service
                     else /* another char */
                     {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
-                        APPL_TRACE_DEBUG0("no matching descriptor found!! start of next characteristic");
+                       APPL_TRACE_DEBUG0("no matching descptr found!!start of next characteristic");
 #endif
                         char_map = FALSE;
                         done = TRUE;
@@ -1178,7 +1193,8 @@ BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SR
             {
 #if (defined BTA_GATT_DEBUG && BTA_GATT_DEBUG == TRUE)
                 APPL_TRACE_DEBUG5("\t Attr[0x%04x] handle[0x%04x] uuid[0x%04x] inst[%d] type[%d]",
-                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16, p_attr->inst_id, p_attr->attr_type);
+                                  j + 1, p_attr->attr_handle, p_attr->p_uuid->uuid16,
+                                  p_attr->inst_id, p_attr->attr_type);
 #endif
                 if (p_attr->attr_type == BTA_GATTC_ATTR_TYPE_CHAR)
                     p_char = p_attr;
@@ -1199,7 +1215,7 @@ BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SR
                         }
                         else
                         {
-                            APPL_TRACE_ERROR0("descriptor does not belong to any chracteristic, error");
+                            APPL_TRACE_ERROR0("descptr does not belong to any chracteristic");
                         }
                     }
                     else
@@ -1249,7 +1265,8 @@ void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid)
                 memset(&cb_data, 0, sizeof(tBTA_GATTC));
 
                 cb_data.srvc_res.conn_id = p_clcb->bta_conn_id;
-                memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid ,sizeof(tBTA_GATT_SRVC_ID));
+                memcpy(&cb_data.srvc_res.service_uuid, &p_cache->service_uuid,
+                        sizeof(tBTA_GATT_SRVC_ID));
 
                 (* p_clcb->p_rcb->p_cback)(BTA_GATTC_SEARCH_RES_EVT, &cb_data);
             }
@@ -1533,7 +1550,8 @@ void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srvc_cb, UINT16 num_attr,
 **
 *******************************************************************************/
 void bta_gattc_fill_nv_attr(tBTA_GATTC_NV_ATTR *p_attr, UINT8 type, UINT16 s_handle,
-                            UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop, BOOLEAN is_primary)
+                            UINT16 e_handle, UINT8 id, tBT_UUID uuid, UINT8 prop,
+                            BOOLEAN is_primary)
 {
     p_attr->s_handle    = s_handle;
     p_attr->e_handle    = e_handle;
index 4f192cb..37a14c9 100644 (file)
@@ -118,6 +118,7 @@ typedef struct
     BD_ADDR                 remote_bda;
     tBTA_GATTC_IF           client_if;
     BOOLEAN                 is_direct;
+    tBTA_TRANSPORT          transport;
 } tBTA_GATTC_API_OPEN;
 
 typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
@@ -202,6 +203,7 @@ typedef struct
     BD_ADDR                 remote_bda;
     tBTA_GATTC_IF           client_if;
     UINT8                   role;
+    tBT_TRANSPORT           transport;
     tGATT_DISCONN_REASON    reason;
 }tBTA_GATTC_INT_CONN;
 
@@ -366,9 +368,11 @@ typedef struct
 {
     UINT16              bta_conn_id;    /* client channel ID, unique for clcb */
     BD_ADDR             bda;
+    tBTA_TRANSPORT      transport;      /* channel transport */
     tBTA_GATTC_RCB      *p_rcb;         /* pointer to the registration CB */
     tBTA_GATTC_SERV     *p_srcb;    /* server cache CB */
     tBTA_GATTC_DATA     *p_q_cmd;   /* command in queue waiting for execution */
+    BOOLEAN             buf_held;
 
 #define BTA_GATTC_NO_SCHEDULE       0
 #define BTA_GATTC_DISC_WAITING      0x01
@@ -444,7 +448,7 @@ extern tBTA_GATTC_CB *bta_gattc_cb_ptr;
 **  Function prototypes
 *****************************************************************************/
 extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
-extern void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
+extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
 
 /* function processed outside SM */
 extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
@@ -491,7 +495,7 @@ extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA
 extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
 extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data);
 extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
-                                       BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu);
+                                       BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport,  UINT16 mtu);
 extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
 #if BLE_INCLUDED == TRUE
@@ -499,11 +503,11 @@ extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA * p_msg);
 #endif
 /* utility functions */
-extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
-extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb);
-extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda);
+extern tBTA_GATTC_CLCB * bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
 extern tBTA_GATTC_RCB * bta_gattc_cl_get_regcb(UINT8 client_if);
 extern tBTA_GATTC_SERV * bta_gattc_find_srcb(BD_ADDR bda);
 extern tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda);
index 932a1d7..c917d4a 100644 (file)
@@ -288,14 +288,16 @@ static char *gattc_state_code(tBTA_GATTC_STATE state_code);
 ** Description      State machine event handling function for GATTC
 **
 **
-** Returns          void
+** Returns          BOOLEAN  : TRUE if queued client request buffer can be immediately released
+**                                        else FALSE
 **
 *******************************************************************************/
-void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
+BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
 {
     tBTA_GATTC_ST_TBL     state_table;
     UINT8               action;
     int                 i;
+    BOOLEAN             rt = TRUE;
 #if BTA_GATT_DEBUG == TRUE
     tBTA_GATTC_STATE in_state = p_clcb->state;
     UINT16         in_event = event;
@@ -320,6 +322,8 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA
         if ((action = state_table[event][i]) != BTA_GATTC_IGNORE)
         {
             (*bta_gattc_action[action])(p_clcb, p_data);
+             p_clcb->buf_held = FALSE;
+             rt = FALSE;
         }
         else
         {
@@ -336,6 +340,7 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA
                           gattc_evt_code(in_event));
     }
 #endif
+return rt;
 }
 
 /*******************************************************************************
@@ -345,7 +350,7 @@ void bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA
 ** Description      GATT client main event handling function.
 **
 **
-** Returns          void
+** Returns          BOOLEAN
 **
 *******************************************************************************/
 BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
@@ -353,6 +358,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
     tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
     tBTA_GATTC_CLCB *p_clcb = NULL;
     tBTA_GATTC_RCB      *p_clreg;
+    BOOLEAN             rt = TRUE;
 #if BTA_GATT_DEBUG == TRUE
     APPL_TRACE_DEBUG1("bta_gattc_hdl_event: Event [%s]", gattc_evt_code(p_msg->event));
 #endif
@@ -410,7 +416,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
 
             if (p_clcb != NULL)
             {
-                bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
+                rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
             }
             else
             {
@@ -421,7 +427,7 @@ BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
     }
 
 
-    return(TRUE);
+    return rt;
 }
 
 
index b52e52c..99b222a 100644 (file)
@@ -163,7 +163,8 @@ UINT8 bta_gattc_num_reg_app(void)
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
+                                              tBTA_TRANSPORT transport)
 {
     tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
     UINT8   i;
@@ -172,6 +173,7 @@ tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bd
     {
         if (p_clcb->in_use &&
             p_clcb->p_rcb->client_if == client_if &&
+            p_clcb->transport == transport &&
             bdcmp(p_clcb->bda, remote_bda) == 0)
             return p_clcb;
     }
@@ -209,7 +211,8 @@ tBTA_GATTC_CLCB * bta_gattc_find_clcb_by_conn_id (UINT16 conn_id)
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                                       tBTA_TRANSPORT transport)
 {
     UINT8               i_clcb = 0;
     tBTA_GATTC_CLCB     *p_clcb = NULL;
@@ -224,6 +227,7 @@ tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_b
             p_clcb                  = &bta_gattc_cb.clcb[i_clcb];
             p_clcb->in_use          = TRUE;
             p_clcb->status          = BTA_GATT_OK;
+            p_clcb->transport       = transport;
             bdcpy(p_clcb->bda, remote_bda);
 
             p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
@@ -256,13 +260,14 @@ tBTA_GATTC_CLCB * bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_b
 ** Returns          pointer to the clcb
 **
 *******************************************************************************/
-tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda)
+tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                                           tBTA_TRANSPORT transport)
 {
     tBTA_GATTC_CLCB *p_clcb ;
 
-    if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda)) == NULL)
+    if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL)
     {
-        p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda);
+        p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
     }
     return p_clcb;
 }
@@ -427,167 +432,19 @@ tBTA_GATTC_SERV * bta_gattc_srcb_alloc(BD_ADDR bda)
 *******************************************************************************/
 BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
 {
-    BOOLEAN in_q = FALSE;
 
-    if (p_clcb->p_q_cmd == NULL && p_data)
-    {
-        UINT16 len;
-        switch (p_data->hdr.event)
-        {
-            case BTA_GATTC_API_SEARCH_EVT:
-            {
-                if (p_data->api_search.p_srvc_uuid)
-                {
-                    len = sizeof(tBTA_GATTC_API_SEARCH) + sizeof(tBT_UUID);
-                }
-                else
-                {
-                    len = sizeof(tBTA_GATTC_API_SEARCH);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_SEARCH));
-                if (p_data->api_search.p_srvc_uuid)
-                {
-                    tBTA_GATTC_API_SEARCH *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_search);
-                    p_buf->p_srvc_uuid = (tBT_UUID *)(p_buf + 1);
-                    memcpy(p_buf->p_srvc_uuid, p_data->api_search.p_srvc_uuid,
-                           sizeof(tBT_UUID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_READ_EVT:
-            {
-                if (p_data->api_read.p_descr_type)
-                {
-                    len = sizeof(tBTA_GATT_ID) + sizeof(tBTA_GATTC_API_READ);
-                }
-                else
-                {
-                    len = sizeof(tBTA_GATTC_API_READ);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ));
-                if (p_data->api_read.p_descr_type)
-                {
-                    tBTA_GATTC_API_READ *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_read);
-                    p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_descr_type, p_data->api_read.p_descr_type,
-                           sizeof(tBTA_GATT_ID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_WRITE_EVT:
-            {
-                tBTA_GATTC_API_WRITE  *p_buf;
-                len = sizeof(tBTA_GATTC_API_WRITE) + p_data->api_write.len;
-                if (p_data->api_write.p_descr_type)
-                {
-                    len += sizeof(tBTA_GATT_ID);
-                }
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_WRITE));
-                p_buf = &(p_clcb->p_q_cmd->api_write);
-                if (p_data->api_write.p_descr_type)
-                {
-                    p_buf->p_descr_type = (tBTA_GATT_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_descr_type, p_data->api_write.p_descr_type,
-                           sizeof(tBTA_GATT_ID));
-                    if (p_buf->len && p_buf->p_value)
-                    {
-                        p_buf->p_value  = (UINT8 *)(p_buf->p_descr_type + 1);
-                        memcpy(p_buf->p_value, p_data->api_write.p_value,
-                               p_data->api_write.len);
-                    }
-                }
-                else if (p_buf->len && p_buf->p_value)
-                {
-                    p_buf->p_value = (UINT8 *)(p_buf + 1);
-                    memcpy(p_buf->p_value, p_data->api_write.p_value,
-                           p_data->api_write.len);
-                }
-                break;
-            }
-            case BTA_GATTC_API_EXEC_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_EXEC);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, len);
-                break;
-            }
-            case BTA_GATTC_API_READ_MULTI_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_READ_MULTI) +
-                      p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, sizeof(tBTA_GATTC_API_READ_MULTI));
-                if (p_data->api_read_multi.num_attr &&
-                    p_data->api_read_multi.p_id_list)
-                {
-                    tBTA_GATTC_API_READ_MULTI *p_buf;
-                    p_buf = &(p_clcb->p_q_cmd->api_read_multi);
-                    p_buf->p_id_list = (tBTA_GATTC_ATTR_ID *)(p_buf + 1);
-                    memcpy(p_buf->p_id_list, p_data->api_read_multi.p_id_list,
-                        p_data->api_read_multi.num_attr * sizeof(tBTA_GATTC_ATTR_ID));
-                }
-                break;
-            }
-            case BTA_GATTC_API_CFG_MTU_EVT:
-            {
-                len = sizeof(tBTA_GATTC_API_CFG_MTU);
-                p_clcb->p_q_cmd = (tBTA_GATTC_DATA *)GKI_getbuf(len);
-                if (p_clcb->p_q_cmd == NULL)
-                {
-                    APPL_TRACE_ERROR0("allocate buffer failed for p_q_cmd");
-                    return FALSE;
-                }
-                memcpy(p_clcb->p_q_cmd, p_data, len);
-                break;
-            }
-            default:
-                APPL_TRACE_ERROR1("queue unsupported command %d", p_data->hdr.event);
-                return FALSE;
-        }
-
-        in_q = TRUE;
-    }
-    else if (p_clcb->p_q_cmd)
-    {
-        APPL_TRACE_ERROR0("already has a pending command!!");
-        /* skip the callback now. ----- need to send callback ? */
-    }
-    else
-    {
-        APPL_TRACE_ERROR0("queue a null command");
-    }
+ if (p_clcb->p_q_cmd == NULL)
+ {
+     p_clcb->p_q_cmd = p_data;
+     p_clcb->buf_held = TRUE;
+ }
+ else
+ {
+     APPL_TRACE_ERROR0("already has a pending command!!");
+     /* skip the callback now. ----- need to send callback ? */
+ }
+ return p_clcb->buf_held;
 
-    return in_q;
 }
 /*******************************************************************************
 **
@@ -738,14 +595,16 @@ void bta_gattc_clear_notif_registration(UINT16 conn_id)
     tBTA_GATTC_IF       gatt_if;
     tBTA_GATTC_RCB      *p_clrcb ;
     UINT8       i;
+    tGATT_TRANSPORT     transport;
 
-    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda))
+    if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport))
     {
         if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL)
         {
             for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
             {
-                if (p_clrcb->notif_reg[i].in_use && !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
+                if (p_clrcb->notif_reg[i].in_use &&
+                    !bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda))
                     memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
             }
         }
@@ -919,7 +778,8 @@ BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if,  BD_ADDR remote_bda, U
 **
 *******************************************************************************/
 void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
-                                BD_ADDR remote_bda, UINT16 conn_id, UINT16 mtu)
+                                BD_ADDR remote_bda, UINT16 conn_id,
+                                tBTA_TRANSPORT transport, UINT16 mtu)
 {
     tBTA_GATTC      cb_data;
 
@@ -931,6 +791,7 @@ void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status
         cb_data.open.client_if = p_clreg->client_if;
         cb_data.open.conn_id = conn_id;
         cb_data.open.mtu = mtu;
+        cb_data.open.transport = transport;
         bdcpy(cb_data.open.remote_bda, remote_bda);
 
         (*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
@@ -1053,16 +914,19 @@ tBTA_GATTC_CLCB * bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
 
     /* try to locate a logic channel */
     if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
-                                             p_msg->int_conn.remote_bda)) == NULL)
+                                             p_msg->int_conn.remote_bda,
+                                             p_msg->int_conn.transport)) == NULL)
     {
         /* for a background connection or listening connection */
-        if (p_msg->int_conn.role == HCI_ROLE_SLAVE ||
+        if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE ||  */
             bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
                                     p_msg->int_conn.remote_bda,
                                     p_msg->int_conn.role))
         {
             /* allocate a new channel */
-            p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if, p_msg->int_conn.remote_bda);
+            p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
+                                          p_msg->int_conn.remote_bda,
+                                          p_msg->int_conn.transport);
         }
     }
     return p_clcb;
@@ -1087,12 +951,13 @@ tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
     if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE)
     {
         p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
-                                            p_msg->int_conn.remote_bda);
+                                            p_msg->int_conn.remote_bda,
+                                            p_msg->int_conn.transport);
     }
     else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
     {
-        APPL_TRACE_DEBUG1("disconnection ID: [%d] not used by BTA",
-                           p_msg->int_conn.hdr.layer_specific);
+        APPL_TRACE_DEBUG1(" disconnection ID: [%d] not used by BTA",
+            p_msg->int_conn.hdr.layer_specific);
     }
     return p_clcb;
 }
index be03655..4a24d66 100644 (file)
 #include <string.h>
 
 static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp);
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
+                                                tGATTS_SRV_CHG_RSP *p_rsp);
 
-static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
+                                      BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                      tGATT_TRANSPORT transport);
 static void bta_gatts_send_request_cback (UINT16 conn_id,
                                           UINT32 trans_id,
                                           tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
@@ -85,7 +88,8 @@ static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_ra
 ** Returns          none.
 **
 *******************************************************************************/
-static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
+static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
+                                              tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
 {
     return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
                                 (tBTA_GATTS_SRV_CHG_REQ *) p_req,
@@ -223,14 +227,16 @@ void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
             p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
             memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
             cb_data.reg_oper.server_if      =
-            p_cb->rcb[first_unuse].gatt_if  = GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
+            p_cb->rcb[first_unuse].gatt_if  = 
+            GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
             if ( !p_cb->rcb[first_unuse].gatt_if)
             {
                 status = BTA_GATT_NO_RESOURCES;
             }
             else
             {
-                if ((p_buf = (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
+                if ((p_buf =
+                  (tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL)
                 {
                     p_buf->hdr.event    = BTA_GATTS_INT_START_IF_EVT;
                     p_buf->server_if    = p_cb->rcb[first_unuse].gatt_if;
@@ -275,7 +281,8 @@ void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
     }
     else
     {
-        APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",p_msg->int_start_if.server_if );
+        APPL_TRACE_ERROR1("Unable to start app.: Unknown interface =%d",
+            p_msg->int_start_if.server_if );
     }
 }
 /*******************************************************************************
@@ -358,7 +365,8 @@ void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 
             if (service_id != 0)
             {
-                memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
+                memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
+                    &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
                 p_cb->srvc_cb[srvc_idx].service_id   = service_id;
                 p_cb->srvc_cb[srvc_idx].inst_num     = p_msg->api_create_svc.inst;
                 p_cb->srvc_cb[srvc_idx].idx          = srvc_idx;
@@ -617,11 +625,7 @@ void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 **
 ** Function         bta_gatts_indicate_handle
 **
-<<<<<<< HEAD
-** Description      GATTS indicate handel value
-=======
 ** Description      GATTS send handle value indication or notification.
->>>>>>> 6ea30bf... LE: UPF 45 bug fixes
 **
 ** Returns          none.
 **
@@ -632,13 +636,14 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
     tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
     tGATT_IF            gatt_if;
     BD_ADDR             remote_bda;
-
+    tBTA_TRANSPORT transport;
 
     p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
 
     if (p_srvc_cb )
     {
-        if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific, &gatt_if, remote_bda))
+        if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
+            &gatt_if, remote_bda, &transport))
         {
             if (p_msg->api_indicate.need_confirm)
 
@@ -653,7 +658,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
                                                         p_msg->api_indicate.value);
 
             /* if over BR_EDR, inform PM for mode change */
-            if (!BTM_IsBleLink(remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
             {
                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
@@ -664,8 +669,7 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
             APPL_TRACE_ERROR1("Unknown connection ID: %d fail sending notification",
                               p_msg->api_indicate.hdr.layer_specific);
         }
-
-        if (status != GATT_SUCCESS && p_msg->api_indicate.need_confirm &&
+        if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
             p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)
         {
             (*p_cb->rcb[p_srvc_cb->rcb_idx].p_cback)(BTA_GATTS_CONF_EVT, (tBTA_GATTS *)&status);
@@ -692,13 +696,22 @@ void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 {
     tBTA_GATTS_RCB      *p_rcb=NULL;
     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
+    UINT16              conn_id;
     UNUSED(p_cb);
 
     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL)
     {
-        if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda, p_msg->api_open.is_direct))
+        /* should always get the connection ID */
+        if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+                        p_msg->api_open.is_direct, p_msg->api_open.transport))
         {
             status = BTA_GATT_OK;
+
+            if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
+                                            &conn_id, p_msg->api_open.transport))
+            {
+                status = BTA_GATT_ALREADY_OPEN;
+            }
         }
     }
     else
@@ -727,7 +740,8 @@ void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 
     if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL)
     {
-        if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda, p_msg->api_cancel_open.is_direct))
+        if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
+                                p_msg->api_cancel_open.is_direct))
         {
             APPL_TRACE_ERROR0("bta_gatts_cancel_open failed for open request");
         }
@@ -759,9 +773,11 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
     tBTA_GATT_STATUS    status= BTA_GATT_ERROR;
     tGATT_IF            gatt_if;
     BD_ADDR             remote_bda;
+    tBTA_GATT_TRANSPORT transport;
+
     UNUSED(p_cb);
 
-    if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda))
+    if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport))
     {
         if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS)
         {
@@ -776,7 +792,7 @@ void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA * p_msg)
 
         if (p_rcb && p_rcb->p_cback)
         {
-            if (!BTM_IsBleLink(remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
                 bta_sys_conn_close( BTA_ID_GATTS ,BTA_ALL_APP_ID, remote_bda);
 
             (*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT,  (tBTA_GATTS *)&status);
@@ -840,19 +856,21 @@ static void bta_gatts_send_request_cback (UINT16 conn_id,
     tBTA_GATTS          cb_data;
     tBTA_GATTS_RCB     *p_rcb;
     tGATT_IF            gatt_if;
+    tBTA_GATT_TRANSPORT transport;
 
     memset(&cb_data, 0 , sizeof(tBTA_GATTS));
 
-    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda))
+    if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport))
     {
         p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
 
-        APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d", conn_id, trans_id, req_type);
+        APPL_TRACE_DEBUG3 ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
+                            conn_id, trans_id, req_type);
 
         if (p_rcb && p_rcb->p_cback)
         {
             /* if over BR_EDR, inform PM for mode change */
-            if (!BTM_IsBleLink(cb_data.req_data.remote_bda))
+            if (transport == BTA_TRANSPORT_BR_EDR)
             {
                 bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
                 bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
@@ -885,7 +903,8 @@ static void bta_gatts_send_request_cback (UINT16 conn_id,
 **
 *******************************************************************************/
 static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                  BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                  BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                  tGATT_TRANSPORT transport)
 {
     tBTA_GATTS      cb_data;
     UINT8           evt = connected ? BTA_GATTS_CONNECT_EVT: BTA_GATTS_DISCONNECT_EVT;
@@ -901,7 +920,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
     if (p_reg && p_reg->p_cback)
     {
         /* there is no RM for GATT */
-        if (!BTM_IsBleLink(bda))
+        if (transport == BTA_TRANSPORT_BR_EDR)
         {
             if (connected)
                 bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
@@ -912,6 +931,7 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
         cb_data.conn.conn_id = conn_id;
         cb_data.conn.server_if = gatt_if;
         cb_data.conn.reason = reason;
+        cb_data.conn.transport = transport;
         memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
         (*p_reg->p_cback)(evt, &cb_data);
     }
index ad30d73..79eb6f9 100644 (file)
@@ -464,11 +464,13 @@ void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
 ** Parameters       server_if: server interface.
 **                  remote_bda: remote device BD address.
 **                  is_direct: direct connection or background auto connection
+**                  transport : Transport on which GATT connection to be opened (BR/EDR or LE)
 **
 ** Returns          void
 **
 *******************************************************************************/
-void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
+void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
+                    tBTA_GATT_TRANSPORT transport)
 {
     tBTA_GATTS_API_OPEN  *p_buf;
 
@@ -477,6 +479,7 @@ void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_dire
         p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
         p_buf->server_if = server_if;
         p_buf->is_direct = is_direct;
+        p_buf->transport = transport;
         memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
 
         bta_sys_sendmsg(p_buf);
index ce9553a..9a12dfd 100644 (file)
@@ -139,10 +139,12 @@ typedef struct
 
 typedef struct
 {
-    BT_HDR              hdr;
-    BD_ADDR             remote_bda;
-    tBTA_GATTS_IF       server_if;
-    BOOLEAN             is_direct;
+    BT_HDR                  hdr;
+    BD_ADDR                 remote_bda;
+    tBTA_GATTS_IF           server_if;
+    BOOLEAN                 is_direct;
+    tBTA_GATT_TRANSPORT     transport;
+
 }tBTA_GATTS_API_OPEN;
 
 typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
index 4f297ee..f2bba4a 100644 (file)
@@ -347,7 +347,7 @@ void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda)
     bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = p_cb->index;
     p_cb->in_use = TRUE;
 
-    BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE);
+    BTA_GATTC_Open(bta_hh_cb.gatt_if, remote_bda, TRUE, BTA_GATT_TRANSPORT_LE);
 }
 /*******************************************************************************
 **
@@ -640,7 +640,8 @@ void bta_hh_le_read_rpt_ref_descr(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rp
 
     while (p_rpt != NULL)
     {
-        if (!p_rpt->in_use) break;
+        if(!p_rpt->in_use)
+            break;
 
         if (p_rpt->rpt_type == BTA_HH_RPTT_INPUT)
         {
@@ -674,8 +675,6 @@ void bta_hh_le_read_rpt_ref_descr(tBTA_HH_DEV_CB *p_dev_cb, tBTA_HH_LE_RPT *p_rp
                 break;
             }
         }
-        else
-            break;
 
         if (p_rpt->index == BTA_HH_LE_RPT_MAX - 1)
             break;
@@ -1210,11 +1209,13 @@ void bta_hh_le_pri_service_discovery(tBTA_HH_DEV_CB *p_cb)
 ** Returns          None
 **
 *******************************************************************************/
-void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void bta_hh_le_encrypt_cback(BD_ADDR bd_addr, tBTA_GATT_TRANSPORT transport,
+                                    void *p_ref_data, tBTM_STATUS result)
 {
     UINT8   idx = bta_hh_find_cb(bd_addr);
     tBTA_HH_DEV_CB *p_dev_cb;
     UNUSED(p_ref_data);
+    UNUSED (transport);
 
     APPL_TRACE_ERROR0("bta_hh_le_encrypt_cback");
 
@@ -1315,7 +1316,7 @@ void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
     }
 
     /* verify bond */
-    BTM_GetSecurityFlags(p_cb->addr, &sec_flag);
+    BTM_GetSecurityFlagsByTransport(p_cb->addr, &sec_flag, BT_TRANSPORT_LE);
 
     /* if link has been encrypted */
     if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
@@ -1327,14 +1328,14 @@ void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf)
     {
         sec_flag = BTM_BLE_SEC_ENCRYPT;
         p_cb->status = BTA_HH_ERR_AUTH_FAILED;
-        BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag);
+        BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag);
     }
     /* unbonded device, report security error here */
     else if (p_cb->sec_mask != BTA_SEC_NONE)
     {
         sec_flag = BTM_BLE_SEC_ENCRYPT_NO_MITM;
         p_cb->status = BTA_HH_ERR_AUTH_FAILED;
-        BTM_SetEncryption(p_cb->addr, bta_hh_le_encrypt_cback, &sec_flag);
+        BTM_SetEncryption(p_cb->addr, BTA_TRANSPORT_LE, bta_hh_le_encrypt_cback, &sec_flag);
     }
     /* otherwise let it go through */
     else
@@ -2620,7 +2621,7 @@ static void bta_hh_le_add_dev_bg_conn(tBTA_HH_DEV_CB *p_cb, BOOLEAN check_bond)
         !p_cb->in_bg_conn && to_add)
     {
         /* add device into BG connection to accept remote initiated connection */
-        BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE);
+        BTA_GATTC_Open(bta_hh_cb.gatt_if, p_cb->addr, FALSE, BTA_GATT_TRANSPORT_LE);
         p_cb->in_bg_conn = TRUE;
 
         BTA_DmBleSetBgConnType(BTA_DM_BLE_CONN_AUTO, NULL);
index 86d9182..b8fcddc 100644 (file)
@@ -200,7 +200,11 @@ typedef UINT16 tBTA_DM_DISC;        /* this discoverability mode is a bit mask a
 
 // btla-specific ++
 typedef UINT16 tBTA_DM_CONN;
-// btla-specific --
+
+#define BTA_TRANSPORT_UNKNOWN   0
+#define BTA_TRANSPORT_BR_EDR    BT_TRANSPORT_BR_EDR
+#define BTA_TRANSPORT_LE        BT_TRANSPORT_LE
+typedef tBT_TRANSPORT tBTA_TRANSPORT;
 
 /* Pairable Modes */
 #define BTA_DM_PAIRABLE         1
@@ -311,6 +315,8 @@ typedef struct
 #define BTA_BLE_LIMIT_DISC_FLAG     BTM_BLE_LIMIT_DISC_FLAG
 #define BTA_BLE_GEN_DISC_FLAG       BTM_BLE_GEN_DISC_FLAG
 #define BTA_BLE_BREDR_NOT_SPT       BTM_BLE_BREDR_NOT_SPT
+#define BTA_BLE_DMT_CONTROLLER_SPT  BTM_BLE_DMT_CONTROLLER_SPT
+#define BTA_BLE_DMT_HOST_SPT        BTM_BLE_DMT_HOST_SPT
 #define BTA_BLE_NON_LIMIT_DISC_FLAG BTM_BLE_NON_LIMIT_DISC_FLAG
 #define BTA_BLE_ADV_FLAG_MASK       BTM_BLE_ADV_FLAG_MASK
 #define BTA_BLE_LIMIT_DISC_MASK     BTM_BLE_LIMIT_DISC_MASK
@@ -439,7 +445,9 @@ typedef UINT8 tBTA_DM_BLE_SCAN_COND_OP;
 #define BTA_DM_BLE_PF_MANU_DATA            BTM_BLE_PF_MANU_DATA
 #define BTA_DM_BLE_PF_SRVC_DATA_PATTERN    BTM_BLE_PF_SRVC_DATA_PATTERN
 #define BTA_DM_BLE_PF_TYPE_MAX             BTM_BLE_PF_TYPE_MAX
+#define BTA_DM_BLE_PF_SRVC_DATA            BTM_BLE_PF_SRVC_DATA
 #define BTA_DM_BLE_PF_TYPE_ALL             BTM_BLE_PF_TYPE_ALL
+#define BTA_DM_BLE_PF_TYPE_MAX             BTM_BLE_PF_TYPE_MAX
 typedef UINT8   tBTA_DM_BLE_PF_COND_TYPE;
 
 typedef union
@@ -541,6 +549,7 @@ typedef struct
 /* Structure associated with BTA_DM_PIN_REQ_EVT */
 typedef struct
 {
+    /* Note: First 3 data members must be, bd_addr, dev_class, and bd_name in order */
     BD_ADDR         bd_addr;            /* BD address peer device. */
     DEV_CLASS       dev_class;          /* Class of Device */
     BD_NAME         bd_name;            /* Name of peer device. */
@@ -674,6 +683,9 @@ typedef struct
 typedef struct
 {
     BD_ADDR         bd_addr;            /* BD address peer device. */
+#if BLE_INCLUDED == TRUE
+    tBTA_TRANSPORT  link_type;
+#endif
 } tBTA_DM_LINK_UP;
 
 /* Structure associated with BTA_DM_LINK_DOWN_EVT */
@@ -682,6 +694,9 @@ typedef struct
     BD_ADDR         bd_addr;            /* BD address peer device. */
     UINT8           status;             /* connection open/closed */
     BOOLEAN         is_removed;         /* TRUE if device is removed when link is down */
+#if BLE_INCLUDED == TRUE
+    tBTA_TRANSPORT  link_type;
+#endif
 } tBTA_DM_LINK_DOWN;
 
 /* Structure associated with BTA_DM_ROLE_CHG_EVT */
@@ -859,6 +874,7 @@ typedef struct
     UINT8               ble_addr_type;
     tBTM_BLE_EVT_TYPE   ble_evt_type;
     tBT_DEVICE_TYPE     device_type;
+    UINT8               flag;
 #endif
 
 } tBTA_DM_INQ_RES;
@@ -920,7 +936,7 @@ typedef void (tBTA_DM_SEARCH_CBACK)(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_
 typedef void (tBTA_DM_EXEC_CBACK) (void * p_param);
 
 /* Encryption callback*/
-typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_STATUS result);
+typedef void (tBTA_DM_ENCRYPT_CBACK) (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result);
 
 #if BLE_INCLUDED == TRUE
 #define BTA_DM_BLE_SEC_NONE         BTM_BLE_SEC_NONE
@@ -980,13 +996,6 @@ typedef UINT8 tBTA_DM_PM_ACTTION;
 #define BTA_DM_PM_PARK_IDX      5 /* the actual index to bta_dm_pm_md[] for PARK mode */
 #endif
 
-#define BTA_DM_SW_BB_TO_MM      BTM_SW_BB_TO_MM
-#define BTA_DM_SW_MM_TO_BB      BTM_SW_MM_TO_BB
-#define BTA_DM_SW_BB_TO_BTC     BTM_SW_BB_TO_BTC
-#define BTA_DM_SW_BTC_TO_BB     BTM_SW_BTC_TO_BB
-
-typedef tBTM_SW_DIR tBTA_DM_SW_DIR;
-
 /* Switch callback events */
 #define BTA_DM_SWITCH_CMPL_EVT      0       /* Completion of the Switch API */
 
@@ -1023,6 +1032,12 @@ typedef tSDP_DISCOVERY_DB       tBTA_DISCOVERY_DB;
 /* Device features mask definitions */
 #define BTA_FEATURE_BYTES_PER_PAGE  BTM_FEATURE_BYTES_PER_PAGE
 #define BTA_EXT_FEATURES_PAGE_MAX   BTM_EXT_FEATURES_PAGE_MAX
+/* ACL type
+*/
+#define BTA_DM_LINK_TYPE_BR_EDR    0x01
+#define BTA_DM_LINK_TYPE_LE        0x02
+#define BTA_DM_LINK_TYPE_ALL       0xFF
+typedef UINT8 tBTA_DM_LINK_TYPE;
 
 /*****************************************************************************
 **  External Function Declarations
@@ -1274,6 +1289,21 @@ BTA_API extern void BTA_DmBond(BD_ADDR bd_addr);
 
 /*******************************************************************************
 **
+** Function         BTA_DmBondByTransport
+**
+** Description      This function initiates a bonding procedure with a peer
+**                  device by designated transport.  The bonding procedure enables
+**                  authentication and optionally encryption on the Bluetooth link.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBondByTransport(BD_ADDR bd_addr, tBTA_TRANSPORT transport);
+
+
+/*******************************************************************************
+**
 ** Function         BTA_DmBondCancel
 **
 ** Description      This function cancels a bonding procedure with a peer
@@ -1596,11 +1626,13 @@ BTA_API extern tBTA_STATUS BTA_DmGetDiRecord( UINT8 get_record_index, tBTA_DI_GE
 **
 ** Parameters:      bd_addr       - Address of the peer device
 **                  remove_dev    - remove device or not after link down
+**                  transport     - which transport to close
+
 **
 ** Returns          void.
 **
 *******************************************************************************/
-BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev);
+BTA_API extern void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transport);
 
 /*******************************************************************************
 **
@@ -1746,7 +1778,8 @@ BTA_API extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type
 ** Returns          void
 **
 *******************************************************************************/
-BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr, tBTA_LE_KEY_VALUE *p_le_key,
+BTA_API extern void BTA_DmAddBleKey (BD_ADDR bd_addr,
+                                     tBTA_LE_KEY_VALUE *p_le_key,
                                      tBTA_LE_KEY_TYPE key_type);
 
 /*******************************************************************************
@@ -1844,6 +1877,25 @@ BTA_API extern void BTA_DmSearchExt(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK_EXT
 BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
                                     tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search);
 
+/*******************************************************************************
+**
+** Function         BTA_DmDiscoverByTransport
+**
+** Description      This function does service discovery on particular transport
+**                  for services of a
+**                  peer device. When services.num_uuid is 0, it indicates all
+**                  GATT based services are to be searched; other wise a list of
+**                  UUID of interested services should be provided through
+**                  p_services->p_uuid.
+**
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services,
+                                              tBTA_DM_SEARCH_CBACK *p_cback, BOOLEAN sdp_search,
+                                              tBTA_TRANSPORT transport);
 
 /*******************************************************************************
 **
@@ -1855,6 +1907,7 @@ BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_
 **                  bring up unencrypted links, then later encrypt them.
 **
 ** Parameters:      bd_addr       - Address of the peer device
+**                  transport     - transport of the link to be encruypted
 **                  p_callback    - Pointer to callback function to indicat the
 **                                  link encryption status
 **                  sec_act       - This is the security action to indicate
@@ -1867,8 +1920,9 @@ BTA_API extern void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_
 **
 **
 *******************************************************************************/
-BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_DM_ENCRYPT_CBACK *p_callback,
-                            tBTA_DM_BLE_SEC_ACT sec_act);
+BTA_API extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+                                        tBTA_DM_ENCRYPT_CBACK *p_callback,
+                                         tBTA_DM_BLE_SEC_ACT sec_act);
 
 
 /*******************************************************************************
@@ -1974,6 +2028,23 @@ BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask,
 *******************************************************************************/
 BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start);
 
+/*******************************************************************************
+**
+** Function         BTA_DmBleUpdateConnectionParams
+**
+** Description      Update connection parameters, can only be used when connection is up.
+**
+** Parameters:      bd_addr   - BD address of the peer
+**                  min_int   -     minimum connection interval, [0x0004~ 0x4000]
+**                  max_int   -     maximum connection interval, [0x0004~ 0x4000]
+**                  latency   -     slave latency [0 ~ 500]
+**                  timeout   -     supervision timeout [0x000a ~ 0xc80]
+**
+** Returns          void
+**
+*******************************************************************************/
+BTA_API extern void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int,
+                                   UINT16 max_int, UINT16 latency, UINT16 timeout);
 #endif
 
 #ifdef __cplusplus
index b53b180..3fec4a0 100644 (file)
@@ -77,21 +77,32 @@ typedef struct
 #define  BTA_GATT_INSUF_RESOURCE            GATT_INSUF_RESOURCE                /* 0x0011 */
 
 
-#define  BTA_GATT_ILLEGAL_PARAMETER         GATT_ILLEGAL_PARAMETER             /* 0x0087 */
-#define  BTA_GATT_NO_RESOURCES              GATT_NO_RESOURCES                  /* 0x0080 */
-#define  BTA_GATT_INTERNAL_ERROR            GATT_INTERNAL_ERROR                /* 0x0081 */
-#define  BTA_GATT_WRONG_STATE               GATT_WRONG_STATE                   /* 0x0082 */
-#define  BTA_GATT_DB_FULL                   GATT_DB_FULL                       /* 0x0083 */
-#define  BTA_GATT_BUSY                      GATT_BUSY                          /* 0x0084 */
-#define  BTA_GATT_ERROR                     GATT_ERROR                         /* 0x0085 */
-#define  BTA_GATT_CMD_STARTED               GATT_CMD_STARTED                   /* 0x0086 */
-#define  BTA_GATT_PENDING                   GATT_PENDING                       /* 0x0088 */
-#define  BTA_GATT_AUTH_FAIL                 GATT_AUTH_FAIL                     /* 0x0089 */
-#define  BTA_GATT_MORE                      GATT_MORE                          /* 0x008a */
-#define  BTA_GATT_INVALID_CFG               GATT_INVALID_CFG                   /* 0x008b */
-#define  BTA_GATT_DUP_REG                   0x008c
-#define  BTA_GATT_ALREADY_OPEN              0x008d                              /* 0x008d */
-#define  BTA_GATT_CANCEL                    0x008e                              /* 0x008e */
+#define  BTA_GATT_NO_RESOURCES              GATT_NO_RESOURCES                  /* 0x80 */
+#define  BTA_GATT_INTERNAL_ERROR            GATT_INTERNAL_ERROR                /* 0x81 */
+#define  BTA_GATT_WRONG_STATE               GATT_WRONG_STATE                   /* 0x82 */
+#define  BTA_GATT_DB_FULL                   GATT_DB_FULL                       /* 0x83 */
+#define  BTA_GATT_BUSY                      GATT_BUSY                          /* 0x84 */
+#define  BTA_GATT_ERROR                     GATT_ERROR                         /* 0x85 */
+#define  BTA_GATT_CMD_STARTED               GATT_CMD_STARTED                   /* 0x86 */
+#define  BTA_GATT_ILLEGAL_PARAMETER         GATT_ILLEGAL_PARAMETER             /* 0x87 */
+#define  BTA_GATT_PENDING                   GATT_PENDING                       /* 0x88 */
+#define  BTA_GATT_AUTH_FAIL                 GATT_AUTH_FAIL                     /* 0x89 */
+#define  BTA_GATT_MORE                      GATT_MORE                          /* 0x8a */
+#define  BTA_GATT_INVALID_CFG               GATT_INVALID_CFG                   /* 0x8b */
+#define  BTA_GATT_SERVICE_STARTED           GATT_SERVICE_STARTED               /* 0x8c */
+#define  BTA_GATT_ENCRYPED_MITM             GATT_ENCRYPED_MITM                 /* GATT_SUCCESS */
+#define  BTA_GATT_ENCRYPED_NO_MITM          GATT_ENCRYPED_NO_MITM              /* 0x8d */
+#define  BTA_GATT_NOT_ENCRYPTED             GATT_NOT_ENCRYPTED                 /* 0x8e */
+
+#define  BTA_GATT_DUP_REG                   0x8f                                /* 0x8f */
+#define  BTA_GATT_ALREADY_OPEN              0x90                                /* 0x90 */
+#define  BTA_GATT_CANCEL                    0x91                                /* 0x91 */
+
+                                             /* 0xE0 ~ 0xFC reserved for future use */
+#define  BTA_GATT_CCC_CFG_ERR                GATT_CCC_CFG_ERR     /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */
+#define  BTA_GATT_PRC_IN_PROGRESS            GATT_PRC_IN_PROGRESS /* 0xFE Procedure Already in progress */
+#define  BTA_GATT_OUT_OF_RANGE               GATT_OUT_OF_RANGE    /* 0xFFAttribute value out of range */
+
 typedef UINT8 tBTA_GATT_STATUS;
 
 #define BTA_GATT_INVALID_CONN_ID   GATT_INVALID_CONN_ID
@@ -325,6 +336,7 @@ typedef struct
     UINT16              conn_id;
     tBTA_GATTC_IF       client_if;
     BD_ADDR             remote_bda;
+    tBTA_TRANSPORT      transport;
     UINT16              mtu;
 }tBTA_GATTC_OPEN;
 
@@ -469,12 +481,9 @@ typedef tGATTS_SRV_CHG     tBTA_GATTS_SRV_CHG;
 typedef tGATTS_SRV_CHG_REQ tBTA_GATTS_SRV_CHG_REQ;
 typedef tGATTS_SRV_CHG_RSP tBTA_GATTS_SRV_CHG_RSP;
 
-enum
-{
-    BTA_GATT_TRANSPORT_LE,
-    BTA_GATT_TRANSPORT_BR_EDR,
-    BTA_GATT_TRANSPORT_LE_BR_EDR
-};
+#define BTA_GATT_TRANSPORT_LE       GATT_TRANSPORT_LE
+#define BTA_GATT_TRANSPORT_BR_EDR   GATT_TRANSPORT_BR_EDR
+#define BTA_GATT_TRANSPORT_LE_BR_EDR    GATT_TRANSPORT_LE_BR_EDR
 typedef UINT8 tBTA_GATT_TRANSPORT;
 
 /* attribute value */
@@ -552,6 +561,7 @@ typedef struct
     BD_ADDR             remote_bda;
     UINT16              conn_id;
     tBTA_GATT_REASON    reason; /* report disconnect reason */
+    tBTA_GATT_TRANSPORT transport;
 }tBTA_GATTS_CONN;
 
 /* GATTS callback data */
@@ -560,7 +570,7 @@ typedef union
     tBTA_GATTS_REG_OPER     reg_oper;
     tBTA_GATTS_CREATE       create;
     tBTA_GATTS_SRVC_OPER    srvc_oper;
-    tBTA_GATT_STATUS        status; /*  BTA_GATTS_CONF_EVT */
+    tBTA_GATT_STATUS        status; /*  BTA_GATTS_CONF_EVT or BTA_GATTS_LISTEN_EVT */
     tBTA_GATTS_ADD_RESULT   add_result;  /* add included service: BTA_GATTS_ADD_INCL_SRVC_EVT
                                            add char : BTA_GATTS_ADD_CHAR_EVT
                                            add char descriptor: BTA_GATTS_ADD_CHAR_DESCR_EVT */
@@ -644,7 +654,8 @@ BTA_API extern void BTA_GATTC_AppDeregister (tBTA_GATTC_IF client_if);
 ** Returns          void
 **
 *******************************************************************************/
-BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct);
+BTA_API extern void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
+                                   BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport);
 
 /*******************************************************************************
 **
@@ -1301,7 +1312,8 @@ BTA_API extern void BTA_GATTC_ConfigureMTU (UINT16 conn_id, UINT16 mtu);
 ** Returns          void
 **
 *******************************************************************************/
-    BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct);
+    BTA_API extern void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda,
+                                        BOOLEAN is_direct, tBTA_GATT_TRANSPORT transport);
 
 
 /*******************************************************************************
index afbd111..f9569b3 100644 (file)
@@ -886,7 +886,7 @@ void bta_jv_get_remote_device_name(tBTA_JV_MSG *p_data)
 {
 
     BTM_ReadRemoteDeviceName(p_data->get_rmt_name.bd_addr,
-        (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback);
+        (tBTM_CMPL_CB *)bta_jv_get_remote_device_name_cback, BT_TRANSPORT_BR_EDR);
 }
 
 /*******************************************************************************
@@ -903,11 +903,16 @@ void bta_jv_set_service_class (tBTA_JV_MSG *p_data)
     tBTA_UTL_COD cod;
 
     /* set class of device */
-    /* BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the API function as defined in the assigned number page.
-    For example: the object transfer bit is bit 20 of the 24-bit Class of device; the value of this bit is 0x00100000 (value 1)
-    Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER        0x1000 // (value 2)
-    This reflects that the service class defined at btm is UINT16, which starts at bit 8 of the 24 bit Class of Device
-    The following statement converts from (value 1) into (value 2) */
+    /* 
+    BTA_JvSetServiceClass(UINT32 service) assumes that the service class passed to the
+    API function as defined in the assigned number page.
+    For example: the object transfer bit is bit 20 of the 24-bit Class of device;
+    the value of this bit is 0x00100000 (value 1)
+    Our btm_api.h defines this bit as #define BTM_COD_SERVICE_OBJ_TRANSFER        0x1000  (value 2)
+    This reflects that the service class defined at btm is UINT16,
+    which starts at bit 8 of the 24 bit Class of Device
+    The following statement converts from (value 1) into (value 2)
+    */
     cod.service = (p_data->set_service.service >> 8);
     utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
 }
@@ -921,9 +926,11 @@ void bta_jv_set_service_class (tBTA_JV_MSG *p_data)
 ** Returns      void
 **
 *******************************************************************************/
-static void bta_jv_sec_cback (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+static void bta_jv_sec_cback (BD_ADDR bd_addr, tBTA_TRANSPORT transport,
+                                    void *p_ref_data, tBTM_STATUS result)
 {
     UNUSED(p_ref_data);
+    UNUSED(transport);
 
     tBTA_JV_SET_ENCRYPTION  set_enc;
     if(bta_jv_cb.p_dm_cback)
@@ -947,7 +954,7 @@ static void bta_jv_sec_cback (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS res
 *******************************************************************************/
 void bta_jv_set_encryption(tBTA_JV_MSG *p_data)
 {
-    BTM_SetEncryption(p_data->set_encrypt.bd_addr, bta_jv_sec_cback, NULL);
+    BTM_SetEncryption(p_data->set_encrypt.bd_addr, BTA_TRANSPORT_BR_EDR, bta_jv_sec_cback, NULL);
 }
 
 /*******************************************************************************
index 16ab2d5..ad0b694 100644 (file)
@@ -495,11 +495,13 @@ BOOLEAN BTA_JvIsAuthorized(BD_ADDR bd_addr)
 BOOLEAN BTA_JvIsEncrypted(BD_ADDR bd_addr)
 {
     BOOLEAN is_encrypted = FALSE;
-    UINT8 sec_flags;
+    UINT8 sec_flags, le_flags;
 
-    if(BTM_GetSecurityFlags(bd_addr, &sec_flags))
+    if (BTM_GetSecurityFlags(bd_addr, &sec_flags) &&
+        BTM_GetSecurityFlagsByTransport(bd_addr, &le_flags, BT_TRANSPORT_LE))
     {
-        if(sec_flags&BTM_SEC_FLAG_ENCRYPTED)
+        if(sec_flags & BTM_SEC_FLAG_ENCRYPTED ||
+           le_flags & BTM_SEC_FLAG_ENCRYPTED)
             is_encrypted = TRUE;
     }
     return is_encrypted;
index 9a69b00..f64c695 100644 (file)
@@ -353,4 +353,34 @@ bt_status_t btif_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
 
 bt_status_t btif_storage_get_remote_version(const bt_bdaddr_t *remote_bd_addr,
                                   bt_remote_version_t *p_ver);
+
+/*******************************************************************************
+**
+** Function         btif_storage_set_dmt_support_type
+**
+** Description      Sets DMT support status for a remote device
+**
+** Returns          BT_STATUS_SUCCESS if config update is successful
+**                  BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+
+bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr,
+                                                   BOOLEAN dmt_supported);
+
+
+
+/*******************************************************************************
+**
+** Function         btif_storage_is_dmt_supported_device
+**
+** Description      checks if a device supports Dual mode topology
+**
+** Returns         TRUE if remote supports DMT else FALSE
+**
+*******************************************************************************/
+
+BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr);
+
+
 #endif /* BTIF_STORAGE_H */
index 44644de..fe4182f 100644 (file)
@@ -327,7 +327,7 @@ static const void* get_profile_interface (const char *profile_id)
     if (is_profile(profile_id, BT_PROFILE_HEALTH_ID))
         return btif_hl_get_interface();
 
-#if BTA_GATT_INCLUDED == TRUE
+#if ( BTA_GATT_INCLUDED == TRUE &&BLE_INCLUDED == TRUE)
     if (is_profile(profile_id, BT_PROFILE_GATT_ID))
         return btif_gatt_get_interface();
 #endif
index e72a95e..40d21fd 100644 (file)
@@ -1073,6 +1073,12 @@ static void btif_dm_search_devices_evt (UINT16 event, char *p_param)
                 ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote device (inquiry)", status);
 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
                 status = btif_storage_set_remote_addr_type(&bdaddr, addr_type);
+                if (( dev_type == BT_DEVICE_TYPE_DUMO)&&
+                   (p_search_data->inq_res.flag & BTA_BLE_DMT_CONTROLLER_SPT) &&
+                   (p_search_data->inq_res.flag & BTA_BLE_DMT_HOST_SPT))
+                 {
+                    btif_storage_set_dmt_support_type (&bdaddr, TRUE);
+                 }
                 ASSERTC(status == BT_STATUS_SUCCESS, "failed to save remote addr type (inquiry)", status);
 #endif
                 /* Callback to notify upper layer of device */
index 59840af..3d6d097 100644 (file)
@@ -141,7 +141,9 @@ typedef struct
     uint8_t     start;
     uint8_t     has_mask;
     int8_t      rssi;
+    uint8_t     flag;
     tBT_DEVICE_TYPE device_type;
+    btgatt_transport_t transport;
 } __attribute__((packed)) btif_gattc_cb_t;
 
 typedef struct
@@ -153,8 +155,8 @@ typedef struct
 typedef struct
 {
     btif_gattc_dev_t remote_dev[BTIF_GATT_MAX_OBSERVED_DEV];
-    uint8_t        addr_type;
-    uint8_t        next_storage_idx;
+    uint8_t            addr_type;
+    uint8_t            next_storage_idx;
 }__attribute__((packed)) btif_gattc_dev_cb_t;
 
 /*******************************************************************************
@@ -482,6 +484,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
             btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
             uint8_t remote_name_len;
             uint8_t *p_eir_remote_name=NULL;
+            bt_device_type_t dev_type;
+            bt_property_t properties;
 
             p_eir_remote_name = BTA_CheckEirData(p_btif_cb->value,
                                          BTM_EIR_COMPLETE_LOCAL_NAME_TYPE, &remote_name_len);
@@ -506,6 +510,19 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
                }
 
             }
+
+            if (( p_btif_cb->device_type == BT_DEVICE_TYPE_DUMO)&&
+               (p_btif_cb->flag & BTA_BLE_DMT_CONTROLLER_SPT) &&
+               (p_btif_cb->flag & BTA_BLE_DMT_HOST_SPT))
+             {
+                btif_storage_set_dmt_support_type (&(p_btif_cb->bd_addr), TRUE);
+             }
+
+             dev_type =  p_btif_cb->device_type;
+             BTIF_STORAGE_FILL_PROPERTY(&properties,
+                        BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type);
+             btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties);
+
             HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb,
                       &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value);
             break;
@@ -570,6 +587,7 @@ static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_dat
             btif_cb.device_type = p_data->inq_res.device_type;
             btif_cb.rssi = p_data->inq_res.rssi;
             btif_cb.addr_type = p_data->inq_res.ble_addr_type;
+            btif_cb.flag = p_data->inq_res.flag;
             if (p_data->inq_res.p_eir)
             {
                 memcpy(btif_cb.value, p_data->inq_res.p_eir, 62);
@@ -663,6 +681,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
             // Ensure device is in inquiry database
             int addr_type = 0;
             int device_type = 0;
+            tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
 
             if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE
                   && device_type != BT_DEVICE_TYPE_BREDR)
@@ -672,8 +691,29 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
             if (!p_cb->is_direct)
                 BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
 
+            switch(device_type)
+            {
+                case BT_DEVICE_TYPE_BREDR:
+                    transport = BTA_GATT_TRANSPORT_BR_EDR;
+                    break;
+
+                case BT_DEVICE_TYPE_BLE:
+                    transport = BTA_GATT_TRANSPORT_LE;
+                    break;
+
+                case BT_DEVICE_TYPE_DUMO:
+                    if ((p_cb->transport == GATT_TRANSPORT_LE) &&
+                        (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE))
+                        transport = BTA_GATT_TRANSPORT_LE;
+                    else
+                        transport = BTA_GATT_TRANSPORT_BR_EDR;
+                    break;
+            }
+
             // Connect!
-            BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct);
+            BTIF_TRACE_DEBUG2 ("BTA_GATTC_Open Transport  = %d, dev type = %d",
+                                transport, device_type);
+            BTA_GATTC_Open(p_cb->client_if, p_cb->bd_addr.address, p_cb->is_direct, transport);
             break;
         }
 
@@ -1057,12 +1097,14 @@ static bt_status_t btif_gattc_scan( int client_if, bool start )
                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
 }
 
-static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr, bool is_direct )
+static bt_status_t btif_gattc_open(int client_if, const bt_bdaddr_t *bd_addr,
+                                        bool is_direct,int transport)
 {
     CHECK_BTGATT_INIT();
     btif_gattc_cb_t btif_cb;
     btif_cb.client_if = (uint8_t) client_if;
     btif_cb.is_direct = is_direct ? 1 : 0;
+    btif_cb.transport = (btgatt_transport_t)transport;
     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
     return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_OPEN,
                                  (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
index 9fc4fad..f5ad0f5 100644 (file)
@@ -100,9 +100,10 @@ typedef struct
     uint8_t             is_direct;
     uint8_t             num_handles;
     uint8_t             properties;
-    uint8_t             transport;
     uint8_t             confirm;
     uint8_t             status;
+    btgatt_transport_t  transport;
+
 } __attribute__((packed)) btif_gatts_cb_t;
 
 
@@ -369,6 +370,7 @@ static void btgatts_handle_event(uint16_t event, char* p_param)
             // Ensure device is in inquiry database
             int addr_type = 0;
             int device_type = 0;
+            tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
 
             if (btif_get_device_type(p_cb->bd_addr.address, &addr_type, &device_type) == TRUE
                   && device_type != BT_DEVICE_TYPE_BREDR)
@@ -378,9 +380,32 @@ static void btgatts_handle_event(uint16_t event, char* p_param)
             if (!p_cb->is_direct)
                 BTA_DmBleSetBgConnType(BTM_BLE_CONN_AUTO, NULL);
 
+            switch(device_type)
+            {
+                case BT_DEVICE_TYPE_BREDR:
+                    transport = BTA_GATT_TRANSPORT_BR_EDR;
+                    break;
+
+                case BT_DEVICE_TYPE_BLE:
+                    transport = BTA_GATT_TRANSPORT_LE;
+                    break;
+
+                case BT_DEVICE_TYPE_DUMO:
+                    if ((p_cb->transport == GATT_TRANSPORT_LE) &&
+                        (btif_storage_is_dmt_supported_device(&(p_cb->bd_addr)) == TRUE))
+                        transport = BTA_GATT_TRANSPORT_LE;
+                    else
+                        transport = BTA_GATT_TRANSPORT_BR_EDR;
+                    break;
+
+                default:
+                    BTIF_TRACE_ERROR1 (" GATT Open :Invalid device type %d",device_type);
+                    return;
+            }
+
             // Connect!
             BTA_GATTS_Open(p_cb->server_if, p_cb->bd_addr.address,
-                           p_cb->is_direct);
+                           p_cb->is_direct, transport);
             break;
         }
 
@@ -489,12 +514,14 @@ static bt_status_t btif_gatts_unregister_app( int server_if )
                                  (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
 }
 
-static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr, bool is_direct )
+static bt_status_t btif_gatts_open( int server_if, const bt_bdaddr_t *bd_addr,
+                                      bool is_direct, int transport )
 {
     CHECK_BTGATT_INIT();
     btif_gatts_cb_t btif_cb;
     btif_cb.server_if = (uint8_t) server_if;
     btif_cb.is_direct = is_direct ? 1 : 0;
+    btif_cb.transport = (btgatt_transport_t)transport;
     bdcpy(btif_cb.bd_addr.address, bd_addr->address);
     return btif_transfer_context(btgatts_handle_event, BTIF_GATTS_OPEN,
                                  (char*) &btif_cb, sizeof(btif_gatts_cb_t), NULL);
index a2cca6a..def2753 100644 (file)
@@ -101,11 +101,12 @@ static char * format_uuid(tBT_UUID bt_uuid, char *str_buf)
 }
 
 static void btif_test_connect_cback(tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                    BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                    BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport)
 {
     UNUSED(gatt_if);
     UNUSED(bda);
     UNUSED(reason);
+    UNUSED (transport);
 
     ALOGD("%s: conn_id=%d, connected=%d", __FUNCTION__, conn_id, connected);
     test_cb.conn_id = connected ? conn_id : 0;
@@ -242,7 +243,7 @@ bt_status_t btif_gattc_test_command_impl(uint16_t command, btgatt_test_params_t*
             if (params->u1 == BT_DEVICE_TYPE_BLE)
                 BTM_SecAddBleDevice(params->bda1->address, NULL, BT_DEVICE_TYPE_BLE, 0);
 
-            if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE) )
+            if ( !GATT_Connect(test_cb.gatt_if, params->bda1->address, TRUE, BT_TRANSPORT_LE) )
             {
                 ALOGE("%s: GATT_Connect failed!", __FUNCTION__);
             }
index 91cf004..4facdef 100644 (file)
@@ -285,7 +285,7 @@ uint16_t set_read_value(btgatt_read_params_t *p_dest, tBTA_GATTC_READ *p_src)
  * Encrypted link map handling
  *******************************************************************************/
 
-static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result);
+static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result);
 
 static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr)
 {
@@ -295,8 +295,10 @@ static BOOLEAN btif_gatt_is_link_encrypted (BD_ADDR bd_addr)
     return BTA_JvIsEncrypted(bd_addr);
 }
 
-static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_STATUS result)
+static void btif_gatt_set_encryption_cb (BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS result)
 {
+    UNUSED(transport);
+
     if (result != BTA_SUCCESS && result != BTA_BUSY)
     {
         bt_bdaddr_t bda;
@@ -312,16 +314,39 @@ void btif_gatt_check_encrypted_link (BD_ADDR bd_addr)
 
     bt_bdaddr_t bda;
     bdcpy(bda.address, bd_addr);
+    int device_type = 0;
+    int addr_type = 0;
 
+#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE))
     if ((btif_storage_get_ble_bonding_key(&bda, BTIF_DM_LE_KEY_PENC,
                     buf, sizeof(btif_dm_ble_penc_keys_t)) == BT_STATUS_SUCCESS)
         && !btif_gatt_is_link_encrypted(bd_addr))
     {
-#if (!defined(BLE_DELAY_REQUEST_ENC) || (BLE_DELAY_REQUEST_ENC == FALSE))
-        BTA_DmSetEncryption(bd_addr,
+        tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
+
+        btif_get_device_type(bd_addr, &addr_type, &device_type);
+        switch(device_type)
+        {
+            case BT_DEVICE_TYPE_BREDR:
+                transport = BTA_GATT_TRANSPORT_BR_EDR;
+                break;
+
+            case BT_DEVICE_TYPE_BLE:
+                transport = BTA_GATT_TRANSPORT_LE;
+                break;
+
+            case BT_DEVICE_TYPE_DUMO:
+                transport = BTA_GATT_TRANSPORT_LE_BR_EDR;
+                break;
+
+            default:
+                BTIF_TRACE_ERROR1 (" GATT Encrypt :Invalid device type %d",device_type);
+                return;
+        }
+        BTA_DmSetEncryption(bd_addr,transport,
                             &btif_gatt_set_encryption_cb, BTM_BLE_SEC_ENCRYPT);
-#endif
     }
+#endif
 }
 
 /*******************************************************************************
index a849938..f364701 100644 (file)
@@ -1744,8 +1744,8 @@ BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_bd_addr)
 
     bd2str(remote_bd_addr, &bdstr);
 
-       /*consider on LAP part of BDA string*/
-       bdstr[8] = '\0';
+    /*consider on LAP part of BDA string*/
+    bdstr[8] = '\0';
 
     int line_size = sizeof(linebuf);
     if(btif_config_get_str("Local", BTIF_STORAGE_PATH_AUTOPAIR_BLACKLIST,
@@ -1757,3 +1757,68 @@ BOOLEAN btif_storage_is_fixed_pin_zeros_keyboard(bt_bdaddr_t *remote_bd_addr)
     return FALSE;
 
 }
+
+/*******************************************************************************
+**
+** Function         btif_storage_set_dmt_support_type
+**
+** Description      Sets DMT support status for a remote device
+**
+** Returns          BT_STATUS_SUCCESS if config update is successful
+**                  BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+
+bt_status_t btif_storage_set_dmt_support_type(const bt_bdaddr_t *remote_bd_addr,
+                                                   BOOLEAN dmt_supported)
+{
+    int ret;
+    bdstr_t bdstr = {0};
+    if(remote_bd_addr)
+    {
+        bd2str(remote_bd_addr, &bdstr);
+    }
+    else
+    {
+        BTIF_TRACE_ERROR1("%s  NULL BD Address", __FUNCTION__);
+        return BT_STATUS_FAIL;
+    }
+
+   ret = btif_config_set_int("Remote", bdstr,"DMTSupported", (int)dmt_supported);
+   return ret ? BT_STATUS_SUCCESS:BT_STATUS_FAIL;
+
+}
+
+/*******************************************************************************
+**
+** Function         btif_storage_is_dmt_supported_device
+**
+** Description      checks if a device supports Dual mode topology
+**
+** Returns         TRUE if remote address is valid and supports DMT else FALSE
+**
+*******************************************************************************/
+
+BOOLEAN btif_storage_is_dmt_supported_device(const bt_bdaddr_t *remote_bd_addr)
+{
+    int    dmt_supported = 0;
+    bdstr_t bdstr = {0};
+    if(remote_bd_addr)
+        bd2str(remote_bd_addr, &bdstr);
+
+    if(remote_bd_addr)
+    {
+        bd2str(remote_bd_addr, &bdstr);
+    }
+    else
+    {
+        BTIF_TRACE_ERROR1("%s  NULL BD Address", __FUNCTION__);
+        return FALSE;
+    }
+
+    btif_config_get_int("Remote", bdstr,"DMTSupported", &dmt_supported);
+
+    return dmt_supported == 1 ? TRUE:FALSE;
+}
+
+
index bfcf724..85304fa 100644 (file)
@@ -65,6 +65,7 @@ void utils_init (void)
 *******************************************************************************/
 void utils_cleanup (void)
 {
+    pthread_mutex_destroy(&utils_mutex);
 }
 
 /*******************************************************************************
index c81cbe5..e6b3bb5 100644 (file)
 #define SMP_HOST_ENCRYPT_INCLUDED FALSE
 #endif
 
-#ifndef SAP_INCLUDED
-#define SAP_INCLUDED FALSE
-#endif
-
 #ifndef SBC_NO_PCM_CPY_OPTION
 #define SBC_NO_PCM_CPY_OPTION FALSE
 #endif
 #define BTA_AG_INCLUDED  TRUE
 #endif
 
-#ifndef BTA_CT_INCLUDED
-#define BTA_CT_INCLUDED  FALSE
-#endif
-
-#ifndef BTA_CG_INCLUDED
-#define BTA_CG_INCLUDED  FALSE
-#endif
-
-#ifndef BTA_DG_INCLUDED
-#define BTA_DG_INCLUDED  FALSE
-#endif
-
-#ifndef BTA_FT_INCLUDED
-#define BTA_FT_INCLUDED FALSE
-#endif
-
-#ifndef BTA_OP_INCLUDED
-#define BTA_OP_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PR_INCLUDED
-#define BTA_PR_INCLUDED FALSE
-#endif
-
-#ifndef BTA_SS_INCLUDED
-#define BTA_SS_INCLUDED FALSE
-#endif
-
 #ifndef BTA_DM_INCLUDED
 #define BTA_DM_INCLUDED TRUE
 #endif
 #define BTA_FS_INCLUDED TRUE
 #endif
 
-#ifndef BTA_AC_INCLUDED
-#define BTA_AC_INCLUDED FALSE
-#endif
-
-#ifndef BTA_HD_INCLUDED
-#define BTA_HD_INCLUDED FALSE
-#endif
-
 #ifndef BTA_HH_INCLUDED
 #define BTA_HH_INCLUDED TRUE
 #endif
 #define BTA_AV_INCLUDED TRUE
 #endif
 
-#ifndef BTA_AV_VDP_INCLUDED
-#define BTA_AV_VDP_INCLUDED FALSE
-#endif
-
-#ifndef BTA_AVK_INCLUDED
-#define BTA_AVK_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PBS_INCLUDED
-#define BTA_PBS_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PBC_INCLUDED
-#define BTA_PBC_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FM_INCLUDED
-#define BTA_FM_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FM_DEBUG
-#define BTA_FM_DEBUG FALSE
-#endif
-
-#ifndef BTA_FMTX_INCLUDED
-#define BTA_FMTX_INCLUDED FALSE
-#endif
-
-#ifndef BTA_FMTX_DEBUG
-#define BTA_FMTX_DEBUG FALSE
-#endif
-
-#ifndef BTA_FMTX_FMRX_SWITCH_WORKAROUND
-#define BTA_FMTX_FMRX_SWITCH_WORKAROUND FALSE
-#endif
-
-#ifndef BTA_FMTX_US_FCC_RULES
-#define BTA_FMTX_US_FCC_RULES FALSE
-#endif
-
-#ifndef BTA_HS_INCLUDED
-#define BTA_HS_INCLUDED FALSE
-#endif
-
-#ifndef BTA_MSE_INCLUDED
-#define BTA_MSE_INCLUDED FALSE
-#endif
-
-#ifndef BTA_MCE_INCLUDED
-#define BTA_MCE_INCLUDED FALSE
-#endif
-
-#ifndef BTA_PLAYBACK_INCLUDED
-#define BTA_PLAYBACK_INCLUDED FALSE
-#endif
-
-#ifndef BTA_SSR_INCLUDED
-#define BTA_SSR_INCLUDED FALSE
-#endif
-
-#ifndef BTA_JV_INCLUDED
-#define BTA_JV_INCLUDED FALSE
+#ifndef BTA_GATT_INCLUDED
+#define BTA_GATT_INCLUDED TRUE
 #endif
 
 #ifndef BTA_DISABLE_DELAY
 #define BTA_DM_SDP_DB_SIZE  8000
 #endif
 
-#ifndef FTS_REJECT_INVALID_OBEX_SET_PATH_REQ
-#define FTS_REJECT_INVALID_OBEX_SET_PATH_REQ FALSE
-#endif
-
 #ifndef HL_INCLUDED
 #define HL_INCLUDED  TRUE
 #endif
 
 
 
-/* #define BYPASS_AVDATATRACE */
-
 /******************************************************************************
 **
 ** Platform-Specific
@@ -1130,16 +1024,6 @@ and USER_HW_DISABLE_API macros */
 #define BTM_MAX_VSE_CALLBACKS           3
 #endif
 
-/* Number of streams for dual stack */
-#ifndef BTM_SYNC_INFO_NUM_STR
-#define BTM_SYNC_INFO_NUM_STR           2
-#endif
-
-/* Number of streams for dual stack in BT Controller */
-#ifndef BTM_SYNC_INFO_NUM_STR_BTC
-#define BTM_SYNC_INFO_NUM_STR_BTC       2
-#endif
-
 /******************************************
 **    Lisbon Features
 *******************************************/
@@ -1412,8 +1296,8 @@ and USER_HW_DISABLE_API macros */
 #define LOCAL_BLE_CONTROLLER_ID         (1)
 #endif
 
-#ifndef BTM_BLE_PRIVACY_SPT
-#define BTM_BLE_PRIVACY_SPT      TRUE
+#ifndef BLE_PRIVACY_SPT
+#define BLE_PRIVACY_SPT      TRUE
 #endif
 
 /******************************************************************************
@@ -1433,6 +1317,12 @@ and USER_HW_DISABLE_API macros */
 #error "can't have GATT without BLE"
 #endif
 
+#ifndef BLE_LLT_INCLUDED
+#define BLE_LLT_INCLUDED    TRUE
+#endif
+#ifndef BTM_DUMO_ADDR_CENTRAL_ENABLED
+#define BTM_DUMO_ADDR_CENTRAL_ENABLED    FALSE
+#endif
 #ifndef ATT_INCLUDED
 #define ATT_INCLUDED         TRUE
 #endif
@@ -1450,7 +1340,7 @@ and USER_HW_DISABLE_API macros */
 #endif
 
 #ifndef BLE_PERIPHERAL_MODE_SUPPORT
-#define BLE_PERIPHERAL_MODE_SUPPORT  FALSE
+#define BLE_PERIPHERAL_MODE_SUPPORT  TRUE
 #endif
 
 #ifndef BLE_PERIPHERAL_DISPLAYONLY
index b9cbf91..7395481 100644 (file)
@@ -641,11 +641,19 @@ static char *alloc(int size)
     APPL_TRACE_DEBUG1("HC alloc size=%d", size);
     */
 
+    /* Requested buffer size cannot exceed GKI_MAX_BUF_SIZE. */
+    if (size > GKI_MAX_BUF_SIZE)
+    {
+         APPL_TRACE_ERROR2("HCI DATA SIZE %d greater than MAX %d",
+                           size, GKI_MAX_BUF_SIZE);
+         return NULL;
+    }
+
     p_hdr = (BT_HDR *) GKI_getbuf ((UINT16) size);
 
     if (p_hdr == NULL)
     {
-        APPL_TRACE_WARNING0("alloc returns NO BUFFER!");
+        APPL_TRACE_WARNING1("alloc returns NO BUFFER! (sz %d)", size);
     }
 
     return ((char *) p_hdr);
index 2256a90..943a3cf 100644 (file)
@@ -70,7 +70,8 @@ const tL2CAP_APPL_INFO avdt_l2c_appl = {
 ** Returns          void
 **
 *******************************************************************************/
-static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void avdt_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+                                                 void *p_ref_data, UINT8 res)
 {
     tAVDT_CCB       *p_ccb = NULL;
     tL2CAP_CFG_INFO cfg;
@@ -92,7 +93,7 @@ static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UIN
 
     if (res == BTM_SUCCESS)
     {
-           /* Send response to the L2CAP layer. */
+        /* Send response to the L2CAP layer. */
         L2CA_ConnectRsp (bd_addr, p_tbl->id, p_tbl->lcid, L2CAP_CONN_OK, L2CAP_CONN_OK);
 
         /* store idx in LCID table, store LCID in routing table */
@@ -127,7 +128,8 @@ static void avdt_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UIN
 ** Returns          void
 **
 *******************************************************************************/
-static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void avdt_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+                                                void *p_ref_data, UINT8 res)
 {
     tAVDT_CCB       *p_ccb = NULL;
     tL2CAP_CFG_INFO cfg;
index 528c809..0c435ef 100644 (file)
@@ -234,9 +234,12 @@ extern void        bnep_send_conn_req (tBNEP_CONN *p_bcb);
 extern void        bnep_send_conn_responce (tBNEP_CONN *p_bcb, UINT16 resp_code);
 extern void        bnep_process_setup_conn_req (tBNEP_CONN *p_bcb, UINT8 *p_setup, UINT8 len);
 extern void        bnep_process_setup_conn_responce (tBNEP_CONN *p_bcb, UINT8 *p_setup);
-extern UINT8       *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len, BOOLEAN is_ext);
-extern void        bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result);
-extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol, BOOLEAN fw_ext_present, UINT8 *p_data);
+extern UINT8       *bnep_process_control_packet (tBNEP_CONN *p_bcb, UINT8 *p, UINT16 *len,
+                                                        BOOLEAN is_ext);
+extern void        bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+                                                    void *p_ref_data, UINT8 result);
+extern tBNEP_RESULT bnep_is_packet_allowed (tBNEP_CONN *p_bcb, BD_ADDR p_dest_addr, UINT16 protocol,
+                                                    BOOLEAN fw_ext_present, UINT8 *p_data);
 extern UINT32      bnep_get_uuid32 (tBT_UUID *src_uuid);
 extern void        bnep_dump_status (void);
 
index 0a8fd6d..faf808b 100644 (file)
@@ -1209,12 +1209,14 @@ void bnepu_send_peer_multicast_filter_rsp (tBNEP_CONN *p_bcb, UINT16 response_co
 ** Returns          void
 **
 *******************************************************************************/
-void bnep_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 result)
+void bnep_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+                                    void *p_ref_data, UINT8 result)
 {
     tBNEP_CONN      *p_bcb = (tBNEP_CONN *)p_ref_data;
     UINT16          resp_code = BNEP_SETUP_CONN_OK;
     BOOLEAN         is_role_change;
     UNUSED(bd_addr);
+    UNUSED(trasnport);
 
     BNEP_TRACE_EVENT1 ("BNEP security callback returned result %d", result);
     if (p_bcb->con_flags & BNEP_FLAGS_CONN_COMPLETED)
index 0a4ed1a..ee30887 100644 (file)
@@ -130,11 +130,14 @@ void btm_acl_init (void)
 **
 ** Description      This function returns the FIRST acl_db entry for the passed BDA.
 **
+** Parameters      bda : BD address of the remote device
+**                 transport : Physical transport used for ACL connection (BR/EDR or LE)
+**
 ** Returns          Returns pointer to the ACL DB for the requested BDA if found.
 **                  NULL if not found.
 **
 *******************************************************************************/
-tACL_CONN *btm_bda_to_acl (BD_ADDR bda)
+tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport)
 {
     tACL_CONN   *p = &btm_cb.acl_db[0];
     UINT16       xx;
@@ -142,7 +145,11 @@ tACL_CONN *btm_bda_to_acl (BD_ADDR bda)
     {
         for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
         {
-            if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN)))
+            if ((p->in_use) && (!memcmp (p->remote_addr, bda, BD_ADDR_LEN))
+#if BLE_INCLUDED == TRUE
+                && p->transport == transport
+#endif
+                )
             {
                 BTM_TRACE_DEBUG0 ("btm_bda_to_acl found");
                 return(p);
@@ -180,7 +187,7 @@ UINT8 btm_handle_to_acl_index (UINT16 hci_handle)
     return(xx);
 }
 
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
 /*******************************************************************************
 **
 ** Function         btm_ble_get_acl_remote_addr
@@ -243,24 +250,24 @@ BOOLEAN btm_ble_get_acl_remote_addr(tBTM_SEC_DEV_REC *p_dev_rec, BD_ADDR conn_ad
 **
 *******************************************************************************/
 void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
-                      UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link)
+                      UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport)
 {
     tBTM_SEC_DEV_REC *p_dev_rec = NULL;
     UINT8             yy;
     tACL_CONN        *p;
     UINT8             xx;
 
-    BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d  is_le_link=%d",
-                      hci_handle,link_role, is_le_link);
+    BTM_TRACE_DEBUG3 ("btm_acl_created hci_handle=%d link_role=%d  transport=%d",
+                      hci_handle,link_role, transport);
     /* Ensure we don't have duplicates */
-    p = btm_bda_to_acl(bda);
+    p = btm_bda_to_acl(bda, transport);
     if (p != (tACL_CONN *)NULL)
     {
         p->hci_handle = hci_handle;
         p->link_role  = link_role;
         btm_save_remote_device_role(bda, link_role);
 #if BLE_INCLUDED == TRUE
-        p->is_le_link = is_le_link;
+        p->transport = transport;
 #endif
         BTM_TRACE_DEBUG6 ("Duplicate btm_acl_created: RemBdAddr: %02x%02x%02x%02x%02x%02x",
                           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
@@ -280,14 +287,23 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
             p->link_up_issued    = FALSE;
 
 #if BLE_INCLUDED == TRUE
-            p->is_le_link        = is_le_link;
-
-            if (is_le_link)
+            p->transport = transport;
+            if (transport == BT_TRANSPORT_LE)
             {
-                p->conn_addr_type = BLE_ADDR_PUBLIC;
-                BTM_GetLocalDeviceAddr(p->conn_addr);
+#if ( BLE_PRIVACY_SPT == TRUE )
+                /*allow central device to use random address for now by skipping the role check */
+                if (btm_cb.ble_ctr_cb.privacy /* && p->link_role == HCI_ROLE_SLAVE */)
+                {
+                    p->conn_addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
+                    memcpy(p->conn_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, BD_ADDR_LEN);
+                }
+                else
+#endif
+                {
+                    p->conn_addr_type = BLE_ADDR_PUBLIC;
+                    BTM_GetLocalDeviceAddr(p->conn_addr);
+                }
             }
-
 #endif
             p->restore_pkt_types = 0;   /* Only exists while SCO is active */
             p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
@@ -307,7 +323,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
                 memcpy (p->remote_name, bdn, BTM_MAX_REM_BD_NAME_LEN);
 
             /* if BR/EDR do something more */
-            if (!is_le_link)
+            if (transport == BT_TRANSPORT_BR_EDR)
             {
                 btsnd_hcic_read_rmt_clk_offset (p->hci_handle);
                 btsnd_hcic_rmt_ver_req (p->hci_handle);
@@ -321,7 +337,7 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
             }
 #endif
 
-            if (p_dev_rec && !is_le_link)
+            if (p_dev_rec && !(transport == BT_TRANSPORT_LE))
             {
                 /* If remote features already known, copy them and continue connection setup */
                 if ((p_dev_rec->num_read_pages) &&
@@ -349,9 +365,9 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
 
 #if (BLE_INCLUDED == TRUE)
             /* If here, features are not known yet */
-            if (p_dev_rec && is_le_link)
+            if (p_dev_rec && transport == BT_TRANSPORT_LE)
             {
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
                 btm_ble_get_acl_remote_addr (p_dev_rec, p->active_remote_addr,
                     &p->active_remote_addr_type);
 #endif
@@ -413,7 +429,7 @@ void btm_acl_report_role_change (UINT8 hci_status, BD_ADDR bda)
 ** Returns          void
 **
 *******************************************************************************/
-void btm_acl_removed (BD_ADDR bda)
+void btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport)
 {
     tACL_CONN   *p;
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
@@ -424,7 +440,7 @@ void btm_acl_removed (BD_ADDR bda)
 #endif
 
     BTM_TRACE_DEBUG0 ("btm_acl_removed");
-    p = btm_bda_to_acl(bda);
+    p = btm_bda_to_acl(bda, transport);
     if (p != (tACL_CONN *)NULL)
     {
         p->in_use = FALSE;
@@ -443,22 +459,29 @@ void btm_acl_removed (BD_ADDR bda)
             {
                 evt_data.event = BTM_BL_DISCN_EVT;
                 evt_data.discn.p_bda = bda;
-
+#if BLE_INCLUDED == TRUE
+                evt_data.discn.handle = p->hci_handle;
+                evt_data.discn.transport = p->transport;
+#endif
                 (*btm_cb.p_bl_changed_cb)(&evt_data);
             }
 
             btm_acl_update_busy_level (BTM_BLI_ACL_DOWN_EVT);
 #else
             if (btm_cb.p_acl_changed_cb)
+#if BLE_INCLUDED == TRUE
+                (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE, p->hci_handle, p->transport);
+#else
                 (*btm_cb.p_acl_changed_cb) (bda, NULL, NULL, NULL, FALSE);
 #endif
+#endif
         }
 
 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
 
-        BTM_TRACE_DEBUG4 ("acl hci_handle=%d is_le_link=%d connectable_mode=0x%0x link_role=%d",
+        BTM_TRACE_DEBUG4 ("acl hci_handle=%d transport=%d connectable_mode=0x%0x link_role=%d",
                           p->hci_handle,
-                          p->is_le_link,
+                          p->transport,
                           btm_cb.ble_ctr_cb.inq_var.connectable_mode,
                           p->link_role);
 
@@ -466,14 +489,14 @@ void btm_acl_removed (BD_ADDR bda)
         if ( p_dev_rec)
         {
             BTM_TRACE_DEBUG1("before update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags);
-            if (p->is_le_link)
+            if (p->transport == BT_TRANSPORT_LE)
             {
                 BTM_TRACE_DEBUG0("LE link down");
-                p_dev_rec->sec_flags &= ~(BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
-                if ( (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) == 0)
+                p_dev_rec->sec_flags &= ~(BTM_SEC_LE_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+                if ( (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN) == 0)
                 {
                     BTM_TRACE_DEBUG0("Not Bonded");
-                    p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHENTICATED | BTM_SEC_LINK_KEY_AUTHED);
+                    p_dev_rec->sec_flags &= ~(BTM_SEC_LE_LINK_KEY_AUTHED | BTM_SEC_LE_AUTHENTICATED);
                 }
                 else
                 {
@@ -541,6 +564,7 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
     tBTM_BL_UPDATE_DATA  evt;
     UINT8 busy_level;
     BTM_TRACE_DEBUG0 ("btm_acl_update_busy_level");
+    BOOLEAN old_inquiry_state = btm_cb.is_inquiry;
     switch (event)
     {
         case BTM_BLI_ACL_UP_EVT:
@@ -590,7 +614,7 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
     else
         busy_level = (UINT8)btm_cb.num_acl;
 
-    if (busy_level != btm_cb.busy_level)
+    if ((busy_level != btm_cb.busy_level) ||(old_inquiry_state != btm_cb.is_inquiry))
     {
         evt.event         = BTM_BL_UPDATE_EVT;
         evt.busy_level    = busy_level;
@@ -619,7 +643,7 @@ tBTM_STATUS BTM_GetRole (BD_ADDR remote_bd_addr, UINT8 *p_role)
 {
     tACL_CONN   *p;
     BTM_TRACE_DEBUG0 ("BTM_GetRole");
-    if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+    if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         *p_role = BTM_ROLE_UNDEFINED;
         return(BTM_UNKNOWN_ADDR);
@@ -682,7 +706,7 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, UINT8 new_role, tBTM_CMPL_CB
         return(BTM_BUSY);
     }
 
-    if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+    if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
         return(BTM_UNKNOWN_ADDR);
 
     /* Finished if already in desired role */
@@ -807,7 +831,7 @@ tBTM_STATUS BTM_ChangeLinkKey (BD_ADDR remote_bd_addr, tBTM_CMPL_CB *p_cb)
     tBTM_PM_PWR_MD settings;
 #endif
     BTM_TRACE_DEBUG0 ("BTM_ChangeLinkKey");
-    if ((p = btm_bda_to_acl(remote_bd_addr)) == NULL)
+    if ((p = btm_bda_to_acl(remote_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
         return(BTM_UNKNOWN_ADDR);
 
     /* Ignore change link key request if the previsous request has not completed */
@@ -1119,9 +1143,8 @@ tBTM_STATUS BTM_SetLinkPolicy (BD_ADDR remote_bda, UINT16 *settings)
         }
     }
 
-    if ((p = btm_bda_to_acl(remote_bda)) != NULL)
-        return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ?
-                                                BTM_CMD_STARTED : BTM_NO_RESOURCES);
+    if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
+        return(btsnd_hcic_write_policy_set (p->hci_handle, *settings) ? BTM_CMD_STARTED : BTM_NO_RESOURCES);
 
     /* If here, no BD Addr found */
     return(BTM_UNKNOWN_ADDR);
@@ -1195,7 +1218,7 @@ tBTM_STATUS BTM_ReadLinkPolicy (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
     if (btm_cb.devcb.p_rlinkp_cmpl_cb)
         return(BTM_BUSY);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         btu_start_timer (&btm_cb.devcb.rlinkp_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
@@ -1634,47 +1657,62 @@ void btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle)
 static void btm_establish_continue (tACL_CONN *p_acl_cb)
 {
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
-    tBTM_BL_EVENT_DATA  evt_data;
+        tBTM_BL_EVENT_DATA  evt_data;
 #endif
-    BTM_TRACE_DEBUG0 ("btm_establish_continue");
+        BTM_TRACE_DEBUG0 ("btm_establish_continue");
 #if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE)
 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
-    if (!p_acl_cb->is_le_link)
+        if (p_acl_cb->transport == BT_TRANSPORT_BR_EDR)
 #endif
-    {
-        /* For now there are a some devices that do not like sending */
-        /* commands events and data at the same time. */
-        /* Set the packet types to the default allowed by the device */
-        btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
+        {
+            /* For now there are a some devices that do not like sending */
+            /* commands events and data at the same time. */
+            /* Set the packet types to the default allowed by the device */
+            btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
 
-        if (btm_cb.btm_def_link_policy)
-            BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
-    }
+            if (btm_cb.btm_def_link_policy)
+                BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
+        }
 #endif
-    p_acl_cb->link_up_issued = TRUE;
+        p_acl_cb->link_up_issued = TRUE;
 
-    /* If anyone cares, tell him database changed */
+        /* If anyone cares, tell him database changed */
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
-    if (btm_cb.p_bl_changed_cb)
-    {
-        evt_data.event = BTM_BL_CONN_EVT;
-        evt_data.conn.p_bda = p_acl_cb->remote_addr;
-        evt_data.conn.p_bdn = p_acl_cb->remote_name;
-        evt_data.conn.p_dc  = p_acl_cb->remote_dc;
-        evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0];
-
+        if (btm_cb.p_bl_changed_cb)
+        {
+            evt_data.event = BTM_BL_CONN_EVT;
+            evt_data.conn.p_bda = p_acl_cb->remote_addr;
+            evt_data.conn.p_bdn = p_acl_cb->remote_name;
+            evt_data.conn.p_dc  = p_acl_cb->remote_dc;
+            evt_data.conn.p_features = p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0];
+#if BLE_INCLUDED == TRUE
+            evt_data.conn.handle = p_acl_cb->hci_handle;
+            evt_data.conn.transport = p_acl_cb->transport;
+#endif
 
-        (*btm_cb.p_bl_changed_cb)(&evt_data);
-    }
-    btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT);
+            (*btm_cb.p_bl_changed_cb)(&evt_data);
+        }
+        btm_acl_update_busy_level (BTM_BLI_ACL_UP_EVT);
+#else
+        if (btm_cb.p_acl_changed_cb)
+#if BLE_INCLUDED == TRUE
+            (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
+                                        p_acl_cb->remote_dc,
+                                        p_acl_cb->remote_name,
+                                        p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
+                                        TRUE,
+                                        p_acl_cb->hci_handle,
+                                        p_acl_cb->transport);
 #else
-    if (btm_cb.p_acl_changed_cb)
-        (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
-                                    p_acl_cb->remote_dc,
-                                    p_acl_cb->remote_name,
-                                    p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
-                                    TRUE);
+            (*btm_cb.p_acl_changed_cb) (p_acl_cb->remote_addr,
+                                        p_acl_cb->remote_dc,
+                                        p_acl_cb->remote_name,
+                                        p_acl_cb->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0],
+                                        TRUE);
+#endif
+
 #endif
+
 }
 
 
@@ -1705,7 +1743,7 @@ void BTM_SetDefaultLinkSuperTout (UINT16 timeout)
 *******************************************************************************/
 tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout)
 {
-    tACL_CONN   *p = btm_bda_to_acl(remote_bda);
+    tACL_CONN   *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
 
     BTM_TRACE_DEBUG0 ("BTM_GetLinkSuperTout");
     if (p != (tACL_CONN *)NULL)
@@ -1729,7 +1767,7 @@ tBTM_STATUS BTM_GetLinkSuperTout (BD_ADDR remote_bda, UINT16 *p_timeout)
 *******************************************************************************/
 tBTM_STATUS BTM_SetLinkSuperTout (BD_ADDR remote_bda, UINT16 timeout)
 {
-    tACL_CONN   *p = btm_bda_to_acl(remote_bda);
+    tACL_CONN   *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
 
     BTM_TRACE_DEBUG0 ("BTM_SetLinkSuperTout");
     if (p != (tACL_CONN *)NULL)
@@ -1816,7 +1854,7 @@ tBTM_STATUS BTM_SetHoldMode (BD_ADDR remote_bda, UINT16 min_interval, UINT16 max
     if (!HCI_HOLD_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
         return(BTM_MODE_UNSUPPORTED);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         /* If the connection is in park or sniff mode, forget about holding it */
@@ -1854,7 +1892,7 @@ tBTM_STATUS BTM_SetSniffMode (BD_ADDR remote_bda, UINT16 min_period, UINT16 max_
     if (!HCI_SNIFF_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
         return(BTM_MODE_UNSUPPORTED);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         /* If the connection is in park mode, forget about sniffing it */
@@ -1888,7 +1926,7 @@ tBTM_STATUS BTM_SetSniffMode (BD_ADDR remote_bda, UINT16 min_period, UINT16 max_
 *******************************************************************************/
 tBTM_STATUS BTM_CancelSniffMode (BD_ADDR remote_bda)
 {
-    tACL_CONN   *p = btm_bda_to_acl(remote_bda);
+    tACL_CONN   *p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_CancelSniffMode ");
     if (p == (tACL_CONN *)NULL)
         return(BTM_UNKNOWN_ADDR);
@@ -1924,7 +1962,7 @@ tBTM_STATUS BTM_SetParkMode (BD_ADDR remote_bda, UINT16 beacon_min_period, UINT1
     if (!HCI_PARK_MODE_SUPPORTED(BTM_ReadLocalFeatures()))
         return(BTM_MODE_UNSUPPORTED);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         /* If the connection is in sniff mode, forget about parking it */
@@ -1962,7 +2000,7 @@ tBTM_STATUS BTM_CancelParkMode (BD_ADDR remote_bda)
     tACL_CONN   *p;
 
     BTM_TRACE_DEBUG0 ("BTM_CancelParkMode");
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         /* If the connection is not in park mode, cannot cancel */
@@ -1996,7 +2034,7 @@ tBTM_STATUS BTM_SetPacketTypes (BD_ADDR remote_bda, UINT16 pkt_types)
     tACL_CONN   *p;
     BTM_TRACE_DEBUG0 ("BTM_SetPacketTypes");
 
-    if ((p = btm_bda_to_acl(remote_bda)) != NULL)
+    if ((p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
         return(btm_set_packet_types (p, pkt_types));
 
     /* If here, no BD Addr found */
@@ -2019,7 +2057,7 @@ UINT16 BTM_ReadPacketTypes (BD_ADDR remote_bda)
     tACL_CONN   *p;
 
     BTM_TRACE_DEBUG0 ("BTM_ReadPacketTypes");
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         return(p->pkt_types_mask);
@@ -2059,7 +2097,7 @@ tBTM_STATUS BTM_ReadAclMode (BD_ADDR remote_bda, UINT8 *p_mode)
                     remote_bda[0], remote_bda[1], remote_bda[2],
                     remote_bda[3], remote_bda[4], remote_bda[5]);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         *p_mode = p->mode;
@@ -2091,7 +2129,7 @@ UINT16 BTM_ReadClockOffset (BD_ADDR remote_bda)
                     remote_bda[0], remote_bda[1], remote_bda[2],
                     remote_bda[3], remote_bda[4], remote_bda[5]);
 
-    if ( (p = btm_bda_to_acl(remote_bda)) != NULL)
+    if ( (p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR)) != NULL)
         return(p->clock_offset);
 
     /* If here, no BD Addr found */
@@ -2108,7 +2146,7 @@ UINT16 BTM_ReadClockOffset (BD_ADDR remote_bda)
 ** Returns          TRUE if connection is up, else FALSE.
 **
 *******************************************************************************/
-BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda)
+BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport)
 {
     tACL_CONN   *p;
 
@@ -2116,7 +2154,7 @@ BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda)
                     remote_bda[0], remote_bda[1], remote_bda[2],
                     remote_bda[3], remote_bda[4], remote_bda[5]);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, transport);
     if (p != (tACL_CONN *)NULL)
     {
         return(TRUE);
@@ -2156,6 +2194,34 @@ UINT16 BTM_GetNumAclLinks (void)
 
 /*******************************************************************************
 **
+** Function         BTM_GetNumLeLinks
+**
+** Description      This function is called to count the number of
+**                   LE ACL links that are active.
+**
+** Returns          UINT16  Number of active LE links
+**
+*******************************************************************************/
+UINT16 BTM_GetNumLeLinks (void)
+{
+    UINT16 yy = 0;
+
+#if BLE_INCLUDED == TRUE
+    tACL_CONN   *p = &btm_cb.acl_db[0];
+    UINT16      xx;
+    BTM_TRACE_DEBUG0 ("BTM_GetNumLeLinks");
+    for (xx = yy = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
+    {
+        if  ((p->in_use) &&(p->transport == BT_TRANSPORT_LE))
+            yy++;
+    }
+#endif
+
+    return(yy);
+}
+
+/*******************************************************************************
+**
 ** Function         btm_get_acl_disc_reason_code
 **
 ** Description      This function is called to get the disconnection reason code
@@ -2182,11 +2248,11 @@ UINT16 btm_get_acl_disc_reason_code (void)
 ** Returns          the handle of the connection, or 0xFFFF if none.
 **
 *******************************************************************************/
-UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda)
+UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport)
 {
     tACL_CONN   *p;
     BTM_TRACE_DEBUG0 ("BTM_GetHCIConnHandle");
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, transport);
     if (p != (tACL_CONN *)NULL)
     {
         return(p->hci_handle);
@@ -2276,7 +2342,7 @@ void btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role)
 {
     UINT8                   *p_bda = (bd_addr) ? bd_addr :
                                         btm_cb.devcb.switch_role_ref_data.remote_bd_addr;
-    tACL_CONN               *p = btm_bda_to_acl(p_bda);
+    tACL_CONN               *p = btm_bda_to_acl(p_bda, BT_TRANSPORT_BR_EDR);
     tBTM_ROLE_SWITCH_CMPL   *p_data = &btm_cb.devcb.switch_role_ref_data;
     tBTM_SEC_DEV_REC        *p_dev_rec;
 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
@@ -2563,7 +2629,7 @@ tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types)
 *******************************************************************************/
 UINT16 btm_get_max_packet_size (BD_ADDR addr)
 {
-    tACL_CONN   *p = btm_bda_to_acl(addr);
+    tACL_CONN   *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     UINT16      pkt_types = 0;
     UINT16      pkt_size = 0;
     BTM_TRACE_DEBUG0 ("btm_get_max_packet_size");
@@ -2621,7 +2687,7 @@ UINT16 btm_get_max_packet_size (BD_ADDR addr)
 tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version,
                                    UINT16 *manufacturer, UINT16 *lmp_sub_version)
 {
-    tACL_CONN        *p = btm_bda_to_acl(addr);
+    tACL_CONN        *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteVersion");
     if (p == NULL)
         return(BTM_UNKNOWN_ADDR);
@@ -2647,7 +2713,7 @@ tBTM_STATUS BTM_ReadRemoteVersion (BD_ADDR addr, UINT8 *lmp_version,
 *******************************************************************************/
 UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr)
 {
-    tACL_CONN        *p = btm_bda_to_acl(addr);
+    tACL_CONN        *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteFeatures");
     if (p == NULL)
     {
@@ -2667,7 +2733,7 @@ UINT8 *BTM_ReadRemoteFeatures (BD_ADDR addr)
 *******************************************************************************/
 UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number)
 {
-    tACL_CONN        *p = btm_bda_to_acl(addr);
+    tACL_CONN        *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_ReadRemoteExtendedFeatures");
     if (p == NULL)
     {
@@ -2692,7 +2758,7 @@ UINT8 *BTM_ReadRemoteExtendedFeatures (BD_ADDR addr, UINT8 page_number)
 *******************************************************************************/
 UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr)
 {
-    tACL_CONN        *p = btm_bda_to_acl(addr);
+    tACL_CONN        *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_ReadNumberRemoteFeaturesPages");
     if (p == NULL)
     {
@@ -2711,7 +2777,7 @@ UINT8 BTM_ReadNumberRemoteFeaturesPages (BD_ADDR addr)
 *******************************************************************************/
 UINT8 *BTM_ReadAllRemoteFeatures (BD_ADDR addr)
 {
-    tACL_CONN        *p = btm_bda_to_acl(addr);
+    tACL_CONN        *p = btm_bda_to_acl(addr, BT_TRANSPORT_BR_EDR);
     BTM_TRACE_DEBUG0 ("BTM_ReadAllRemoteFeatures");
     if (p == NULL)
     {
@@ -2794,7 +2860,7 @@ tBTM_STATUS BTM_SetQoS (BD_ADDR bd, FLOW_SPEC *p_flow, tBTM_CMPL_CB *p_cb)
     if (btm_cb.devcb.p_qossu_cmpl_cb)
         return(BTM_BUSY);
 
-    if ( (p = btm_bda_to_acl(bd)) != NULL)
+    if ( (p = btm_bda_to_acl(bd, BT_TRANSPORT_BR_EDR)) != NULL)
     {
         btu_start_timer (&btm_cb.devcb.qossu_timer, BTU_TTYPE_BTM_ACL, BTM_DEV_REPLY_TIMEOUT);
         btm_cb.devcb.p_qossu_cmpl_cb = p_cb;
@@ -2878,7 +2944,7 @@ tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
     if (btm_cb.devcb.p_rssi_cmpl_cb)
         return(BTM_BUSY);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         btu_start_timer (&btm_cb.devcb.rssi_timer, BTU_TTYPE_BTM_ACL,
@@ -2923,7 +2989,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
     if (btm_cb.devcb.p_lnk_qual_cmpl_cb)
         return(BTM_BUSY);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
     if (p != (tACL_CONN *)NULL)
     {
         btu_start_timer (&btm_cb.devcb.lnk_quality_timer, BTU_TTYPE_BTM_ACL,
@@ -2956,7 +3022,7 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
 ** Returns          BTM_CMD_STARTED if successfully initiated or error code
 **
 *******************************************************************************/
-tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb)
 {
     tACL_CONN   *p;
     BOOLEAN     ret;
@@ -2971,7 +3037,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
     if (btm_cb.devcb.p_tx_power_cmpl_cb)
         return(BTM_BUSY);
 
-    p = btm_bda_to_acl(remote_bda);
+    p = btm_bda_to_acl(remote_bda, transport);
     if (p != (tACL_CONN *)NULL)
     {
         btu_start_timer (&btm_cb.devcb.tx_power_timer, BTU_TTYPE_BTM_ACL,
@@ -2980,7 +3046,7 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
         btm_cb.devcb.p_tx_power_cmpl_cb = p_cb;
 
 #if BLE_INCLUDED == TRUE
-        if (p->is_le_link)
+        if (p->transport == BT_TRANSPORT_LE)
         {
             memcpy(btm_cb.devcb.read_tx_pwr_addr, remote_bda, BD_ADDR_LEN);
             ret = btsnd_hcic_ble_read_adv_chnl_tx_power();
@@ -3183,9 +3249,9 @@ void btm_read_link_quality_complete (UINT8 *p)
 ** Returns          BTM_SUCCESS if successfully initiated, otherwise BTM_NO_RESOURCES.
 **
 *******************************************************************************/
-tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr)
+tBTM_STATUS btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport)
 {
-    UINT16  hci_handle = BTM_GetHCIConnHandle(bd_addr);
+    UINT16  hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
     tBTM_STATUS status = BTM_SUCCESS;
 
     BTM_TRACE_DEBUG0 ("btm_remove_acl");
@@ -3459,6 +3525,11 @@ BOOLEAN  btm_acl_notif_conn_collision (BD_ADDR bda)
 
         evt_data.event = BTM_BL_COLLISION_EVT;
         evt_data.conn.p_bda = bda;
+
+#if BLE_INCLUDED == TRUE
+        evt_data.conn.transport = BT_TRANSPORT_BR_EDR;
+        evt_data.conn.handle = BTM_INVALID_HCI_HANDLE;
+#endif
         (*btm_cb.p_bl_changed_cb)(&evt_data);
         return TRUE;
     }
index 5b61b76..9bd771a 100644 (file)
@@ -35,9 +35,6 @@
 #include "btm_ble_api.h"
 #include "smp_api.h"
 #include "l2c_int.h"
-#if (defined BLE_BRCM_INCLUDED && BLE_BRCM_INCLUDED == TRUE)
-#include "brcm_ble.h"
-#endif
 #include "gap_api.h"
 #include "bt_utils.h"
 
@@ -94,7 +91,8 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d
                 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
                 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
                 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
-                p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+                p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
+                p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
 
                 /* update conn params, use default value for background connection params */
                 p_dev_rec->conn_params.min_conn_int     =
@@ -102,7 +100,7 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d
                 p_dev_rec->conn_params.supervision_tout =
                 p_dev_rec->conn_params.slave_latency    = BTM_BLE_CONN_PARAM_UNDEF;
 
-                BTM_TRACE_DEBUG1 ("hci_handl=0x%x ",  p_dev_rec->hci_handle );
+                BTM_TRACE_DEBUG1 ("hci_handl=0x%x ",  p_dev_rec->ble_hci_handle );
                 break;
             }
         }
@@ -290,7 +288,7 @@ void BTM_GetDeviceDHK (BT_OCTET16 dhk)
 *******************************************************************************/
 void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_ADDR_TYPE *p_addr_type)
 {
-    tACL_CONN       *p_acl = btm_bda_to_acl(remote_bda);
+    tACL_CONN       *p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE);
 
     if (p_acl == NULL)
     {
@@ -316,6 +314,7 @@ void BTM_ReadConnectionAddr (BD_ADDR remote_bda, BD_ADDR local_conn_addr, tBLE_A
 *******************************************************************************/
 BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
 {
+#if (BLE_INCLUDED == TRUE)
     UINT8                xx;
     tACL_CONN            *p;
 
@@ -327,7 +326,10 @@ BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
 
     p = &btm_cb.acl_db[xx];
 
-    return(p->is_le_link);
+    return (p->transport == BT_TRANSPORT_LE);
+#else
+    return FALSE;
+#endif
 }
 
 /*******************************************************************************
@@ -335,27 +337,33 @@ BOOLEAN BTM_IsBleConnection (UINT16 conn_handle)
 ** Function         BTM_ReadRemoteConnectionAddr
 **
 ** Description      This function is read the remote device address currently used
-**                  .
 **
-** Returns          void
+** Parameters     pseudo_addr: pseudo random address available
+**                conn_addr:connection address used
+**                p_addr_type : BD Address type, Public or Random of the address used
+**
+** Returns          BOOLEAN , TRUE if connection to remote device exists, else FALSE
 **
 *******************************************************************************/
-BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, tBLE_ADDR_TYPE *p_addr_type)
+BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr,
+                                               tBLE_ADDR_TYPE *p_addr_type)
 {
-    BOOLEAN         st = TRUE;
-    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
-#if BTM_BLE_PRIVACY_SPT == TRUE
-    tACL_CONN       *p = btm_bda_to_acl (pseudo_addr);
+ BOOLEAN         st = TRUE;
+#if (BLE_PRIVACY_SPT == TRUE)
+    tACL_CONN       *p = btm_bda_to_acl (pseudo_addr, BT_TRANSPORT_LE);
 
     if (p == NULL)
     {
-        BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find matching address");
+        BTM_TRACE_ERROR0("BTM_ReadRemoteConnectionAddr can not find connection"
+                        " with matching address");
         return FALSE;
     }
 
     memcpy(conn_addr, p->active_remote_addr, BD_ADDR_LEN);
     *p_addr_type = p->active_remote_addr_type;
 #else
+    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_addr);
+
     memcpy(conn_addr, pseudo_addr, BD_ADDR_LEN);
     if (p_dev_rec != NULL)
     {
@@ -363,6 +371,7 @@ BOOLEAN BTM_ReadRemoteConnectionAddr(BD_ADDR pseudo_addr, BD_ADDR conn_addr, tBL
     }
 #endif
     return st;
+
 }
 /*******************************************************************************
 **
@@ -412,7 +421,7 @@ void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey)
         return;
     }
 
-    p_dev_rec->sec_flags   |= BTM_SEC_LINK_KEY_AUTHED;
+    p_dev_rec->sec_flags   |= BTM_SEC_LE_LINK_KEY_AUTHED;
     BTM_TRACE_DEBUG0 ("BTM_BlePasskeyReply");
     SMP_PasskeyReply(bd_addr, res_smp, passkey);
 #endif
@@ -444,7 +453,7 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data)
         return;
     }
 
-    p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+    p_dev_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
     SMP_OobDataReply(bd_addr, res_smp, len, p_data);
 #endif
 }
@@ -694,24 +703,6 @@ void btm_ble_test_command_complete(UINT8 *p)
 
 /*******************************************************************************
 **
-** Function         BTM_IsBleLink
-**
-** Description      This function is to check the link type is BLE or BR/EDR.
-**
-** Returns          TRUE if BLE link; FALSE if BR/EDR.
-**
-*******************************************************************************/
-BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr)
-{
-    tACL_CONN         *p;
-    BTM_TRACE_DEBUG0 ("BTM_IsBleLink");
-    if ((p = btm_bda_to_acl(bd_addr)) != NULL)
-        return p->is_le_link;
-    else
-        return FALSE;
-}
-/*******************************************************************************
-**
 ** Function         BTM_UseLeLink
 **
 ** Description      This function is to select the underneath physical link to use.
@@ -726,9 +717,13 @@ BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr)
     tBLE_ADDR_TYPE      addr_type;
     BOOLEAN             use_le = FALSE;
 
-    if ((p = btm_bda_to_acl(bd_addr)) != NULL)
+    if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR)) != NULL)
     {
-        use_le = (p->is_le_link);
+        return use_le;
+    }
+    else if ((p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_LE)) != NULL)
+    {
+        use_le = TRUE;
     }
     else
     {
@@ -902,11 +897,11 @@ void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY
                 p_rec->ble.keys.ediv = p_keys->penc_key.ediv;
                 p_rec->ble.keys.key_size = p_keys->penc_key.key_size;
                 p_rec->ble.key_type |= BTM_LE_KEY_PENC;
-                p_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
+                p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_KNOWN;
                 if (p_keys->penc_key.sec_level == SMP_SEC_AUTHENTICATED)
-                    p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+                    p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
                 else
-                    p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
+                    p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
                 BTM_TRACE_DEBUG3("BTM_LE_KEY_PENC key_type=0x%x sec_flags=0x%x sec_leve=0x%x",
                                  p_rec->ble.key_type,
                                  p_rec->sec_flags,
@@ -931,11 +926,11 @@ void btm_sec_save_le_key(BD_ADDR bd_addr, tBTM_LE_KEY_TYPE key_type, tBTM_LE_KEY
                 p_rec->ble.keys.srk_sec_level = p_keys->pcsrk_key.sec_level;
                 p_rec->ble.keys.counter  = p_keys->pcsrk_key.counter;
                 p_rec->ble.key_type |= BTM_LE_KEY_PCSRK;
-                p_rec->sec_flags |=  BTM_SEC_LINK_KEY_KNOWN;
+                p_rec->sec_flags |=  BTM_SEC_LE_LINK_KEY_KNOWN;
                 if ( p_keys->pcsrk_key.sec_level== SMP_SEC_AUTHENTICATED)
-                    p_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+                    p_rec->sec_flags |= BTM_SEC_LE_LINK_KEY_AUTHED;
                 else
-                    p_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
+                    p_rec->sec_flags &= ~BTM_SEC_LE_LINK_KEY_AUTHED;
 
                 BTM_TRACE_DEBUG4("BTM_LE_KEY_PCSRK key_type=0x%x sec_flags=0x%x sec_level=0x%x peer_counter=%d",
                                  p_rec->ble.key_type,
@@ -1081,9 +1076,9 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE
         BTM_TRACE_DEBUG1 ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags);
 
         /* currently encrpted  */
-        if (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
+        if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED)
         {
-            if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)
+            if (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED)
                 cur_sec_level = BTM_LE_SEC_AUTHENTICATED;
             else
                 cur_sec_level = BTM_LE_SEC_UNAUTHENTICATE;
@@ -1191,7 +1186,7 @@ tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 lin
             break;
 
         default:
-            cmd = BTM_SUCCESS;
+            cmd = BTM_WRONG_MODE;
             break;
     }
     return cmd;
@@ -1235,40 +1230,48 @@ void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv)
 ** Description      This function is called to start LE encryption.
 **
 **
-** Returns          void
+** Returns          BTM_SUCCESS if encryption was started successfully
 **
 *******************************************************************************/
-BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
+tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
 {
     tBTM_CB *p_cb = &btm_cb;
     tBTM_SEC_DEV_REC    *p_rec = btm_find_dev (bda);
     BT_OCTET8    dummy_rand = {0};
-    BOOLEAN     rt = FALSE;
+    tBTM_STATUS  rt = BTM_NO_RESOURCES;
 
     BTM_TRACE_DEBUG0 ("btm_ble_start_encrypt");
 
-    if (!p_rec ||
-        (p_rec && p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING))
-        return FALSE;
+    if (!p_rec )
+    {
+        BTM_TRACE_ERROR0("Link is not active, can not encrypt!");
+        return BTM_WRONG_MODE;
+    }
+
+    if (p_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
+    {
+        BTM_TRACE_WARNING0("Link Encryption is active, Busy!");
+        return BTM_BUSY;
+    }
 
-    p_cb->enc_handle = p_rec->hci_handle;
+    p_cb->enc_handle = p_rec->ble_hci_handle;
 
     if (use_stk)
     {
-        if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, dummy_rand, 0, stk))
-            rt = TRUE;
+        if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, dummy_rand, 0, stk))
+            rt = BTM_CMD_STARTED;
     }
     else if (p_rec->ble.key_type & BTM_LE_KEY_PENC)
     {
-        if (btsnd_hcic_ble_start_enc(p_rec->hci_handle, p_rec->ble.keys.rand,
+        if (btsnd_hcic_ble_start_enc(p_rec->ble_hci_handle, p_rec->ble.keys.rand,
                                       p_rec->ble.keys.ediv, p_rec->ble.keys.ltk))
-            rt = TRUE;
+            rt = BTM_CMD_STARTED;
     }
     else
     {
         BTM_TRACE_ERROR0("No key available to encrypt the link");
     }
-    if (rt)
+    if (rt == BTM_CMD_STARTED)
     {
         if (p_rec->sec_state == BTM_SEC_STATE_IDLE)
             p_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
@@ -1312,9 +1315,9 @@ void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
     if (p_dev_rec->p_callback && enc_cback)
     {
         if (encr_enable)
-            btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS);
+            btm_sec_dev_rec_cback_event(p_dev_rec, BTM_SUCCESS, TRUE);
         else if (p_dev_rec->role_master)
-            btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING);
+            btm_sec_dev_rec_cback_event(p_dev_rec, BTM_ERR_PROCESSING, TRUE);
 
     }
     /* to notify GATT to send data if any request is pending */
@@ -1399,7 +1402,7 @@ void btm_ble_ltk_request_reply(BD_ADDR bda,  BOOLEAN use_stk, BT_OCTET16 stk)
     }
 
     BTM_TRACE_DEBUG0 ("btm_ble_ltk_request_reply");
-    p_cb->enc_handle = p_rec->hci_handle;
+    p_cb->enc_handle = p_rec->ble_hci_handle;
     p_cb->key_size = p_rec->ble.keys.key_size;
 
     BTM_TRACE_ERROR1("key size = %d", p_rec->ble.keys.key_size);
@@ -1477,7 +1480,7 @@ UINT8 btm_ble_io_capabilities_req(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_LE_IO_REQ *p
     return callback_rc;
 }
 
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
 /*******************************************************************************
 **
 ** Function         btm_ble_resolve_random_addr_on_conn_cmpl
@@ -1556,7 +1559,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role,
 #if (BT_USE_TRACES == TRUE)
     if (p_dev_rec)
     {
-        BTM_TRACE_EVENT4 ("Security Manager: btm_sec_connected :  handle:%d  enc_mode:%d  bda:%x RName:%s",
+        BTM_TRACE_EVENT4 ("Security Manager: btm_ble_connected :  handle:%d  enc_mode:%d  bda:%x RName:%s",
                           handle,  enc_mode,
                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
                           p_dev_rec->sec_bd_name);
@@ -1565,7 +1568,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role,
     }
     else
     {
-        BTM_TRACE_EVENT3 ("Security Manager: btm_sec_connected:   handle:%d  enc_mode:%d  bda:%x ",
+        BTM_TRACE_EVENT3 ("Security Manager: btm_ble_connected:   handle:%d  enc_mode:%d  bda:%x ",
                           handle,  enc_mode,
                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
     }
@@ -1583,14 +1586,14 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role,
 
     /* update device information */
     p_dev_rec->device_type |= BT_DEVICE_TYPE_BLE;
-    p_dev_rec->hci_handle = handle;
+    p_dev_rec->ble_hci_handle = handle;
     p_dev_rec->ble.ble_addr_type = addr_type;
 
     p_dev_rec->role_master = FALSE;
     if (role == HCI_ROLE_MASTER)
         p_dev_rec->role_master = TRUE;
 
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
     if (!addr_matched)
         p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_PSEUDO;
 
@@ -1613,7 +1616,7 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role,
 ******************************************************************************/
 void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len)
 {
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
     UINT8       *p_data = p;
 #endif
     UINT8       role, status, bda_type;
@@ -1631,10 +1634,10 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len)
 
     if (status == 0)
     {
-#if (BTM_BLE_PRIVACY_SPT == TRUE )
+#if (BLE_PRIVACY_SPT == TRUE )
         /* possiblly receive connection complete with resolvable random on
            slave role while the device has been paired */
-        if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
+        if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda))
         {
             btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data);
         }
@@ -1679,9 +1682,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len)
             }
         }
     }
-
     btm_ble_set_conn_st(BLE_CONN_IDLE);
-
     btm_ble_update_mode_operation(role, bda, TRUE);
 }
 
@@ -1709,10 +1710,12 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
             case SMP_PASSKEY_REQ_EVT:
             case SMP_PASSKEY_NOTIF_EVT:
             case SMP_OOB_REQ_EVT:
-                p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
+                p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
+
             case SMP_SEC_REQUEST_EVT:
                 memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
                 p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+                btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
                 /* fall through */
             case SMP_COMPLT_EVT:
                 if (btm_cb.api.p_le_callback)
@@ -1731,7 +1734,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
                     BTM_TRACE_DEBUG3 ("after update result=%d sec_level=0x%x sec_flags=0x%x",
                                       res, p_data->cmplt.sec_level , p_dev_rec->sec_flags );
 
-                    btm_sec_dev_rec_cback_event(p_dev_rec, res);
+                    btm_sec_dev_rec_cback_event(p_dev_rec, res, TRUE);
 
                     if (p_data->cmplt.is_pair_cancel && btm_cb.api.p_bond_cancel_cmpl_callback )
                     {
@@ -1744,7 +1747,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
                         if (!btm_cb.devcb.no_disc_if_pair_fail && p_data->cmplt.reason != SMP_CONN_TOUT)
                         {
                             BTM_TRACE_DEBUG0 ("Pairing failed - Remove ACL");
-                            btm_remove_acl(bd_addr);
+                            btm_remove_acl(bd_addr, BT_TRANSPORT_LE);
                         }
                         else
                         {
@@ -1754,7 +1757,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
                     }
 #else
                     if (res != BTM_SUCCESS && p_data->cmplt.reason != SMP_CONN_TOUT)
-                        btm_remove_acl(bd_addr);
+                        btm_remove_acl(bd_addr, BT_TRANSPORT_LE);
 #endif
 
                     BTM_TRACE_DEBUG3 ("btm_cb pairing_state=%x pairing_flags=%x pin_code_len=%x",
index 96d35c4..7341cd2 100644 (file)
@@ -57,7 +57,7 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)
     btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
                                     (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
                                     (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
-                                     BLE_ADDR_PUBLIC,
+                                     btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
                                      scan_policy);
 }
 /*******************************************************************************
@@ -88,12 +88,13 @@ BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
             if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 &&
                 memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0)
             {
-                 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
+                started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type,
+                                                         p_dev_rec->ble.static_addr);
             }
         }
         else
         {
-            if (!BTM_BLE_IS_RESOLVE_BDA(bd_addr))
+            if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr))
             {
                     started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
             }
@@ -255,9 +256,9 @@ void btm_ble_add_2_white_list_complete(UINT8 status)
 }
 /*******************************************************************************
 **
-** Function         btm_ble_add_2_white_list_complete
+** Function         btm_ble_remove_from_white_list_complete
 **
-** Description      This function read the current white list size.
+** Description      This function remove the white list element complete.
 *******************************************************************************/
 void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len)
 {
@@ -284,7 +285,7 @@ UINT8 btm_ble_count_unconn_dev_in_whitelist(void)
     for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++)
     {
         if (p_cb->bg_dev_list[i].in_use &&
-            !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr))
+            !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr, BT_TRANSPORT_LE))
         {
             count ++;
         }
@@ -363,12 +364,12 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start)
     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
     BD_ADDR dummy_bda = {0};
     BOOLEAN exec = TRUE;
-    UINT8  own_addr_type = BLE_ADDR_PUBLIC;
     UINT16 scan_int, scan_win;
 
     if (start)
     {
-        if (p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
+        if ((p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
+            && btm_ble_topology_check(BTM_BLE_STATE_INIT))
         {
             btm_execute_wl_dev_operation();
 
@@ -380,7 +381,9 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start)
                                                 0x01,                   /* UINT8 white_list     */
                                                 BLE_ADDR_PUBLIC,        /* UINT8 addr_type_peer */
                                                 dummy_bda,              /* BD_ADDR bda_peer     */
-                                                own_addr_type,         /* UINT8 addr_type_own, not allow random address for central  */
+                                                p_cb->addr_mgnt_cb.own_addr_type,
+                                                   /* UINT8 addr_type_own,
+                                                   not allow random address for central  */
                                                 BTM_BLE_CONN_INT_MIN_DEF,   /* UINT16 conn_int_min  */
                                                 BTM_BLE_CONN_INT_MAX_DEF,   /* UINT16 conn_int_max  */
                                                 BTM_BLE_CONN_SLAVE_LATENCY_DEF,  /* UINT16 conn_latency  */
@@ -407,7 +410,7 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start)
         if (p_cb->conn_state == BLE_BG_CONN)
         {
             btsnd_hcic_ble_create_conn_cancel();
-            btm_ble_set_conn_st (BLE_CONN_CANCEL); 
+            btm_ble_set_conn_st (BLE_CONN_CANCEL);
 
         }
         else
@@ -446,26 +449,27 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK   *p_select_c
 
     if (start)
     {
-        if (btm_cb.btm_inq_vars.inq_active == BTM_INQUIRY_INACTIVE)
+        if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity))
         {
             if (p_select_cback != NULL)
                 btm_cb.ble_ctr_cb.p_select_cback = p_select_cback;
 
+            btm_execute_wl_dev_operation();
+
             btm_update_scanner_filter_policy(SP_ADV_WL);
             btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS;
 
             if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS,  /* use passive scan by default */
                                                 scan_int, /* scan interval */
                                                 scan_win,    /* scan window */
-                                                BLE_ADDR_PUBLIC,         /* own device, DUMO always use public */
+                                                p_cb->addr_mgnt_cb.own_addr_type,
                                                 SP_ADV_WL)              /* process advertising packets only from devices in the White List */
                 )
                 return FALSE;
 
-            if (p_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE
-                )
+            if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN))
             {
-                BTM_TRACE_ERROR0("peripheral device cannot initiate a selective connection");
+                BTM_TRACE_ERROR0("peripheral device cannot initiate passive scan for a selective connection");
                 return FALSE;
             }
             else if (p_cb->bg_dev_num > 0 && btm_ble_count_unconn_dev_in_whitelist() > 0 )
@@ -475,9 +479,7 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK   *p_select_c
                     return FALSE;
 
                 /* mark up inquiry status flag */
-                btm_cb.btm_inq_vars.inq_active |= BTM_LE_SELECT_CONN_ACTIVE;
-                p_cb->inq_var.proc_mode = BTM_BLE_SELECT_SCAN;
-                p_cb->conn_state                = BLE_BG_CONN;
+                p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE;
             }
         }
         else
@@ -488,13 +490,13 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK   *p_select_c
     }
     else /* disable selective connection mode */
     {
-        btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_SELECT_CONN_ACTIVE;
-        btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
+        p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE;
+        p_cb->p_select_cback = NULL;
+
 
-        btm_update_scanner_filter_policy(SP_ADV_ALL);
         /* stop scanning */
-            if (!btsnd_hcic_ble_set_scan_enable(FALSE, TRUE)) /* duplicate filtering enabled */
-                return FALSE;
+        if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity))
+            btm_ble_stop_scan(); /* duplicate filtering enabled */
         btm_update_scanner_filter_policy(SP_ADV_ALL);
     }
     return TRUE;
@@ -569,7 +571,7 @@ static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)
     }
     if (wl_state & BTM_BLE_WL_ADV)
     {
-        btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE);
+        btm_ble_stop_adv();
     }
 
 }
@@ -588,7 +590,7 @@ static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)
 
     if (wl_state & BTM_BLE_WL_ADV)
     {
-        btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE);
+       btm_ble_start_adv();
     }
 
 }
@@ -645,6 +647,10 @@ tBTM_BLE_CONN_ST btm_ble_get_conn_st(void)
 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)
 {
     btm_cb.ble_ctr_cb.conn_state = new_st;
+    if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
+        btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
+    else
+        btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
 }
 
 /*******************************************************************************
@@ -689,6 +695,7 @@ BOOLEAN btm_send_pending_direct_conn(void )
 
     return rt;
 }
+
 #endif
 
 
index 39f344c..f9bd1aa 100644 (file)
@@ -37,6 +37,8 @@
 #if (BLE_INCLUDED == TRUE)
 #include "gattdefs.h"
 
+#include "btm_ble_int.h"
+
 #define BTM_BLE_NAME_SHORT                  0x01
 #define BTM_BLE_NAME_CMPL                   0x02
 
@@ -55,26 +57,156 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
                                      BD_ADDR_PTR p_addr_ptr,
                                      tBLE_ADDR_TYPE *p_init_addr_type,
                                      tBLE_ADDR_TYPE *p_own_addr_type);
-static tBTM_STATUS btm_ble_start_adv(void);
-static tBTM_STATUS btm_ble_stop_adv(void);
-
+static void btm_ble_stop_observe(void);
 
+#define BTM_BLE_INQ_RESULT          0x01
+#define BTM_BLE_OBS_RESULT          0x02
+#define BTM_BLE_SEL_CONN_RESULT     0x04
 
-/*******************************************************************************
-**
-** Function         BTM_BleReset
-**
-** Description      This function is called to reset ULP controller.
-**
-** Parameters       None.
-**
-** Returns          void
-**
-*******************************************************************************/
-void BTM_BleReset(void)
+/* LE states combo bit to check */
+const UINT8 btm_le_state_combo_tbl[BTM_BLE_STATE_MAX][BTM_BLE_STATE_MAX][2] =
 {
-    btsnd_hcic_ble_reset();
-}
+    {/* single state support */
+        {HCI_SUPP_LE_STATES_CONN_ADV_MASK, HCI_SUPP_LE_STATES_CONN_ADV_OFF},  /* conn_adv */
+        {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* init */
+        {HCI_SUPP_LE_STATES_INIT_MASK, HCI_SUPP_LE_STATES_INIT_OFF}, /* master */
+        {HCI_SUPP_LE_STATES_SLAVE_MASK, HCI_SUPP_LE_STATES_SLAVE_OFF}, /* slave */
+        {0, 0},                   /* todo: lo du dir adv, not covered ? */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF}, /* hi duty dir adv */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_OFF},   /*  passive scan */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF},  /*   active scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_MASK, HCI_SUPP_LE_STATESSCAN_ADV_OFF}   /* scanable adv */
+    },
+    {    /* conn_adv =0 */
+        {0, 0},                                                                           /* conn_adv */
+        {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF},      /* init: 32 */
+        {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF},  /* master: 35 */
+        {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* slave: 38,*/
+        {0, 0},                                                                           /* lo du dir adv */
+        {0, 0},                                                                            /* hi duty dir adv */
+        {0, 0},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF},   /*  passive scan */
+        {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF},  /*   active scan */
+        {0, 0}   /* scanable adv */
+    },
+    {   /* init */
+        {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF},      /* conn_adv: 32 */
+        {0, 0},                                                                             /* init */
+        {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF},          /* master 28 */
+        {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* slave 41 */
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* lo du dir adv 34 */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF},     /* hi duty dir adv 33 */
+        {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF},  /*  non connectable adv */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF},   /* passive scan */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF},  /*  active scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF}   /* scanable adv */
+
+    },
+    {   /* master */
+        {HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF},  /* conn_adv: 35 */
+        {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF},          /* init 28 */
+        {HCI_SUPP_LE_STATES_INIT_MASTER_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_OFF},          /* master 28 */
+        {HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF},      /* slave: 32 */
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF},  /* lo duty cycle adv 37 */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF},   /* hi duty cycle adv 36 */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF},  /*  non connectable adv */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF},   /*  passive scan */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF},  /*   active scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF}   /*  scanable adv */
+
+    },
+    { /* slave */
+        {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF}, /* conn_adv: 38,*/
+        {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* init 41 */
+        {HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK, HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF}, /* master 41 */
+        {HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF},        /* slave: 38,*/
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF},  /* lo duty cycle adv 40 */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF},   /* hi duty cycle adv 39 */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF},   /* passive scan */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF},  /*  active scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF}   /* scanable adv */
+
+    },
+    { /* lo duty cycle adv */
+        {0, 0}, /* conn_adv: 38,*/
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF} ,/* init 34 */
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF}, /* master 37 */
+        {HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF}, /* slave: 40 */
+        {0, 0},  /* lo duty cycle adv 40 */
+        {0, 0},   /* hi duty cycle adv 39 */
+        {0, 0},  /*  non connectable adv */
+        {0, 0},   /* TODO: passive scan, not covered? */
+        {0, 0},  /* TODO:  active scan, not covered? */
+        {0, 0}   /*  scanable adv */
+    },
+    { /* hi duty cycle adv */
+        {0, 0}, /* conn_adv: 38,*/
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF}, /* init 33 */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF}, /* master 36 */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF},   /* slave: 39*/
+        {0, 0},  /* lo duty cycle adv 40 */
+        {0, 0},   /* hi duty cycle adv 39 */
+        {0, 0},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF},   /* passive scan */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF},  /* active scan */
+        {0, 0}   /* scanable adv */
+    },
+    { /* non connectable adv */
+        {0, 0}, /* conn_adv: */
+        {HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK, HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF}, /* init  */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF}, /* master  */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF},   /* slave: */
+        {0, 0},  /* lo duty cycle adv */
+        {0, 0},   /* hi duty cycle adv */
+        {0, 0},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF},   /* passive scan */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF},  /*  active scan */
+        {0, 0}   /* scanable adv */
+    },
+    { /* passive scan */
+        {HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF}, /* conn_adv: */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF}, /* init  */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF}, /* master  */
+        {HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF},   /* slave: */
+        {0, 0},  /* lo duty cycle adv */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF},   /* hi duty cycle adv */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF},  /*  non connectable adv */
+        {0, 0},   /* passive scan */
+        {0, 0},  /* active scan */
+         {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF}   /* scanable adv */
+    },
+    { /* active scan */
+        {HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF}, /* conn_adv: */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF}, /* init  */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF}, /* master  */
+        {HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK, HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF},   /* slave: */
+        {0, 0},  /* lo duty cycle adv */
+        {HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF},   /* hi duty cycle adv */
+        {HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF},  /*  non connectable adv */
+        {0, 0},   /* TODO: passive scan */
+        {0, 0},  /* TODO:  active scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF}   /*  scanable adv */
+    },
+    { /* scanable adv */
+        {0, 0}, /* conn_adv: */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF}, /* init  */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF}, /* master  */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF},   /* slave: */
+        {0, 0},  /* lo duty cycle adv */
+        {0, 0},   /* hi duty cycle adv */
+        {0, 0},  /* non connectable adv */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF},   /*  passive scan */
+        {HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK, HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF},  /*  active scan */
+        {0, 0}   /* scanable adv */
+    }
+
+};
+/* check LE combo state supported */
+#define BTM_LE_STATES_SUPPORTED(x, y, z)      ((x)[(z)] & (y))
+
+
 /*******************************************************************************
 **
 ** Function         BTM_BleUpdateAdvWhitelist
@@ -122,10 +254,13 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy)
         btm_ble_stop_adv ();
 
         if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE)
-            p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type);
+            p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type,
+                                                              &p_cb->adv_addr_type);
 
-        btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min,
-                                         p_cb->adv_interval_max,
+        btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
+                                         BTM_BLE_GAP_ADV_SLOW_INT),
+                                         (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max :
+                                         BTM_BLE_GAP_ADV_SLOW_INT),
                                          p_cb->evt_type,
                                          p_cb->adv_addr_type,
                                          init_addr_type,
@@ -155,7 +290,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration,
                            tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
 {
     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
-    tBTM_STATUS     status = BTM_NO_RESOURCES;
+    tBTM_STATUS     status = BTM_WRONG_MODE;
 
     BTM_TRACE_EVENT1 ("BTM_BleObserve : scan_type:%d",btm_cb.btm_inq_vars.scan_type);
 
@@ -165,63 +300,50 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration,
     if (start)
     {
         /* shared inquiry database, do not allow observe if any inquiry is active */
-        if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
+        if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
         {
-            /*check if an interleave scan is already in progress*/
-            if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL
-                && btm_cb.btm_inq_vars.p_inq_results_cb != NULL)
-            {
-                BTM_TRACE_EVENT0 ("BTM_BleObserve general inq in progress, redirecting the results");
-                btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
-                btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
-                return BTM_SUCCESS;
-            }
-            else
-                return BTM_BUSY;
+            BTM_TRACE_ERROR0("Observe Already Active");
+            return status;
         }
-        btm_cb.btm_inq_vars.scan_type = INQ_LE_OBSERVE;
-        btm_cb.btm_inq_vars.p_inq_ble_results_cb = p_results_cb;
-        btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = p_cmpl_cb;
-        p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
 
-        /* allow config scanning type */
-        if (btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
+        btm_cb.ble_ctr_cb.p_obs_results_cb = p_results_cb;
+        btm_cb.ble_ctr_cb.p_obs_cmpl_cb = p_cmpl_cb;
+        status = BTM_CMD_STARTED;
+
+        /* scan is not started */
+        if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+        {
+            p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
+            /* allow config scanning type */
+            btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
                                             (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
                                             (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
-                                            BLE_ADDR_PUBLIC,
-                                            BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */
+                                            btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
+                                            BTM_BLE_DEFAULT_SFP); /* assume observe always not using white list */
+
+            status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
+        }
+        if (status == BTM_CMD_STARTED)
         {
-            /* start scan, disable duplicate filtering */
-            if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
-            {
-                status = BTM_SUCCESS;
-                p_inq->proc_mode = BTM_BLE_OBSERVE;
-                btm_cb.btm_inq_vars.inq_active |= BTM_LE_OBSERVE_ACTIVE;
+            btm_cb.ble_ctr_cb.scan_activity |= BTM_LE_OBSERVE_ACTIVE;
 
-                if (duration != 0)
-                {
-                    /* start inquiry timer */
-                    btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration);
-                }
-            }
+            if (duration != 0)
+                /* start observer timer */
+                btu_start_timer (&btm_cb.ble_ctr_cb.obs_timer_ent, BTU_TTYPE_BLE_OBSERVE, duration);
         }
     }
-    else/*start = 0*/
+    else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
     {
-        if(btm_cb.btm_inq_vars.scan_type == INQ_GENERAL)
-        {
-            //Dont stop the scan. Just nullify the cbs
-            btm_cb.btm_inq_vars.p_inq_ble_results_cb = NULL;
-            btm_cb.btm_inq_vars.p_inq_ble_cmpl_cb = NULL;
-        }
-        else if (p_inq->proc_mode == BTM_BLE_OBSERVE)
-        {
-            btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE;
-            btm_ble_stop_scan();
-        }
+        status = BTM_CMD_STARTED;
+        btm_ble_stop_observe();
+    }
+    else
+    {
+        BTM_TRACE_ERROR0("Observe not active");
     }
 
     return status;
+
 }
 
 /*******************************************************************************
@@ -255,8 +377,10 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
     if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE)
     {
         /* update adv params */
-        if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
-                                              (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+        if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
+                                              BTM_BLE_GAP_ADV_INT),
+                                              (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max :
+                                              BTM_BLE_GAP_ADV_INT),
                                               evt_type,
                                               p_addr_cb->own_addr_type,
                                               p_cb->direct_bda.type,
@@ -270,7 +394,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
 
         status = btm_ble_start_adv ();
     }
-    else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+    else if (!start)
     {
         status = btm_ble_stop_adv();
     }
@@ -278,7 +402,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
     {
         status = BTM_WRONG_MODE;
         BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode",
-            (start ? "Start" : "Stop"), (start ? "alerady" :"not"));
+            (start ? "Start" : "Stop"), (start ? "already" :"not"));
     }
     return status;
 }
@@ -309,7 +433,42 @@ void BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK   *p_scan_req_cback)
 #endif
 }
 
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
+/*******************************************************************************
+**
+** Function         BTM_BleConfigPrivacy
+**
+** Description      This function is called to enable or disable the privacy in
+**                   LE channel of the local device.
+**
+** Parameters       enable: TRUE to enable it; FALSE to disable it.
+**
+** Returns          void
+**
+*******************************************************************************/
+void BTM_BleConfigPrivacy(BOOLEAN enable)
+{
+    tBTM_BLE_CB     *p_cb = &btm_cb.ble_ctr_cb;
+
+    BTM_TRACE_EVENT0 (" BTM_BleConfigPrivacy");
+
+    if (p_cb->privacy != enable)
+    {
+        p_cb->privacy = enable;
+
+        if (p_cb->privacy)
+        {
+            /* generate resolvable private address */
+            btm_gen_resolvable_private_addr();
+        }
+        else /* if privacy disabled, always use public address */
+        {
+            p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC;
+        }
+    }
+}
+
+
 /*******************************************************************************
 **
 ** Function         btm_ble_resolve_random_addr_on_adv
@@ -486,11 +645,13 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
 {
     UINT8 evt_type;
 
+    UNUSED(p_own_addr_type);
+
     if ( p_cb->directed_conn)
     {
         /*  direct adv mode does not have privacy if privacy
-            is not enabled or no reconn addr config */
-        *p_own_addr_type   = BLE_ADDR_PUBLIC;
+        is not enabled or no reconn addr config */
+
         *p_init_addr_type  = p_cb->direct_bda.type;
          memcpy(p_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN);
         evt_type = BTM_BLE_CONNECT_DIR_EVT;
@@ -498,6 +659,16 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
     else /* undirect adv mode */
     {
         evt_type = BTM_BLE_CONNECT_EVT;
+
+#if BLE_PRIVACY_SPT == TRUE
+        /* may need to reset random address if privacy is enabled */
+        if (btm_cb.ble_ctr_cb.privacy && /* own addr_type is random */
+            !BTM_BLE_IS_RESOLVE_BDA(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr))
+        {
+            /* need to generate RRA and update random addresss in controller */
+            btm_gen_resolvable_private_addr();
+        }
+#endif
     }
 
     return evt_type;
@@ -704,7 +875,7 @@ tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p
 {
     tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
     UINT8  *p;
-    UINT16   mask = data_mask;
+    tBTM_BLE_AD_MASK   mask = data_mask;
 
     BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData ");
 
@@ -930,7 +1101,99 @@ static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_ds
 
     return p_flag;
 }
+/*******************************************************************************
+**
+** Function         btm_ble_select_adv_interval
+**
+** Description      select adv interval based on device mode
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_ble_select_adv_interval(tBTM_BLE_INQ_CB *p_cb, UINT8 evt_type, UINT16 *p_adv_int_min, UINT16 *p_adv_int_max)
+{
+    if (p_cb->adv_interval_min && p_cb->adv_interval_max)
+    {
+        *p_adv_int_min = p_cb->adv_interval_min;
+        *p_adv_int_max = p_cb->adv_interval_max;
+    }
+    else
+    {
+        switch (evt_type)
+        {
+        case BTM_BLE_CONNECT_EVT:
+            *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_1;
+            break;
+
+        case BTM_BLE_NON_CONNECT_EVT:
+        case BTM_BLE_DISCOVER_EVT:
+            *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_FAST_INT_2;
+            break;
+        /* connectable directed event */
+        case BTM_BLE_CONNECT_DIR_EVT:
+            *p_adv_int_min = BTM_BLE_GAP_ADV_DIR_MIN_INT;
+            *p_adv_int_max = BTM_BLE_GAP_ADV_DIR_MAX_INT;
+            break;
+
+        default:
+            *p_adv_int_min = *p_adv_int_max = BTM_BLE_GAP_ADV_SLOW_INT;
+            break;
+        }
+    }
+    return;
+}
+/*******************************************************************************
+**
+** Function         btm_ble_set_adv_flag
+**
+** Description      Set adv flag in adv data.
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_ble_set_adv_flag(UINT16 connect_mode, UINT16 disc_mode)
+{
+    UINT8 flag = 0, old_flag = 0;
+    tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data;
+
+    if (p_adv_data->p_flags != NULL)
+        flag = old_flag = *(p_adv_data->p_flags);
+
+    /* BR/EDR non-discoverable , non-connectable */
+    if ((disc_mode & BTM_DISCOVERABLE_MASK) == 0 &&
+        (connect_mode & BTM_CONNECTABLE_MASK) == 0)
+        flag |= BTM_BLE_BREDR_NOT_SPT;
+    else
+        flag &= ~BTM_BLE_BREDR_NOT_SPT;
+
+    /* if local controller support, mark both controller and host support in flag */
+    if (HCI_SIMUL_LE_BREDR_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
+        flag |= (BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT);
+    else
+        flag &= ~(BTM_BLE_DMT_CONTROLLER_SPT|BTM_BLE_DMT_HOST_SPT);
+
+    BTM_TRACE_ERROR1("disc_mode %04x", disc_mode);
+    /* update discoverable flag */
+    if (disc_mode & BTM_BLE_LIMITED_DISCOVERABLE)
+    {
+        flag &= ~BTM_BLE_GEN_DISC_FLAG;
+        flag |= BTM_BLE_LIMIT_DISC_FLAG ;
+    }
+    else if (disc_mode & BTM_BLE_GENERAL_DISCOVERABLE)
+    {
+        flag |= BTM_BLE_GEN_DISC_FLAG;
+        flag &= ~BTM_BLE_LIMIT_DISC_FLAG;
+    }
+    else /* remove all discoverable flags */
+    {
+        flag &= ~(BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG);
+    }
 
+    if (flag != old_flag)
+    {
+        btm_ble_update_adv_flag(flag);
+    }
+}
 /*******************************************************************************
 **
 ** Function         btm_ble_set_discoverability
@@ -947,7 +1210,6 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
     tBTM_LE_RANDOM_CB   *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
     tBTM_BLE_INQ_CB     *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     UINT16              mode = (combined_mode &  BTM_BLE_DISCOVERABLE_MASK);
-    UINT8               flag = 0;
     UINT8               new_mode = BTM_BLE_ADV_ENABLE;
     UINT8               evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \
                                    ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\
@@ -955,7 +1217,8 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
     tBTM_STATUS         status = BTM_SUCCESS;
     BD_ADDR             p_addr_ptr= {0};
     tBLE_ADDR_TYPE      init_addr_type = BLE_ADDR_PUBLIC,
-                        own_addr_type = p_addr_cb->own_addr_type;;
+                        own_addr_type = p_addr_cb->own_addr_type;
+    UINT16              adv_int_min, adv_int_max;
 
     BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
 
@@ -963,56 +1226,28 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
     if (mode > BTM_BLE_MAX_DISCOVERABLE)
         return(BTM_ILLEGAL_VALUE);
 
-    p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK);
-    p_cb->discoverable_mode = mode;
+    btm_ble_set_adv_flag (btm_cb.btm_inq_vars.connectable_mode, combined_mode);
 
-    if (!p_cb->br_edr_supported_flag)
-    {
-        flag = BTM_BLE_BREDR_NOT_SPT;
-        BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag);
-    }
+    evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
 
-    BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag);
+    if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE && mode == BTM_BLE_NON_DISCOVERABLE)
+        new_mode = BTM_BLE_ADV_DISABLE;
 
-    if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE)
-    {
-        BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE ");
-        /* write ADV data with limited disc flag */
-        if (mode == BTM_BLE_LIMITED_DISCOVERABLE)
-            flag |= BTM_BLE_LIMIT_DISC_FLAG ;
-        else
-            flag |= BTM_BLE_GEN_DISC_FLAG;
-    }
-    else  /* non-discoverable */
-    {
-        BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE ");
+    btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max);
 
-        if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE)
-        {
-            p_cb->br_edr_supported_flag = 0;
-
-            BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp ");
-            if (!p_cb->scan_rsp )
-                   new_mode = BTM_BLE_ADV_DISABLE;
-
-        }
-        else
-        {
-            p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
-        }
-    }
-    btm_ble_update_adv_flag(flag);
+    btu_stop_timer(&p_cb->fast_adv_timer);
 
     /* update adv params if start advertising */
     BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type);
+
     if (new_mode == BTM_BLE_ADV_ENABLE &&
-        (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type))
+        (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type || !p_cb->fast_adv_on))
     {
         btm_ble_stop_adv();
 
         /* update adv params */
-        if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
-                                              (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+        if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
+                                              adv_int_max,
                                               evt_type,
                                               own_addr_type,
                                               init_addr_type,
@@ -1036,11 +1271,18 @@ tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
         else
             status = btm_ble_stop_adv();
     }
+    if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+    {
+        p_cb->fast_adv_on = TRUE;
+        /* start initial GAP mode adv timer */
+        btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV,
+                          BTM_BLE_GAP_FAST_ADV_TOUT);
+    }
 
     /* set up stop advertising timer */
     if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE)
     {
-        BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT);
+        BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (180 secs)", BTM_BLE_GAP_LIM_TOUT);
         /* start Tgap(lim_timeout) */
         btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC,
                          BTM_BLE_GAP_LIM_TOUT);
@@ -1064,57 +1306,39 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
     tBTM_LE_RANDOM_CB       *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
     tBTM_BLE_INQ_CB         *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     UINT16                  mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK);
-    UINT8                   cur_flag = 0;
-    UINT8                   cur_br_edr_not_sup_flag;
-    UINT8                   new_flag;
     UINT8                   new_mode = BTM_BLE_ADV_ENABLE;
     UINT8                   evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT;
     tBTM_STATUS             status = BTM_SUCCESS;
     BD_ADDR                 p_addr_ptr =  {0};
     tBLE_ADDR_TYPE          init_addr_type = BLE_ADDR_PUBLIC,
                             own_addr_type = p_addr_cb->own_addr_type;
+    UINT16                  adv_int_min, adv_int_max;
 
     BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode);
+
     /*** Check mode parameter ***/
     if (mode > BTM_BLE_MAX_CONNECTABLE)
         return(BTM_ILLEGAL_VALUE);
-    if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags)
-        cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ;
-    cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT));
 
-    p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4);
-    if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag)
-    {
-        new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT));
-        BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag,  cur_flag);
-        btm_ble_update_adv_flag(new_flag);
-    }
     p_cb->connectable_mode = mode;
 
-    if (mode == BTM_BLE_NON_CONNECTABLE)
-    {
-        if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
-        {
-            p_cb->br_edr_supported_flag = 0;
-            BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp");
-            if(!p_cb->scan_rsp)
-                   new_mode = BTM_BLE_ADV_DISABLE;
+    btm_ble_set_adv_flag (combined_mode,  btm_cb.btm_inq_vars.discoverable_mode);
 
-        }
-    }
-    else /* connectable */
-    {
-        evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
-    }
+    evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type);
+
+    if (mode == BTM_BLE_NON_CONNECTABLE && p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE)
+        new_mode = BTM_BLE_ADV_DISABLE;
 
+    btm_ble_select_adv_interval(p_cb, evt_type, &adv_int_min, &adv_int_max);
+
+    btu_stop_timer(&p_cb->fast_adv_timer);
     /* update adv params if needed */
-    if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type)
-        && new_mode == BTM_BLE_ADV_ENABLE)
+    if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type || !p_cb->fast_adv_on))
     {
         btm_ble_stop_adv();
 
-        if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT),
-                                              (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT),
+        if (!btsnd_hcic_ble_write_adv_params (adv_int_min,
+                                              adv_int_max,
                                               evt_type,
                                               own_addr_type,
                                               init_addr_type,
@@ -1132,24 +1356,22 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
     /* update advertising mode */
     if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode)
     {
-        if (btsnd_hcic_ble_set_adv_enable (new_mode))
-        {
-            status = BTM_SUCCESS;
-
-            p_cb->adv_mode = new_mode;
-
-            if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE &&
-                p_cb->afp != AP_SCAN_CONN_ALL)
-                btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
-            else
-                btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
-
-        }
+        if (new_mode == BTM_BLE_ADV_ENABLE)
+            status = btm_ble_start_adv();
+        else
+            status = btm_ble_stop_adv();
+    }
+    if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+    {
+        p_cb->fast_adv_on = TRUE;
+        /* start initial GAP mode adv timer */
+        btu_start_timer (&p_cb->fast_adv_timer, BTU_TTYPE_BLE_GAP_FAST_ADV,
+                             BTM_BLE_GAP_FAST_ADV_TOUT);
     }
-
     return status;
 }
 
+
 /*******************************************************************************
 **
 ** Function         btm_ble_start_inquiry
@@ -1171,24 +1393,32 @@ tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
 *******************************************************************************/
 tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8   duration)
 {
-    tBTM_STATUS status = BTM_NO_RESOURCES;
-    tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
+    tBTM_STATUS status = BTM_CMD_STARTED;
+    tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
+    tBTM_INQUIRY_VAR_ST      *p_inq = &btm_cb.btm_inq_vars;
 
-    BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active);
+    BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = 0x%02x", mode, btm_cb.btm_inq_vars.inq_active);
 
-    if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE)
+    /* if selective connection is active, or inquiry is already active, reject it */
+    if (BTM_BLE_IS_INQ_ACTIVE(p_ble_cb->scan_activity) ||
+        BTM_BLE_IS_SEL_CONN_ACTIVE (p_ble_cb->scan_activity))
     {
-        BTM_TRACE_ERROR0("LE scan is active, can not start inquiry");
+        BTM_TRACE_ERROR0("LE Inquiry is active, can not start inquiry");
         return(BTM_BUSY);
     }
 
-    btm_update_scanner_filter_policy(SP_ADV_ALL);
+    if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
+    {
+        btm_update_scanner_filter_policy(SP_ADV_ALL);
+        status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
+    }
 
-    /* start scan, already enable duplicate filtering */
-    if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE))
+    if (status == BTM_CMD_STARTED)
     {
-        status = BTM_CMD_STARTED;
-        p_inq->proc_mode = mode;
+        p_inq->inq_active |= mode;
+        p_ble_cb->scan_activity |= mode;
+
+        BTM_TRACE_DEBUG1("btm_ble_start_inquiry inq_active = 0x%02x", p_inq->inq_active);
 
         if (duration != 0)
         {
@@ -1198,6 +1428,7 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8   duration)
     }
 
     return status;
+
 }
 
 /*******************************************************************************
@@ -1508,68 +1739,54 @@ void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, U
 ** Returns          void
 **
 *******************************************************************************/
-BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
+UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p)
 {
-    BOOLEAN             is_discoverable = FALSE;
-    UINT8               *p_flag, flag = 0;
+    UINT8               *p_flag, flag = 0, rt = 0;
     UINT8                data_len;
     tBTM_INQ_PARMS      *p_cond = &btm_cb.btm_inq_vars.inqparms;
+    tBTM_BLE_INQ_CB     *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
 
-    STREAM_TO_UINT8    (data_len, p);
+    UNUSED(p);
 
     /* for observer, always "discoverable */
-    if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE ||
-        (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN &&
-        btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE))
-        return TRUE;
+    if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+        rt |= BTM_BLE_OBS_RESULT;
+
+    if (BTM_BLE_IS_SEL_CONN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity) &&
+        (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT))
+        rt |= BTM_BLE_SEL_CONN_RESULT;
 
     /* does not match filter condition */
     if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR &&
         memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0)
     {
         BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition");
-        return FALSE;
-    }
-
-    /* scan response does not include the flag */
-    if (evt_type == BTM_BLE_SCAN_RSP_EVT)
-        return FALSE;
-
-    if (data_len > BTM_BLE_ADV_DATA_LEN_MAX)
-    {
-        BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len);
-        return FALSE;
+        return rt;
     }
 
-    if (data_len != 0)
+    if (p_le_inq_cb->adv_len != 0)
     {
-        if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
+        if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache,
+            BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL)
         {
             flag = * p_flag;
 
-            if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) &&
+            if ((btm_cb.btm_inq_vars.inq_active & BTM_BLE_GENERAL_INQUIRY) &&
                 (flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0)
             {
                 BTM_TRACE_DEBUG0("Find Generable Discoverable device");
-                is_discoverable = TRUE;
+                rt |= BTM_BLE_INQ_RESULT;
             }
 
-            else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY &&
+            else if (btm_cb.btm_inq_vars.inq_active & BTM_BLE_LIMITED_INQUIRY &&
                      (flag & BTM_BLE_LIMIT_DISC_FLAG) != 0)
             {
                 BTM_TRACE_DEBUG0("Find limited discoverable device");
-                is_discoverable = TRUE;
+                rt |= BTM_BLE_INQ_RESULT;
             }
-
         }
     }
-
-    if (!is_discoverable)
-    {
-        BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag);
-    }
-
-    return is_discoverable;
+    return rt;
 }
 
 /*******************************************************************************
@@ -1742,7 +1959,7 @@ void btm_ble_process_adv_pkt (UINT8 *p_data)
     BD_ADDR             bda;
     UINT8               evt_type = 0, *p = p_data;
     UINT8               addr_type = 0;
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
     BOOLEAN             match = FALSE;
 #endif
 
@@ -1765,15 +1982,12 @@ void btm_ble_process_adv_pkt (UINT8 *p_data)
 
 
     /* Only process the results if the inquiry is still active */
-    if ((btm_cb.btm_inq_vars.inq_active & BTM_LE_SCAN_ACTIVE_MASK) == 0 &&
-        (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE ||
-         /* or selective auto connection is active */
-         btm_cb.ble_ctr_cb.p_select_cback == NULL))
+    if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
         return;
 
     BTM_TRACE_DEBUG6("btm_ble_process_adv_pkt:bda= %0x:%0x:%0x:%0x:%0x:%0x",
                                      bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]);
-#if (defined BTM_BLE_PRIVACY_SPT && BTM_BLE_PRIVACY_SPT == TRUE)
+#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
 #if SMP_INCLUDED == TRUE
     /* always do RRA resolution on host */
     if (!match && BTM_BLE_IS_RESOLVE_BDA(bda))
@@ -1803,13 +2017,12 @@ void btm_ble_process_adv_pkt (UINT8 *p_data)
 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
 {
     tINQ_DB_ENT          *p_i;
-    BOOLEAN              to_report = FALSE;
-    BOOLEAN              to_report_LE = TRUE; //var for reporting to LE observe
     tBTM_INQUIRY_VAR_ST  *p_inq = &btm_cb.btm_inq_vars;
     tBTM_INQ_RESULTS_CB  *p_inq_results_cb = p_inq->p_inq_results_cb;
-    tBTM_INQ_RESULTS_CB  *p_inq_ble_results_cb = p_inq->p_inq_ble_results_cb;
+    tBTM_INQ_RESULTS_CB  *p_obs_results_cb = btm_cb.ble_ctr_cb.p_obs_results_cb;
     tBTM_BLE_INQ_CB      *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var;
-    BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: addr_type: %d, evt_type: %d", addr_type, evt_type);
+    BOOLEAN     update = TRUE;
+    UINT8       result = 0;
 
     p_i = btm_inq_db_find (bda);
 
@@ -1817,26 +2030,23 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
     if (btm_inq_find_bdaddr(bda))
     {
         /* never been report as an LE device */
-        if ((p_i &&
+        if (p_i &&
             (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) ||
               /* scan repsonse to be updated */
               (!p_i->scan_rsp)))
-            ||
-            btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE)
         {
-            BTM_TRACE_DEBUG0("update new BLE information ");
-            to_report = TRUE;
+            update = TRUE;
+        }
+        else if (BTM_BLE_IS_OBS_ACTIVE(btm_cb.ble_ctr_cb.scan_activity))
+        {
+            update = FALSE;
         }
         else
         {
-            to_report = FALSE;
+            /* if yes, skip it */
+            return; /* assumption: one result per event */
         }
     }
-    else /* not been processed in this round */
-    {
-        to_report = TRUE;
-    }
-
     /* If existing entry, use that, else get  a new one (possibly reusing the oldest) */
     if (p_i == NULL)
     {
@@ -1846,25 +2056,22 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
         }
         else
             return;
-
-        if (to_report && btm_ble_is_discoverable(bda, evt_type, p))
-        {
-            to_report = TRUE;
-        }
-        else
-        {
-            BTM_TRACE_ERROR0("discard adv pkt");
-            to_report = FALSE;
-        }
     }
     else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */
     {
         p_inq->inq_cmpl_info.num_resp++;
     }
     /* update the LE device information in inquiry database */
-    to_report_LE = btm_ble_update_inq_result(p_i, addr_type, evt_type, p);
-    if (to_report)
-        to_report = to_report_LE;
+    if (!btm_ble_update_inq_result(p_i, addr_type, evt_type, p))
+        return;
+
+    if ((result = btm_ble_is_discoverable(bda, evt_type, p)) == 0)
+    {
+        BTM_TRACE_ERROR0("discard adv pkt");
+        return;
+    }
+    if (!update)
+        result &= ~BTM_BLE_INQ_RESULT;
 #if BTM_USE_INQ_RESULTS_FILTER == TRUE
     /* If the number of responses found and limited, issue a cancel inquiry */
     if (p_inq->inqparms.max_resps &&
@@ -1882,8 +2089,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
                 (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0)
                 btsnd_hcic_inq_cancel();
 
-            /* stop LE scan now */
-            btm_ble_stop_scan();
+            btm_ble_stop_inquiry();
 
 #if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE
             btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
@@ -1891,28 +2097,54 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
         }
     }
 #endif
-
-    BTM_TRACE_DEBUG2("btm_ble_process_adv_pkt_cont: to_report =%d, to_report_le=%d",
-                                                               to_report, to_report_LE);
     /* background connection in selective connection mode */
     if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)
     {
-        if (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE &&
-            (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT))
+        if (result & BTM_BLE_SEL_CONN_RESULT)
             btm_send_sel_conn_callback(bda, evt_type, p, addr_type);
         else
         {
             BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection");
         }
     }
-    else if (to_report || to_report_LE)
+    else
     {
-        if(p_inq_results_cb && to_report)
+        if (p_inq_results_cb && (result & BTM_BLE_INQ_RESULT))
+        {
             (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
-        if(p_inq_ble_results_cb && to_report_LE)
-            (p_inq_ble_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results,
-                                                      p_le_inq_cb->adv_data_cache);
+        }
+        if (p_obs_results_cb && (result & BTM_BLE_OBS_RESULT))
+        {
+            (p_obs_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         btm_ble_start_scan
+**
+** Description      Start the BLE scan.
+**
+** Returns          void
+**
+*******************************************************************************/
+tBTM_STATUS btm_ble_start_scan (UINT8 filter_enable)
+{
+    tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
+    tBTM_STATUS status = BTM_CMD_STARTED;
+
+    /* start scan, disable duplicate filtering */
+    if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, filter_enable))
+        status = BTM_NO_RESOURCES;
+    else
+    {
+        if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI)
+            btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
+        else
+            btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
     }
+    return status;
 }
 
 /*******************************************************************************
@@ -1926,44 +2158,135 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
 *******************************************************************************/
 void btm_ble_stop_scan(void)
 {
-    tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
-    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
-
     BTM_TRACE_EVENT0 ("btm_ble_stop_scan ");
 
-    btu_stop_timer (&p_cb->inq_timer_ent);
-
     /* Clear the inquiry callback if set */
-    p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE;
-    p_cb->proc_mode = BTM_BLE_INQUIRY_NONE;
+    btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
 
     /* stop discovery now */
     btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
 
+    btm_update_scanner_filter_policy(SP_ADV_ALL);
+}
+/*******************************************************************************
+**
+** Function         btm_ble_stop_inquiry
+**
+** Description      Stop the BLE Inquiry.
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_ble_stop_inquiry(void)
+{
+    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
+    tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
+
+    btu_stop_timer (&p_ble_cb->inq_var.inq_timer_ent);
+
+    p_ble_cb->scan_activity &=  ~BTM_BLE_INQUIRY_MASK;
+
+    /* If no more scan activity, stop LE scan now */
+    if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
+        btm_ble_stop_scan();
+
     /* If we have a callback registered for inquiry complete, call it */
     BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d",
                       p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
 
-    btm_update_scanner_filter_policy(SP_ADV_ALL);
-
     btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK));
+}
+
+/*******************************************************************************
+**
+** Function         btm_ble_stop_observe
+**
+** Description      Stop the BLE Observe.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btm_ble_stop_observe(void)
+{
+    tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
+    tBTM_CMPL_CB *p_obs_cb = p_ble_cb->p_obs_cmpl_cb;
+
+    btu_stop_timer (&p_ble_cb->obs_timer_ent);
 
+    p_ble_cb->scan_activity &= ~BTM_LE_OBSERVE_ACTIVE;
+
+    p_ble_cb->p_obs_results_cb = NULL;
+    p_ble_cb->p_obs_cmpl_cb = NULL;
+
+    if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
+        btm_ble_stop_scan();
+
+    if (p_obs_cb)
+        (p_obs_cb)((tBTM_INQUIRY_CMPL *) &btm_cb.btm_inq_vars.inq_cmpl_info);
+}
+/*******************************************************************************
+**
+** Function         btm_ble_adv_states_operation
+**
+** Description      Set or clear adv states in topology mask
+**
+** Returns          operation status. TRUE if sucessful, FALSE otherwise.
+**
+*******************************************************************************/
+typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK);
+static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UINT8 adv_evt)
+{
+    BOOLEAN rt = FALSE;
+
+    switch (adv_evt)
+    {
+    case BTM_BLE_CONNECT_EVT:
+        rt  = (*p_handler)(BTM_BLE_STATE_CONN_ADV_BIT);
+        break;
+
+    case  BTM_BLE_NON_CONNECT_EVT:
+        rt  = (*p_handler) (BTM_BLE_STATE_NON_CONN_ADV_BIT);
+        break;
+    case BTM_BLE_CONNECT_DIR_EVT:
+        rt  =  (*p_handler) (BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT);
+        break;
+
+    case BTM_BLE_DISCOVER_EVT:
+        rt  =  (*p_handler) (BTM_BLE_STATE_SCAN_ADV_BIT);
+        break;
+
+    default:
+        BTM_TRACE_ERROR1("unknown adv event : %d", adv_evt);
+        break;
+    }
+
+    return rt;
 }
 
+
 /*******************************************************************************
 **
 ** Function         btm_ble_start_adv
 **
-** Description      Stop the BLE advertising.
+** Description      start the BLE advertising.
 **
 ** Returns          void
 **
 *******************************************************************************/
-static tBTM_STATUS btm_ble_start_adv(void)
+tBTM_STATUS btm_ble_start_adv(void)
 {
     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS     rt = BTM_NO_RESOURCES;
 
+    if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type))
+        return BTM_WRONG_MODE;
+
+    if (p_cb->afp != AP_SCAN_CONN_ALL)
+    {
+        btm_execute_wl_dev_operation();
+        btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
+    }
+
     if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE))
     {
         if (p_cb->afp != AP_SCAN_CONN_ALL)
@@ -1972,13 +2295,13 @@ static tBTM_STATUS btm_ble_start_adv(void)
          p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
 
          rt = BTM_SUCCESS;
-     }
-     else
-     {
-         p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
-         btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
-     }
-     return rt;
+    }
+    else
+    {
+        p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
+        btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+    }
+    return rt;
 }
 /*******************************************************************************
 **
@@ -1989,7 +2312,7 @@ static tBTM_STATUS btm_ble_start_adv(void)
 ** Returns          void
 **
 *******************************************************************************/
-static tBTM_STATUS btm_ble_stop_adv(void)
+tBTM_STATUS btm_ble_stop_adv(void)
 {
     tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
     tBTM_STATUS rt = BTM_SUCCESS;
@@ -1998,18 +2321,143 @@ static tBTM_STATUS btm_ble_stop_adv(void)
     {
         if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE))
         {
+            p_cb->fast_adv_on = FALSE;
             p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
             btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
+
+            /* clear all adv states */
+            btm_ble_clear_topology_mask (BTM_BLE_STATE_ALL_ADV_MASK);
         }
         else
             rt = BTM_NO_RESOURCES;
     }
     return rt;
+}
+
+
+/*******************************************************************************
+**
+** Function         btm_ble_set_topology_mask
+**
+** Description      set BLE topology mask
+**
+** Returns          TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state_mask)
+{
+    BOOLEAN rt = TRUE;
+
+    request_state_mask &= BTM_BLE_STATE_ALL_MASK;
+
+    btm_cb.ble_ctr_cb.cur_states |= request_state_mask;
+
+    return rt;
+}
+/*******************************************************************************
+**
+** Function         btm_ble_clear_topology_mask
+**
+** Description      Clear BLE topology bit mask
+**
+** Returns          TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_clear_topology_mask (tBTM_BLE_STATE_MASK request_state_mask)
+{
+    request_state_mask &= BTM_BLE_STATE_ALL_MASK;
+
+    btm_cb.ble_ctr_cb.cur_states &= ~request_state_mask;
+
+    return TRUE;
+}
+/*******************************************************************************
+**
+** Function         btm_ble_update_mode_operation
+**
+** Description      This function update the GAP role operation when a link status
+**                  is updated.
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel)
+{
+    tACL_CONN   *pa = &btm_cb.acl_db[0];
+    UINT16       xx;
+    UINT16       mask = BTM_BLE_STATE_ALL_CONN_MASK;
+
+    UNUSED(bd_addr);
+    UNUSED (conn_cancel);
+
+    if (link_role == HCI_ROLE_SLAVE)
+    {
+        btm_cb.ble_ctr_cb.inq_var.adv_mode  = BTM_BLE_ADV_DISABLE;
+        /* clear all adv states */
+        mask |= BTM_BLE_STATE_ALL_ADV_MASK;
+    }
+
+    btm_ble_clear_topology_mask (mask);
+
+    /* check the device link role maps */
+    for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++)
+    {
+        if (pa->in_use && pa->transport == BT_TRANSPORT_LE)
+        {
+            if (pa->link_role == HCI_ROLE_MASTER)
+                btm_ble_set_topology_mask (BTM_BLE_STATE_MASTER_BIT);
+            else
+                btm_ble_set_topology_mask (BTM_BLE_STATE_SLAVE_BIT);
+        }
+    }
+
+    if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE)
+    {
+        btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
+    }
 
+    if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
+    {
+        if (!btm_send_pending_direct_conn())
+        {
+            btm_ble_resume_bg_conn();
+        }
+    }
 }
 
 /*******************************************************************************
 **
+** Function         btm_ble_start_slow_adv
+**
+** Description      Restart adv with slow adv interval
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btm_ble_start_slow_adv (void)
+{
+    tBTM_BLE_INQ_CB         *p_cb = &btm_cb.ble_ctr_cb.inq_var;
+    BD_ADDR                 p_addr_ptr= {0};
+
+    if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE)
+    {
+        btm_ble_stop_adv();
+
+        btsnd_hcic_ble_write_adv_params (BTM_BLE_GAP_ADV_SLOW_INT,
+                                         BTM_BLE_GAP_ADV_SLOW_INT,
+                                         p_cb->evt_type,
+                                         p_cb->adv_addr_type,
+                                         btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,/* slow adv
+                                         mode never goes into directed adv */
+                                         p_addr_ptr,
+                                         p_cb->adv_chnl_map,
+                                         p_cb->afp);
+
+        btm_ble_start_adv();
+    }
+}
+/*******************************************************************************
+**
 ** Function         btm_ble_timeout
 **
 ** Description      Called when BTM BLE inquiry timer expires
@@ -2019,17 +2467,23 @@ static tBTM_STATUS btm_ble_stop_adv(void)
 *******************************************************************************/
 void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
 {
+    BTM_TRACE_EVENT0 ("btm_ble_timeout");
+
     switch (p_tle->event)
     {
+        case BTU_TTYPE_BLE_OBSERVE:
+            btm_ble_stop_observe();
+            break;
+
         case BTU_TTYPE_BLE_INQUIRY:
-            btm_ble_stop_scan();
+            btm_ble_stop_inquiry();
             break;
 
         case BTU_TTYPE_BLE_GAP_LIM_DISC:
             /* lim_timeout expiried, limited discovery should exit now */
-            btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG);
+            btm_cb.btm_inq_vars.discoverable_mode &= ~BTM_BLE_LIMITED_DISCOVERABLE;
 
-            btm_ble_stop_adv();
+            btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, btm_cb.btm_inq_vars.discoverable_mode);
             break;
 
         case BTU_TTYPE_BLE_RANDOM_ADDR:
@@ -2040,6 +2494,14 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
             }
             break;
 
+        case BTU_TTYPE_BLE_GAP_FAST_ADV:
+            /* fast adv is completed, fall back to slow adv interval */
+            btm_ble_start_slow_adv();
+            break;
+
+        default:
+            break;
+
     }
 }
 
@@ -2058,13 +2520,13 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle)
 void btm_ble_read_remote_features_complete(UINT8 *p)
 {
     tACL_CONN        *p_acl_cb = &btm_cb.acl_db[0];
-    UINT8             status;
     UINT16            handle;
     int               xx;
 
     BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete ");
 
-    STREAM_TO_UINT8  (status, p);
+    /* Skip status */
+    p++;
     STREAM_TO_UINT16 (handle, p);
 
     /* Look up the connection by handle and copy features */
@@ -2076,6 +2538,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p)
             break;
         }
     }
+
 }
 
 /*******************************************************************************
@@ -2120,58 +2583,6 @@ void btm_ble_dir_adv_tout(void)
 
 /*******************************************************************************
 **
-** Function         btm_ble_update_mode_operation
-**
-** Description      This function update the GAP role operation when a link status
-**                  is updated.
-**
-** Returns          void
-**
-*******************************************************************************/
-void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel)
-{
-    tACL_CONN   *pa = &btm_cb.acl_db[0];
-    UINT16       xx;
-    UINT8        dev_role = link_role;
-    UNUSED(bd_addr);
-    UNUSED(conn_cancel);
-
-    BTM_TRACE_DEBUG1("btm_ble_update_mode_operation adv_mode = %d", btm_cb.ble_ctr_cb.inq_var.adv_mode );
-
-    /* update periphera role operation */
-    /* If we are LE connectable, check if we need to start advertising again */
-    if (link_role == HCI_ROLE_UNKNOWN)
-        /* && btm_cb.ble_ctr_cb.inq_var.connectable_mode != BTM_BLE_NON_CONNECTABLE) */
-    {
-        for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++)
-        {
-            /* If any other LE link is up, we are still not connectable */
-            if (pa->in_use && pa->is_le_link)
-            {
-                dev_role = pa->link_role;
-                break;
-            }
-        }
-    }
-
-    if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE  &&
-        (dev_role == HCI_ROLE_UNKNOWN )) /* when device has no connection, update adv here */
-        /* if already in connection, no connectable adv is allowed unless scatternet is enabled */
-    {
-        btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
-    }
-
-    if (btm_ble_get_conn_st() == BLE_CONN_IDLE)
-    {
-        if (!btm_send_pending_direct_conn())
-        {
-            btm_ble_resume_bg_conn();
-        }
-    }
-}
-
-/*******************************************************************************
-**
 ** Function         btm_ble_init
 **
 ** Description      Initialize the control block variable values.
@@ -2186,6 +2597,7 @@ void btm_ble_init (void)
     BTM_TRACE_EVENT0 ("btm_ble_init ");
 
     memset(p_cb, 0, sizeof(tBTM_BLE_CB));
+    p_cb->cur_states       = 0;
 
     p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
     p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
@@ -2201,4 +2613,76 @@ void btm_ble_init (void)
     p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
 }
 
+/*******************************************************************************
+**
+** Function         btm_ble_topology_check
+**
+** Description      check to see requested state is supported. One state check at
+**                  a time is supported
+**
+** Returns          TRUE is request is allowed, FALSE otherwise.
+**
+*******************************************************************************/
+BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request_state_mask)
+{
+    BOOLEAN rt = FALSE;
+    UINT32  llt_mask = 0;
+    UINT8   *p;
+
+    UINT8   state_offset = 0;
+    UINT16  cur_states = btm_cb.ble_ctr_cb.cur_states;
+    UINT8   mask, offset;
+    UINT8   request_state = 0;
+
+    /* check only one bit is set and within valid range */
+    if (request_state_mask == BTM_BLE_STATE_INVALID ||
+        request_state_mask > BTM_BLE_STATE_SCAN_ADV_BIT ||
+        (request_state_mask & (request_state_mask -1 )) != 0)
+    {
+        BTM_TRACE_ERROR1("illegal state requested: %d", request_state_mask);
+        return rt;
+    }
+
+    while (request_state_mask)
+    {
+        request_state_mask >>= 1;
+        request_state ++;
+    }
+
+    /* check if the requested state is supported or not */
+    mask = btm_le_state_combo_tbl[0][request_state - 1][0];
+    offset = btm_le_state_combo_tbl[0][request_state-1][1];
+
+    if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset))
+    {
+        BTM_TRACE_ERROR1("state requested not supported: %d", request_state);
+        return rt;
+    }
+
+    rt = TRUE;
+    /* make sure currently active states are all supported in conjunction with the requested
+       state. If the bit in table is not set, the combination is not supported */
+    while (cur_states != 0)
+    {
+        if (cur_states & 0x01)
+        {
+            mask = btm_le_state_combo_tbl[request_state][state_offset][0];
+            offset = btm_le_state_combo_tbl[request_state][state_offset][1];
+
+            if (mask != 0 && offset != 0)
+            {
+                if (!BTM_LE_STATES_SUPPORTED(btm_cb.devcb.le_supported_states, mask, offset))
+                {
+                    rt = FALSE;
+                    break;
+                }
+            }
+        }
+        cur_states >>= 1;
+        state_offset ++;
+    }
+    return rt;
+}
+
+
 #endif  /* BLE_INCLUDED */
index 7a05507..f3cb771 100644 (file)
 #define BTM_BLE_GAP_DISC_SCAN_INT   18         /* Interval(scan_int) = 11.25 ms= 0x0010 * 0.625 ms */
 #define BTM_BLE_GAP_DISC_SCAN_WIN   18         /* scan_window = 11.25 ms= 0x0010 * 0.625 ms */
 #define BTM_BLE_GAP_ADV_INT         512         /* Tgap(gen_disc) = 1.28 s= 512 * 0.625 ms */
-#define BTM_BLE_GAP_LIM_TOUT        30          /* Tgap(lim_timeout) = 30.72 s max, round down to 30 */
+#define BTM_BLE_GAP_LIM_TOUT        180          /* Tgap(lim_timeout) = 180s max */
 
 
+#define BTM_BLE_GAP_ADV_FAST_INT_1         48         /* TGAP(adv_fast_interval1) = 30(used) ~ 60 ms  = 48 *0.625 */
+#define BTM_BLE_GAP_ADV_FAST_INT_2         160         /* TGAP(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_SLOW_INT           2048         /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_DIR_MAX_INT        800         /* Tgap(dir_conn_adv_int_max) = 500 ms = 800 * 0.625 ms */
+#define BTM_BLE_GAP_ADV_DIR_MIN_INT        400         /* Tgap(dir_conn_adv_int_min) = 250 ms = 400 * 0.625 ms */
+
+#define BTM_BLE_GAP_FAST_ADV_TOUT          30
+
 #define BTM_BLE_SEC_REQ_ACT_NONE           0
 #define BTM_BLE_SEC_REQ_ACT_ENCRYPT        1 /* encrypt the link using current key or key refresh */
 #define BTM_BLE_SEC_REQ_ACT_PAIR           2
@@ -75,6 +83,16 @@ typedef UINT8   tBTM_BLE_SEC_REQ_ACT;
 #define BLE_RESOLVE_ADDR_MASK                0xc0   /* bit 6, and bit7 */
 #define BTM_BLE_IS_RESOLVE_BDA(x)           ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB)
 
+/* LE scan activity bit mask, continue with LE inquiry bits */
+#define BTM_LE_SELECT_CONN_ACTIVE      0x40     /* selection connection is in progress */
+#define BTM_LE_OBSERVE_ACTIVE          0x80     /* observe is in progress */
+
+/* BLE scan activity mask checking */
+#define BTM_BLE_IS_SCAN_ACTIVE(x)   ((x) & BTM_BLE_SCAN_ACTIVE_MASK)
+#define BTM_BLE_IS_INQ_ACTIVE(x)   ((x) & BTM_BLE_INQUIRY_MASK)
+#define BTM_BLE_IS_OBS_ACTIVE(x)   ((x) & BTM_LE_OBSERVE_ACTIVE)
+#define BTM_BLE_IS_SEL_CONN_ACTIVE(x)   ((x) & BTM_LE_SELECT_CONN_ACTIVE)
+
 typedef struct
 {
     UINT16              data_mask;
@@ -103,11 +121,6 @@ typedef struct
 
     UINT16           discoverable_mode;
     UINT16           connectable_mode;
-    UINT16           br_edr_supported_flag;  /* combined BR EDR discoverable and connectable mode */
-                                             /* only meaningful when it is zero. This means
-                                                BR EDR is not supported*/
-    UINT8            proc_mode;        /* current procedure mode : inquiry or discovery */
-
     UINT16           scan_window;
     UINT16           scan_interval;
     UINT8            scan_type;        /* current scan type: active or passive */
@@ -121,6 +134,8 @@ typedef struct
     UINT8            adv_mode;
     tBLE_BD_ADDR     direct_bda;
     BOOLEAN          directed_conn;
+    BOOLEAN          fast_adv_on;
+    TIMER_LIST_ENT   fast_adv_timer;
 
     UINT8            adv_len;
     UINT8            adv_data_cache[BTM_BLE_CACHE_ADV_DATA_MAX];
@@ -148,8 +163,8 @@ typedef void (tBTM_BLE_ADDR_CBACK) (BD_ADDR_PTR static_random, void *p);
 /* random address management control block */
 typedef struct
 {
-    tBLE_ADDR_TYPE                 own_addr_type;         /* local device LE address type */
-    BD_ADDR                                private_addr;
+    tBLE_ADDR_TYPE              own_addr_type;         /* local device LE address type */
+    BD_ADDR                     private_addr;
     BD_ADDR                     random_bda;
     BOOLEAN                     busy;
     UINT16                       index;
@@ -198,6 +213,37 @@ typedef struct
     void    *p_param;
 }tBTM_BLE_CONN_REQ;
 
+/* LE state request */
+#define BTM_BLE_STATE_INVALID               0
+#define BTM_BLE_STATE_CONN_ADV              1
+#define BTM_BLE_STATE_INIT                  2
+#define BTM_BLE_STATE_MASTER                3
+#define BTM_BLE_STATE_SLAVE                 4
+#define BTM_BLE_STATE_LO_DUTY_DIR_ADV       5
+#define BTM_BLE_STATE_HI_DUTY_DIR_ADV       6
+#define BTM_BLE_STATE_NON_CONN_ADV          7
+#define BTM_BLE_STATE_PASSIVE_SCAN          8
+#define BTM_BLE_STATE_ACTIVE_SCAN           9
+#define BTM_BLE_STATE_SCAN_ADV              10
+#define BTM_BLE_STATE_MAX                   11
+typedef UINT8 tBTM_BLE_STATE;
+
+#define BTM_BLE_STATE_CONN_ADV_BIT          0x0001
+#define BTM_BLE_STATE_INIT_BIT              0x0002
+#define BTM_BLE_STATE_MASTER_BIT            0x0004
+#define BTM_BLE_STATE_SLAVE_BIT             0x0008
+#define BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT   0x0010
+#define BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT   0x0020
+#define BTM_BLE_STATE_NON_CONN_ADV_BIT      0x0040
+#define BTM_BLE_STATE_PASSIVE_SCAN_BIT      0x0080
+#define BTM_BLE_STATE_ACTIVE_SCAN_BIT       0x0100
+#define BTM_BLE_STATE_SCAN_ADV_BIT          0x0200
+typedef UINT16 tBTM_BLE_STATE_MASK;
+
+#define BTM_BLE_STATE_ALL_MASK              0x03ff
+#define BTM_BLE_STATE_ALL_ADV_MASK          (BTM_BLE_STATE_CONN_ADV_BIT|BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT|BTM_BLE_STATE_SCAN_ADV_BIT)
+#define BTM_BLE_STATE_ALL_SCAN_MASK         (BTM_BLE_STATE_PASSIVE_SCAN_BIT|BTM_BLE_STATE_ACTIVE_SCAN_BIT)
+#define BTM_BLE_STATE_ALL_CONN_MASK         (BTM_BLE_STATE_MASTER_BIT|BTM_BLE_STATE_SLAVE_BIT)
 
 typedef struct
 {
@@ -210,11 +256,18 @@ typedef struct
 */
 typedef struct
 {
+    UINT8            scan_activity;         /* LE scan activity mask */
+
     /*****************************************************
     **      BLE Inquiry
     *****************************************************/
     tBTM_BLE_INQ_CB     inq_var;
 
+    /* observer callback and timer */
+    tBTM_INQ_RESULTS_CB *p_obs_results_cb;
+    tBTM_CMPL_CB        *p_obs_cmpl_cb;
+    TIMER_LIST_ENT      obs_timer_ent;
+
     /* background connection procedure cb value */
     tBTM_BLE_CONN_TYPE  bg_conn_type;
     UINT16              scan_int;
@@ -236,12 +289,18 @@ typedef struct
     tBTM_LE_RANDOM_CB   addr_mgnt_cb;
 
     BOOLEAN          enabled;
+#if BLE_PRIVACY_SPT == TRUE
+        BOOLEAN          privacy;               /* privacy enabled or disabled */
+#endif
     tBTM_BLE_WL_OP  wl_op_q[BTM_BLE_MAX_BG_CONN_DEV_NUM];
 
 #ifdef BTM_BLE_PC_ADV_TEST_MODE
     tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback;
 #endif
 
+    /* current BLE link state */
+    tBTM_BLE_STATE_MASK           cur_states;  /* bit mask of tBTM_BLE_STATE */
+
 } tBTM_BLE_CB;
 
 #ifdef __cplusplus
@@ -259,15 +318,20 @@ extern tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode);
 extern tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8   duration);
 extern void btm_ble_dir_adv_tout(void);
 
-extern void btm_ble_stop_scan(void);
-extern void btm_ble_att_db_init(void);
+extern void btm_ble_stop_scan();
+extern void btm_ble_stop_inquiry(void);
 extern void btm_ble_init (void);
 extern void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, tBLE_ADDR_TYPE addr_type, BOOLEAN addr_matched);
 extern void btm_ble_read_remote_features_complete(UINT8 *p);
 extern void btm_ble_write_adv_enable_complete(UINT8 * p);
 extern void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len);
+extern void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len);
 extern tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
 extern void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st);
+extern tBTM_STATUS btm_ble_start_adv(void);
+extern tBTM_STATUS btm_ble_stop_adv(void);
+extern tBTM_STATUS btm_ble_start_scan (UINT8 filter_enb);
+
 
 
 /* LE security function from btm_sec.c */
@@ -277,7 +341,7 @@ extern void btm_ble_ltk_request_reply(BD_ADDR bda,  BOOLEAN use_stk, BT_OCTET16
 extern UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data);
 extern tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 link_role);
 extern void btm_ble_ltk_request(UINT16 handle, UINT8 rand[8], UINT16 ediv);
-extern BOOLEAN btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk);
+extern tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk);
 extern void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable);
 #endif
 
@@ -312,6 +376,7 @@ extern BOOLEAN btm_ble_renew_bg_conn_params(BOOLEAN add, BD_ADDR bd_addr);
 extern UINT8 btm_ble_count_unconn_dev_in_whitelist(void);
 extern void btm_write_dir_conn_wl(BD_ADDR target_addr);
 extern void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bda, BOOLEAN conn_ccancel);
+extern BOOLEAN btm_execute_wl_dev_operation(void);
 
 /* direct connection utility */
 extern BOOLEAN btm_send_pending_direct_conn(void);
@@ -322,6 +387,9 @@ extern void btm_gen_resolvable_private_addr (void);
 extern void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p);
 extern void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p);
 extern void btm_ble_update_reconnect_address(BD_ADDR bd_addr);
+extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
+extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
+extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
 
 #if BTM_BLE_CONFORMANCE_TESTING == TRUE
 BT_API extern void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc);
index 0dd534c..fbf4df1 100644 (file)
@@ -64,6 +64,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
     int               i, j;
     BOOLEAN           found = FALSE;
 
+    BTM_TRACE_API2("%s, link key type:%x", __FUNCTION__,key_type);
     p_dev_rec = btm_find_dev (bd_addr);
     if (!p_dev_rec)
     {
@@ -79,7 +80,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
                 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
                 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
                 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
-                p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+                p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
 
 #if BLE_INCLUDED == TRUE
                 /* use default value for background connection params */
@@ -172,7 +173,7 @@ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr)
 {
     tBTM_SEC_DEV_REC  *p_dev_rec;
 
-    if (BTM_IsAclConnectionUp(bd_addr))
+    if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR))
     {
         BTM_TRACE_WARNING0("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active");
         return(FALSE);
@@ -215,9 +216,9 @@ char *BTM_SecReadDevName (BD_ADDR bd_addr)
 ** Function         btm_sec_alloc_dev
 **
 ** Description      Look for the record in the device database for the record
-**                  with specified handle
+**                  with specified address
 **
-** Returns          Pointer to the record
+** Returns          Pointer to the record or NULL
 **
 *******************************************************************************/
 tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
@@ -278,7 +279,10 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
 
     memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
 
-    p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr);
+#if BLE_INCLUDED == TRUE
+    p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
+#endif
+    p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
     p_dev_rec->timestamp = btm_cb.dev_rec_count++;
 
     return(p_dev_rec);
@@ -376,7 +380,11 @@ tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
     {
         if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
-            && (p_dev_rec->hci_handle == handle))
+            && ((p_dev_rec->hci_handle == handle)
+#if BLE_INCLUDED == TRUE
+            ||(p_dev_rec->ble_hci_handle == handle)
+#endif
+                ))
             return(p_dev_rec);
     }
     return(NULL);
@@ -440,7 +448,7 @@ tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr)
 **                  the oldest non-paired device.  If all devices are paired it
 **                  deletes the oldest paired device.
 **
-** Returns          Pointer to the record
+** Returns          Pointer to the record or NULL
 **
 *******************************************************************************/
 tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
@@ -454,7 +462,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
     {
         if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0)
-            || ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) != 0))
+            || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) != 0))
             continue; /* Device is paired so skip it */
 
         if (p_dev_rec->timestamp < ot)
index 240bd2f..8117c45 100644 (file)
@@ -483,6 +483,25 @@ static void btm_read_ble_local_supported_features(void)
     /* Send a Read Local Supported Features message to the Host Controller. */
     btsnd_hcic_ble_read_local_spt_feat ();
 }
+
+/*******************************************************************************
+**
+** Function         btm_read_ble_local_supported_states
+**
+** Description      Local function called to send a read BLE local supported
+**                  features command
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btm_read_ble_local_supported_states(void)
+{
+    BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states ");
+    btu_start_timer (&btm_cb.devcb.reset_timer, BTU_TTYPE_BTM_DEV_CTL, BTM_DEV_REPLY_TIMEOUT);
+
+    /* Send a Read Local Supported states message to the Host Controller. */
+    btsnd_hcic_ble_read_supported_states ();
+}
 #endif
 /*******************************************************************************
 **
@@ -808,6 +827,36 @@ void btm_read_ble_buf_size_complete (UINT8 *p, UINT16 evt_len)
 
         l2c_link_processs_ble_num_bufs (lm_num_le_bufs);
     }
+    btm_read_ble_local_supported_states();
+}
+/*******************************************************************************
+**
+** Function         btm_read_ble_local_supported_states_complete
+**
+** Description      This function is called when command complete for
+**                  Read LE Local Supported states complete is received.
+**
+** Returns          void
+**
+*******************************************************************************/
+void btm_read_ble_local_supported_states_complete (UINT8 *p, UINT16 evt_len)
+{
+    UINT8       status;
+
+    UNUSED(evt_len);
+    BTM_TRACE_DEBUG0("btm_read_ble_local_supported_states_complete ");
+
+    btu_stop_timer (&btm_cb.devcb.reset_timer);
+
+    STREAM_TO_UINT8  (status, p);
+    if (status == HCI_SUCCESS)
+    {
+        STREAM_TO_ARRAY(&btm_cb.devcb.le_supported_states, p, BTM_LE_SUPPORT_STATE_SIZE);
+    }
+    else
+    {
+        BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status);
+    }
 
     btm_read_ble_local_supported_features();
 }
@@ -842,6 +891,8 @@ void btm_read_ble_local_supported_features_complete (UINT8 *p, UINT16 evt_len)
         BTM_TRACE_WARNING1 ("btm_read_ble_local_supported_features_complete status = %d", status);
     }
 
+    btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF);
+
 #if BTM_INTERNAL_BB == TRUE
     {
         UINT8 buf[9] = BTM_INTERNAL_LOCAL_FEA;
@@ -874,6 +925,8 @@ void btm_read_white_list_size_complete(UINT8 *p, UINT16 evt_len)
         STREAM_TO_UINT8(btm_cb.ble_ctr_cb.max_filter_entries, p);
         btm_cb.ble_ctr_cb.num_empty_filter = btm_cb.ble_ctr_cb.max_filter_entries;
     }
+    /* write LE host support and simultatunous LE supported */
+    btsnd_hcic_ble_write_host_supported(BTM_BLE_HOST_SUPPORT, BTM_BLE_SIMULTANEOUS_HOST);
 
     btm_get_ble_buffer_size();
 }
index 24f91a8..01cbd56 100644 (file)
@@ -796,10 +796,10 @@ tBTM_STATUS BTM_CancelInquiry(void)
 #if BLE_INCLUDED == TRUE
             if (((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
 #if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
-            &&(active_mode & BTM_LE_INQ_ACTIVE_MASK)
+            &&(active_mode & BTM_BLE_INQ_ACTIVE_MASK)
 #endif
             )
-                btm_ble_stop_scan();
+                btm_ble_stop_inquiry();
 #endif
         }
 
@@ -869,7 +869,6 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p
             p_inq->scan_type = INQ_GENERAL;
             p_inq->inq_active = BTM_INQUIRY_INACTIVE;
             btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
-            btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
             btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
         }
         else
@@ -1080,7 +1079,8 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, tBTM_INQ_RESULTS_CB *p
 **                  BTM_WRONG_MODE if the device is not up.
 **
 *******************************************************************************/
-tBTM_STATUS  BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
+tBTM_STATUS  BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
+                                                ,tBT_TRANSPORT transport)
 {
     tBTM_INQ_INFO   *p_cur = NULL;
     tINQ_DB_ENT     *p_i;
@@ -1101,7 +1101,7 @@ tBTM_STATUS  BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb)
     BTM_TRACE_API0 ("no device found in inquiry db");
 
 #if (BLE_INCLUDED == TRUE)
-    if (BTM_UseLeLink(remote_bda))
+    if (transport == BT_TRANSPORT_LE)
     {
         return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
     }
@@ -2266,7 +2266,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
 
 #if BLE_INCLUDED == TRUE
                 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
-                    btm_ble_stop_scan();
+                    btm_ble_stop_inquiry();
 #endif
 
 
@@ -2493,14 +2493,13 @@ void btm_process_inq_complete (UINT8 status, UINT8 mode)
                 (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
         }
 #if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
-            if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
-            {
-                /* make inquiry inactive for next iteration */
-                p_inq->inq_active = BTM_INQUIRY_INACTIVE;
-                /* call the inquiry again */
-                BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
-                return;
-            }
+        if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
+        {
+            /* make inquiry inactive for next iteration */
+            p_inq->inq_active = BTM_INQUIRY_INACTIVE;
+            /* call the inquiry again */
+            BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
+        }
 #endif
     }
     if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete
@@ -3422,9 +3421,6 @@ void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results )
                 BTM_AddEirService( p_results->eir_uuid, uuid16 );
         }
     }
-
-    BTM_TRACE_DEBUG2("btm_set_eir_uuid eir_uuid=0x%08X %08X",
-                     p_results->eir_uuid[1], p_results->eir_uuid[0] );
 }
 #endif
 
index 7865b3e..913e253 100644 (file)
@@ -46,7 +46,7 @@
 typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1];
 #endif
 
-#define  BTM_ACL_IS_CONNECTED(bda)   (btm_bda_to_acl (bda) != NULL)
+#define  BTM_ACL_IS_CONNECTED(bda)   (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL)
 
 /* Definitions for Server Channel Number (SCN) management
 */
@@ -119,8 +119,9 @@ typedef struct
 #if BTM_PWR_MGR_INCLUDED == FALSE
     UINT8           mode;
 #endif /* BTM_PWR_MGR_INCLUDED */
+
 #if BLE_INCLUDED == TRUE
-    UINT8           is_le_link;
+    tBT_TRANSPORT   transport;
     BD_ADDR         conn_addr;              /* local device address used for this connection */
     UINT8           conn_addr_type;         /* local device address type for this connection */
     BD_ADDR         active_remote_addr;     /* remote address used on this connection */
@@ -189,24 +190,29 @@ typedef struct
     BD_FEATURES          local_lmp_features[HCI_EXT_FEATURES_PAGE_MAX + 1];
 
 #if BLE_INCLUDED == TRUE
+
+    tBTM_CMPL_CB        *p_le_test_cmd_cmpl_cb;   /* Callback function to be called when
+                                                  LE test mode command has been sent successfully */
+
     BD_ADDR                 read_tx_pwr_addr;   /* read TX power target address     */
     BD_FEATURES             local_le_features;  /* Local LE Supported features mask for the device */
 
     tBTM_BLE_LOCAL_ID_KEYS  id_keys;        /* local BLE ID keys                    */
     BT_OCTET16              er;             /* BLE encryption key                   */
 
+#define BTM_LE_SUPPORT_STATE_SIZE   8
+UINT8                   le_supported_states[BTM_LE_SUPPORT_STATE_SIZE];
+
+
+
 #if BTM_BLE_CONFORMANCE_TESTING == TRUE
     BOOLEAN                 no_disc_if_pair_fail;
-    BOOLEAN                            enable_test_mac_val;
+    BOOLEAN                 enable_test_mac_val;
     BT_OCTET8               test_mac;
-    BOOLEAN                            enable_test_local_sign_cntr;
-    UINT32                             test_local_sign_cntr;
+    BOOLEAN                 enable_test_local_sign_cntr;
+    UINT32                  test_local_sign_cntr;
 #endif
 
-#if BLE_INCLUDED == TRUE
-    tBTM_CMPL_CB        *p_le_test_cmd_cmpl_cb;   /* Callback function to be called when
-                                                  LE test mode command has been sent successfully */
-#endif
 
 #endif  /* BLE_INCLUDED */
 
@@ -218,6 +224,7 @@ typedef struct
     tBTM_IO_CAP          loc_io_caps;       /* IO capability of the local device */
     BOOLEAN              loc_auth_req;      /* the auth_req flag  */
     BD_FEATURES          brcm_features;     /* Broadcom specific features bit mask  */
+#define BTM_RELOAD_LE_HOST_FEATURE      0x10
 
 #define BTM_RE_READ_1ST_PAGE            0x01            /* Set it if you set at least one of "..._HOST_MAY_SUPP_..." bits */
 #define BTM_HOST_MAY_SUPP_SSP           0x02
@@ -504,12 +511,13 @@ typedef struct
     tBLE_ADDR_TYPE      ble_addr_type;  /* LE device type: public or random address */
     tBLE_ADDR_TYPE      static_addr_type;   /* static address type */
     BD_ADDR             static_addr;    /* static address */
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
     BD_ADDR             cur_rand_addr;  /* current random address */
 
 #define BTM_BLE_ADDR_PSEUDO         0   /* address index device record */
 #define BTM_BLE_ADDR_RRA            1   /* cur_rand_addr */
 #define BTM_BLE_ADDR_STATIC         2   /* static_addr  */
+
     UINT8               active_addr_type;
 #endif
 
@@ -519,6 +527,7 @@ typedef struct
 #endif
 } tBTM_SEC_BLE;
 
+
 #endif  /* BLE_INCLUDED */
 
 /*
@@ -546,8 +555,14 @@ typedef struct
 #define BTM_SEC_LINK_KEY_AUTHED 0x20
 #define BTM_SEC_ROLE_SWITCHED   0x40
 #define BTM_SEC_IN_USE          0x80
+    /* LE link security flag */
+#define BTM_SEC_LE_AUTHENTICATED   0x0200       /* 0x0200 */
+#define BTM_SEC_LE_ENCRYPTED       0x0400      /* 0x04 */
+#define BTM_SEC_LE_NAME_KNOWN      0x0800
+#define BTM_SEC_LE_LINK_KEY_KNOWN  0x1000       /* 0x10 */
+#define BTM_SEC_LE_LINK_KEY_AUTHED 0x2000
 
-    UINT8           sec_flags;          /* Current device security state      */
+    UINT16           sec_flags;          /* Current device security state      */
 
     tBTM_BD_NAME    sec_bd_name;        /* User friendly name of the device. (may be truncated to save space in dev_rec table) */
     BD_FEATURES     features[HCI_EXT_FEATURES_PAGE_MAX + 1];           /* Features supported by the device */
@@ -589,6 +604,7 @@ typedef struct
     BOOLEAN     rmt_auth_req;           /* the auth_req flag as in the IO caps rsp evt */
 
 #if (BLE_INCLUDED == TRUE)
+    UINT16              ble_hci_handle;         /* use in DUMO connection */
     UINT8               enc_key_size;           /* current link encryption key size */
     tBTM_SEC_BLE        ble;
     tBT_DEVICE_TYPE     device_type;
@@ -612,6 +628,7 @@ typedef struct
 #define BTM_SEC_IS_SM4_LEGACY(sm) ((BOOLEAN)(BTM_SM4_KNOWN == ((sm)&BTM_SM4_TRUE)))
 #define BTM_SEC_IS_SM4_UNKNOWN(sm) ((BOOLEAN)(BTM_SM4_UNKNOWN == ((sm)&BTM_SM4_TRUE)))
 
+#define BTM_SEC_LE_MASK    (BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED|BTM_SEC_LE_LINK_KEY_KNOWN|BTM_SEC_LE_LINK_KEY_AUTHED)
 
 /*
 ** Define device configuration structure
@@ -726,11 +743,13 @@ typedef UINT8 tBTM_PAIRING_STATE;
 
 #define BTM_PAIR_FLAGS_WE_STARTED_DD    0x01    /* We want to do dedicated bonding              */
 #define BTM_PAIR_FLAGS_PEER_STARTED_DD  0x02    /* Peer initiated dedicated bonding             */
-#define BTM_PAIR_FLAGS_DISC_WHEN_DONE   0x04
+#define BTM_PAIR_FLAGS_DISC_WHEN_DONE   0x04    /* Disconnect when done     */
 #define BTM_PAIR_FLAGS_PIN_REQD         0x08    /* set this bit when pin_callback is called     */
 #define BTM_PAIR_FLAGS_PRE_FETCH_PIN    0x10    /* set this bit when pre-fetch pin     */
 #define BTM_PAIR_FLAGS_REJECTED_CONNECT 0x20    /* set this bit when rejected incoming connection  */
 #define BTM_PAIR_FLAGS_WE_CANCEL_DD     0x40    /* set this bit when cancelling a bonding procedure */
+#define BTM_PAIR_FLAGS_LE_ACTIVE        0x80    /* use this bit when SMP pairing is active */
+
 
 typedef struct
 {
@@ -975,8 +994,8 @@ extern BOOLEAN btm_lookup_eir(BD_ADDR_PTR p_rem_addr);
 extern void         btm_acl_init (void);
 extern void         btm_acl_timeout (TIMER_LIST_ENT  *p_tle);
 extern void         btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
-                                     UINT16 hci_handle, UINT8 link_role, UINT8 is_le_link);
-extern void         btm_acl_removed (BD_ADDR bda);
+                                     UINT16 hci_handle, UINT8 link_role, tBT_TRANSPORT transport);
+extern void         btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport);
 extern void         btm_acl_device_down (void);
 extern void         btm_acl_update_busy_level (tBTM_BLI_EVENT event);
 extern void         btm_acl_link_key_change (UINT16 handle, UINT8 status);
@@ -995,7 +1014,7 @@ extern void         btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 cloc
 extern void         btm_acl_role_changed (UINT8 hci_status, BD_ADDR bd_addr, UINT8 new_role);
 extern void         btm_acl_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable);
 BTM_API extern UINT16       btm_get_acl_disc_reason_code (void);
-BTM_API extern tBTM_STATUS  btm_remove_acl (BD_ADDR bd_addr);
+BTM_API extern tBTM_STATUS  btm_remove_acl (BD_ADDR bd_addr, tBT_TRANSPORT transport);
 extern void         btm_read_remote_features_complete (UINT8 *p);
 extern void         btm_read_remote_ext_features_complete (UINT8 *p);
 extern void         btm_read_remote_ext_features_failed (UINT8 status, UINT16 handle);
@@ -1005,7 +1024,7 @@ extern void         btm_acl_chk_peer_pkt_type_support (tACL_CONN *p, UINT16 *p_p
 // btla-specific --
 /* Read maximum data packet that can be sent over current connection */
 extern UINT16 btm_get_max_packet_size (BD_ADDR addr);
-extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda);
+extern tACL_CONN *btm_bda_to_acl (BD_ADDR bda, tBT_TRANSPORT transport);
 extern BOOLEAN    btm_acl_notif_conn_collision (BD_ADDR bda);
 
 #if BTM_PWR_MGR_INCLUDED == FALSE
@@ -1139,7 +1158,7 @@ extern void  btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UIN
 extern void  btm_sec_link_key_request (UINT8 *p_bda);
 extern void  btm_sec_pin_code_request (UINT8 *p_bda);
 extern void  btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset);
-extern void  btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res);
+extern void  btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_trasnport);
 
 #if BLE_INCLUDED == TRUE
 extern void  btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC  *p_dev_rec);
index 02e3a6a..711a69b 100644 (file)
@@ -420,7 +420,11 @@ static int btm_pm_find_acl_ind(BD_ADDR remote_bda)
 
     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p++)
     {
-        if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN)))
+        if ((p->in_use) && (!memcmp (p->remote_addr, remote_bda, BD_ADDR_LEN))
+#if (BLE_INCLUDED == TRUE)
+            && p->transport == BT_TRANSPORT_BR_EDR
+#endif
+            )
         {
 #if BTM_PM_DEBUG == TRUE
             BTM_TRACE_DEBUG2( "btm_pm_find_acl_ind ind:%d, st:%d", xx, btm_cb.pm_mode_db[xx].state);
@@ -848,15 +852,17 @@ void btm_pm_proc_mode_change (UINT8 hci_status, UINT16 hci_handle, UINT8 mode, U
     BTM_TRACE_DEBUG2( "btm_pm_proc_mode_change new state:0x%x (old:0x%x)", p_cb->state, old_state);
 #endif
 
-    if ((p_cb->state == HCI_MODE_ACTIVE) &&
-        ((p_lcb = l2cu_find_lcb_by_bd_addr (p->remote_addr)) != NULL))
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr(p->remote_addr, BT_TRANSPORT_BR_EDR)) != NULL)
     {
-        /* There might be any pending packets due to SNIFF or PENDING state */
-        /* Trigger L2C to start transmission of the pending packets.        */
-        BTM_TRACE_DEBUG0 ("btm mode change to active; check l2c_link for outgoing packets");
-        l2c_link_check_send_pkts (p_lcb, NULL, NULL);
+        if ((p_cb->state == BTM_PM_ST_ACTIVE) || (p_cb->state == BTM_PM_ST_SNIFF))
+        {
+            /* There might be any pending packets due to SNIFF or PENDING state */
+            /* Trigger L2C to start transmission of the pending packets. */
+            BTM_TRACE_DEBUG0("btm mode change to active; check l2c_link for outgoing packets");
+            l2c_link_check_send_pkts(p_lcb, NULL, NULL);
 
         //btu_stop_timer (&p_lcb->timer_entry);
+        }
     }
 
     /* notify registered parties */
@@ -955,7 +961,9 @@ void btm_pm_proc_ssr_evt (UINT8 *p, UINT16 evt_len)
         }
     }
 }
+
 #endif
+
 #else /* BTM_PWR_MGR_INCLUDED == TRUE */
 
 /*******************************************************************************
@@ -984,6 +992,7 @@ tBTM_STATUS BTM_ReadPowerMode (BD_ADDR remote_bda, tBTM_PM_MODE *p_mode)
 
 #endif
 
+
 /*******************************************************************************
 **
 ** Function         BTM_IsPowerManagerOn
@@ -998,3 +1007,5 @@ BOOLEAN BTM_IsPowerManagerOn (void)
 {
     return BTM_PWR_MGR_INCLUDED;
 }
+
+
index 2200b71..1ef3827 100644 (file)
@@ -582,7 +582,7 @@ tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types
     /* If originating, ensure that there is an ACL connection to the BD Address */
     if (is_orig)
     {
-        if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF))
+        if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF))
             return (BTM_UNKNOWN_ADDR);
     }
 
@@ -682,7 +682,7 @@ tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types
                 {
                     /* If role change is in progress, do not proceed with SCO setup
                      * Wait till role change is complete */
-                    p_acl = btm_bda_to_acl(remote_bda);
+                    p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
                     if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
                     {
                         BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle);
@@ -740,7 +740,7 @@ void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
     {
         if ((p->state == SCO_ST_PEND_UNPARK) &&
-            ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
+            ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
 
         {
             BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
@@ -774,7 +774,7 @@ void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
     {
         if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
-            ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
+            ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
 
         {
             BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
index 09f41b7..625297c 100644 (file)
@@ -80,13 +80,19 @@ static BOOLEAN  btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC  *p_dev_rec);
 static UINT8    btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec);
 BOOLEAN         btm_sec_are_all_trusted(UINT32 p_mask[]);
 
-static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason);
+static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle);
+UINT8           btm_sec_start_role_switch (tBTM_SEC_DEV_REC *p_dev_rec);
 tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state);
 
 static BOOLEAN  btm_sec_set_security_level ( CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
                                             UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
                                             UINT32 mx_chan_id);
 
+static BOOLEAN btm_dev_authenticated(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_dev_encrypted(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_dev_authorized(tBTM_SEC_DEV_REC *p_dev_rec);
+static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec);
+
 /* TRUE - authenticated link key is possible */
 static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] =
 {
@@ -103,6 +109,78 @@ static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] =
 
 /*******************************************************************************
 **
+** Function         btm_dev_authenticated
+**
+** Description      check device is authenticated
+**
+** Returns          BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+    if(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)
+    {
+        return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         btm_dev_encrypted
+**
+** Description      check device is encrypted
+**
+** Returns          BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_encrypted (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+    if(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
+    {
+        return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         btm_dev_authorized
+**
+** Description      check device is authorized
+**
+** Returns          BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_dev_authorized (tBTM_SEC_DEV_REC *p_dev_rec)
+{
+    if(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED)
+    {
+        return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         btm_serv_trusted
+**
+** Description      check service is trusted
+**
+** Returns          BOOLEAN TRUE or FALSE
+**
+*******************************************************************************/
+static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec)
+{
+    if(BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask, p_serv_rec->service_id))
+    {
+        return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*******************************************************************************
+**
 ** Function         BTM_SecRegister
 **
 ** Description      Application manager calls this function to register for
@@ -121,28 +199,29 @@ BOOLEAN  BTM_SecRegister (tBTM_APPL_INFO *p_cb_info)
     BTM_TRACE_EVENT0 ("BTM_Sec: application registered");
 
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
-
     if (p_cb_info->p_le_callback)
     {
-#if SMP_INCLUDED == TRUE
-        BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
-        SMP_Register(btm_proc_smp_cback);
-#endif
-        /* if no IR is loaded, need to regenerate all the keys */
-        if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
+        BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
+
+        if (p_cb_info->p_le_callback)
         {
-            btm_ble_reset_id();
+    #if SMP_INCLUDED == TRUE
+            BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
+            SMP_Register(btm_proc_smp_cback);
+    #endif
+            /* if no IR is loaded, need to regenerate all the keys */
+            if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
+            {
+                btm_ble_reset_id();
+            }
+        }
+        else
+        {
+            BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
         }
-    }
-    else
-    {
-        BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
     }
 #endif
 
-
-
     btm_cb.api = *p_cb_info;
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
      BTM_TRACE_ERROR1 ("BTM_SecRegister: btm_cb.api.p_le_callback = 0x%x ", btm_cb.api.p_le_callback);
@@ -270,7 +349,34 @@ BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 * p_sec_flags)
 
     if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
     {
-        *p_sec_flags = p_dev_rec->sec_flags;
+        *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
+        return(TRUE);
+    }
+    BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false");
+    return(FALSE);
+}
+
+/*******************************************************************************
+**
+** Function         BTM_GetSecurityFlagsByTransport
+**
+** Description      Get security flags for the device on a particular transport
+**
+** Returns          BOOLEAN TRUE or FALSE is device found
+**
+*******************************************************************************/
+BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 * p_sec_flags,
+                                                tBT_TRANSPORT transport)
+{
+    tBTM_SEC_DEV_REC *p_dev_rec;
+
+    if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
+    {
+        if (transport == BT_TRANSPORT_BR_EDR)
+            *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
+        else
+            *p_sec_flags = (UINT8) (p_dev_rec->sec_flags >> 8);
+
         return(TRUE);
     }
     BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false");
@@ -958,7 +1064,8 @@ void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin,
             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
             p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
 
-            (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
+            if (btm_cb.api.p_auth_complete_callback)
+                (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
                                                     p_dev_rec->sec_bd_name, HCI_ERR_AUTH_FAILURE);
         }
         return;
@@ -1028,25 +1135,21 @@ void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[])
 
     if (res != BTM_SUCCESS)
     {
-        btm_sec_dev_rec_cback_event (p_dev_rec, res);
+        btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
         return;
     }
 
     if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
     {
-        btm_sec_dev_rec_cback_event (p_dev_rec, res);
+        btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
     }
 }
 
-
-
 /*******************************************************************************
 **
-** Function         BTM_SecBond
+** Function         btm_sec_bond_by_transport
 **
-** Description      This function is called to perform bonding with peer device.
-**                  If the connection is already up, but not secure, pairing
-**                  is attempted.  If already paired BTM_SUCCESS is returned.
+** Description      this is the bond function that will start either SSP or SMP.
 **
 ** Parameters:      bd_addr      - Address of the device to bond
 **                  pin_len      - length in bytes of the PIN Code
@@ -1055,16 +1158,20 @@ void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[])
 **
 **  Note: After 2.1 parameters are not used and preserved here not to change API
 *******************************************************************************/
-tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+                                       UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
 {
     tBTM_SEC_DEV_REC *p_dev_rec;
     tBTM_STATUS      status;
     UINT8            *p_features;
     UINT8            ii;
-
-    BTM_TRACE_API6 ("BTM_SecBond BDA: %02x:%02x:%02x:%02x:%02x:%02x",
+    tACL_CONN        *p= btm_bda_to_acl(bd_addr, transport);
+    BTM_TRACE_API6 ("btm_sec_bond_by_transport BDA: %02x:%02x:%02x:%02x:%02x:%02x",
                     bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
 
+    BTM_TRACE_DEBUG1("btm_sec_bond_by_transport: Transport used %d" , transport);
+
+
     /* Other security process is in progress */
     if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
     {
@@ -1075,13 +1182,19 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr
     if ((p_dev_rec = btm_find_or_alloc_dev (bd_addr)) == NULL)
     {
         return(BTM_NO_RESOURCES);
-        }
+    }
 
     BTM_TRACE_DEBUG1 ("before update sec_flags=0x%x", p_dev_rec->sec_flags);
 
     /* Finished if connection is active and already paired */
-    if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
-         &&  (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) )
+    if ( ((p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_BR_EDR
+         &&  (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
+#if (BLE_INCLUDED == TRUE)
+        ||((p_dev_rec->ble_hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_LE
+         &&  (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED))
+#endif
+
+         )
     {
         BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
         return(BTM_SUCCESS);
@@ -1107,25 +1220,28 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr
     if (trusted_mask)
         BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
 
-    p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
-                                  | BTM_SEC_ROLE_SWITCHED  | BTM_SEC_LINK_KEY_AUTHED);
-
-
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    /* LE device, do SMP pairing */
-    if (BTM_UseLeLink(bd_addr))
+    if (transport == BT_TRANSPORT_LE)
     {
+        p_dev_rec->sec_flags &= ~ BTM_SEC_LE_MASK;
+
         if (SMP_Pair(bd_addr) == SMP_STARTED)
         {
-            btm_cb.pairing_state = BTM_PAIR_STATE_WAIT_AUTH_COMPLETE;
+            btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
             p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+            btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
             return BTM_CMD_STARTED;
         }
-        else
-            return(BTM_NO_RESOURCES);
+
+        btm_cb.pairing_flags = 0;
+        return(BTM_NO_RESOURCES);
     }
 #endif
 
+    p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
+                                  | BTM_SEC_ROLE_SWITCHED  | BTM_SEC_LINK_KEY_AUTHED);
+
+
     BTM_TRACE_DEBUG1 ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
     if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
     {
@@ -1157,7 +1273,7 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr
 #endif
 
     /* If connection already exists... */
-    if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
+    if (p && p->hci_handle != BTM_SEC_INVALID_HANDLE)
     {
         if (!btm_sec_start_authentication (p_dev_rec))
             return(BTM_NO_RESOURCES);
@@ -1185,14 +1301,15 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr
              * -> RNR (to learn if peer is 2.1)
              * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
             btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
-            BTM_ReadRemoteDeviceName(bd_addr, NULL);
+            BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR);
         }
         else
         {
             /* We are accepting connection request from peer */
             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
         }
-        BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d", btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
+        BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d",
+            btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
         return BTM_CMD_STARTED;
     }
 
@@ -1207,23 +1324,78 @@ tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 tr
     return status;
 }
 
+/*******************************************************************************
+**
+** Function         BTM_SecBondByTransport
+**
+** Description      This function is called to perform bonding with peer device.
+**                  If the connection is already up, but not secure, pairing
+**                  is attempted.  If already paired BTM_SUCCESS is returned.
+**
+** Parameters:      bd_addr      - Address of the device to bond
+**                  transport    - doing SSP over BR/EDR or SMP over LE
+**                  pin_len      - length in bytes of the PIN Code
+**                  p_pin        - pointer to array with the PIN Code
+**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
+**  Note: After 2.1 parameters are not used and preserved here not to change API
+*******************************************************************************/
+tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+                                    UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+{
+#if SMP_INCLUDED == TRUE
+    tBT_DEVICE_TYPE     dev_type;
+    tBLE_ADDR_TYPE      addr_type;
+
+    BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
+    /* LE device, do SMP pairing */
+    if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) ||
+        (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0))
+    {
+        return BTM_ILLEGAL_ACTION;
+    }
+#endif
+    return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
+}
 
 /*******************************************************************************
 **
+** Function         BTM_SecBond
+**
+** Description      This function is called to perform bonding with peer device.
+**                  If the connection is already up, but not secure, pairing
+**                  is attempted.  If already paired BTM_SUCCESS is returned.
+**
+** Parameters:      bd_addr      - Address of the device to bond
+**                  pin_len      - length in bytes of the PIN Code
+**                  p_pin        - pointer to array with the PIN Code
+**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
+**  Note: After 2.1 parameters are not used and preserved here not to change API
+*******************************************************************************/
+tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
+{
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
+#if BLE_INCLUDED == TRUE
+    if (BTM_UseLeLink(bd_addr))
+        transport = BT_TRANSPORT_LE;
+#endif
+    return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
+}
+/*******************************************************************************
+**
 ** Function         BTM_SecBondCancel
 **
 ** Description      This function is called to cancel ongoing bonding process
 **                  with peer device.
 **
 ** Parameters:      bd_addr      - Address of the peer device
+**                         transport    - FALSE for BR/EDR link; TRUE for LE link
 **
 *******************************************************************************/
 tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
 {
     tBTM_SEC_DEV_REC *p_dev_rec;
-#if SMP_INCLUDED == TRUE
-    tACL_CONN   *p=NULL;
-#endif
 
     BTM_TRACE_API2 ("BTM_SecBondCancel()  State: %s flags:0x%x",
                     btm_pair_state_descr (btm_cb.pairing_state), btm_cb.pairing_flags);
@@ -1233,19 +1405,17 @@ tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
         return BTM_UNKNOWN_ADDR;
 
 #if SMP_INCLUDED == TRUE
-    p = btm_bda_to_acl(bd_addr);
-    if (p && p->is_le_link &&
-        (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING))
+    if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE)
     {
-        BTM_TRACE_DEBUG0 ("Cancel LE pairing");
-        if (SMP_PairCancel(bd_addr))
+        if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
         {
-            return BTM_CMD_STARTED;
-        }
-        else
-        {
-            return BTM_WRONG_MODE;
+            BTM_TRACE_DEBUG0 ("Cancel LE pairing");
+            if (SMP_PairCancel(bd_addr))
+            {
+                return BTM_CMD_STARTED;
+            }
         }
+        return BTM_WRONG_MODE;
     }
 
 #endif
@@ -1271,7 +1441,7 @@ tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
 
             /* If the HCI link was set up by Bonding process */
             if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
-                return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER);
+                return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
             else
                 l2cu_update_lcb_4_bonding(bd_addr, FALSE);
 
@@ -1375,6 +1545,8 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
 **                  p_ref_data    - pointer to any data the caller wishes to receive
 **                                  in the callback function upon completion.
 *                                   can be set to NULL if not used.
+**                  transport  -    TRUE to encryption the link over LE trasnport
+**                                  or FALSE for BR/EDR trasnport
 **
 ** Returns          BTM_SUCCESS   - already encrypted
 **                  BTM_PENDING   - command will be returned in the callback
@@ -1383,41 +1555,45 @@ tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
 **                  BTM_MODE_UNSUPPORTED - if security manager not linked in.
 **
 *******************************************************************************/
-tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
+tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SEC_CBACK *p_callback,
                                void *p_ref_data)
 {
     tBTM_SEC_DEV_REC  *p_dev_rec;
     tBTM_STATUS       rc;
-
 #if BLE_INCLUDED == TRUE
-    tACL_CONN         *p;
-    p = btm_bda_to_acl(bd_addr);
+   tACL_CONN         *p = btm_bda_to_acl(bd_addr, transport);
 #endif
 
     p_dev_rec = btm_find_dev (bd_addr);
-    if (!p_dev_rec || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE))
+
+    if (!p_dev_rec ||
+        (transport == BT_TRANSPORT_BR_EDR && p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
+#if BLE_INCLUDED == TRUE
+        || (transport == BT_TRANSPORT_LE && p_dev_rec->ble_hci_handle == BTM_SEC_INVALID_HANDLE)
+#endif
+        )
     {
         /* Connection should be up and runnning */
         BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption not connected");
 
         if (p_callback)
-            (*p_callback) (bd_addr, p_ref_data, BTM_WRONG_MODE);
+            (*p_callback) (bd_addr, transport, p_ref_data, BTM_WRONG_MODE);
 
         return(BTM_WRONG_MODE);
     }
 
-
-    if (
-#if BLE_INCLUDED == TRUE
-       !p->is_le_link &&
+    if ((transport == BT_TRANSPORT_BR_EDR &&
+         (p_dev_rec->sec_flags &  BTM_SEC_ENCRYPTED))
+#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
+         || (transport == BT_TRANSPORT_LE &&
+           (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED))
 #endif
-       (p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
-       == (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
+          )
     {
         BTM_TRACE_EVENT0 ("Security Manager: BTM_SetEncryption already encrypted");
 
         if (p_callback)
-            (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+            (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
         return(BTM_SUCCESS);
     }
@@ -1428,7 +1604,7 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
         BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption busy");
 
         if (p_callback)
-            (*p_callback) (bd_addr, p_ref_data, BTM_BUSY);
+            (*p_callback) (bd_addr, transport, p_ref_data, BTM_BUSY);
 
         return(BTM_BUSY);
     }
@@ -1441,8 +1617,9 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
     BTM_TRACE_API4 ("Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x Required:0x%x",
                     p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags,
                     p_dev_rec->security_required);
+
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    if (p->is_le_link)
+    if (transport == BT_TRANSPORT_LE)
     {
         rc = btm_ble_set_encryption(bd_addr, p_ref_data, p->link_role);
     }
@@ -1451,12 +1628,12 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
 
         rc = btm_sec_execute_procedure (p_dev_rec);
 
-    if ( rc != BTM_CMD_STARTED)
+    if (rc != BTM_CMD_STARTED && rc != BTM_BUSY)
     {
         if (p_callback)
         {
             p_dev_rec->p_callback = NULL;
-            (*p_callback) (bd_addr, p_dev_rec->p_ref_data, rc);
+            (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc);
         }
     }
     return(rc);
@@ -1465,13 +1642,13 @@ tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
 /*******************************************************************************
  * disconnect the ACL link, if it's not done yet.
 *******************************************************************************/
-static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason)
+static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle)
 {
     UINT8       old_state = p_dev_rec->sec_state;
     tBTM_STATUS status = BTM_CMD_STARTED;
 
     BTM_TRACE_EVENT2 ("btm_sec_send_hci_disconnect:  handle:0x%x, reason=0x%x",
-                      p_dev_rec->hci_handle, reason);
+                      conn_handle, reason);
 
     /* if some other thread disconnecting, we do not send second command */
     if (BTM_SEC_STATE_DISCONNECTING != old_state)
@@ -1480,16 +1657,18 @@ static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UIN
 
 #if BTM_DISC_DURING_RS == TRUE
         /* If a Role Switch is in progress, delay the HCI Disconnect to avoid controller problem (4329B1) */
-        if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)
+        if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING &&
+             p_dev_rec->hci_handle == conn_handle)
+
         {
-                 BTM_TRACE_ERROR0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
+                 BTM_TRACE_DEBUG0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
                  p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
                  status = BTM_SUCCESS;
         }
         else
 #endif
         /* Tear down the HCI link */
-        if (!btsnd_hcic_disconnect (p_dev_rec->hci_handle, reason))
+        if (!btsnd_hcic_disconnect (conn_handle, reason))
         {
             /* could not send disconnect. restore old state */
             p_dev_rec->sec_state = old_state;
@@ -1579,7 +1758,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
             btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
 
             if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
-                btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+                btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
             else
                 BTM_SecBondCancel(bd_addr);
 
@@ -1951,9 +2130,17 @@ static BOOLEAN btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC  *p_dev_rec, BOOLEAN
     if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
     {
         is_possible = FALSE;
+        if(p_dev_rec->p_cur_service)
+        {
         BTM_TRACE_DEBUG5 ("btm_sec_is_upgrade_possible id:%d, link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, flags:x%x",
                           p_dev_rec->p_cur_service->service_id, p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps,
                           mtm_check, p_dev_rec->p_cur_service->security_flags);
+        }
+        else
+        {
+            BTM_TRACE_DEBUG3 ("btm_sec_is_upgrade_possible link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, ",
+                          p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check);
+        }
         /* Already have a link key to the connected peer. Is the link key secure enough?
         ** Is a link key upgrade even possible?
         */
@@ -2050,6 +2237,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
     tBTM_STATUS   rc = BTM_SUCCESS;
     BOOLEAN       chk_acp_auth_done = FALSE;
     BOOLEAN is_originator;
+    BOOLEAN     transport = FALSE; /* should check PSM range in LE connection oriented L2CAP connection */
 
 #if (L2CAP_UCD_INCLUDED == TRUE)
     if (conn_type & CONNECTION_TYPE_ORIG_MASK)
@@ -2077,7 +2265,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
     {
         BTM_TRACE_WARNING1 ("btm_sec_l2cap_access_req()  PSM:%d no application registerd", psm);
 
-        (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
+        (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
 
         return(BTM_MODE_UNSUPPORTED);
     }
@@ -2085,7 +2273,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
     /* SDP connection we will always let through */
     if (BT_PSM_SDP == psm)
     {
-        (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS_NO_SECURITY);
+        (*p_callback) (bd_addr,transport, p_ref_data, BTM_SUCCESS_NO_SECURITY);
 
         return(BTM_SUCCESS);
     }
@@ -2119,7 +2307,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
         if (rc == BTM_SUCCESS)
         {
             if (p_callback)
-                (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
+                (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
 
             return(BTM_SUCCESS);
         }
@@ -2148,9 +2336,9 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             if (is_originator)
             {
                 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
-                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
-                    ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
-                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
+                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+                    ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) ||
+                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && btm_dev_authorized(p_dev_rec)  && btm_dev_encrypted(p_dev_rec))) )
                 {
                     rc = BTM_SUCCESS;
                 }
@@ -2158,9 +2346,12 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             else
             {
                 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
-                    ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
-                    ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
-                    ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
+                (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec)) ||
+                (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)) ||
+                (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
+                (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
+                (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_encrypted(p_dev_rec))) ||
+                (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS)  && btm_dev_encrypted(p_dev_rec) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))))
                 {
                     rc = BTM_SUCCESS;
                 }
@@ -2169,7 +2360,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             if (rc == BTM_SUCCESS)
             {
                 if (p_callback)
-                    (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
+                    (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
 
                 return(BTM_SUCCESS);
             }
@@ -2262,7 +2453,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             p_dev_rec->security_required = old_security_required;
             p_dev_rec->is_originator     = old_is_originator;
 
-            (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+            (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
             return(BTM_SUCCESS);
         }
@@ -2277,7 +2468,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
         p_dev_rec->security_required = old_security_required;
         p_dev_rec->is_originator     = old_is_originator;
 
-        (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
+        (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
 
         return(BTM_SUCCESS);
     }
@@ -2299,7 +2490,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
             BTM_TRACE_ERROR0 ("peer should have initiated security process by now (SM4 to SM4)");
             p_dev_rec->p_callback        = p_callback;
             p_dev_rec->sec_state         = BTM_SEC_STATE_DELAY_FOR_ENC;
-            (*p_callback) (bd_addr, p_ref_data, rc);
+            (*p_callback) (bd_addr, transport, p_ref_data, rc);
 
             return(BTM_SUCCESS);
         }
@@ -2330,7 +2521,7 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
     if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
     {
         p_dev_rec->p_callback = NULL;
-        (*p_callback) (bd_addr, p_dev_rec->p_ref_data, (UINT8)rc);
+        (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, (UINT8)rc);
     }
 
     return(rc);
@@ -2368,6 +2559,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
     tBTM_SEC_SERV_REC *p_serv_rec;
     tBTM_STATUS        rc;
     UINT16             security_required;
+    BOOLEAN transport   = FALSE;/* should check PSM range in LE connection oriented L2CAP connection */
 
     BTM_TRACE_DEBUG1 ("btm_sec_mx_access_request is_originator:%d", is_originator);
     /* Find or get oldest record */
@@ -2380,7 +2572,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
     if (!p_serv_rec)
     {
         if (p_callback)
-            (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
+            (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
 
         BTM_TRACE_ERROR3 ("Security Manager: MX service not found PSM:%d Proto:%d SCN:%d",
                           psm, mx_proto_id, mx_chan_id);
@@ -2406,8 +2598,8 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
             if (is_originator)
             {
                 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
-                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
-                    ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
+                    ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+                    ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
                     )
                 {
                     rc = BTM_SUCCESS;
@@ -2416,8 +2608,11 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
             else
             {
                 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
-                    ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
-                    ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
+                    ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
+                    (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
+                    (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
+                    (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))&& btm_dev_encrypted(p_dev_rec))) ||
+                    ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
                     )
                 {
                     rc = BTM_SUCCESS;
@@ -2462,7 +2657,7 @@ tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_o
         {
             p_dev_rec->p_callback = NULL;
 
-            (*p_callback) (bd_addr, p_ref_data, (UINT8)rc);
+            (*p_callback) (bd_addr,transport, p_ref_data, (UINT8)rc);
         }
     }
 
@@ -2666,7 +2861,7 @@ void btm_sec_check_pending_reqs (void)
         while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_dequeue (&bq)) != NULL)
         {
             /* Check that the ACL is still up before starting security procedures */
-            if (btm_bda_to_acl(p_e->bd_addr) != NULL)
+            if (btm_bda_to_acl(p_e->bd_addr, BT_TRANSPORT_BR_EDR) != NULL)
             {
                 BTM_TRACE_EVENT4 ("btm_sec_check_pending_reqs() submitting  PSM: 0x%04x  Is_Orig: %u  mx_proto_id: %u  mx_chan_id: %u",
                                   p_e->psm, p_e->is_orig, p_e->mx_proto_id, p_e->mx_chan_id);
@@ -2747,9 +2942,13 @@ void btm_sec_dev_reset (void)
          * right now. */
         if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
     {
+        btsnd_hcic_write_simple_pairing_mode(HCI_SP_MODE_ENABLED);
 #if BLE_INCLUDED == TRUE
         btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
                                   (UINT8 *)HCI_DUMO_EVENT_MASK_EXT);
+
+        btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF);
+
 #else
         btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
                                   (UINT8 *)HCI_LISBON_EVENT_MASK_EXT);
@@ -2815,7 +3014,7 @@ static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec)
     tL2C_LCB         *p_lcb;
 
     /* Make sure an L2cap link control block is available */
-    if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE)) == NULL)
+    if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         BTM_TRACE_WARNING6 ("Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]",
                             p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
@@ -2827,7 +3026,7 @@ static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec)
     /* set up the control block to indicated dedicated bonding */
     btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
 
-    if (l2cu_create_conn(p_lcb) == FALSE)
+    if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE)
     {
         BTM_TRACE_WARNING6 ("Security Manager: failed create  [%02x%02x%02x%02x%02x%02x]",
                             p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
@@ -2995,23 +3194,29 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
             {
                 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
 
-                (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
-                                                        p_dev_rec->sec_bd_name, status);
+                if (btm_cb.api.p_auth_complete_callback)
+                    (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
+                                                            p_dev_rec->sec_bd_name, status);
                 return;
             }
 
             /* if peer is very old legacy devices, HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is not reported */
             if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
             {
-                /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.
-                 * If it is set, there may be a race condition */
-                               BTM_TRACE_EVENT1 ("btm_sec_rmt_name_request_complete  IS_SM4_UNKNOWN Flags:0x%04x", btm_cb.pairing_flags);
+                /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.*/
+                /* If it is set, there may be a race condition */
+                BTM_TRACE_DEBUG1 ("btm_sec_rmt_name_request_complete  IS_SM4_UNKNOWN Flags:0x%04x",
+                                   btm_cb.pairing_flags);
                 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0)
                 {
                     p_dev_rec->sm4 |= BTM_SM4_KNOWN;
                 }
             }
 
+            BTM_TRACE_DEBUG5("%s, SM4 Value: %x, Legacy:%d,IS SM4:%d, Unknown:%d",__FUNCTION__,
+                p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4),
+                BTM_SEC_IS_SM4(p_dev_rec->sm4),BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4));
+
             /* BT 2.1 or carkit, bring up the connection to force the peer to request PIN.
             ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if needed)
             */
@@ -3030,6 +3235,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
 
                     btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
 
+                    if (btm_cb.api.p_auth_complete_callback)
                     (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
                                                             p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
                 }
@@ -3040,7 +3246,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
         {
             BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: wrong BDA, retry with pairing BDA");
 
-            BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL);
+            BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR);
             return;
         }
     }
@@ -3084,7 +3290,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
     /* If get name failed, notify the waiting layer */
     if (status != HCI_SUCCESS)
     {
-        btm_sec_dev_rec_cback_event  (p_dev_rec, BTM_ERR_PROCESSING);
+        btm_sec_dev_rec_cback_event  (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
         return;
     }
 
@@ -3102,7 +3308,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
         return;
 
     /* There is no next procedure or start of procedure failed, notify the waiting layer */
-    btm_sec_dev_rec_cback_event  (p_dev_rec, status);
+    btm_sec_dev_rec_cback_event  (p_dev_rec, status, FALSE);
 }
 
 /*******************************************************************************
@@ -3592,7 +3798,7 @@ void btm_simple_pair_complete (UINT8 *p)
     if (disc)
     {
         /* simple pairing failed */
-        btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+        btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
     }
 }
 
@@ -3831,7 +4037,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status)
         p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
 
         if (status != HCI_SUCCESS)
-            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER);
+            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
         else
             l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
 
@@ -3871,11 +4077,11 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status)
             }
         }
 
-        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
 
         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
         {
-            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
         }
         return;
     }
@@ -3887,7 +4093,7 @@ void btm_sec_auth_complete (UINT16 handle, UINT8 status)
 
     /* If there is no next procedure, or procedure failed to start, notify the caller */
     if (status != BTM_CMD_STARTED)
-        btm_sec_dev_rec_cback_event (p_dev_rec, status);
+        btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
 }
 
 /*******************************************************************************
@@ -3933,7 +4139,8 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
 {
     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    tACL_CONN         *p_acl;
+    tACL_CONN       *p_acl = NULL;
+    UINT8           acl_idx = btm_handle_to_acl_index(handle);
 #endif
     BTM_TRACE_EVENT3 ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d",
                       status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable);
@@ -3952,19 +4159,30 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
         return;
 
     if ((status == HCI_SUCCESS) && encr_enable)
-        p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+    {
+        if (p_dev_rec->hci_handle == handle)
+            p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+        else
+            p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
+    }
 
     /* It is possible that we decrypted the link to perform role switch */
     /* mark link not to be encrypted, so that when we execute security next time it will kick in again */
     if ((status == HCI_SUCCESS) && !encr_enable)
-        p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
+    {
+        if (p_dev_rec->hci_handle == handle)
+            p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
+        else
+            p_dev_rec->sec_flags &= ~BTM_SEC_LE_ENCRYPTED;
+    }
 
     BTM_TRACE_DEBUG1 ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
 
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
-    p_acl = btm_bda_to_acl(p_dev_rec->bd_addr);
+    if (acl_idx != MAX_L2CAP_LINKS )
+        p_acl = &btm_cb.acl_db[acl_idx];
 
-    if (p_acl && p_acl->is_le_link)
+    if (p_acl && p_acl->transport == BT_TRANSPORT_LE)
     {
         btm_ble_link_encrypted(p_dev_rec->bd_addr, encr_enable);
         return;
@@ -3991,7 +4209,7 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
     /* If encryption setup failed, notify the waiting layer */
     if (status != HCI_SUCCESS)
     {
-        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
         return;
     }
 
@@ -4000,7 +4218,7 @@ void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
 
     /* If there is no next procedure, or procedure failed to start, notify the caller */
     if (status != BTM_CMD_STARTED)
-        btm_sec_dev_rec_cback_event (p_dev_rec, status);
+        btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
 }
 
 /*******************************************************************************
@@ -4060,6 +4278,7 @@ static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
 
         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
 
+        if (btm_cb.api.p_auth_complete_callback)
         (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
                                                 p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
     }
@@ -4081,6 +4300,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
     UINT8            res;
     BOOLEAN          is_pairing_device = FALSE;
     tACL_CONN        *p_acl_cb;
+    UINT8            bit_shift = 0;
 
     btm_acl_resubmit_page();
 
@@ -4108,9 +4328,6 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
         if (status == HCI_SUCCESS)
         {
             p_dev_rec = btm_sec_alloc_dev (bda);
-#if BLE_INCLUDED == TRUE
-            p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
-#endif
         }
         else
         {
@@ -4121,6 +4338,10 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
     }
     else    /* Update the timestamp for this device */
     {
+
+#if BLE_INCLUDED == TRUE
+        bit_shift = (handle == p_dev_rec->ble_hci_handle) ? 8 :0;
+#endif
         p_dev_rec->timestamp = btm_cb.dev_rec_count++;
         if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
         {
@@ -4147,7 +4368,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
                     else
                     {
                         btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
-                        BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL);
+                        BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR);
                     }
 #if BTM_DISC_DURING_RS == TRUE
                     p_dev_rec->rs_disc_pending   = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
@@ -4164,6 +4385,10 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
         }
     }
 
+#if BLE_INCLUDED == TRUE
+    p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
+#endif
+
 #if BTM_DISC_DURING_RS == TRUE
     p_dev_rec->rs_disc_pending   = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
 #endif
@@ -4185,7 +4410,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
             {
                 /* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
                 btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
-                BTM_ReadRemoteDeviceName(bda, NULL);
+                BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR);
                 return;
             }
 
@@ -4221,7 +4446,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
         if (is_pairing_device)
         {
             p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
-            p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED);
+            p_dev_rec->sec_flags &= ~((BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED) << bit_shift);
             BTM_TRACE_DEBUG1 ("security_required:%x ", p_dev_rec->security_required );
 
             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
@@ -4234,17 +4459,33 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
                                                         p_dev_rec->sec_bd_name, status);
             }
         }
-        else if ((status == HCI_ERR_AUTH_FAILURE)                   ||
+ /*
+     Do not send authentication failure, if following conditions hold good
+      1.  BTM Sec Pairing state is idle
+      2.  Link key for the remote device is present.
+      3.  Remote is SSP capable.
+  */
+        else if  ((p_dev_rec->link_key_type  <= BTM_LKEY_TYPE_REMOTE_UNIT) &&
+                 (((status == HCI_ERR_AUTH_FAILURE)                      ||
                  (status == HCI_ERR_KEY_MISSING)                         ||
                  (status == HCI_ERR_HOST_REJECT_SECURITY)                ||
                  (status == HCI_ERR_PAIRING_NOT_ALLOWED)                 ||
                  (status == HCI_ERR_UNIT_KEY_USED)                       ||
                  (status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
                  (status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE)           ||
-                 (status == HCI_ERR_REPEATED_ATTEMPTS))
+                 (status == HCI_ERR_REPEATED_ATTEMPTS))))
         {
             p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
-            p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
+            p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN << bit_shift);
+
+
+#ifdef BRCM_NOT_4_BTE
+            /* If we rejected pairing, pass this special result code */
+            if (btm_cb.acl_disc_reason == HCI_ERR_HOST_REJECT_SECURITY)
+            {
+                status = HCI_ERR_HOST_REJECT_SECURITY;
+            }
+#endif
 
             /* We need to notify host that the key is not known any more */
             if (btm_cb.api.p_auth_complete_callback)
@@ -4257,9 +4498,9 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
 
         if (status == HCI_ERR_CONNECTION_TOUT || status == HCI_ERR_LMP_RESPONSE_TIMEOUT  ||
             status == HCI_ERR_UNSPECIFIED     || status == HCI_ERR_PAGE_TIMEOUT)
-            btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT);
+            btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT, FALSE);
         else
-            btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+            btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
 
         return;
     }
@@ -4304,7 +4545,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
     /* role may not be correct here, it will be updated by l2cap, but we need to */
     /* notify btm_acl that link is up, so starting of rmt name request will not */
     /* set paging flag up */
-    p_acl_cb = btm_bda_to_acl(bda);
+    p_acl_cb = btm_bda_to_acl(bda, BT_TRANSPORT_BR_EDR);
     if (p_acl_cb)
     {
         /* whatever is in btm_establish_continue() without reporting the BTM_BL_CONN_EVT event */
@@ -4318,19 +4559,19 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
             BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
 #endif
     }
-    btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, FALSE);
+    btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, BT_TRANSPORT_BR_EDR);
 
     /* Initialize security flags.  We need to do that because some            */
     /* authorization complete could have come after the connection is dropped */
     /* and that would set wrong flag that link has been authorized already    */
-    p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
-                              BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+    p_dev_rec->sec_flags &= ~((BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
+                              BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED) << bit_shift);
 
     if (enc_mode != HCI_ENCRYPT_MODE_DISABLED)
-        p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
+        p_dev_rec->sec_flags |= ((BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED) << bit_shift);
 
     if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
-        p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
+        p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED << bit_shift);
 
     p_dev_rec->link_key_changed = FALSE;
 
@@ -4341,7 +4582,7 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
     if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator)
     {
         if ((res = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
-            btm_sec_dev_rec_cback_event (p_dev_rec, res);
+            btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
     }
     return;
 }
@@ -4371,7 +4612,7 @@ void btm_sec_role_changed (void *p_ref_data)
     if (((p_dev_rec->security_required & BTM_SEC_FORCE_MASTER) && !p_dev_rec->role_master)
         || ((p_dev_rec->security_required & BTM_SEC_FORCE_SLAVE)  &&  p_dev_rec->role_master))
     {
-        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
+        btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
         return;
     }
 
@@ -4384,7 +4625,7 @@ void btm_sec_role_changed (void *p_ref_data)
 
     if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
     {
-        btm_sec_dev_rec_cback_event (p_dev_rec, res);
+        btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
     }
 }
 
@@ -4418,7 +4659,7 @@ tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
         return(BTM_BUSY);
     }
 
-    return(btm_sec_send_hci_disconnect(p_dev_rec, reason));
+    return(btm_sec_send_hci_disconnect(p_dev_rec, reason, handle));
 }
 
 /*******************************************************************************
@@ -4437,6 +4678,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
     UINT8             old_pairing_flags = btm_cb.pairing_flags;
     int               result = HCI_ERR_AUTH_FAILURE;
     tBTM_SEC_CALLBACK   *p_callback = NULL;
+    tBT_TRANSPORT      transport = BT_TRANSPORT_BR_EDR;
 
     /* If page was delayed for disc complete, can do it now */
     btm_cb.discing = FALSE;
@@ -4446,6 +4688,8 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
     if (!p_dev_rec)
         return;
 
+    transport  = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR: BT_TRANSPORT_LE;
+
     p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
 
 #if BTM_DISC_DURING_RS == TRUE
@@ -4487,16 +4731,24 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
         }
     }
 
-    p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
-    p_dev_rec->sec_state  = BTM_SEC_STATE_IDLE;
-
 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
     p_dev_rec->enc_key_size = 0;
     btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, FALSE);
     /* see sec_flags processing in btm_acl_removed */
+
+    if (transport == BT_TRANSPORT_LE)
+    {
+        p_dev_rec->ble_hci_handle = BTM_SEC_INVALID_HANDLE;
+        p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED);
+    }
+    else
 #endif
-    p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+    {
+        p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
+        p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
+    }
 
+    p_dev_rec->sec_state  = BTM_SEC_STATE_IDLE;
     p_dev_rec->security_required = BTM_SEC_NONE;
 
     p_callback = p_dev_rec->p_callback;
@@ -4506,7 +4758,7 @@ void btm_sec_disconnected (UINT16 handle, UINT8 reason)
     {
         p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before
                                          we do, this call back must be reset here */
-        (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING);
+        (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING);
     }
 
     BTM_TRACE_EVENT1("after Update sec_flags=0x%x", p_dev_rec->sec_flags);
@@ -4741,7 +4993,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
                                   (p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]);
                 break;
             }
-            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
+            btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
             break;
 
@@ -5379,7 +5631,7 @@ static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle)
     if (status != BTM_CMD_STARTED)
     {
         /* There is no next procedure or start of procedure failed, notify the waiting layer */
-        btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status);
+        btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status, FALSE);
     }
 }
 
@@ -5604,7 +5856,7 @@ static char *btm_pair_state_descr (tBTM_PAIRING_STATE state)
 ** Parameters:      void
 **
 *******************************************************************************/
-void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res)
+void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN transport)
 {
     tBTM_SEC_CALLBACK   *p_callback = p_dev_rec->p_callback;
 
@@ -5612,7 +5864,7 @@ void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res)
     {
         p_dev_rec->p_callback = NULL;
 
-        (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, res);
+        (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, res);
 
     }
     btm_sec_check_pending_reqs();
@@ -5690,7 +5942,7 @@ static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC  *p_dev_rec)
             if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0))
             {
                 BTM_TRACE_DEBUG0("btm_sec_check_prefetch_pin: PIN code callback called");
-                if (btm_bda_to_acl(p_dev_rec->bd_addr) == NULL)
+                if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL)
                 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
                 (btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
             }
@@ -5741,12 +5993,14 @@ BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda)
     tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda);
     BOOLEAN is_bonded= FALSE;
 
+    if (p_dev_rec &&
 #if (SMP_INCLUDED== TRUE)
-    if (p_dev_rec && (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
+        ((p_dev_rec->ble.key_type && (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN))||
+#endif
+         (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
     {
         is_bonded = TRUE;
     }
-#endif
     BTM_TRACE_DEBUG1 ("btm_sec_is_a_bonded_dev is_bonded=%d", is_bonded);
     return(is_bonded);
 }
index 0081850..fa19515 100644 (file)
@@ -37,6 +37,7 @@
 #include "btm_api.h"
 #include "btm_int.h"
 
+
 // btla-specific ++
 #define LOG_TAG "BTLD"
 #if (defined(ANDROID_APP_INCLUDED) && (ANDROID_APP_INCLUDED == TRUE) && (!defined(LINUX_NATIVE)) )
@@ -136,6 +137,9 @@ static void btu_ble_read_remote_feat_evt (UINT8 *p);
 static void btu_ble_ll_conn_param_upd_evt (UINT8 *p);
 static void btu_ble_proc_ltk_req (UINT8 *p);
 static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p);
+#if (BLE_LLT_INCLUDED == TRUE)
+static void btu_ble_rc_param_req_evt(UINT8 *p);
+#endif
     #endif
 /*******************************************************************************
 **
@@ -421,6 +425,12 @@ void btu_hcif_process_event (UINT8 controller_id, BT_HDR *p_msg)
                 case HCI_BLE_LTK_REQ_EVT: /* received only at slave device */
                     btu_ble_proc_ltk_req(p);
                     break;
+#if (BLE_LLT_INCLUDED == TRUE)
+               case HCI_BLE_RC_PARAM_REQ_EVT:
+                    btu_ble_rc_param_req_evt(p);
+                    break;
+#endif
+
             }
             break;
 #endif /* BLE_INCLUDED */
@@ -1138,6 +1148,10 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l
             btm_ble_write_adv_enable_complete(p);
             break;
 
+        case HCI_BLE_READ_SUPPORTED_STATES:
+            btm_read_ble_local_supported_states_complete(p, evt_len);
+            break;
+
         case HCI_BLE_TRANSMITTER_TEST:
         case HCI_BLE_RECEIVER_TEST:
         case HCI_BLE_TEST_END:
@@ -2266,16 +2280,7 @@ static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len)
 
 static void btu_ble_ll_conn_param_upd_evt (UINT8 *p)
 {
-    /* LE connection update has completed successfully as a master. */
-    /* We can enable the update request if the result is a success. */
-    /* extract the HCI handle first */
-    UINT8   status;
-    UINT16  handle;
-    BT_TRACE_0(TRACE_LAYER_HCI, TRACE_TYPE_EVENT, "btu_ble_ll_conn_param_upd_evt");
-
-    STREAM_TO_UINT8  (status, p);
-    STREAM_TO_UINT16 (handle, p);
-    L2CA_HandleConnUpdateEvent(handle, status);
+    /* This is empty until an upper layer cares about returning event */
 }
 
 static void btu_ble_read_remote_feat_evt (UINT8 *p)
@@ -2299,5 +2304,21 @@ static void btu_ble_proc_ltk_req (UINT8 *p)
 /**********************************************
 ** End of BLE Events Handler
 ***********************************************/
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+static void btu_ble_rc_param_req_evt(UINT8 *p)
+{
+    UINT16 handle;
+    UINT16  int_min, int_max, latency, timeout;
+
+    STREAM_TO_UINT16(handle, p);
+    STREAM_TO_UINT16(int_min, p);
+    STREAM_TO_UINT16(int_max, p);
+    STREAM_TO_UINT16(latency, p);
+    STREAM_TO_UINT16(timeout, p);
+
+    l2cble_process_rc_param_request_evt(handle, int_min, int_max, latency, timeout);
+}
+#endif /* BLE_LLT_INCLUDED */
+
 #endif /* BLE_INCLUDED */
 
index 9c09214..5b5108a 100644 (file)
@@ -400,6 +400,9 @@ BTU_API UINT32 btu_task (UINT32 param)
                     case BTU_TTYPE_L2CAP_HOLD:
                     case BTU_TTYPE_L2CAP_INFO:
                     case BTU_TTYPE_L2CAP_FCR_ACK:
+#if (BLE_INCLUDED == TRUE)
+                    case BTU_TTYPE_L2CAP_END_CONN_UPD:
+#endif
 
                         l2c_process_timeout (p_tle);
                         break;
@@ -473,6 +476,8 @@ BTU_API UINT32 btu_task (UINT32 param)
                     case BTU_TTYPE_BLE_INQUIRY:
                     case BTU_TTYPE_BLE_GAP_LIM_DISC:
                     case BTU_TTYPE_BLE_RANDOM_ADDR:
+                    case BTU_TTYPE_BLE_GAP_FAST_ADV:
+                    case BTU_TTYPE_BLE_OBSERVE:
                         btm_ble_timeout(p_tle);
                         break;
 
index fb90d03..e04fc8e 100644 (file)
@@ -734,7 +734,7 @@ UINT16 GAP_GetRemoteDeviceName (BD_ADDR addr, tGAP_CALLBACK *callback)
         p_cb->gap_cback = callback;
         p_cb->event = GAP_EVT_REM_NAME_COMPLETE;     /* Return event expected */
 
-        btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index]);
+        btm_status = BTM_ReadRemoteDeviceName (addr, gap_cb.btm_cback[p_cb->index], BT_TRANSPORT_BR_EDR);
 
         /* If the name was not returned immediately, or if an error occurred, release the control block */
         if ((retval = gap_convert_btm_status (btm_status)) != GAP_CMD_INITIATED)
index d44577d..d67bf5a 100644 (file)
@@ -57,7 +57,8 @@
 static void gap_ble_s_attr_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE op_code, tGATTS_DATA *p_data);
 
 /* client connection callback */
-static void  gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void  gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+                                            tGATT_DISCONN_REASON reason, tGATT_TRANSPORT transport);
 static void  gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
 
 static tGATT_CBACK gap_cback =
@@ -213,65 +214,6 @@ UINT16 gap_get_conn_id_if_connected (BD_ADDR bd_addr)
     return(GATT_INVALID_CONN_ID);
 }
 
-/*******************************************************************************
-**
-** Function         gap_ble_enqueue_op
-**
-** Description      enqueue a GAP operation when GAP client is busy
-**
-** Returns          void
-**
-*******************************************************************************/
-void gap_ble_enqueue_op( tGAP_CLCB * p_clcb, UINT8 op, BD_ADDR reconn_addr, UINT8 privacy_flag, void *p_cback)
-{
-    tGAP_BLE_PENDING_OP  *p_op = (tGAP_BLE_PENDING_OP *)GKI_getbuf(sizeof(tGAP_BLE_PENDING_OP));
-
-    if (p_op != NULL)
-    {
-        p_op->op = op;
-        p_op->p_pending_cback = p_cback;
-
-        if (op == GATT_SET_GAP_PRIVACY_FLAG)
-            p_op->pending_data.privacy_flag = privacy_flag;
-        else if (op == GATT_UPDATE_RECONN_ADDR)
-            memcpy(p_op->pending_data.reconn_addr, reconn_addr, BD_ADDR_LEN);
-
-        GKI_enqueue(&p_clcb->pending_op_q, p_op);
-    }
-}
-
-/*******************************************************************************
-**
-** Function         gap_ble_process_pending_op
-**
-** Description      get next pending operation and process it
-**
-** Returns          void
-**
-*******************************************************************************/
-static BOOLEAN gap_ble_process_pending_op(tGAP_CLCB *p_clcb)
-{
-    tGAP_BLE_PENDING_OP *p_pending_op = (tGAP_BLE_PENDING_OP *)GKI_dequeue(&p_clcb->pending_op_q);
-    BOOLEAN         started = FALSE;
-
-    if (p_pending_op != NULL)
-    {
-        if (p_pending_op->op == GATT_UPDATE_RECONN_ADDR)
-        {
-            GAP_BleUpdateReconnectAddr( p_clcb->bda,
-                                        p_pending_op->pending_data.reconn_addr,
-                                        (tGAP_BLE_RECONN_ADDR_CBACK *)p_pending_op->p_pending_cback);
-            started = TRUE;
-        }
-        GKI_freebuf(p_pending_op);
-    }
-    else
-    {
-        GAP_TRACE_EVENT0("No pending operation");
-    }
-
-    return started;
-}
 
 /*******************************************************************************
 **   GAP Attributes Database Request callback
@@ -316,16 +258,6 @@ tGATT_STATUS gap_read_attr_value (UINT16 handle, tGATT_VALUE *p_value, BOOLEAN i
                     p_value->len = 2;
                     break;
 
-                case GATT_UUID_GAP_PRIVACY_FLAG:
-                    UINT8_TO_STREAM(p, p_db_attr->attr_value.privacy);
-                    p_value->len = 1;
-                    break;
-
-                case GATT_UUID_GAP_RECONN_ADDR:
-                    p_value->len = BD_ADDR_LEN;
-                    BDADDR_TO_STREAM(p, p_db_attr->attr_value.reconn_bda);
-                    break;
-
                 case GATT_UUID_GAP_PREF_CONN_PARAM:
                     UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_min); /* int_min */
                     UINT16_TO_STREAM(p, p_db_attr->attr_value.conn_param.int_max); /* int_max */
@@ -357,18 +289,6 @@ tGATT_STATUS gap_proc_read (tGATTS_REQ_TYPE type, tGATT_READ_REQ *p_data, tGATTS
 
     return status;
 }
-BOOLEAN gap_read_local_reconn_addr(BD_ADDR_PTR reconn_bda)
-{
-    BD_ADDR dummy_bda = {0};
-
-    if (memcmp(gap_cb.reconn_bda, dummy_bda, BD_ADDR_LEN) != 0)
-    {
-        memcpy(reconn_bda, gap_cb.reconn_bda, BD_ADDR_LEN);
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
 
 /******************************************************************************
 **
@@ -389,26 +309,7 @@ UINT8 gap_proc_write_req( tGATTS_REQ_TYPE type, tGATT_WRITE_REQ *p_data)
     {
         if (p_data-> handle == p_db_attr->handle)
         {
-            if (p_data->offset != 0) return GATT_NOT_LONG;
-            if (p_data->is_prep) return GATT_REQ_NOT_SUPPORTED;
-
-/* DO NOT SUPPORT RECONNECTION ADDRESS FOR NOW
-
-            if (p_db_attr->uuid == GATT_UUID_GAP_RECONN_ADDR)
-            {
-                if (!btm_cb.ble_ctr_cb.privacy)
-                    return GATT_WRITE_NOT_PERMIT;
-                if (p_data->len != BD_ADDR_LEN) return GATT_INVALID_ATTR_LEN;
-
-                STREAM_TO_BDADDR(p_db_attr->attr_value.reconn_bda, p);
-                // write direct connection address
-                memcpy(&gap_cb.reconn_bda, p_db_attr->attr_value.reconn_bda, BD_ADDR_LEN);
-
-                return GATT_SUCCESS;
-            }
-            else
-*/
-            return GATT_WRITE_NOT_PERMIT;
+                return GATT_WRITE_NOT_PERMIT;
         }
     }
     return GATT_NOT_FOUND;
@@ -513,6 +414,21 @@ void gap_attr_db_init(void)
                                                 GATT_CHAR_PROP_BIT_READ);
     p_db_attr ++;
 
+#if BTM_PERIPHERAL_ENABLED == TRUE       /* Only needed for peripheral testing */
+    /* add preferred connection parameter characteristic
+    */
+    uuid.uu.uuid16 = p_db_attr->uuid = GATT_UUID_GAP_PREF_CONN_PARAM;
+    p_db_attr->attr_value.conn_param.int_max = GAP_PREFER_CONN_INT_MAX; /* 6 */
+    p_db_attr->attr_value.conn_param.int_min = GAP_PREFER_CONN_INT_MIN; /* 0 */
+    p_db_attr->attr_value.conn_param.latency = GAP_PREFER_CONN_LATENCY; /* 0 */
+    p_db_attr->attr_value.conn_param.sp_tout = GAP_PREFER_CONN_SP_TOUT; /* 2000 */
+    p_db_attr->handle = GATTS_AddCharacteristic(service_handle,
+                                                &uuid,
+                                                GATT_PERM_READ,
+                                                GATT_CHAR_PROP_BIT_READ);
+    p_db_attr ++;
+#endif
+
     /* start service now */
     memset (&app_uuid.uu.uuid128, 0x81, LEN_UUID_128);
 
@@ -596,8 +512,6 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_
             (* p_dev_name_cback)(status, p_clcb->bda, len, (char *)p_name);
     }
 
-    if (!gap_ble_process_pending_op(p_clcb) &&
-        p_clcb->cl_op_uuid == 0)
         GATT_Disconnect(p_clcb->conn_id);
 
 }
@@ -612,11 +526,14 @@ void gap_ble_cl_op_cmpl(tGAP_CLCB *p_clcb, BOOLEAN status, UINT16 len, UINT8 *p_
 **
 *******************************************************************************/
 static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                     BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                     BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                     tGATT_TRANSPORT transport)
 {
     tGAP_CLCB   *p_clcb = gap_find_clcb_by_bd_addr (bda);
     UINT16      cl_op_uuid;
+
     UNUSED(gatt_if);
+    UNUSED(transport);
 
     GAP_TRACE_EVENT5 ("gap_ble_c_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x",
                       (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],
@@ -636,9 +553,6 @@ static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_
         p_clcb->conn_id = conn_id;
         p_clcb->connected = TRUE;
 
-        /* Do not use reconnection address for now -->
-          check privacy enabled? set reconnect address
-        btm_ble_update_reconnect_address(bda);*/
     }
     else
     {
@@ -659,6 +573,10 @@ static void gap_ble_c_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_
             {
                 GAP_BleReadPeerDevName (bda, (tGAP_BLE_DEV_NAME_CBACK *)p_clcb->p_cback);
             }
+            else if (cl_op_uuid == GATT_UUID_GAP_PREF_CONN_PARAM)
+            {
+                 GAP_BleReadPeerPrefConnParams(bda);
+            }
         }
         /* current link disconnect */
         else
@@ -695,7 +613,7 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
 
     GAP_TRACE_EVENT3 ("gap_ble_c_cmpl_cback() - op_code: 0x%02x  status: 0x%02x  read_type: 0x%04x", op, status, op_type);
     /* Currently we only issue read commands */
-    if (op != GATTC_OPTYPE_READ && op != GATTC_OPTYPE_WRITE)
+    if (op != GATTC_OPTYPE_READ)
         return;
 
     if (status != GATT_SUCCESS)
@@ -731,7 +649,6 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
             break;
         case GATT_UUID_GAP_ICON:
             break;
-
     }
 }
 
@@ -806,18 +723,20 @@ BOOLEAN GAP_BleReadPeerPrefConnParams (BD_ADDR peer_bda)
         return(FALSE);
 
     /* hold the link here */
-    GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
-
-    if (p_clcb->connected)
+    if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE))
     {
-    return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL);
-    }
-    /* Mark currently active operation */
-    p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM;
-
-    return(TRUE);
 
+        if (p_clcb->connected)
+        {
+            return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_PREF_CONN_PARAM, NULL);
+        }
+        /* Mark currently active operation */
+        p_clcb->cl_op_uuid = GATT_UUID_GAP_PREF_CONN_PARAM;
 
+        return(TRUE);
+    }
+    else
+        return FALSE;
 }
 
 /*******************************************************************************
@@ -839,10 +758,10 @@ BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_DEV_NAME_CBACK *p_cba
     if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL)
     {
         if ((p_clcb = gap_clcb_alloc(0, peer_bda)) == NULL)
-    {
-        GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached");
+        {
+            GAP_TRACE_ERROR0("GAP_BleReadPeerDevName max connection reached");
             return FALSE;
-    }
+        }
         p_clcb->connected = FALSE;
     }
 
@@ -855,21 +774,26 @@ BOOLEAN GAP_BleReadPeerDevName (BD_ADDR peer_bda, tGAP_BLE_DEV_NAME_CBACK *p_cba
         return(FALSE);
 
     /* hold the link here */
-    GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
 
-    if (p_clcb->connected)
+    if (GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE, BT_TRANSPORT_LE))
     {
-        return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback);
-    }
+        if (p_clcb->connected)
+        {
+            return gap_ble_cl_read_request(p_clcb, GATT_UUID_GAP_DEVICE_NAME, (void *)p_cback);
+        }
 
-    p_clcb->p_cback = (void *)p_cback;
-    /* Mark currently active operation */
-    p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME;
+        p_clcb->p_cback = (void *)p_cback;
+        /* Mark currently active operation */
+        p_clcb->cl_op_uuid = GATT_UUID_GAP_DEVICE_NAME;
 
 
-    return(TRUE);
+        return(TRUE);
+    }
+    else
+        return FALSE;
 }
 
+
 /*******************************************************************************
 **
 ** Function         GAP_BleCancelReadPeerDevName
@@ -907,73 +831,6 @@ BOOLEAN GAP_BleCancelReadPeerDevName (BD_ADDR peer_bda)
     return(TRUE);
 }
 
-/*******************************************************************************
-**
-** Function         GAP_BleUpdateReconnectAddr
-**
-** Description      Start a process to udpate the reconnect address if remote devive
-**                  has privacy enabled.
-**
-** Returns          TRUE if read started, else FALSE if GAP is busy
-**
-*******************************************************************************/
-BOOLEAN GAP_BleUpdateReconnectAddr (BD_ADDR peer_bda, BD_ADDR reconn_addr,
-                                    tGAP_BLE_RECONN_ADDR_CBACK *p_cback)
-{
-    tGAP_CLCB         *p_clcb;
-    tGATT_DISC_PARAM   param;
-
-    if (p_cback == NULL)
-        return(FALSE);
-
-    /* This function should only be called if there is a connection to  */
-    /* the peer. Get a client handle for that connection.               */
-    if ((p_clcb = gap_find_clcb_by_bd_addr (peer_bda)) == NULL ||
-        !p_clcb->connected)
-    {
-        GAP_TRACE_ERROR0("No connection, can not update reconnect address");
-        return(FALSE);
-    }
-
-    GAP_TRACE_API3 ("GAP_BleUpdateReconnectAddr() - BDA: %08x%04x  cl_op_uuid: 0x%04x",
-                    (peer_bda[0]<<24)+(peer_bda[1]<<16)+(peer_bda[2]<<8)+peer_bda[3],
-                    (peer_bda[4]<<8)+peer_bda[5], p_clcb->cl_op_uuid);
-
-    /* For now we only handle one at a time */
-    if (p_clcb->cl_op_uuid != 0)
-    {
-        gap_ble_enqueue_op(p_clcb, GATT_UPDATE_RECONN_ADDR, reconn_addr, 0, (void *)p_cback);
-        return(FALSE);
-    }
-
-    /* hold the link here */
-    GATT_Connect(gap_cb.gatt_if, p_clcb->bda, TRUE);
-
-    memset(&param, 0, sizeof(tGATT_DISC_PARAM));
-
-    param.service.len       = LEN_UUID_16;
-    param.service.uu.uuid16 = GATT_UUID_GAP_RECONN_ADDR;
-    param.s_handle          = 1;
-    param.e_handle          = 0xFFFF;
-
-    if (GATTC_Discover(p_clcb->conn_id, GATT_DISC_CHAR, &param) != GATT_SUCCESS)
-    {
-        GAP_TRACE_ERROR0 ("GAP_BleReadPeerPrefConnParams: GATT_Read Failed");
-        /* release the link here */
-        GATT_Disconnect(p_clcb->conn_id);
-        return(FALSE);
-    }
-    else
-    {
-        p_clcb->p_cback     = (void *)p_cback;
-        memcpy(p_clcb->reconn_addr, reconn_addr, BD_ADDR_LEN);
-        p_clcb->cl_op_uuid  = GATT_UUID_GAP_RECONN_ADDR;
-    }
-
-    return TRUE;
-
-}
-
 #endif  /* BLE_INCLUDED */
 
 
index 44bb5ec..5e26ce2 100644 (file)
@@ -799,10 +799,11 @@ static void gap_checks_con_flags (tGAP_CCB    *p_ccb)
 ** Returns          void
 **
 *******************************************************************************/
-static void gap_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void gap_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tGAP_CCB *p_ccb = (tGAP_CCB *)p_ref_data;
     UNUSED(bd_addr);
+    UNUSED (transport);
 
     GAP_TRACE_EVENT3 ("gap_sec_check_complete conn_state:%d, conn_flags:0x%x, status:%d",
         p_ccb->con_state, p_ccb->con_flags, res);
index 866ad7a..e852d20 100644 (file)
@@ -183,7 +183,7 @@ void gap_find_addr_name_cb (tBTM_REMOTE_DEV_NAME *p)
                 if ((p_cb->p_cur_inq = BTM_InqDbNext(p_cb->p_cur_inq)) != NULL)
                 {
                     if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
-                        (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED)
+                        (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                         return;     /* This routine will get called again with the next results */
                     else
                         p_result->status = gap_convert_btm_status ((tBTM_STATUS) p->status);
@@ -246,7 +246,7 @@ void gap_find_addr_inq_cb (tBTM_INQUIRY_CMPL *p)
                 if ((p_cb->p_cur_inq = BTM_InqDbFirst()) != NULL)
                 {
                     if ((BTM_ReadRemoteDeviceName (p_cb->p_cur_inq->results.remote_bd_addr,
-                        (tBTM_CMPL_CB *) gap_find_addr_name_cb)) == BTM_CMD_STARTED)
+                        (tBTM_CMPL_CB *) gap_find_addr_name_cb, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
                         return;     /* Wait for the response in gap_find_addr_name_cb() */
                     else
                         p_result->status = gap_convert_btm_status (p->status);
index 3348599..51ea284 100644 (file)
@@ -162,7 +162,7 @@ BT_HDR *attp_build_browse_cmd(UINT8 op_code, UINT16 s_hdl, UINT16 e_hdl, tBT_UUI
 ** Returns          pointer to the command buffer.
 **
 *******************************************************************************/
-BT_HDR *attp_build_read_handles_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type)
+BT_HDR *attp_build_read_by_type_value_cmd (UINT16 payload_size, tGATT_FIND_TYPE_VALUE *p_value_type)
 {
     BT_HDR      *p_buf = NULL;
     UINT8       *p;
@@ -606,7 +606,7 @@ tGATT_STATUS attp_send_cl_msg (tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code,
             break;
 
         case GATT_REQ_FIND_TYPE_VALUE:
-            p_cmd = attp_build_read_handles_cmd(p_tcb->payload_size, &p_msg->find_type_value);
+            p_cmd = attp_build_read_by_type_value_cmd(p_tcb->payload_size, &p_msg->find_type_value);
             break;
 
         case GATT_REQ_READ_MULTI:
index 54ea0f0..0321fe8 100644 (file)
@@ -238,7 +238,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
         }
     }
 
-    if (!gatts_init_service_db(&p_list->svc_db, *p_svc_uuid, is_pri, s_hdl , num_handles))
+    if (!gatts_init_service_db(&p_list->svc_db, p_svc_uuid, is_pri, s_hdl , num_handles))
     {
         GATT_TRACE_ERROR0 ("GATTS_ReserveHandles: service DB initialization failed");
         if (p_list)
@@ -366,7 +366,8 @@ UINT16 GATTS_AddCharDescriptor (UINT16 service_handle,
         return 0;
     }
     if (p_descr_uuid == NULL ||
-        (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len !=  LEN_UUID_16))
+        (p_descr_uuid->len != LEN_UUID_128 && p_descr_uuid->len !=  LEN_UUID_16
+         && p_descr_uuid->len !=  LEN_UUID_32))
     {
         GATT_TRACE_DEBUG0("Illegal parameter");
         return 0;
@@ -689,8 +690,13 @@ tGATT_STATUS GATTS_HandleValueNotification (UINT16 conn_id, UINT16 attr_handle,
         memcpy (notif.value, p_val, val_len);
         notif.auth_req = GATT_AUTH_REQ_NONE;;
 
-        p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)&notif);
-        cmd_sent = attp_send_sr_msg (p_tcb, p_buf);
+        if ((p_buf = attp_build_sr_msg (p_tcb, GATT_HANDLE_VALUE_NOTIF, (tGATT_SR_MSG *)&notif))
+                   != NULL)
+        {
+            cmd_sent = attp_send_sr_msg (p_tcb, p_buf);
+        }
+        else
+            cmd_sent = GATT_NO_RESOURCES;
     }
     return cmd_sent;
 }
@@ -1147,12 +1153,12 @@ tGATT_STATUS GATTC_SendHandleValueConfirm (UINT16 conn_id, UINT16 handle)
 ** Returns          void
 **
 *******************************************************************************/
-void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout)
+void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout, tBT_TRANSPORT transport)
 {
     tGATT_TCB       *p_tcb;
     BOOLEAN         status = FALSE;
 
-    if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL)
+    if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, transport)) != NULL)
     {
         if (p_tcb->att_lcid == L2CAP_ATT_CID)
         {
@@ -1275,7 +1281,7 @@ void GATT_Deregister (tGATT_IF gatt_if)
                 if (!gatt_num_apps_hold_link(p_tcb))
                 {
                     /* this will disconnect the link or cancel the pending connect request at lower layer*/
-                    gatt_disconnect(p_tcb->peer_bda);
+                    gatt_disconnect(p_tcb);
                 }
             }
 
@@ -1323,19 +1329,20 @@ void GATT_StartIf (tGATT_IF gatt_if)
     BD_ADDR     bda;
     UINT8       start_idx, found_idx;
     UINT16      conn_id;
+    tGATT_TRANSPORT transport ;
 
     GATT_TRACE_API1 ("GATT_StartIf gatt_if=%d", gatt_if);
     if ((p_reg = gatt_get_regcb(gatt_if)) != NULL)
     {
         p_reg = &gatt_cb.cl_rcb[gatt_if - 1];
         start_idx = 0;
-        while (gatt_find_the_connected_bda(start_idx, bda, &found_idx))
+        while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport))
         {
-            p_tcb = gatt_find_tcb_by_addr(bda);
+            p_tcb = gatt_find_tcb_by_addr(bda, transport);
             if (p_reg->app_cb.p_conn_cb && p_tcb)
             {
                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, gatt_if);
-                (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0);
+                (*p_reg->app_cb.p_conn_cb)(gatt_if, bda, conn_id, TRUE, 0, transport);
             }
             start_idx = ++found_idx;
         }
@@ -1357,9 +1364,10 @@ void GATT_StartIf (tGATT_IF gatt_if)
 ** Returns          TRUE if connection started; FALSE if connection start failure.
 **
 *******************************************************************************/
-BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct){
+BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct, tBT_TRANSPORT transport)
+{
     tGATT_REG    *p_reg;
-    BOOLEAN status;
+    BOOLEAN status = FALSE;
 
     GATT_TRACE_API1 ("GATT_Connect gatt_if=%d", gatt_if);
 
@@ -1371,9 +1379,16 @@ BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct){
     }
 
     if (is_direct)
-        status = gatt_act_connect (p_reg, bd_addr);
+        status = gatt_act_connect (p_reg, bd_addr, transport);
     else
+    {
+        if (transport == BT_TRANSPORT_LE)
         status = gatt_update_auto_connect_dev(gatt_if,TRUE, bd_addr, TRUE);
+        else
+        {
+            GATT_TRACE_ERROR0("Unsupported transport for background connection");
+        }
+    }
 
     return status;
 
@@ -1414,7 +1429,8 @@ BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct
         {
             GATT_TRACE_DEBUG0("GATT_CancelConnect - unconditional");
             start_idx = 0;
-            p_tcb = gatt_find_tcb_by_addr(bd_addr);
+            /* only LE connection can be cancelled */
+            p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
             if (p_tcb && gatt_num_apps_hold_link(p_tcb))
             {
                 while (status && gatt_find_app_hold_link(p_tcb, start_idx, &found_idx, &temp_gatt_if))
@@ -1486,7 +1502,7 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id)
         gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
         if (!gatt_num_apps_hold_link(p_tcb))
         {
-            gatt_disconnect(p_tcb->peer_bda);
+            gatt_disconnect(p_tcb);
         }
         ret = GATT_SUCCESS;
     }
@@ -1508,7 +1524,8 @@ tGATT_STATUS GATT_Disconnect (UINT16 conn_id)
 ** Returns          TRUE the ligical link information is found for conn_id
 **
 *******************************************************************************/
-BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr)
+BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr,
+                                tBT_TRANSPORT *p_transport)
 {
 
     tGATT_IF        gatt_if = GATT_GET_GATT_IF(conn_id);
@@ -1523,6 +1540,7 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_
     {
         memcpy(bd_addr, p_tcb->peer_bda, BD_ADDR_LEN);
         *p_gatt_if = gatt_if;
+        *p_transport = p_tcb->transport;
         status = TRUE;
     }
     return status;
@@ -1539,14 +1557,16 @@ BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_
 ** Parameters        gatt_if: applicaiton interface (input)
 **                   bd_addr: peer device address. (input)
 **                   p_conn_id: connection id  (output)
+**                   transport: transport option
 **
 ** Returns          TRUE the logical link is connected
 **
 *******************************************************************************/
-BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id)
+BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id,
+                                  tBT_TRANSPORT transport)
 {
     tGATT_REG       *p_reg = gatt_get_regcb(gatt_if);
-    tGATT_TCB       *p_tcb= gatt_find_tcb_by_addr(bd_addr);
+    tGATT_TCB       *p_tcb= gatt_find_tcb_by_addr(bd_addr, transport);
     BOOLEAN         status=FALSE;
 
     if (p_reg && p_tcb && (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN) )
@@ -1598,10 +1618,7 @@ BOOLEAN GATT_Listen (tGATT_IF gatt_if, BOOLEAN start, BD_ADDR_PTR bd_addr)
         p_reg->listening = start ? GATT_LISTEN_TO_ALL : GATT_LISTEN_TO_NONE;
     }
 
-    gatt_update_listen_mode();
-
-    return status;
-
+    return gatt_update_listen_mode();
 }
 
 #endif
index 1ee4ae3..60beaa7 100644 (file)
@@ -41,7 +41,8 @@
 #endif
 
 static void gatt_profile_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data);
-static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
+                                         BOOLEAN connected, tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
 
 static tGATT_CBACK gatt_profile_cback =
 {
@@ -87,14 +88,15 @@ UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda)
 ** Returns          Pointer to the found link conenction control block.
 **
 *******************************************************************************/
-tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda)
+static tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda, tBT_TRANSPORT transport)
 {
     UINT8 i_clcb;
     tGATT_PROFILE_CLCB    *p_clcb = NULL;
 
     for (i_clcb = 0, p_clcb= gatt_cb.profile_clcb; i_clcb < GATT_MAX_APPS; i_clcb++, p_clcb++)
     {
-        if (p_clcb->in_use && p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
+        if (p_clcb->in_use && p_clcb->transport == transport &&
+            p_clcb->connected && !memcmp(p_clcb->bda, bda, BD_ADDR_LEN))
         {
             return p_clcb;
         }
@@ -112,7 +114,7 @@ tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda)
 ** Returns           NULL if not found. Otherwise pointer to the connection link block.
 **
 *******************************************************************************/
-tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda)
+tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT tranport)
 {
     UINT8                   i_clcb = 0;
     tGATT_PROFILE_CLCB      *p_clcb = NULL;
@@ -124,6 +126,7 @@ tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda)
             p_clcb->in_use      = TRUE;
             p_clcb->conn_id     = conn_id;
             p_clcb->connected   = TRUE;
+            p_clcb->transport   = tranport;
             memcpy (p_clcb->bda, bda, BD_ADDR_LEN);
             break;
         }
@@ -215,7 +218,8 @@ static void gatt_profile_request_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_
 **
 *******************************************************************************/
 static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                        BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                        BOOLEAN connected, tGATT_DISCONN_REASON reason,
+                                        tBT_TRANSPORT transport)
 {
     UNUSED(gatt_if);
 
@@ -225,7 +229,7 @@ static void gatt_profile_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 co
 
     if (connected)
     {
-        if (gatt_profile_clcb_alloc(conn_id, bda) == NULL)
+        if (gatt_profile_clcb_alloc(conn_id, bda, transport) == NULL)
         {
             GATT_TRACE_ERROR0 ("gatt_profile_connect_cback: no_resource");
             return;
index 7dc99e1..b093725 100644 (file)
@@ -114,9 +114,8 @@ void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf)
     }
     else
     {
-        /* if this is a bad signature, assume from attacker, ignore it */
-        GATT_TRACE_ERROR0("Signature Verification Failed");
-        gatt_disconnect(p_tcb->peer_bda);
+        /* if this is a bad signature, assume from attacker, ignore it  */
+        GATT_TRACE_ERROR0("Signature Verification Failed, data ignored");
     }
 
     return;
@@ -157,7 +156,7 @@ void gatt_sec_check_complete(BOOLEAN sec_check_ok, tGATT_CLCB   *p_clcb, UINT8 s
 ** Returns
 **
 *******************************************************************************/
-void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
+void gatt_enc_cmpl_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
 {
     tGATT_TCB   *p_tcb;
     UINT8       sec_flag;
@@ -167,7 +166,7 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
     UNUSED(p_ref_data);
 
     GATT_TRACE_DEBUG0("gatt_enc_cmpl_cback");
-    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
     {
         if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENC_PENDING)
             return;
@@ -178,8 +177,9 @@ void gatt_enc_cmpl_cback(BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result)
             {
                 if (gatt_get_sec_act(p_tcb) == GATT_SEC_ENCRYPT_MITM )
                 {
-                    BTM_GetSecurityFlags(bd_addr, &sec_flag);
-                    if (sec_flag & sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
+                    BTM_GetSecurityFlagsByTransport(bd_addr, &sec_flag, transport);
+
+                    if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
                     {
                         status = TRUE;
                     }
@@ -232,7 +232,7 @@ void gatt_notify_enc_cmpl(BD_ADDR bd_addr)
     UINT16       count;
     UINT8        i = 0;
 
-    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE)) != NULL)
     {
         for (i = 0; i < GATT_MAX_APPS; i++)
         {
@@ -316,9 +316,7 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb )
     UINT8               sec_flag;
     tGATT_TCB           *p_tcb = p_clcb->p_tcb;
     tGATT_AUTH_REQ      auth_req = p_clcb->auth_req;
-
     BOOLEAN             is_link_encrypted= FALSE;
-    BOOLEAN             is_le_link=FALSE;
     BOOLEAN             is_link_key_known=FALSE;
     BOOLEAN             is_key_mitm=FALSE;
     UINT8               key_type;
@@ -327,8 +325,8 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb )
     if (auth_req == GATT_AUTH_REQ_NONE )
         return act;
 
-    is_le_link = BTM_UseLeLink(p_tcb->peer_bda);
-    BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag);
+    BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_clcb->p_tcb->transport);
+
     btm_ble_link_sec_check(p_tcb->peer_bda, auth_req, &sec_act);
 
     /* if a encryption is pending, need to wait */
@@ -336,24 +334,15 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb )
         auth_req != GATT_AUTH_REQ_NONE)
         return GATT_SEC_ENC_PENDING;
 
-    if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
+    if (sec_flag & (BTM_SEC_FLAG_ENCRYPTED| BTM_SEC_FLAG_LKEY_KNOWN))
     {
-        is_link_encrypted = TRUE;
-        is_link_key_known = TRUE;
-
-        if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
-        {
-            is_key_mitm = TRUE;
-        }
+        if (sec_flag & BTM_SEC_FLAG_ENCRYPTED)
+            is_link_encrypted = TRUE;
 
-    }
-    else if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN)
-    {
         is_link_key_known = TRUE;
+
         if (sec_flag & BTM_SEC_FLAG_LKEY_AUTHED)
-        {
             is_key_mitm = TRUE;
-        }
     }
 
     /* first check link key upgrade required or not */
@@ -377,7 +366,7 @@ tGATT_SEC_ACTION gatt_determine_sec_act(tGATT_CLCB *p_clcb )
     /* now check link needs to be encrypted or not if the link key upgrade is not required */
     if (act == GATT_SEC_OK)
     {
-        if (is_le_link &&
+        if (p_tcb->transport == BT_TRANSPORT_LE &&
             (p_clcb->operation == GATTC_OPTYPE_WRITE) &&
             (p_clcb->op_subtype == GATT_WRITE_NO_RSP))
         {
@@ -430,7 +419,7 @@ tGATT_STATUS gatt_get_link_encrypt_status(tGATT_TCB *p_tcb)
     tGATT_STATUS    encrypt_status = GATT_NOT_ENCRYPTED;
     UINT8           sec_flag=0;
 
-    BTM_GetSecurityFlags(p_tcb->peer_bda, &sec_flag);
+    BTM_GetSecurityFlagsByTransport(p_tcb->peer_bda, &sec_flag, p_tcb->transport);
 
     if ((sec_flag & BTM_SEC_FLAG_ENCRYPTED) && (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN))
     {
@@ -510,7 +499,7 @@ BOOLEAN gatt_security_check_start(tGATT_CLCB *p_clcb)
             {
                 GATT_TRACE_DEBUG0("gatt_security_check_start: Encrypt now or key upgreade first");
                 gatt_convert_sec_action(gatt_sec_act, &btm_ble_sec_act);
-                btm_status = BTM_SetEncryption(p_tcb->peer_bda, gatt_enc_cmpl_cback, &btm_ble_sec_act);
+                btm_status = BTM_SetEncryption(p_tcb->peer_bda, p_tcb->transport , gatt_enc_cmpl_cback, &btm_ble_sec_act);
                 if ( (btm_status != BTM_SUCCESS) && (btm_status != BTM_CMD_STARTED))
                 {
                     GATT_TRACE_ERROR1("gatt_security_check_start BTM_SetEncryption failed btm_status=%d", btm_status);
index e8c41fc..930cd35 100644 (file)
@@ -27,6 +27,7 @@
 #if BLE_INCLUDED == TRUE
 
 #include <string.h>
+#include "bt_utils.h"
 #include "gki.h"
 #include "gatt_int.h"
 
@@ -102,6 +103,13 @@ void gatt_act_discovery(tGATT_CLCB *p_clcb)
             cl_req.find_type_value.s_handle = p_clcb->s_handle;
             cl_req.find_type_value.e_handle = p_clcb->e_handle;
             cl_req.find_type_value.value_len = p_clcb->uuid.len;
+            /* if service type is 32 bits UUID, convert it now */
+            if (p_clcb->uuid.len == LEN_UUID_32)
+            {
+                cl_req.find_type_value.value_len = LEN_UUID_128;
+                gatt_convert_uuid32_to_uuid128(cl_req.find_type_value.value, p_clcb->uuid.uu.uuid32);
+            }
+            else
             memcpy (cl_req.find_type_value.value,  &p_clcb->uuid.uu, p_clcb->uuid.len);
         }
 
@@ -402,11 +410,13 @@ void gatt_send_prepare_write(tGATT_TCB  *p_tcb, tGATT_CLCB *p_clcb)
 ** Returns          void
 **
 *******************************************************************************/
-static void gatt_process_find_type_value_rsp (tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
+void gatt_process_find_type_value_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
 {
     tGATT_DISC_RES      result;
     UINT8               *p = p_data;
 
+    UNUSED(p_tcb);
+
     GATT_TRACE_DEBUG0("gatt_process_find_type_value_rsp ");
     /* unexpected response */
     if (p_clcb->operation != GATTC_OPTYPE_DISCOVERY || p_clcb->op_subtype != GATT_DISC_SRVC_BY_UUID)
@@ -445,11 +455,15 @@ static void gatt_process_find_type_value_rsp (tGATT_CLCB *p_clcb, UINT16 len, UI
 ** Returns          void
 **
 *******************************************************************************/
-static void gatt_process_read_info_rsp(tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_data)
+void gatt_process_read_info_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
+                                UINT16 len, UINT8 *p_data)
 {
     tGATT_DISC_RES  result;
     UINT8   *p = p_data, uuid_len = 0, type;
 
+    UNUSED(p_tcb);
+    UNUSED(op_code);
+
     if (len < GATT_INFO_RSP_MIN_LEN)
     {
         GATT_TRACE_ERROR0("invalid Info Response PDU received, discard.");
@@ -500,10 +514,14 @@ static void gatt_process_read_info_rsp(tGATT_CLCB *p_clcb, UINT16 len, UINT8 *p_
 ** Returns          void.
 **
 *******************************************************************************/
-static void gatt_proc_disc_error_rsp(tGATT_CLCB *p_clcb, UINT8 opcode, UINT8 reason)
+void gatt_proc_disc_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 opcode,
+                              UINT16 handle, UINT8 reason)
 {
     tGATT_STATUS    status = (tGATT_STATUS) reason;
 
+    UNUSED(p_tcb);
+    UNUSED(handle);
+
     GATT_TRACE_DEBUG2("gatt_proc_disc_error_rsp reason: %02x cmd_code %04x", reason, opcode);
 
     switch (opcode)
@@ -536,12 +554,16 @@ static void gatt_proc_disc_error_rsp(tGATT_CLCB *p_clcb, UINT8 opcode, UINT8 rea
 ** Returns          void
 **
 *******************************************************************************/
-static void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 *p_data)
+void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
+                            UINT16 len, UINT8 *p_data)
 {
     UINT8   opcode, reason, * p= p_data;
     UINT16  handle;
     tGATT_VALUE  *p_attr = (tGATT_VALUE *)p_clcb->p_attr_buf;
 
+    UNUSED(op_code);
+    UNUSED(len);
+
     GATT_TRACE_DEBUG0("gatt_process_error_rsp ");
     STREAM_TO_UINT8(opcode, p);
     STREAM_TO_UINT16(handle, p);
@@ -549,7 +571,7 @@ static void gatt_process_error_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 *
 
     if (p_clcb->operation == GATTC_OPTYPE_DISCOVERY)
     {
-        gatt_proc_disc_error_rsp(p_clcb, opcode, reason);
+        gatt_proc_disc_error_rsp(p_tcb, p_clcb, opcode, handle, reason);
     }
     else
     {
@@ -921,12 +943,14 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
 ** Returns          void
 **
 *******************************************************************************/
-static void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb,
-                                  UINT16 len, UINT8 *p_data)
+void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb,  UINT8 op_code,
+                           UINT16 len, UINT8 *p_data)
 {
     UINT16      offset = p_clcb->counter;
     UINT8       * p= p_data;
 
+    UNUSED(op_code);
+
     if (p_clcb->operation == GATTC_OPTYPE_READ)
     {
         if (p_clcb->op_subtype != GATT_READ_BY_HANDLE)
@@ -1169,7 +1193,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code,
         switch (op_code)
         {
             case GATT_RSP_ERROR:
-                gatt_process_error_rsp(p_tcb, p_clcb, p_data);
+                gatt_process_error_rsp(p_tcb, p_clcb, op_code, len, p_data);
                 break;
 
             case GATT_RSP_MTU:       /* 2 bytes mtu */
@@ -1177,7 +1201,7 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code,
                 break;
 
             case GATT_RSP_FIND_INFO:
-                gatt_process_read_info_rsp(p_clcb, len, p_data);
+                gatt_process_read_info_rsp(p_tcb, p_clcb, op_code, len, p_data);
                 break;
 
             case GATT_RSP_READ_BY_TYPE:
@@ -1188,11 +1212,11 @@ void gatt_client_handle_server_rsp (tGATT_TCB *p_tcb, UINT8 op_code,
             case GATT_RSP_READ:
             case GATT_RSP_READ_BLOB:
             case GATT_RSP_READ_MULTI:
-                gatt_process_read_rsp(p_tcb, p_clcb, len, p_data);
+                gatt_process_read_rsp(p_tcb, p_clcb, op_code, len, p_data);
                 break;
 
             case GATT_RSP_FIND_TYPE_VALUE: /* disc service with UUID */
-                gatt_process_find_type_value_rsp(p_clcb, len, p_data);
+                gatt_process_find_type_value_rsp(p_tcb, p_clcb, len, p_data);
                 break;
 
             case GATT_RSP_WRITE:
index 268bc7d..a1b0a8a 100644 (file)
@@ -27,6 +27,7 @@
 #if BLE_INCLUDED == TRUE
 
 #include "bt_trace.h"
+#include "bt_utils.h"
 
 #include <stdio.h>
 #include <string.h>
 **              L O C A L    F U N C T I O N     P R O T O T Y P E S            *
 *********************************************************************************/
 static BOOLEAN allocate_svc_db_buf(tGATT_SVC_DB *p_db);
-static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *p_uuid128, tGATT_PERM perm);
+static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm);
 static BOOLEAN deallocate_attr_in_db(tGATT_SVC_DB *p_db, void *p_attr);
 static BOOLEAN copy_extra_byte_in_db(tGATT_SVC_DB *p_db, void **p_dst, UINT16 len);
 
-static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri);
+static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri);
 static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
                                                 UINT16 handle, UINT16 offset, UINT32 trans_id);
 
@@ -58,7 +59,7 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
 ** Returns          Status of te operation.
 **
 *******************************************************************************/
-BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service,  BOOLEAN is_pri,
+BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service,  BOOLEAN is_pri,
                                UINT16 s_hdl, UINT16 num_handle)
 {
     if (!allocate_svc_db_buf(p_db))
@@ -74,9 +75,7 @@ BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service,  BOOLEAN is
     p_db->next_handle   = s_hdl;
     p_db->end_handle    = s_hdl + num_handle;
 
-    gatts_db_add_service_declaration(p_db, service, is_pri);
-
-    return TRUE;
+    return gatts_db_add_service_declaration(p_db, p_service, is_pri);
 }
 
 /*******************************************************************************
@@ -115,6 +114,7 @@ tBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db)
 **
 *******************************************************************************/
 static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
+                                                 UINT16 offset,
                                                  BOOLEAN read_long,
                                                  tGATT_SEC_FLAG sec_flag,
                                                  UINT8 key_size)
@@ -122,6 +122,7 @@ static tGATT_STATUS gatts_check_attr_readability(tGATT_ATTR16 *p_attr,
     UINT16          min_key_size;
     tGATT_PERM      perm = p_attr->permission;
 
+    UNUSED(offset);
     min_key_size = (((perm & GATT_ENCRYPT_KEY_SIZE_MASK) >> 12));
     if (min_key_size != 0 )
     {
@@ -223,14 +224,14 @@ static tGATT_STATUS read_attr_value (void *p_attr,
                       offset,
                       read_long);
 
-    status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, read_long, sec_flag, key_size);
-
-    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
-        uuid16 = p_attr16->uuid;
+    status = gatts_check_attr_readability((tGATT_ATTR16 *)p_attr, offset, read_long, sec_flag, key_size);
 
     if (status != GATT_SUCCESS)
         return status;
 
+    if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
+        uuid16 = p_attr16->uuid;
+
     status = GATT_NO_RESOURCES;
 
     if (read_long &&
@@ -261,6 +262,12 @@ static tGATT_STATUS read_attr_value (void *p_attr,
             {
                 UINT16_TO_STREAM(p, ((tGATT_ATTR16 *)(p_attr16->p_next))->uuid);
             }
+            /* convert a 32bits UUID to 128 bits */
+            else if (((tGATT_ATTR32 *)(p_attr16->p_next))->uuid_type == GATT_ATTR_UUID_TYPE_32)
+            {
+                gatt_convert_uuid32_to_uuid128 (p, ((tGATT_ATTR32 *)(p_attr16->p_next))->uuid);
+                p += LEN_UUID_128;
+            }
             else
             {
                 ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *)(p_attr16->p_next))->uuid, LEN_UUID_128);
@@ -271,13 +278,17 @@ static tGATT_STATUS read_attr_value (void *p_attr,
     }
     else if (uuid16 == GATT_UUID_INCLUDE_SERVICE)
     {
-        len = (p_attr16->p_value->incl_handle.service_type.len == 2) ? 6 : 4;
+        if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
+            len = 6;
+        else
+            len = 4;
+
         if (mtu >= len)
         {
             UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.s_handle);
             UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.e_handle);
 
-            if (p_attr16->p_value->incl_handle.service_type.len == 2)
+            if (p_attr16->p_value->incl_handle.service_type.len == LEN_UUID_16)
             {
                 UINT16_TO_STREAM(p, p_attr16->p_value->incl_handle.service_type.uu.uuid16);
             }
@@ -345,6 +356,11 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB   *p_tcb,
                 attr_uuid.len = LEN_UUID_16;
                 attr_uuid.uu.uuid16 = p_attr->uuid;
             }
+            else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
+            {
+                attr_uuid.len = LEN_UUID_32;
+                attr_uuid.uu.uuid32 = ((tGATT_ATTR32 *)p_attr)->uuid;
+            }
             else
             {
                 attr_uuid.len = LEN_UUID_128;
@@ -436,6 +452,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e
                                    tBT_UUID service)
 {
     tGATT_ATTR16      *p_attr;
+    tBT_UUID         uuid = {LEN_UUID_16, {GATT_UUID_INCLUDE_SERVICE}};
 
     GATT_TRACE_DEBUG3("gatts_add_included_service: s_hdl = 0x%04x e_hdl = 0x%04x uuid = 0x%04x",
                       s_handle, e_handle, service.uu.uuid16);
@@ -446,7 +463,7 @@ UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e
         return 0;
     }
 
-    if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, GATT_UUID_INCLUDE_SERVICE, NULL, GATT_PERM_READ)) != NULL)
+    if ((p_attr = (tGATT_ATTR16 *) allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
     {
         if (copy_extra_byte_in_db(p_db, (void **)&p_attr->p_value, sizeof(tGATT_INCL_SRVC)))
         {
@@ -485,11 +502,11 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
                                  tBT_UUID * p_char_uuid)
 {
     tGATT_ATTR16     *p_char_decl, *p_char_val;
-    UINT16          uuid16 = (p_char_uuid->len == LEN_UUID_16) ? p_char_uuid->uu.uuid16 : 0;
+    tBT_UUID        uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
 
     GATT_TRACE_DEBUG2("gatts_add_characteristic perm=0x%0x property=0x%0x", perm, property);
 
-    if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, GATT_UUID_CHAR_DECLARE, NULL, GATT_PERM_READ)) != NULL)
+    if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL)
     {
         if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL)))
         {
@@ -497,7 +514,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
             return 0;
         }
 
-        p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, uuid16, p_char_uuid->uu.uuid128, perm);
+        p_char_val = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_char_uuid, perm);
 
         if (p_char_val == NULL)
         {
@@ -578,14 +595,12 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
                              tBT_UUID *     p_descr_uuid)
 {
     tGATT_ATTR16    *p_char_dscptr;
-    UINT16    uuid16  = (p_descr_uuid->len == LEN_UUID_16)? p_descr_uuid->uu.uuid16 : 0;
 
     GATT_TRACE_DEBUG1("gatts_add_char_descr uuid=0x%04x", p_descr_uuid->uu.uuid16);
 
     /* Add characteristic descriptors */
     if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db,
-                                                             uuid16,
-                                                             p_descr_uuid->uu.uuid128,
+                                                             p_descr_uuid,
                                                              perm))
         == NULL)
     {
@@ -695,7 +710,7 @@ tGATT_STATUS gatts_read_attr_perm_check(tGATT_SVC_DB *p_db,
         {
             if (p_attr->handle == handle)
             {
-                status = gatts_check_attr_readability (p_attr,
+                status = gatts_check_attr_readability (p_attr, 0,
                                                        is_long,
                                                        sec_flag, key_size);
                 break;
@@ -812,7 +827,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
                     GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE");
                 }
                 /* LE security mode 2 attribute  */
-                else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED))
+                else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)
+                    &&  (perm & GATT_WRITE_ALLOWED) == 0)
                 {
                     status = GATT_INSUF_AUTHENTICATION;
                     GATT_TRACE_ERROR0( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required");
@@ -842,7 +858,8 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
                             break;
                         }
                     }
-                    else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128)
+                    else if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128 ||
+                                             p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
                     {
                          status = GATT_SUCCESS;
                     }
@@ -897,25 +914,32 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code,
 **
 **
 ** Parameter        p_db    : database pointer.
+**                  p_uuid:     pointer to attribute UUID
 **                  service : type of attribute to be added.
 **
 ** Returns          pointer to the newly allocated attribute.
 **
 *******************************************************************************/
-static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid128, tGATT_PERM perm)
+static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, tBT_UUID *p_uuid, tGATT_PERM perm)
 {
     tGATT_ATTR16    *p_attr16 = NULL, *p_last;
+    tGATT_ATTR32    *p_attr32 = NULL;
     tGATT_ATTR128   *p_attr128 = NULL;
-    UINT16      len = (uuid16 == 0) ? sizeof(tGATT_ATTR128): sizeof(tGATT_ATTR16);
+    UINT16      len = sizeof(tGATT_ATTR128);
 
-    GATT_TRACE_DEBUG1("allocate attr %d bytes ",len);
-
-    if (uuid16 == GATT_ILLEGAL_UUID && uuid128 == NULL)
+    if (p_uuid == NULL)
     {
         GATT_TRACE_ERROR0("illegal UUID");
         return NULL;
     }
 
+    if (p_uuid->len == LEN_UUID_16)
+        len = sizeof(tGATT_ATTR16);
+    else if (p_uuid->len == LEN_UUID_32)
+        len = sizeof(tGATT_ATTR32);
+
+    GATT_TRACE_DEBUG1("allocate attr %d bytes ",len);
+
     if (p_db->end_handle <= p_db->next_handle)
     {
         GATT_TRACE_DEBUG2("handle space full. handle_max = %d next_handle = %d",
@@ -931,21 +955,25 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1
             return NULL;
         }
     }
-
+    memset(p_db->p_free_mem, 0, len);
     p_attr16 = (tGATT_ATTR16 *) p_db->p_free_mem;
-    p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
-
-    memset(p_attr16, 0, len);
 
-    if (uuid16 != GATT_ILLEGAL_UUID)
+    if (p_uuid->len == LEN_UUID_16 && p_uuid->uu.uuid16 != GATT_ILLEGAL_UUID)
     {
         p_attr16->uuid_type = GATT_ATTR_UUID_TYPE_16;
-        p_attr16->uuid = uuid16;
+        p_attr16->uuid = p_uuid->uu.uuid16;
     }
-    else
+    else if (p_uuid->len == LEN_UUID_32)
     {
+        p_attr32 = (tGATT_ATTR32 *) p_db->p_free_mem;
+        p_attr32->uuid_type = GATT_ATTR_UUID_TYPE_32;
+        p_attr32->uuid = p_uuid->uu.uuid32;
+    }
+    else if (p_uuid->len == LEN_UUID_128)
+    {
+        p_attr128 = (tGATT_ATTR128 *) p_db->p_free_mem;
         p_attr128->uuid_type = GATT_ATTR_UUID_TYPE_128;
-        memcpy(p_attr128->uuid, uuid128, LEN_UUID_128);
+        memcpy(p_attr128->uuid, p_uuid->uu.uuid128, LEN_UUID_128);
     }
 
     p_db->p_free_mem += len;
@@ -970,9 +998,14 @@ static void *allocate_attr_in_db(tGATT_SVC_DB *p_db, UINT16 uuid16, UINT8 *uuid1
 
     if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16)
     {
-        GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid = [0x%04x] perm=0x%02x ",
+        GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid16 = [0x%04x] perm=0x%02x ",
                           p_attr16->handle, p_attr16->uuid, p_attr16->permission);
     }
+    else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32)
+    {
+        GATT_TRACE_DEBUG3("=====> handle = [0x%04x] uuid32 = [0x%08x] perm=0x%02x ",
+                          p_attr32->handle, p_attr32->uuid, p_attr32->permission);
+    }
     else
     {
         GATT_TRACE_DEBUG4("=====> handle = [0x%04x] uuid128 = [0x%02x:0x%02x] perm=0x%02x ",
@@ -1151,21 +1184,44 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
 ** Returns          void
 **
 *******************************************************************************/
-static void gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri)
+static BOOLEAN gatts_db_add_service_declaration(tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri)
 {
     tGATT_ATTR16  *p_attr;
-    UINT16      service_type = is_pri ? GATT_UUID_PRI_SERVICE: GATT_UUID_SEC_SERVICE;
+    tBT_UUID    uuid = {LEN_UUID_16, {0}};
+    BOOLEAN     rt = FALSE;
 
     GATT_TRACE_DEBUG0( "add_service_declaration");
 
+    if (is_pri)
+        uuid.uu.uuid16 = GATT_UUID_PRI_SERVICE;
+    else
+        uuid.uu.uuid16 = GATT_UUID_SEC_SERVICE;
+
     /* add service declration record */
-    if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, service_type, NULL, GATT_PERM_READ))) != NULL)
+    if ((p_attr = (tGATT_ATTR16 *)(allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ))) != NULL)
     {
         if (copy_extra_byte_in_db (p_db, (void **)&p_attr->p_value, sizeof(tBT_UUID)))
         {
-            memcpy (&p_attr->p_value->uuid, &service, sizeof(tBT_UUID));
+            if (p_service->len == LEN_UUID_16)
+            {
+                p_attr->p_value->uuid.len = LEN_UUID_16;
+                p_attr->p_value->uuid.uu.uuid16 = p_service->uu.uuid16;
+            }
+            else if (p_service->len == LEN_UUID_32)
+            {
+                p_attr->p_value->uuid.len = LEN_UUID_128;
+                gatt_convert_uuid32_to_uuid128(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid32);
+            }
+            else
+            {
+                p_attr->p_value->uuid.len = LEN_UUID_128;
+                memcpy(p_attr->p_value->uuid.uu.uuid128, p_service->uu.uuid128, LEN_UUID_128);
+            }
+            rt = TRUE;
         }
+
     }
+    return rt;
 }
 
 #endif /* BLE_INCLUDED */
index 1f81d63..b6bb95c 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "bt_target.h"
 
-#if BLE_INCLUDED == TRUE
-
 
 #include "bt_trace.h"
 #include "gatt_api.h"
@@ -169,6 +167,7 @@ typedef union
 */
 #define GATT_ATTR_UUID_TYPE_16      0
 #define GATT_ATTR_UUID_TYPE_128     1
+#define GATT_ATTR_UUID_TYPE_32      2
 typedef UINT8   tGATT_ATTR_UUID_TYPE;
 
 /* 16 bits UUID Attribute in server database
@@ -184,6 +183,20 @@ typedef struct
     UINT16                              uuid;
 } tGATT_ATTR16;
 
+/* 32 bits UUID Attribute in server database
+*/
+typedef struct
+{
+    void                                *p_next;  /* pointer to the next attribute,
+                                                    either tGATT_ATTR16, tGATT_ATTR32 or tGATT_ATTR128 */
+    tGATT_ATTR_VALUE                    *p_value;
+    tGATT_ATTR_UUID_TYPE                uuid_type;
+    tGATT_PERM                          permission;
+    UINT16                              handle;
+    UINT32                              uuid;
+} tGATT_ATTR32;
+
+
 /* 128 bits UUID Attribute in server database
 */
 typedef struct
@@ -340,6 +353,7 @@ typedef struct
     BUFFER_Q        pending_enc_clcb;   /* pending encryption channel q */
     tGATT_SEC_ACTION sec_act;
     BD_ADDR         peer_bda;
+    tBT_TRANSPORT   transport;
     UINT32          trans_id;
 
     UINT16          att_lcid;           /* L2CAP channel ID for ATT */
@@ -400,6 +414,7 @@ typedef struct
     BOOLEAN                 in_use;
     TIMER_LIST_ENT          rsp_timer_ent;  /* peer response timer */
     UINT8                   retry_count;
+
 } tGATT_CLCB;
 
 typedef struct
@@ -454,6 +469,7 @@ typedef struct
     BOOLEAN in_use;
     BOOLEAN connected;
     BD_ADDR bda;
+    tBT_TRANSPORT   transport;
 }tGATT_PROFILE_CLCB;
 
 typedef struct
@@ -524,9 +540,9 @@ GATT_API extern void gatt_set_err_rsp(BOOLEAN enable, UINT8 req_op_code, UINT8 e
 extern void gatt_init (void);
 
 /* from gatt_main.c */
-extern BOOLEAN gatt_disconnect (BD_ADDR rem_bda);
-extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr);
-extern BOOLEAN gatt_connect (BD_ADDR rem_bda,  tGATT_TCB *p_tcb);
+extern BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb);
+extern BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport);
+extern BOOLEAN gatt_connect (BD_ADDR rem_bda,  tGATT_TCB *p_tcb, tBT_TRANSPORT transport);
 extern void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf);
 extern void gatt_update_app_use_link_flag ( tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN is_add, BOOLEAN check_acl_link);
 
@@ -541,9 +557,8 @@ extern void gatt_add_a_bonded_dev_for_srv_chg (BD_ADDR bda);
 
 /* from gatt_attr.c */
 extern UINT16 gatt_profile_find_conn_id_by_bd_addr(BD_ADDR bda);
-extern tGATT_PROFILE_CLCB *gatt_profile_find_clcb_by_bd_addr(BD_ADDR bda);
 extern BOOLEAN gatt_profile_clcb_dealloc (UINT16 conn_id);
-extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda);
+extern tGATT_PROFILE_CLCB *gatt_profile_clcb_alloc (UINT16 conn_id, BD_ADDR bda, tBT_TRANSPORT transport);
 
 
 /* Functions provided by att_protocol.c */
@@ -558,7 +573,8 @@ extern UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 en
 extern BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid, UINT16 len, UINT8 **p_data);
 extern UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid);
 extern BOOLEAN gatt_uuid_compare(tBT_UUID src, tBT_UUID tar);
-extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size);
+extern void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32);
+extern void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size);
 extern void gatt_start_rsp_timer(UINT16 clcb_idx);
 extern void gatt_start_conf_timer(tGATT_TCB    *p_tcb);
 extern void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle);
@@ -573,13 +589,13 @@ extern tGATTS_PENDING_NEW_SRV_START *gatt_sr_is_new_srv_chg(tBT_UUID *p_app_uuid
 extern BOOLEAN gatt_is_srv_chg_ind_pending (tGATT_TCB *p_tcb);
 extern tGATTS_SRV_CHG *gatt_is_bda_in_the_srv_chg_clt_list (BD_ADDR bda);
 
-extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx);
+extern BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx, tBT_TRANSPORT *p_transport);
 extern void gatt_set_srv_chg(void);
 extern void gatt_delete_dev_from_srv_chg_clt_list(BD_ADDR bd_addr);
 extern tGATT_VALUE *gatt_add_pending_ind(tGATT_TCB  *p_tcb, tGATT_VALUE *p_ind);
 extern tGATTS_PENDING_NEW_SRV_START *gatt_add_pending_new_srv_start( tGATTS_HNDL_RANGE *p_new_srv_start);
 extern void gatt_free_srvc_db_buffer_app_id(tBT_UUID *p_app_id);
-extern void gatt_update_listen_mode(void);
+extern BOOLEAN gatt_update_listen_mode(void);
 
 /* reserved handle list */
 extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
@@ -635,16 +651,16 @@ extern BOOLEAN gatt_find_app_hold_link(tGATT_TCB *p_tcb, UINT8 start_idx, UINT8
 extern UINT8 gatt_num_apps_hold_link(tGATT_TCB *p_tcb);
 extern UINT8 gatt_num_clcb_by_bd_addr(BD_ADDR bda);
 extern tGATT_TCB * gatt_find_tcb_by_cid(UINT16 lcid);
-extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda);
+extern tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport);
 extern tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx);
-extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda);
-
+extern tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport);
+extern BOOLEAN gatt_send_ble_burst_data (BD_ADDR remote_bda,  BT_HDR *p_buf);
 
 /* GATT client functions */
 extern void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb);
 extern UINT8 gatt_send_write_msg(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 op_code, UINT16 handle,
                                  UINT16 len, UINT16 offset, UINT8 *p_data);
-extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason);
+extern void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport);
 extern void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data);
 
 extern void gatt_act_discovery(tGATT_CLCB *p_clcb);
@@ -667,7 +683,7 @@ extern tGATT_SEC_ACTION gatt_get_sec_act(tGATT_TCB *p_tcb);
 extern void gatt_set_sec_act(tGATT_TCB *p_tcb, tGATT_SEC_ACTION sec_act);
 
 /* gatt_db.c */
-extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
+extern BOOLEAN gatts_init_service_db (tGATT_SVC_DB *p_db, tBT_UUID *p_service, BOOLEAN is_pri, UINT16 s_hdl, UINT16 num_handle);
 extern UINT16 gatts_add_included_service (tGATT_SVC_DB *p_db, UINT16 s_handle, UINT16 e_handle, tBT_UUID service);
 extern UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tGATT_CHAR_PROP property, tBT_UUID *p_char_uuid);
 extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID *p_dscp_uuid);
@@ -684,4 +700,4 @@ extern tBT_UUID * gatts_get_service_uuid (tGATT_SVC_DB *p_db);
 extern void gatt_reset_bgdev_list(void);
 #endif
 
-#endif /* BLE_INCLUDED */
+
index d5e017b..59c6759 100644 (file)
@@ -44,7 +44,7 @@
 /********************************************************************************/
 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
 /********************************************************************************/
-static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason);
+static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport);
 static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf);
 
 static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 l2cap_cid, UINT16 psm, UINT8 l2cap_id);
@@ -143,15 +143,14 @@ void gatt_init (void)
 ** Returns          TRUE if connection is started, otherwise return FALSE.
 **
 *******************************************************************************/
-BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
+BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb, tBT_TRANSPORT transport)
 {
     BOOLEAN             gatt_ret = FALSE;
 
     if (gatt_get_ch_state(p_tcb) != GATT_CH_OPEN)
         gatt_set_ch_state(p_tcb, GATT_CH_CONN);
 
-    /* select the physical link for GATT connection */
-    if (BTM_UseLeLink(rem_bda))
+    if (transport == BT_TRANSPORT_LE)
     {
         p_tcb->att_lcid = L2CAP_ATT_CID;
         gatt_ret = L2CA_ConnectFixedChnl (L2CAP_ATT_CID, rem_bda);
@@ -171,15 +170,14 @@ BOOLEAN gatt_connect (BD_ADDR rem_bda, tGATT_TCB *p_tcb)
 **
 ** Description      This function is called to disconnect to an ATT device.
 **
-** Parameter        rem_bda: remote device address to disconnect from.
+** Parameter        p_tcb: pointer to the TCB to disconnect.
 **
 ** Returns          TRUE: if connection found and to be disconnected; otherwise
 **                  return FALSE.
 **
 *******************************************************************************/
-BOOLEAN gatt_disconnect (BD_ADDR rem_bda)
+BOOLEAN gatt_disconnect (tGATT_TCB *p_tcb)
 {
-    tGATT_TCB           *p_tcb = gatt_find_tcb_by_addr(rem_bda);
     BOOLEAN             ret = FALSE;
     tGATT_CH_STATE      ch_state;
     GATT_TRACE_DEBUG0 ("gatt_disconnect ");
@@ -194,12 +192,12 @@ BOOLEAN gatt_disconnect (BD_ADDR rem_bda)
                 if (ch_state == GATT_CH_OPEN)
                 {
                     /* only LCB exist between remote device and local */
-                    ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, rem_bda);
+                    ret = L2CA_RemoveFixedChnl (L2CAP_ATT_CID, p_tcb->peer_bda);
                 }
                 else
                 {
                     gatt_set_ch_state(p_tcb, GATT_CH_CLOSING);
-                    ret = L2CA_CancelBleConnectReq (rem_bda);
+                    ret = L2CA_CancelBleConnectReq (p_tcb->peer_bda);
                 }
             }
             else
@@ -286,13 +284,14 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN
 
     if (check_acl_link &&
         p_tcb &&
-        (BTM_GetHCIConnHandle(p_tcb->peer_bda) != GATT_INVALID_ACL_HANDLE))
+         p_tcb->att_lcid == L2CAP_ATT_CID && /* only update link idle timer for fixed channel */
+        (BTM_GetHCIConnHandle(p_tcb->peer_bda, p_tcb->transport) != GATT_INVALID_ACL_HANDLE))
     {
         if (is_add)
         {
             GATT_TRACE_DEBUG0("GATT disables link idle timer");
             /* acl link is connected disable the idle timeout */
-            GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT);
+            GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
         }
         else
         {
@@ -301,7 +300,7 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN
                 /* acl link is connected but no application needs to use the link
                    so set the timeout value to GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP seconds */
                 GATT_TRACE_DEBUG1("GATT starts link idle timer =%d sec", GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
-                GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP);
+                GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP, p_tcb->transport);
             }
 
         }
@@ -317,25 +316,22 @@ void gatt_update_app_use_link_flag (tGATT_IF gatt_if, tGATT_TCB *p_tcb, BOOLEAN
 ** Returns          void.
 **
 *******************************************************************************/
-BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr)
+BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr, tBT_TRANSPORT transport)
 {
     BOOLEAN     ret = FALSE;
     tGATT_TCB   *p_tcb;
     UINT8       st;
 
-    GATT_TRACE_DEBUG0("gatt_act_connect");
-
-    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) != NULL)
+    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr, transport)) != NULL)
     {
         ret = TRUE;
         st = gatt_get_ch_state(p_tcb);
 
         /* before link down, another app try to open a GATT connection */
         if(st == GATT_CH_OPEN &&  gatt_num_apps_hold_link(p_tcb) == 0 &&
-            /* only connection on fix channel when the l2cap channel is already open */
-            p_tcb->att_lcid == L2CAP_ATT_CID )
+            transport == BT_TRANSPORT_LE )
         {
-            if (!gatt_connect(bd_addr,  p_tcb))
+            if (!gatt_connect(bd_addr,  p_tcb, transport))
                 ret = FALSE;
         }
         else if(st == GATT_CH_CLOSING)
@@ -346,9 +342,9 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr)
     }
     else
     {
-        if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL)
+        if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, transport)) != NULL)
         {
-            if (!gatt_connect(bd_addr,  p_tcb))
+            if (!gatt_connect(bd_addr,  p_tcb, transport))
             {
                 GATT_TRACE_ERROR0("gatt_connect failed");
                 memset(p_tcb, 0, sizeof(tGATT_TCB));
@@ -380,19 +376,22 @@ BOOLEAN gatt_act_connect (tGATT_REG *p_reg, BD_ADDR bd_addr)
 **                      connected (conn = TRUE)/disconnected (conn = FALSE).
 **
 *******************************************************************************/
-static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason)
+static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected,
+                                   UINT16 reason, tBT_TRANSPORT transport)
 {
 
-    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr);
-
+    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, transport);
     BOOLEAN                 check_srv_chg = FALSE;
     tGATTS_SRV_CHG          *p_srv_chg_clt=NULL;
 
+    /* ignore all fixed channel connect/disconnect on BR/EDR link for GATT */
+    if (transport == BT_TRANSPORT_BR_EDR)
+        return;
+
     GATT_TRACE_DEBUG3 ("GATT   ATT protocol channel with BDA: %08x%04x is %s",
                        (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
                        (bd_addr[4]<<8)+bd_addr[5], (connected) ? "connected" : "disconnected");
 
-
     if ((p_srv_chg_clt = gatt_is_bda_in_the_srv_chg_clt_list(bd_addr)) != NULL)
     {
         check_srv_chg = TRUE;
@@ -405,11 +404,6 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re
 
     if (connected)
     {
-        GATT_TRACE_DEBUG1("connected is TRUE reason=%d",reason );
-        /* BR/EDR lik, ignore this callback */
-        if (reason == 0)
-            return;
-
         /* do we have a channel initiating a connection? */
         if (p_tcb)
         {
@@ -426,9 +420,10 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re
             }
         }
         /* this is incoming connection or background connection callback */
+
         else
         {
-            if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) != NULL)
+            if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_LE)) != NULL)
             {
                 p_tcb->att_lcid = L2CAP_ATT_CID;
 
@@ -450,7 +445,7 @@ static void gatt_le_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 re
     }
     else
     {
-        gatt_cleanup_upon_disc(bd_addr, reason);
+        gatt_cleanup_upon_disc(bd_addr, reason, transport);
         GATT_TRACE_DEBUG0 ("ATT disconnected");
     }
 }
@@ -475,7 +470,7 @@ static void gatt_le_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf)
     tGATT_TCB    *p_tcb;
 
     /* Find CCB based on bd addr */
-    if ((p_tcb = gatt_find_tcb_by_addr (bd_addr)) != NULL &&
+    if ((p_tcb = gatt_find_tcb_by_addr (bd_addr, BT_TRANSPORT_LE)) != NULL &&
         gatt_get_ch_state(p_tcb) >= GATT_CH_OPEN)
     {
         gatt_data_process(p_tcb, p_buf);
@@ -508,7 +503,7 @@ static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 lcid, UINT16
     /* do we already have a control channel for this peer? */
     UINT8       result = L2CAP_CONN_OK;
     tL2CAP_CFG_INFO cfg;
-    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_BR_EDR);
     UNUSED(psm);
 
     GATT_TRACE_ERROR1("Connection indication cid = %d", lcid);
@@ -516,7 +511,7 @@ static void gatt_l2cif_connect_ind_cback (BD_ADDR  bd_addr, UINT16 lcid, UINT16
     if (p_tcb == NULL)
     {
         /* allocate tcb */
-        if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr)) == NULL)
+        if ((p_tcb = gatt_allocate_tcb_by_bdaddr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
         {
             /* no tcb available, reject L2CAP connection */
             result = L2CAP_CONN_NO_RESOURCES;
@@ -586,7 +581,7 @@ void gatt_l2cif_connect_cfm_cback(UINT16 lcid, UINT16 result)
             /* else initiating connection failure */
             else
             {
-                gatt_cleanup_upon_disc(p_tcb->peer_bda, GATT_CONN_L2C_FAILURE);
+                gatt_cleanup_upon_disc(p_tcb->peer_bda, result, GATT_TRANSPORT_BR_EDR);
             }
         }
         else /* wrong state, disconnect it */
@@ -701,11 +696,8 @@ void gatt_l2cif_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
                 }
                 else
                 {
-                    if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) &&
-                        btm_sec_is_le_capable_dev(p_tcb->peer_bda))
-                    {
+                    if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
                         gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
-                    }
                 }
 
                 /* send callback */
@@ -738,20 +730,17 @@ void gatt_l2cif_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
             /* send L2CAP disconnect response */
             L2CA_DisconnectRsp(lcid);
         }
-
         if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
         {
-            if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) &&
-                btm_sec_is_le_capable_dev(p_tcb->peer_bda))
+            if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
                 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
         }
-
         /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
-        if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0)
+        if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
             reason = GATT_CONN_TERMINATE_PEER_USER;
 
         /* send disconnect callback */
-        gatt_cleanup_upon_disc(p_tcb->peer_bda, reason);
+        gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
     }
 }
 
@@ -777,17 +766,16 @@ void gatt_l2cif_disconnect_cfm_cback(UINT16 lcid, UINT16 result)
         /* If the device is not in the service changed client list, add it... */
         if (gatt_is_bda_in_the_srv_chg_clt_list(p_tcb->peer_bda) == NULL)
         {
-            if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda) &&
-                btm_sec_is_le_capable_dev(p_tcb->peer_bda))
+            if (btm_sec_is_a_bonded_dev(p_tcb->peer_bda))
                 gatt_add_a_bonded_dev_for_srv_chg(p_tcb->peer_bda);
         }
 
         /* send disconnect callback */
         /* if ACL link is still up, no reason is logged, l2cap is disconnect from peer */
-        if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda)) == 0)
+        if ((reason = L2CA_GetDisconnectReason(p_tcb->peer_bda, p_tcb->transport)) == 0)
             reason = GATT_CONN_TERMINATE_LOCAL_HOST;
 
-        gatt_cleanup_upon_disc(p_tcb->peer_bda, reason);
+        gatt_cleanup_upon_disc(p_tcb->peer_bda, reason, GATT_TRANSPORT_BR_EDR);
     }
 }
 
@@ -846,16 +834,17 @@ static void gatt_send_conn_cback(tGATT_TCB *p_tcb)
             if (p_reg->app_cb.p_conn_cb)
             {
                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
-                (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id, TRUE, 0);
+                (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if, p_tcb->peer_bda, conn_id,
+                                          TRUE, 0, p_tcb->transport);
             }
         }
     }
 
 
-    if (gatt_num_apps_hold_link(p_tcb))
+    if (gatt_num_apps_hold_link(p_tcb) &&  p_tcb->att_lcid == L2CAP_ATT_CID )
     {
         /* disable idle timeout if one or more clients are holding the link disable the idle timer */
-        GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT);
+        GATT_SetIdleTimeout(p_tcb->peer_bda, GATT_LINK_NO_IDLE_TIMEOUT, p_tcb->transport);
     }
 }
 
@@ -894,7 +883,6 @@ void gatt_data_process (tGATT_TCB *p_tcb, BT_HDR *p_buf)
             if (op_code == GATT_SIGN_CMD_WRITE)
             {
                 gatt_verify_signature(p_tcb, p_buf);
-                return;
             }
             else
             {
@@ -1068,6 +1056,7 @@ void gatt_proc_srv_chg (void)
     BD_ADDR             bda;
     BOOLEAN             srv_chg_ind_pending=FALSE;
     tGATT_TCB           *p_tcb;
+    tBT_TRANSPORT      transport;
 
     GATT_TRACE_DEBUG0 ("gatt_proc_srv_chg");
 
@@ -1075,7 +1064,7 @@ void gatt_proc_srv_chg (void)
     {
         gatt_set_srv_chg();
         start_idx =0;
-        while (gatt_find_the_connected_bda(start_idx, bda, &found_idx))
+        while (gatt_find_the_connected_bda(start_idx, bda, &found_idx, &transport))
         {
             p_tcb = &gatt_cb.tcb[found_idx];;
             srv_chg_ind_pending  = gatt_is_srv_chg_ind_pending(p_tcb);
index c006dd2..226aad0 100644 (file)
@@ -328,7 +328,7 @@ tGATT_STATUS gatt_sr_process_app_rsp (tGATT_TCB *p_tcb, tGATT_IF gatt_if,
 ** Returns          void
 **
 *******************************************************************************/
-static void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT8 *p_data)
+void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data)
 {
     UINT8   *p = p_data, flag, i = 0;
     UINT32  trans_id = 0;
@@ -336,11 +336,13 @@ static void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT8
     tGATT_IF gatt_if;
     UINT16  conn_id;
 
+    UNUSED(len);
+
 #if GATT_CONFORMANCE_TESTING == TRUE
     if (gatt_cb.enable_err_rsp && gatt_cb.req_op_code == op_code)
     {
-        GATT_TRACE_DEBUG2("conf test forced err rsp for %s error status=%d",
-                           __FUNCTION__,gatt_cb.err_status);
+        GATT_TRACE_DEBUG1("Conformance tst: forced err rspv for Execute Write: error status=%d",
+        gatt_cb.err_status);
 
         gatt_send_error_rsp (p_tcb, gatt_cb.err_status, gatt_cb.req_op_code, gatt_cb.handle, FALSE);
 
@@ -409,7 +411,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
     p_tcb->sr_cmd.multi_req.num_handles = 0;
 
     gatt_sr_get_sec_info(p_tcb->peer_bda,
-                         (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+                         p_tcb->transport,
                          &sec_flag,
                          &key_size);
 
@@ -527,7 +529,7 @@ void gatt_process_read_multi_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
 *******************************************************************************/
 static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_tcb,
                                                     UINT8 op_code, UINT16 s_hdl,
-                                                    UINT16 e_hdl, tBT_UUID value)
+                                                    UINT16 e_hdl, UINT8 *p_data, tBT_UUID value)
 {
     tGATT_STATUS    status = GATT_NOT_FOUND;
     UINT8           handle_len =4, *p ;
@@ -536,6 +538,8 @@ static tGATT_STATUS gatt_build_primary_service_rsp (BT_HDR *p_msg, tGATT_TCB *p_
     tGATT_SRV_LIST_ELEM  *p_srv=NULL;
     tBT_UUID       *p_uuid;
 
+    UNUSED(p_data);
+
     p = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
 
     p_srv = p_list->p_first;
@@ -643,7 +647,7 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg,
         if (p_attr->handle >= s_hdl)
         {
             if (p_msg->offset == 0)
-                p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128) ? GATT_INFO_TYPE_PAIR_128 : GATT_INFO_TYPE_PAIR_16;
+                p_msg->offset = (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) ? GATT_INFO_TYPE_PAIR_16 : GATT_INFO_TYPE_PAIR_128;
 
             if (len >= info_pair_len[p_msg->offset - 1])
             {
@@ -652,12 +656,17 @@ static tGATT_STATUS gatt_build_find_info_rsp(tGATT_SR_REG *p_rcb, BT_HDR *p_msg,
                     UINT16_TO_STREAM(p, p_attr->handle);
                     UINT16_TO_STREAM(p, p_attr->uuid);
                 }
-                else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 &&
-                         p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128  )
+                else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_128  )
                 {
                     UINT16_TO_STREAM(p, p_attr->handle);
                     ARRAY_TO_STREAM (p, ((tGATT_ATTR128 *) p_attr)->uuid, LEN_UUID_128);
                 }
+                else if (p_msg->offset == GATT_INFO_TYPE_PAIR_128 && p_attr->uuid_type == GATT_ATTR_UUID_TYPE_32)
+                {
+                    UINT16_TO_STREAM(p, p_attr->handle);
+                    gatt_convert_uuid32_to_uuid128(p, ((tGATT_ATTR32 *) p_attr)->uuid);
+                    p += LEN_UUID_128;
+                }
                 else
                 {
                     GATT_TRACE_ERROR0("format mismatch");
@@ -764,6 +773,7 @@ void gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 l
     BT_HDR          *p_msg = NULL;
     UINT16          msg_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
 
+    memset (&value, 0, sizeof(tBT_UUID));
     reason = gatts_validate_packet_format(op_code, &len, &p_data, &uuid, &s_hdl, &e_hdl);
 
     if (reason == GATT_SUCCESS)
@@ -786,7 +796,7 @@ void gatts_process_primary_service_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 l
                 else
                 {
                     memset(p_msg, 0, msg_len);
-                    reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, value);
+                    reason = gatt_build_primary_service_rsp (p_msg, p_tcb, op_code, s_hdl, e_hdl, p_data, value);
                 }
             }
         }
@@ -1025,7 +1035,7 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
                       p_rcb->e_hdl < s_hdl))
                 {
                     gatt_sr_get_sec_info(p_tcb->peer_bda,
-                                         (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+                                         p_tcb->transport,
                                          &sec_flag,
                                          &key_size);
 
@@ -1120,7 +1130,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
     }
 
     gatt_sr_get_sec_info(p_tcb->peer_bda,
-                         (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+                         p_tcb->transport,
                          &sec_flag,
                          &key_size);
 
@@ -1173,7 +1183,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
 **
 *******************************************************************************/
 static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8 op_code,
-                                   UINT16 handle, UINT8 *p_data)
+                                   UINT16 handle, UINT16 len, UINT8 *p_data)
 {
     UINT16          buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
     tGATT_STATUS    reason;
@@ -1181,6 +1191,7 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
     UINT8           sec_flag, key_size, *p;
     UINT16          offset = 0, value_len = 0;
 
+    UNUSED (len);
     if ((p_msg =  (BT_HDR *)GKI_getbuf(buf_len)) == NULL)
     {
         GATT_TRACE_ERROR0("gatts_process_find_info failed. no resources.");
@@ -1199,7 +1210,7 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
         buf_len = p_tcb->payload_size - 1;
 
         gatt_sr_get_sec_info(p_tcb->peer_bda,
-                             (BOOLEAN)(p_tcb->att_lcid == L2CAP_ATT_CID),
+                             p_tcb->transport,
                              &sec_flag,
                              &key_size);
 
@@ -1289,7 +1300,7 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
                         {
                             case GATT_REQ_READ: /* read char/char descriptor value */
                             case GATT_REQ_READ_BLOB:
-                                gatts_process_read_req(p_tcb, p_rcb, op_code, handle, p);
+                                gatts_process_read_req(p_tcb, p_rcb, op_code, handle, len, p);
                                 break;
 
                             case GATT_REQ_WRITE: /* write char/char descriptor value */
@@ -1506,7 +1517,7 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code,
                 break;
 
             case GATT_REQ_EXEC_WRITE:
-                gatt_process_exec_write_req (p_tcb, op_code, p_data);
+                gatt_process_exec_write_req (p_tcb, op_code, len, p_data);
                 break;
 
             case GATT_REQ_READ_MULTI:
index 978c88c..d3d4c92 100644 (file)
@@ -705,7 +705,8 @@ BOOLEAN gatt_remove_an_item_from_list(tGATT_HDL_LIST_INFO *p_list, tGATT_HDL_LIS
 ** Returns           TRUE if found
 **
 *******************************************************************************/
-BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx)
+BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found_idx,
+                                    tBT_TRANSPORT *p_transport)
 {
     UINT8 i;
     BOOLEAN found = FALSE;
@@ -717,6 +718,7 @@ BOOLEAN gatt_find_the_connected_bda(UINT8 start_idx, BD_ADDR bda, UINT8 *p_found
         {
             memcpy( bda, gatt_cb.tcb[i].peer_bda, BD_ADDR_LEN);
             *p_found_idx = i;
+            *p_transport = gatt_cb.tcb[i].transport;
             found = TRUE;
             GATT_TRACE_DEBUG6("gatt_find_the_connected_bda bda :%02x-%02x-%02x-%02x-%02x-%02x",
                               bda[0],  bda[1], bda[2],  bda[3], bda[4],  bda[5]);
@@ -833,19 +835,19 @@ BOOLEAN gatt_is_bda_connected(BD_ADDR bda)
 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
 **
 *******************************************************************************/
-UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda)
+UINT8 gatt_find_i_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
 {
-    UINT8 i = 0, j = GATT_INDEX_INVALID;
+    UINT8 i = 0;
 
     for ( ; i < GATT_MAX_PHY_CHANNEL; i ++)
     {
-        if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN))
+        if (!memcmp(gatt_cb.tcb[i].peer_bda, bda, BD_ADDR_LEN) &&
+            gatt_cb.tcb[i].transport == transport)
         {
-            j = i;
-            break;
+            return i;
         }
     }
-    return j;
+    return GATT_INDEX_INVALID;
 }
 
 
@@ -877,12 +879,12 @@ tGATT_TCB * gatt_get_tcb_by_idx(UINT8 tcb_idx)
 ** Returns           NULL if not found. Otherwise index to the tcb.
 **
 *******************************************************************************/
-tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda)
+tGATT_TCB * gatt_find_tcb_by_addr(BD_ADDR bda, tBT_TRANSPORT transport)
 {
     tGATT_TCB   *p_tcb = NULL;
     UINT8 i = 0;
 
-    if ((i = gatt_find_i_tcb_by_addr(bda)) != GATT_INDEX_INVALID)
+    if ((i = gatt_find_i_tcb_by_addr(bda, transport)) != GATT_INDEX_INVALID)
         p_tcb = &gatt_cb.tcb[i];
 
     return p_tcb;
@@ -919,14 +921,14 @@ UINT8 gatt_find_i_tcb_free(void)
 ** Returns           GATT_INDEX_INVALID if not found. Otherwise index to the tcb.
 **
 *******************************************************************************/
-tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda)
+tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport)
 {
     UINT8 i = 0;
     BOOLEAN allocated = FALSE;
     tGATT_TCB    *p_tcb = NULL;
 
     /* search for existing tcb with matching bda    */
-    i = gatt_find_i_tcb_by_addr(bda);
+    i = gatt_find_i_tcb_by_addr(bda, transport);
     /* find free tcb */
     if (i == GATT_INDEX_INVALID)
     {
@@ -944,6 +946,7 @@ tGATT_TCB * gatt_allocate_tcb_by_bdaddr(BD_ADDR bda)
             GKI_init_q (&p_tcb->pending_ind_q);
             p_tcb->in_use = TRUE;
             p_tcb->tcb_idx = i;
+            p_tcb->transport = transport;
         }
         memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN);
     }
@@ -970,6 +973,23 @@ void gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16
 
 /*******************************************************************************
 **
+** Function         gatt_convert_uuid32_to_uuid128
+**
+** Description      Convert a 32 bits UUID to be an standard 128 bits one.
+**
+** Returns          TRUE if two uuid match; FALSE otherwise.
+**
+*******************************************************************************/
+void gatt_convert_uuid32_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT32 uuid_32)
+{
+    UINT8   *p = &uuid_128[LEN_UUID_128 - 4];
+
+    memcpy (uuid_128, base_uuid, LEN_UUID_128);
+
+    UINT32_TO_STREAM(p, uuid_32);
+}
+/*******************************************************************************
+**
 ** Function         gatt_uuid_compare
 **
 ** Description      Compare two UUID to see if they are the same.
@@ -989,11 +1009,17 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
     }
 
     /* If both are 16-bit, we can do a simple compare */
-    if (src.len == 2 && tar.len == 2)
+    if (src.len == LEN_UUID_16 && tar.len == LEN_UUID_16)
     {
         return src.uu.uuid16 == tar.uu.uuid16;
     }
 
+    /* If both are 32-bit, we can do a simple compare */
+    if (src.len == LEN_UUID_32 && tar.len == LEN_UUID_32)
+    {
+        return src.uu.uuid32 == tar.uu.uuid32;
+    }
+
     /* One or both of the UUIDs is 128-bit */
     if (src.len == LEN_UUID_16)
     {
@@ -1001,6 +1027,11 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
         gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
         ps = su;
     }
+    else if (src.len == LEN_UUID_32)
+    {
+        gatt_convert_uuid32_to_uuid128(su, src.uu.uuid32);
+        ps = su;
+    }
     else
         ps = src.uu.uuid128;
 
@@ -1010,6 +1041,12 @@ BOOLEAN gatt_uuid_compare (tBT_UUID src, tBT_UUID tar)
         gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
         pt = tu;
     }
+    else if (tar.len == LEN_UUID_32)
+    {
+        /* convert a 32 bits UUID to 128 bits value */
+        gatt_convert_uuid32_to_uuid128(tu, tar.uu.uuid32);
+        pt = tu;
+    }
     else
         pt = tar.uu.uuid128;
 
@@ -1035,6 +1072,12 @@ UINT8 gatt_build_uuid_to_stream(UINT8 **p_dst, tBT_UUID uuid)
         UINT16_TO_STREAM (p, uuid.uu.uuid16);
         len = LEN_UUID_16;
     }
+    else if (uuid.len == LEN_UUID_32) /* always convert 32 bits into 128 bits as alwats */
+    {
+        gatt_convert_uuid32_to_uuid128(p, uuid.uu.uuid32);
+        p += LEN_UUID_128;
+        len = LEN_UUID_128;
+    }
     else if (uuid.len == LEN_UUID_128)
     {
         ARRAY_TO_STREAM (p, uuid.uu.uuid128, LEN_UUID_128);
@@ -1090,7 +1133,11 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 *
                     STREAM_TO_UINT16(p_uuid_rec->uu.uuid16, p_uuid);
                 }
                 else
-                    is_base_uuid = FALSE;
+                {
+                    p_uuid += (LEN_UUID_128 - LEN_UUID_32);
+                    p_uuid_rec->len = LEN_UUID_32;
+                    STREAM_TO_UINT32(p_uuid_rec->uu.uuid32, p_uuid);
+                }
             }
             if (!is_base_uuid)
             {
@@ -1100,6 +1147,9 @@ BOOLEAN gatt_parse_uuid_from_cmd(tBT_UUID *p_uuid_rec, UINT16 uuid_size, UINT8 *
             *p_data += LEN_UUID_128;
             break;
 
+        /* do not allow 32 bits UUID in ATT PDU now */
+        case LEN_UUID_32:
+            GATT_TRACE_ERROR0("DO NOT ALLOW 32 BITS UUID IN ATT PDU");
         case 0:
         default:
             if (uuid_size != 0) ret = FALSE;
@@ -1200,7 +1250,7 @@ void gatt_rsp_timeout(TIMER_LIST_ENT *p_tle)
     }
 
     GATT_TRACE_WARNING0("gatt_rsp_timeout disconnecting...");
-    gatt_disconnect (p_clcb->p_tcb->peer_bda);
+    gatt_disconnect (p_clcb->p_tcb);
 }
 
 /*******************************************************************************
@@ -1330,12 +1380,11 @@ UINT8 gatt_sr_alloc_rcb(tGATT_HDL_LIST_ELEM *p_list )
 ** Returns          void
 **
 *******************************************************************************/
-void gatt_sr_get_sec_info(BD_ADDR rem_bda, BOOLEAN le_conn, UINT8 *p_sec_flag, UINT8 *p_key_size)
+void gatt_sr_get_sec_info(BD_ADDR rem_bda, tBT_TRANSPORT transport, UINT8 *p_sec_flag, UINT8 *p_key_size)
 {
     UINT8           sec_flag = 0;
-    UNUSED(le_conn);
 
-    BTM_GetSecurityFlags(rem_bda, &sec_flag);
+    BTM_GetSecurityFlagsByTransport(rem_bda, &sec_flag, transport);
 
     sec_flag &= (GATT_SEC_FLAG_LKEY_UNAUTHED | GATT_SEC_FLAG_LKEY_AUTHED | GATT_SEC_FLAG_ENCRYPTED);
 
@@ -1438,6 +1487,14 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl)
         case LEN_UUID_16:
             SDP_AddServiceClassIdList(sdp_handle, 1, &p_uuid->uu.uuid16);
             break;
+
+        case LEN_UUID_32:
+            UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES);
+            UINT32_TO_BE_STREAM (p, p_uuid->uu.uuid32);
+            SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE,
+                              (UINT32) (p - buff), buff);
+            break;
+
         case LEN_UUID_128:
             UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES);
             ARRAY_TO_BE_STREAM (p, p_uuid->uu.uuid128, LEN_UUID_128);
@@ -1889,7 +1946,8 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
     tGATT_TCB *p_tcb=NULL;
     BOOLEAN status= TRUE;
 
-    p_tcb = gatt_find_tcb_by_addr(bda);
+    p_tcb = gatt_find_tcb_by_addr(bda, BT_TRANSPORT_LE);
+
     if (p_tcb)
     {
         if (gatt_get_ch_state(p_tcb) == GATT_CH_OPEN)
@@ -1902,7 +1960,7 @@ BOOLEAN gatt_cancel_open(tGATT_IF gatt_if, BD_ADDR bda)
             gatt_update_app_use_link_flag(gatt_if, p_tcb, FALSE, FALSE);
             if (!gatt_num_apps_hold_link(p_tcb))
             {
-                gatt_disconnect(p_tcb->peer_bda);
+                gatt_disconnect(p_tcb);
             }
         }
     }
@@ -2131,7 +2189,7 @@ void gatt_end_operation(tGATT_CLCB *p_clcb, tGATT_STATUS status, void *p_data)
 ** Returns          16 bits uuid.
 **
 *******************************************************************************/
-void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason)
+void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
 {
     tGATT_TCB       *p_tcb = NULL;
     tGATT_CLCB      *p_clcb;
@@ -2142,9 +2200,10 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason)
 
     GATT_TRACE_DEBUG0 ("gatt_cleanup_upon_disc ");
 
-    if ((p_tcb = gatt_find_tcb_by_addr(bda)) != NULL)
+    if ((p_tcb = gatt_find_tcb_by_addr(bda, transport)) != NULL)
     {
         GATT_TRACE_DEBUG0 ("found p_tcb ");
+        gatt_set_ch_state(p_tcb, GATT_CH_CLOSE);
         for (i = 0; i < GATT_CL_MAX_LCB; i ++)
         {
             p_clcb = &gatt_cb.clcb[i];
@@ -2172,7 +2231,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason)
             {
                 conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_reg->gatt_if);
                 GATT_TRACE_DEBUG3 ("found p_reg tcb_idx=%d gatt_if=%d  conn_id=0x%x", p_tcb->tcb_idx, p_reg->gatt_if, conn_id);
-                (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason);
+                (*p_reg->app_cb.p_conn_cb)(p_reg->gatt_if,  bda, conn_id, FALSE, reason, transport);
             }
         }
         memset(p_tcb, 0, sizeof(tGATT_TCB));
@@ -2228,6 +2287,10 @@ void gatt_dbg_display_uuid(tBT_UUID bt_uuid)
     {
         sprintf(str_buf, "0x%04x", bt_uuid.uu.uuid16);
     }
+    else if (bt_uuid.len == LEN_UUID_32)
+    {
+        sprintf(str_buf, "0x%08x", (unsigned int)bt_uuid.uu.uuid32);
+    }
     else if (bt_uuid.len == LEN_UUID_128)
     {
         x += sprintf(&str_buf[x], "0x%02x%02x%02x%02x%02x%02x%02x%02x",
@@ -2406,7 +2469,7 @@ BOOLEAN gatt_add_bg_dev_list(tGATT_REG *p_reg,  BD_ADDR bd_addr, BOOLEAN is_init
 *******************************************************************************/
 BOOLEAN gatt_remove_bg_dev_for_app(tGATT_IF gatt_if, BD_ADDR bd_addr)
 {
-    tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+    tGATT_TCB    *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
     BOOLEAN       status;
 
     if (p_tcb)
@@ -2628,7 +2691,7 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_
 {
     BOOLEAN         ret = FALSE;
     tGATT_REG        *p_reg;
-    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr);
+    tGATT_TCB       *p_tcb = gatt_find_tcb_by_addr(bd_addr, BT_TRANSPORT_LE);
 
     GATT_TRACE_API0 ("gatt_update_auto_connect_dev ");
     /* Make sure app is registered */
@@ -2659,54 +2722,6 @@ BOOLEAN gatt_update_auto_connect_dev (tGATT_IF gatt_if, BOOLEAN add, BD_ADDR bd_
 
 /*******************************************************************************
 **
-** Function         gatt_get_conn_id
-**
-** Description      This function returns a connecttion handle to a ATT server
-**                  if the server is already connected
-**
-** Parameters       gatt_if: client interface.
-**                  bd_addr: peer device address.
-**
-** Returns          Connection handle or invalid handle value
-**
-*******************************************************************************/
-UINT16 gatt_get_conn_id (tGATT_IF gatt_if, BD_ADDR bd_addr)
-{
-    tGATT_REG       *p_reg;
-    tGATT_CLCB      *p_clcb;
-    tGATT_TCB       *p_tcb;
-    UINT8           i;
-
-    GATT_TRACE_API1 ("GATTC_GetConnIfConnected gatt_if=%d", gatt_if);
-    /* Do we have a transport to the peer ? If not, we are not connected */
-    if ((p_tcb = gatt_find_tcb_by_addr(bd_addr)) == NULL)
-    {
-        GATT_TRACE_EVENT0 ("GATTC_GetConnIfConnected - no TCB found");
-        return(GATT_INVALID_CONN_ID);
-    }
-
-    /* Make sure app is registered */
-    if ((p_reg = gatt_get_regcb(gatt_if)) == NULL)
-    {
-        GATT_TRACE_ERROR1("GATTC_GetConnIfConnected - gatt_if is not registered", gatt_if);
-        return(GATT_INVALID_CONN_ID);
-    }
-
-    /* Now see if the app already has a client control block to that peer */
-    for (i = 0, p_clcb = gatt_cb.clcb; i < GATT_CL_MAX_LCB; i++, p_clcb++)
-    {
-        if ( p_clcb->in_use && (p_clcb->p_reg == p_reg) && (p_clcb->p_tcb == p_tcb) )
-        {
-            return(p_clcb->conn_id);
-        }
-    }
-
-    /* If here, failed to allocate a client control block */
-    GATT_TRACE_ERROR1 ("gatt_get_conn_id: not connected- gatt_if: %u", gatt_if);
-    return(GATT_INVALID_CONN_ID);
-}
-/*******************************************************************************
-**
 ** Function     gatt_add_pending_new_srv_start
 **
 ** Description  Add a pending new srv start to the new service start queue
@@ -2736,12 +2751,13 @@ tGATT_PENDING_ENC_CLCB* gatt_add_pending_enc_channel_clcb(tGATT_TCB *p_tcb, tGAT
 ** Returns    Pointer to the new service start buffer, NULL no buffer available
 **
 *******************************************************************************/
-void gatt_update_listen_mode(void)
+BOOLEAN gatt_update_listen_mode(void)
 {
     UINT8           ii = 0;
     tGATT_REG       *p_reg = &gatt_cb.cl_rcb[0];
     UINT8           listening = 0;
     UINT16          connectability, window, interval;
+    BOOLEAN         rt = TRUE;
 
     for (; ii < GATT_MAX_APPS; ii ++, p_reg ++)
     {
@@ -2757,16 +2773,24 @@ void gatt_update_listen_mode(void)
     else
         BTM_BleUpdateAdvFilterPolicy (AP_SCAN_CONN_WL);
 
-    connectability = BTM_ReadConnectability (&window, &interval);
-
-    if (listening != GATT_LISTEN_TO_NONE)
+    if (rt)
     {
-        connectability |= BTM_BLE_CONNECTABLE;
+        connectability = BTM_ReadConnectability (&window, &interval);
+
+        if (listening != GATT_LISTEN_TO_NONE)
+        {
+            connectability |= BTM_BLE_CONNECTABLE;
+        }
+        else
+        {
+            if ((connectability & BTM_BLE_CONNECTABLE) == 0)
+            connectability &= ~BTM_BLE_CONNECTABLE;
+        }
+        /* turning on the adv now */
+        btm_ble_set_connectability(connectability);
     }
-    else
-        connectability &= ~BTM_BLE_CONNECTABLE;
-    /* turning on the adv now */
-    BTM_SetConnectability(connectability, window, interval);
+
+    return rt;
 
 }
 #endif
index aa2e747..860fb7a 100644 (file)
 
 #if (defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
 
-BOOLEAN btsnd_hcic_ble_reset(void)
-{
-    BT_HDR *p;
-    UINT8 *pp;
-
-    if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
-        return (FALSE);
-
-    pp = (UINT8 *)(p + 1);
-
-    p->len    = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
-    p->offset = 0;
-
-    UINT16_TO_STREAM (pp,  HCI_BLE_RESET);
-    UINT8_TO_STREAM  (pp,  0);
-
-    btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID,  p);
-    return (TRUE);
-
-}
-
 BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask)
 {
     BT_HDR *p;
@@ -856,4 +835,62 @@ BOOLEAN btsnd_hcic_ble_write_host_supported (UINT8 le_host_spt, UINT8 simul_le_h
     return (TRUE);
 }
 
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+
+BOOLEAN btsnd_hcic_ble_rc_param_req_reply(  UINT16 handle,
+                                            UINT16 conn_int_min, UINT16 conn_int_max,
+                                            UINT16 conn_latency, UINT16 conn_timeout,
+                                            UINT16 min_ce_len, UINT16 max_ce_len  )
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY)) == NULL)
+        return (FALSE);
+
+    pp = (UINT8 *)(p + 1);
+
+    p->len    = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY;
+    p->offset = 0;
+
+    UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_REPLY);
+    UINT8_TO_STREAM  (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY);
+
+    UINT16_TO_STREAM (pp, handle);
+    UINT16_TO_STREAM (pp, conn_int_min);
+    UINT16_TO_STREAM (pp, conn_int_max);
+    UINT16_TO_STREAM (pp, conn_latency);
+    UINT16_TO_STREAM (pp, conn_timeout);
+    UINT16_TO_STREAM (pp, min_ce_len);
+    UINT16_TO_STREAM (pp, max_ce_len);
+
+    btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID,  p);
+    return (TRUE);
+}
+
+BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason)
+{
+    BT_HDR *p;
+    UINT8 *pp;
+
+    if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY)) == NULL)
+        return (FALSE);
+
+    pp = (UINT8 *)(p + 1);
+
+    p->len    = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY;
+    p->offset = 0;
+
+    UINT16_TO_STREAM (pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY);
+    UINT8_TO_STREAM  (pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY);
+
+    UINT16_TO_STREAM (pp, handle);
+    UINT8_TO_STREAM (pp, reason);
+
+    btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID,  p);
+    return (TRUE);
+}
 #endif
+
+#endif
+
index 00c9d05..6fbf849 100644 (file)
@@ -163,10 +163,11 @@ tHID_STATUS hidh_conn_disconnect (UINT8 dhandle)
 **                  send security block L2C connection response.
 **
 *******************************************************************************/
-void hidh_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void hidh_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tHID_HOST_DEV_CTB *p_dev= (tHID_HOST_DEV_CTB *) p_ref_data;
     UNUSED(bd_addr);
+    UNUSED (transport);
 
     if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
     {
@@ -316,7 +317,7 @@ void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle)
 ** Returns          void
 **
 *******************************************************************************/
-void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void hidh_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tHID_HOST_DEV_CTB *p_dev = (tHID_HOST_DEV_CTB *) p_ref_data;
     UINT8 dhandle;
@@ -325,6 +326,7 @@ void hidh_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
 #endif
     UINT32 reason;
     UNUSED(bd_addr);
+    UNUSED (transport);
 
     dhandle = ((UINT32)p_dev - (UINT32)&(hh_cb.devices[0]))/ sizeof(tHID_HOST_DEV_CTB);
     if( res == BTM_SUCCESS && p_dev->conn.conn_state == HID_CONN_STATE_SECURITY )
@@ -880,6 +882,13 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
     UINT8       use_data = 0 ;
     BOOLEAN     blank_datc = FALSE;
 
+    if (!BTM_IsAclConnectionUp(hh_cb.devices[dhandle].addr, BT_TRANSPORT_BR_EDR))
+    {
+        if (buf)
+            GKI_freebuf ((void *)buf);
+        return( HID_ERR_NO_CONNECTION );
+    }
+
     if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED)
     {
         if (buf)
index 33fb884..e7a7937 100644 (file)
@@ -497,6 +497,10 @@ typedef struct
 #define BLE_ADDR_TYPE_MASK      (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC)
 typedef UINT8 tBLE_ADDR_TYPE;
 
+#define BT_TRANSPORT_BR_EDR    1
+#define BT_TRANSPORT_LE        2
+typedef UINT8 tBT_TRANSPORT;
+
 #define BLE_ADDR_IS_STATIC(x)   ((x[0] & 0xC0) == 0xC0)
 
 typedef struct
index f4b17d4..368e70d 100644 (file)
@@ -200,20 +200,20 @@ typedef UINT8 (tBTM_FILTER_CB) (BD_ADDR bd_addr, DEV_CLASS dc);
 /* BTM_IsInquiryActive return values (Bit Mask)
  * Note: These bit masks are associated with the inquiry modes (BTM_*_INQUIRY) */
 #define BTM_INQUIRY_INACTIVE        0x0     /* no inquiry in progress */
-#define BTM_GENERAL_INQUIRY_ACTIVE  0x1     /* a general inquiry is in progress */
-#define BTM_LIMITED_INQUIRY_ACTIVE  0x2     /* a limited inquiry is in progress */
+#define BTM_GENERAL_INQUIRY_ACTIVE  BTM_GENERAL_INQUIRY     /* a general inquiry is in progress */
+#define BTM_LIMITED_INQUIRY_ACTIVE  BTM_LIMITED_INQUIRY     /* a limited inquiry is in progress */
 #define BTM_PERIODIC_INQUIRY_ACTIVE 0x8     /* a periodic inquiry is active */
 #define BTM_SSP_INQUIRY_ACTIVE      0x4     /* SSP is active, so inquiry is disallowed (work around for FW bug) */
-#define BTM_LE_GENERAL_INQUIRY_ACTIVE  0x10     /* a general inquiry is in progress */
-#define BTM_LE_LIMITED_INQUIRY_ACTIVE  0x20     /* a limited inquiry is in progress */
-#define BTM_LE_SELECT_CONN_ACTIVE         0x40     /* selection connection is in progress */
-#define BTM_LE_OBSERVE_ACTIVE             0x80     /* selection connection is in progress */
+#define BTM_LE_GENERAL_INQUIRY_ACTIVE  BTM_BLE_GENERAL_INQUIRY     /* a general inquiry is in progress */
+#define BTM_LE_LIMITED_INQUIRY_ACTIVE  BTM_BLE_LIMITED_INQUIRY      /* a limited inquiry is in progress */
+#define BTM_LE_SELECT_CONN_ACTIVE   0x40     /* selection connection is in progress */
+#define BTM_LE_OBSERVE_ACTIVE       0x80     /* selection connection is in progress */
 
 /* inquiry activity mask */
-#define BTM_BR_INQ_ACTIVE_MASK            (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */
-#define BTM_LE_SCAN_ACTIVE_MASK                   0xF0     /* LE scan activity mask */
-#define BTM_LE_INQ_ACTIVE_MASK            (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/
-#define BTM_INQUIRY_ACTIVE_MASK                   (BTM_BR_INQ_ACTIVE_MASK | BTM_LE_INQ_ACTIVE_MASK) /* inquiry activity mask */
+#define BTM_BR_INQ_ACTIVE_MASK        (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE|BTM_PERIODIC_INQUIRY_ACTIVE) /* BR/EDR inquiry activity mask */
+#define BTM_BLE_SCAN_ACTIVE_MASK      0xF0     /* LE scan activity mask */
+#define BTM_BLE_INQ_ACTIVE_MASK       (BTM_LE_GENERAL_INQUIRY_ACTIVE|BTM_LE_LIMITED_INQUIRY_ACTIVE) /* LE inquiry activity mask*/
+#define BTM_INQUIRY_ACTIVE_MASK       (BTM_BR_INQ_ACTIVE_MASK | BTM_BLE_INQ_ACTIVE_MASK) /* inquiry activity mask */
 
 /* Define scan types */
 #define BTM_SCAN_TYPE_STANDARD      0
@@ -659,6 +659,7 @@ typedef struct
 typedef struct
 {
     UINT16      status;
+    BD_ADDR     bd_addr;
     UINT16      length;
     BD_NAME     remote_bd_name;
 } tBTM_REMOTE_DEV_NAME;
@@ -837,6 +838,10 @@ typedef struct
     DEV_CLASS_PTR   p_dc;       /* The device class */
     BD_NAME_PTR     p_bdn;      /* The device name */
     UINT8          *p_features; /* pointer to the remote device's features page[0] (supported features page) */
+#if BLE_INCLUDED == TRUE
+    UINT16          handle;     /* connection handle */
+    tBT_TRANSPORT   transport; /* link is LE or not */
+#endif
 } tBTM_BL_CONN_DATA;
 
 /* the data type associated with BTM_BL_DISCN_EVT */
@@ -844,6 +849,10 @@ typedef struct
 {
     tBTM_BL_EVENT   event;  /* The event reported. */
     BD_ADDR_PTR     p_bda;  /* The address of the disconnected device */
+#if BLE_INCLUDED == TRUE
+    UINT16          handle; /* disconnected connection handle */
+    tBT_TRANSPORT   transport; /* link is LE link or not */
+#endif
 } tBTM_BL_DISCN_DATA;
 
 /* Busy-Level shall have the inquiry_paging mask set when
@@ -893,10 +902,16 @@ typedef void (tBTM_BL_CHANGE_CB) (tBTM_BL_EVENT_DATA *p_data);
 ** changes. First param is BD address, second is if added or removed.
 ** Registered through BTM_AclRegisterForChanges call.
 */
+#if BLE_INCLUDED == TRUE
+typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc,
+                                      BD_NAME p_bdn, UINT8 *features,
+                                      BOOLEAN is_new, UINT16 handle,
+                                      tBT_TRANSPORT transport);
+#else
 typedef void (tBTM_ACL_DB_CHANGE_CB) (BD_ADDR p_bda, DEV_CLASS p_dc,
                                       BD_NAME p_bdn, UINT8 *features,
                                       BOOLEAN is_new);
-
+#endif
 /*****************************************************************************
 **  SCO CHANNEL MANAGEMENT
 *****************************************************************************/
@@ -1565,7 +1580,8 @@ typedef void (tBTM_MKEY_CALLBACK) (BD_ADDR bd_addr, UINT8 status, UINT8 key_flag
 **              optional data passed in by BTM_SetEncryption
 **              tBTM_STATUS - result of the operation
 */
-typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, void *p_ref_data, tBTM_STATUS result);
+typedef void (tBTM_SEC_CBACK) (BD_ADDR bd_addr, tBT_TRANSPORT trasnport,
+                                void *p_ref_data, tBTM_STATUS result);
 
 /* Bond Cancel complete. Parameters are
 **              Result of the cancel operation
@@ -1897,73 +1913,6 @@ typedef struct
 #define BTM_VSC_NFC_SUPPORTED(x) ((x)[BTM_FEATURE_NFC_OFF] & BTM_FEATURE_NFC_MASK)
 
 
-/************************
-**  Dual-Stack support
-*************************/
-/* BTM_SYNC_FAIL_EVT reason codes */
-#define BTM_SYNC_SUCCESS                    0
-#define BTM_SYNC_FAIL_BTE_SWITCH_REJECTED   1
-#define BTM_SYNC_FAIL_TRANS_PAUSE           2
-#define BTM_SYNC_FAIL_CORE_SYNC             3
-#define BTM_SYNC_FAIL_BTA_SYNC              4
-#define BTM_SYNC_FAIL_TRANS_RESUME          5
-#define BTM_SYNC_FAIL_RESYNC                6
-#define BTM_SYNC_FAIL_ERROR                 7
-#define BTM_SYNC_FAIL_UIPC_OPEN             8
-typedef UINT8 tBTM_SYNC_STATUS;
-
-/* Direction of sync (used by BTM_SyncStack) */
-#define BTM_SW_BB_TO_MM     0
-#define BTM_SW_TO_BB        1   /* Switch back to baseband stack (from either MM or BTC host) */
-#define BTM_SW_RESYNC       2
-#define BTM_SW_BB_TO_BTC    3   /* Switch from baseband stack to Bluetooth Controller Host stack */
-#define BTM_SW_MM_TO_BB     4
-#define BTM_SW_BTC_TO_BB    5
-typedef UINT8 tBTM_SW_DIR;
-
-/* Stack synchronization events (returned by tBTM_SYNC_STACK_CBACK callback) */
-#define BTM_SYNC_CPLT_EVT   0
-#define BTM_SYNC_BTA_EVT    1
-#define BTM_RESYNC_CPLT_EVT 2
-#define BTM_UIPC_OPENED_EVT 3
-#define BTM_UIPC_CLOSED_EVT 4
-typedef UINT8 tBTM_SYNC_STACK_EVT;
-
-/* Synchronization info from BTA/application that will be sent when calling BTE sync request functions */
-typedef struct
-{
-    tBTM_SW_DIR dir;
-    UINT16      lcid[BTM_SYNC_INFO_NUM_STR];
-    UINT8       avdt_handle[BTM_SYNC_INFO_NUM_STR];
-} tBTM_SYNC_INFO;
-
-/* Stack synchonization callback function
-** Parameters are
-**              event:  stack synchronization event
-**              status: BTM_SUCCESS if event was successful
-*/
-typedef void (*tBTM_SYNC_STACK_CBACK)(tBTM_SYNC_STACK_EVT event, tBTM_SYNC_STATUS status);
-
-
-/* Sync complete callback function. Called by bte layers after synchronization is complete
-** so that BTM_SYNC can procede with the next step for switching stack to MM
-**
-** Parameters are
-**              status: BTM_SUCCESS if synchronization was successful
-*/
-typedef void (*tBTM_SYNC_CPLT_CBACK)(tBTM_STATUS status);
-
-
-
-/* IPC event callback function. Called by BTM when an IPC event is received.
-** These events are currently sent to DM through the callback function.
-**
-** Parameters are
-**              status: BTM_SUCCESS if synchronization was successful
-**              p_data: Actual message in the IPC
-*/
-typedef void (tBTM_IPC_EVT_CBACK)(tBTM_STATUS status, BT_HDR *p_data);
-
 /* MIP evnets, callbacks    */
 enum
 {
@@ -2659,7 +2608,8 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn);
 **
 *******************************************************************************/
     BTM_API extern tBTM_STATUS  BTM_ReadRemoteDeviceName (BD_ADDR remote_bda,
-                                                          tBTM_CMPL_CB *p_cb);
+                                                          tBTM_CMPL_CB *p_cb,
+                                                          tBT_TRANSPORT transport);
 
 
 /*******************************************************************************
@@ -3187,7 +3137,7 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn);
 ** Returns          TRUE if connection is up, else FALSE.
 **
 *******************************************************************************/
-    BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda);
+    BTM_API extern BOOLEAN BTM_IsAclConnectionUp (BD_ADDR remote_bda, tBT_TRANSPORT transport);
 
 
 /*******************************************************************************
@@ -3273,7 +3223,8 @@ BTM_API extern BOOLEAN BTM_TryAllocateSCN(UINT8 scn);
 **                  BTM_BUSY if command is already in progress
 **
 *******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb);
+    BTM_API extern tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda,
+                                                      tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb);
 
 /*******************************************************************************
 **
@@ -3640,7 +3591,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 ** Returns          TRUE if registered OK, else FALSE
 **
 *******************************************************************************/
-    BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_callback);
+    BTM_API extern BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (
+                                                        tBTM_LINK_KEY_CALLBACK *p_callback);
 
 
 /*******************************************************************************
@@ -3653,7 +3605,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 ** Returns          TRUE if registered OK, else FALSE
 **
 *******************************************************************************/
-    BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback);
+    BTM_API extern BOOLEAN BTM_SecAddRmtNameNotifyCallback (
+                                                               tBTM_RMT_NAME_CALLBACK *p_callback);
 
 
 /*******************************************************************************
@@ -3666,7 +3619,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 ** Returns          TRUE if OK, else FALSE
 **
 *******************************************************************************/
-    BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback);
+    BTM_API extern BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (
+                                                            tBTM_RMT_NAME_CALLBACK *p_callback);
 
 
 /*******************************************************************************
@@ -3709,6 +3663,22 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 
 /*******************************************************************************
 **
+** Function         BTM_GetSecurityFlagsByTransport
+**
+** Description      Get security flags for the device on a particular transport
+**
+** Parameters      bd_addr: BD address of remote device
+**                  p_sec_flags : Out parameter to be filled with security flags for the connection
+**                  transport :  Physical transport of the connection (BR/EDR or LE)
+**
+** Returns          BOOLEAN TRUE or FALSE is device found
+**
+*******************************************************************************/
+    BTM_API extern BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr,
+                                UINT8 * p_sec_flags, tBT_TRANSPORT transport);
+
+/*******************************************************************************
+**
 ** Function         BTM_ReadTrustedMask
 **
 ** Description      Get trusted mask for the device
@@ -3789,9 +3759,10 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 ** Returns          TRUE if registered OK, else FALSE
 **
 *******************************************************************************/
-    BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
-                                                    UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
-                                                    UINT32 mx_chan_id);
+    BTM_API extern BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name,
+                                                          UINT8 service_id, UINT16 sec_level,
+                                                          UINT16 psm, UINT32 mx_proto_id,
+                                                          UINT32 mx_chan_id);
 
 /*******************************************************************************
 **
@@ -3951,10 +3922,37 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 **
 ** Description      This function is called to perform bonding with peer device.
 **
+** Parameters:      bd_addr      - Address of the device to bond
+**                  pin_len      - length in bytes of the PIN Code
+**                  p_pin        - pointer to array with the PIN Code
+**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
+
 ** Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
 **
 *******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]);
+    BTM_API extern tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr,
+                                            UINT8 pin_len, UINT8 *p_pin,
+                                            UINT32 trusted_mask[]);
+
+/*******************************************************************************
+**
+** Function         BTM_SecBondByTransport
+**
+** Description      This function is called to perform bonding by designated transport
+**
+** Parameters:      bd_addr      - Address of the device to bond
+**                  pin_len      - length in bytes of the PIN Code
+**                  p_pin        - pointer to array with the PIN Code
+**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
+**                  transport :  Physical transport to use for bonding (BR/EDR or LE)
+**
+** Returns          BTM_CMD_STARTED if successfully initiated, otherwise error
+**
+*******************************************************************************/
+    BTM_API extern tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr,
+                                            tBT_TRANSPORT transport,
+                                            UINT8 pin_len, UINT8 *p_pin,
+                                            UINT32 trusted_mask[]);
 
 /*******************************************************************************
 **
@@ -3993,8 +3991,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 **                  BTM_MODE_UNSUPPORTED - if security manager not linked in.
 **
 *******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
-                                                  void *p_ref_data);
+    BTM_API extern tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport,
+                                                  tBTM_SEC_CBACK *p_callback, void *p_ref_data);
 
 /*******************************************************************************
 **
@@ -4079,7 +4077,8 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 **                  r           - simple pairing Randomizer  C.
 **
 *******************************************************************************/
-    BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r);
+    BTM_API extern void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr,
+                                                        BT_OCTET16 c, BT_OCTET16 r);
 
 /*******************************************************************************
 **
@@ -4232,7 +4231,7 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
 ** Returns          the handle of the connection, or 0xFFFF if none.
 **
 *******************************************************************************/
-    BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda);
+    BTM_API extern UINT16 BTM_GetHCIConnHandle (BD_ADDR remote_bda, tBT_TRANSPORT transport);
 
 
 /*******************************************************************************
@@ -4419,171 +4418,6 @@ BTM_API extern tBTM_STATUS BTM_SetWBSCodec (tBTM_SCO_CODEC_TYPE codec_type);
     BTM_API extern UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid,
                                              UINT8 *p_uuid_list, UINT8 max_num_uuid);
 
-/*******************************************************************************
-**
-** Function         BTM_SyncStack
-**
-** Description      For Dual-Stack support. Called to initiate switching to/from
-**                  main stack (running on phone baseband) to mm stack (light
-**                  stack running on multi-media chip)
-**
-** Parameters       sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack
-**                            BTM_SW_MM_TO_BB: switch from MM to BB stack
-**                            BTM_SW_RESYNC: resync MM and BB stacks
-**
-**                  p_sync_cback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_SyncStack(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_cback);
-
-/*******************************************************************************
-**
-** Function         BTM_SyncBtaRsp
-**
-** Description      For Dual-Stack support. Called to indicate that upper layers
-**                  (e.g. BTA or application) have completed synchronizing bta/app
-**                  specific layers for switching.
-**
-**                  Called in response to 'BTM_SYNC_BTA_EVT'
-**
-** Parameters       status: BTM_SUCESS: bta/app successfully synchronized
-**                          otherwise:  sync was unsuccessfule. Abort switch.
-**
-**                  p_btm_sync_info: information from bta/app that will be needed
-**                                  by BTE (avdt and l2cap) for switching.
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_SyncBtaRsp(tBTM_STATUS status, tBTM_SYNC_INFO *p_btm_sync_info);
-
-/*******************************************************************************
-**
-** Function         BTM_OpenUIPC
-**
-** Description      For Dual-Stack support. Called to open UIPC between
-**                  main stack (running on phone baseband) to embedded light stack
-**                  (running on Multimedia or Bluetooth Controller chip)
-**
-** Parameters       sync_dir: BTM_SW_BB_TO_MM: switch from BB to MM stack
-**                            BTM_SW_BB_TO_BTC:switch from BB to BTC stack
-**
-**                  p_sync_callback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_OpenUIPC(tBTM_SW_DIR sync_dir, tBTM_SYNC_STACK_CBACK p_sync_callback);
-
-/*******************************************************************************
-**
-** Function         BTM_CloseUIPC
-**
-** Description      For Dual-Stack support. Called to close UIPC between
-**                  main stack (running on phone baseband) to embedded light stack
-**                  (running on Multimedia or Bluetooth Controller chip)
-**
-** Parameters
-**                  p_sync_callback: callback function for event notification
-** Returns
-**
-*******************************************************************************/
-    BTM_API extern tBTM_STATUS BTM_CloseUIPC(tBTM_SYNC_STACK_CBACK p_sync_callback);
-
-/*******************************************************************************
-**
-** Function         BTM_IpcSend
-**
-** Description      For Dual-Stack support. Called to send ipc messages from
-**                  full stack to lite stack and vice-versa. This API is
-**                  typically called by bta layers e.g. bta_av.
-**
-**
-** Parameters       len:    Length of the buffer in the ipc message
-**
-**                  buffer: Pointer to the buffer to be passed in the IPC message
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_IpcSend(UINT16 len, UINT8* buffer);
-
-/*******************************************************************************
-**
-** Function         BTM_IpcSendBuf
-**
-** Description      For Dual-Stack support. Called to send ipc messages from
-**                  full stack to lite stack and vice-versa. This API is
-**                  typically called by bta layers e.g. bta_av_sync.
-**
-**
-** Parameters       p_buf: Pointer to the buffer to be passed in the IPC message
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_IpcSendBuf(BT_HDR* p_buf);
-
-/*******************************************************************************
-**
-** Function         BTM_RegIpcEvtHandler
-**
-** Description      registers the DM provided handler for IPC events
-**
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_RegIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback);
-
-/*******************************************************************************
-**
-** Function         BTM_RegRTIpcEvtHandler
-**
-** Description      registers the RT(Audio Routing) provided handler for IPC events
-**
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_RegRTIpcEvtHandler(tBTM_IPC_EVT_CBACK *p_cback);
-
-/*****************************************************************************
-**  N2BT
-*****************************************************************************/
-
-/* Data callback for N2BT */
-    typedef void (tBTM_N2BT_DATA_CB) (BD_ADDR bd_addr, UINT16 handle, UINT8 *p_data, UINT16 datalen);
-
-/*******************************************************************************
-**
-** Function         BTM_N2BtAcquire
-**
-** Description      Put controller into acquisition mode
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_N2BtAcquire(BD_ADDR bd_addr, UINT16 timeout,
-                                        UINT8 freq, UINT8 src_addrlen, UINT8 sensor_flags,
-                                        UINT8 sensor_type, UINT8 sensor_clk_accuracy,
-                                        UINT16 add_rx_window, UINT16 init_crc,
-                                        UINT32 ac_low, UINT32 ac_high, UINT16 pkt_hdr,
-                                        UINT16 list_dur, UINT16 list_int,
-                                        UINT8 oor_missed_pkts, tBTM_VSC_CMPL_CB *p_cb,
-                                        tBTM_N2BT_DATA_CB *p_data_cback);
-
-/*******************************************************************************
-**
-** Function         BTM_N2BtDisconnect
-**
-** Description      Disconnects all N2BT devices
-**
-** Returns          void
-**
-*******************************************************************************/
-    BTM_API extern void BTM_N2BtDisconnect(void);
-
 /*****************************************************************************
 **  SCO OVER HCI
 *****************************************************************************/
index 584ce9a..0bfaea9 100644 (file)
 #define CHNL_MAP_LEN    5
 typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN];
 
-#define BTM_BLE_CONNECT_EVT     0x00
-#define BTM_BLE_CONNECT_DIR_EVT 0x01
-#define BTM_BLE_DISCOVER_EVT    0x02
-#define BTM_BLE_NON_CONNECT_EVT 0x03
+/* 0x00-0x04 only used for set advertising parameter command */
+#define BTM_BLE_CONNECT_EVT     0x00   /* 0x00-0x04 only used for set advertising
+                                            parameter command */
+#define BTM_BLE_CONNECT_DIR_EVT 0x01   /* Connectable directed advertising */
+#define BTM_BLE_DISCOVER_EVT    0x02  /* Scannable undirected advertising */
+#define BTM_BLE_NON_CONNECT_EVT 0x03  /* Non connectable undirected advertising */
+#define BTM_BLE_CONNECT_LO_DUTY_DIR_EVT 0x04        /* Connectable low duty
+                                                       cycle directed advertising  */
+    /* 0x00 - 0x05 can be received on adv event type */
 #define BTM_BLE_SCAN_RSP_EVT    0x04
-#define BTM_BLE_SCAN_REQ_EVT    0x06
+#define BTM_BLE_SCAN_REQ_EVT    0x05
 #define BTM_BLE_UNKNOWN_EVT     0xff
 
 #define BTM_BLE_UNKNOWN_EVT     0xff
@@ -191,27 +196,33 @@ typedef struct
 #define BTM_BLE_LIMIT_DISC_FLAG         (0x01 << 0)
 #define BTM_BLE_GEN_DISC_FLAG           (0x01 << 1)
 #define BTM_BLE_BREDR_NOT_SPT           (0x01 << 2)
+/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support */
+#define BTM_BLE_DMT_CONTROLLER_SPT      (0x01 << 3)
+#define BTM_BLE_DMT_HOST_SPT            (0x01 << 4)
+
 #define BTM_BLE_NON_LIMIT_DISC_FLAG     (0x00 )         /* lowest bit unset */
 #define BTM_BLE_ADV_FLAG_MASK           (BTM_BLE_LIMIT_DISC_FLAG | BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG)
 #define BTM_BLE_LIMIT_DISC_MASK         (BTM_BLE_LIMIT_DISC_FLAG )
 
-#define BTM_BLE_AD_BIT_DEV_NAME        (0x0001 << 0)
-#define BTM_BLE_AD_BIT_FLAGS           (0x0001 << 1)
-#define BTM_BLE_AD_BIT_MANU            (0x0001 << 2)
-#define BTM_BLE_AD_BIT_TX_PWR          (0x0001 << 3)
-#define BTM_BLE_AD_BIT_INT_RANGE       (0x0001 << 5)
-#define BTM_BLE_AD_BIT_SERVICE         (0x0001 << 6)
-#define BTM_BLE_AD_BIT_SERVICE_SOL     (0x0001 << 7)
-#define BTM_BLE_AD_BIT_SERVICE_DATA    (0x0001 << 8)
-#define BTM_BLE_AD_BIT_SIGN_DATA       (0x0001 << 9)
-#define BTM_BLE_AD_BIT_SERVICE_128SOL  (0x0001 << 10)
-#define BTM_BLE_AD_BIT_APPEARANCE      (0x0001 << 11)
-#define BTM_BLE_AD_BIT_PUBLIC_ADDR      (0x0001 << 12)
-#define BTM_BLE_AD_BIT_RANDOM_ADDR      (0x0001 << 13)
-
-#define BTM_BLE_AD_BIT_PROPRIETARY     (0x0001 << 15)
-
-typedef  UINT16  tBTM_BLE_AD_MASK;
+#define BTM_BLE_AD_BIT_DEV_NAME        (0x00000001 << 0)
+#define BTM_BLE_AD_BIT_FLAGS           (0x00000001 << 1)
+#define BTM_BLE_AD_BIT_MANU            (0x00000001 << 2)
+#define BTM_BLE_AD_BIT_TX_PWR          (0x00000001 << 3)
+#define BTM_BLE_AD_BIT_INT_RANGE       (0x00000001 << 5)
+#define BTM_BLE_AD_BIT_SERVICE         (0x00000001 << 6)
+#define BTM_BLE_AD_BIT_SERVICE_SOL     (0x00000001 << 7)
+#define BTM_BLE_AD_BIT_SERVICE_DATA    (0x00000001 << 8)
+#define BTM_BLE_AD_BIT_SIGN_DATA       (0x00000001 << 9)
+#define BTM_BLE_AD_BIT_SERVICE_128SOL  (0x00000001 << 10)
+#define BTM_BLE_AD_BIT_APPEARANCE      (0x00000001 << 11)
+#define BTM_BLE_AD_BIT_PUBLIC_ADDR      (0x00000001 << 12)
+#define BTM_BLE_AD_BIT_RANDOM_ADDR       (0x00000001 << 13)
+#define BTM_BLE_AD_BIT_SERVICE_32        (0x00000001 << 4)
+#define BTM_BLE_AD_BIT_SERVICE_32SOL     (0x00000001 << 14)
+
+#define BTM_BLE_AD_BIT_PROPRIETARY     (0x00000001 << 15)
+
+typedef  UINT32  tBTM_BLE_AD_MASK;
 
 #define BTM_BLE_AD_TYPE_FLAG            HCI_EIR_FLAGS_TYPE                  /* 0x01 */
 #define BTM_BLE_AD_TYPE_16SRV_PART      HCI_EIR_MORE_16BITS_UUID_TYPE       /* 0x02 */
@@ -233,6 +244,11 @@ typedef  UINT16  tBTM_BLE_AD_MASK;
 #define BTM_BLE_AD_TYPE_PUBLIC_TARGET   0x17
 #define BTM_BLE_AD_TYPE_RANDOM_TARGET   0x18
 #define BTM_BLE_AD_TYPE_APPEARANCE      0x19
+#define BTM_BLE_AD_TYPE_ADV_INT         0x1a
+#define BTM_BLE_AD_TYPE_32SOL_SRV_UUID  0x1b
+#define BTM_BLE_AD_TYPE_32SERVICE_DATA  0x1c
+#define BTM_BLE_AD_TYPE_128SERVICE_DATA 0x1d
+
 #define BTM_BLE_AD_TYPE_MANU            HCI_EIR_MANUFACTURER_SPECIFIC_TYPE      /* 0xff */
 typedef UINT8   tBTM_BLE_AD_TYPE;
 
@@ -252,12 +268,30 @@ typedef struct
     UINT16      *p_uuid;
 }tBTM_BLE_SERVICE;
 
+/* Service tag supported in the device */
+typedef struct
+{
+    UINT8       num_service;
+    BOOLEAN     list_cmpl;
+    UINT32      *p_uuid;
+}tBTM_BLE_32SERVICE;
+
+
 typedef struct
 {
     UINT8       len;
     UINT8      *p_val;
 }tBTM_BLE_MANU;
 
+
+typedef struct
+{
+    tBT_UUID    service_uuid;
+    UINT8       len;
+    UINT8      *p_val;
+}tBTM_BLE_SERVICE_DATA;
+
+
 typedef struct
 {
     UINT8       adv_type;
@@ -273,9 +307,12 @@ typedef struct
 
 typedef struct
 {
-    tBTM_BLE_MANU           manu;                      /* manufactuer data */
+    tBTM_BLE_SERVICE_DATA   *p_service_data;
+    tBTM_BLE_MANU           manu;           /* manufactuer data */
     tBTM_BLE_INT_RANGE      int_range;      /* slave prefered conn interval range */
     tBTM_BLE_SERVICE        services;       /* services */
+    tBTM_BLE_32SERVICE      service_32b;     /* 32 bits Service UUID */
+    tBTM_BLE_32SERVICE      sol_service_32b;    /* List of 32 bit Service Solicitation UUIDs */
     UINT16                  appearance;
     UINT8                   flag;
     tBTM_BLE_PROPRIETARY    *p_proprietary;
@@ -434,19 +471,6 @@ BTM_API extern tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask,
 
 /*******************************************************************************
 **
-** Function         BTM_BleReset
-**
-** Description      This function is called to reset ULP controller.
-**
-** Parameters       None.
-**
-** Returns          void
-**
-*******************************************************************************/
-BTM_API extern void BTM_BleReset(void);
-
-/*******************************************************************************
-**
 ** Function         BTM_BleObserve
 **
 ** Description      This procedure keep the device listening for advertising
@@ -866,25 +890,28 @@ void BTM_BleTestEnd(tBTM_CMPL_CB *p_cmd_cmpl_cback);
 
 /*******************************************************************************
 **
-** Function         BTM_IsBleLink
+** Function         BTM_UseLeLink
 **
-** Description      This function is to check the link type is BLE or BR/EDR.
+** Description      This function is to select the underneath physical link to use.
 **
-** Returns          TRUE if BLE link; FALSE if BR/EDR.
+** Returns          TRUE to use LE, FALSE use BR/EDR.
 **
 *******************************************************************************/
-BTM_API extern BOOLEAN BTM_IsBleLink (BD_ADDR bd_addr);
+BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr);
 
 /*******************************************************************************
 **
-** Function         BTM_UseLeLink
+** Function         BTM_BleStackEnable
 **
-** Description      This function is to select the underneath physical link to use.
+** Description      Enable/Disable BLE functionality on stack regarless controller
+**                  capability.
 **
-** Returns          TRUE to use LE, FALSE use BR/EDR.
+** Parameters:      enable: TRUE to enable, FALSE to disable.
+**
+** Returns          TRUE if added OK, else FALSE
 **
 *******************************************************************************/
-BTM_API extern BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr);
+BTM_API extern tBTM_STATUS BTM_BleStackEnable (BOOLEAN enable);
 
 #ifdef __cplusplus
 }
index 4f0e162..805fea7 100644 (file)
@@ -153,10 +153,15 @@ typedef void (*tBTU_EVENT_CALLBACK)(BT_HDR *p_hdr);
 #define BTU_TTYPE_ATT_WAIT_FOR_APP_RSP              104
 #define BTU_TTYPE_ATT_WAIT_FOR_IND_ACK              105
 
-#define BTU_TTYPE_UCD_TO                            106
+#define BTU_TTYPE_L2CAP_END_CONN_UPD                106
+
+#define BTU_TTYPE_BLE_GAP_FAST_ADV                  107
+#define BTU_TTYPE_BLE_OBSERVE                       108
+
+
+#define BTU_TTYPE_UCD_TO                            109
+
 
-/* BTU timer event for TBFC */
-#define BTU_TTYPE_TBFC_RESUME                       107
 
 /* Define the BTU_TASK APPL events
 */
index a17510f..645323d 100644 (file)
@@ -225,6 +225,9 @@ typedef union
 typedef void (tGAP_BLE_DEV_NAME_CBACK)(BOOLEAN status, BD_ADDR addr, UINT16 length, char *p_name);
 
 typedef void (tGAP_BLE_RECONN_ADDR_CBACK)(BOOLEAN status, BD_ADDR addr, BD_ADDR reconn_bda);
+#if BLE_PRIVACY_SPT == TRUE
+typedef void (tGAP_BLE_PRIVACY_CBACK)(BOOLEAN status, BD_ADDR addr, BOOLEAN privacy_enabled);
+#endif
 
 /*****************************************************************************
 **  External Function Declarations
@@ -440,10 +443,16 @@ GAP_API extern UINT16 GAP_SetPairableMode (UINT16 mode, BOOLEAN connect_only_pai
 **
 ** Description      This function is called to initiate bonding with peer device
 **
+** Parameters:      bd_addr      - Address of the device to bond
+**                  pin_len      - length in bytes of the PIN Code
+**                  p_pin        - pointer to array with the PIN Code
+**                  trusted_mask - bitwise OR of trusted services (array of UINT32)
+**
 ** Returns          tBTM_STATUS - BTM_CMD_STARTED of successfully initiated
 **
 *******************************************************************************/
-GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[]);
+GAP_API extern UINT8 GAP_Bond (BD_ADDR bd_addr, UINT8 pin_len,
+                               UINT8 *p_pin, UINT32 trusted_mask[]);
 
 /*******************************************************************************
 **
index f3df8b7..9da7d9c 100644 (file)
 **  Constants
 *****************************************************************************/
 /* Success code and error codes */
-#define  GATT_SUCCESS                        0x0000
-#define  GATT_INVALID_HANDLE                 0x0001
-#define  GATT_READ_NOT_PERMIT                0x0002
-#define  GATT_WRITE_NOT_PERMIT               0x0003
-#define  GATT_INVALID_PDU                    0x0004
-#define  GATT_INSUF_AUTHENTICATION           0x0005
-#define  GATT_REQ_NOT_SUPPORTED              0x0006
-#define  GATT_INVALID_OFFSET                 0x0007
-#define  GATT_INSUF_AUTHORIZATION            0x0008
-#define  GATT_PREPARE_Q_FULL                 0x0009
-#define  GATT_NOT_FOUND                      0x000a
-#define  GATT_NOT_LONG                       0x000b
-#define  GATT_INSUF_KEY_SIZE                 0x000c
-#define  GATT_INVALID_ATTR_LEN               0x000d
-#define  GATT_ERR_UNLIKELY                   0x000e
-#define  GATT_INSUF_ENCRYPTION               0x000f
-#define  GATT_UNSUPPORT_GRP_TYPE             0x0010
-#define  GATT_INSUF_RESOURCE                 0x0011
-
-
-#define  GATT_ILLEGAL_PARAMETER              0x0087
-#define  GATT_NO_RESOURCES                   0x0080
-#define  GATT_INTERNAL_ERROR                 0x0081
-#define  GATT_WRONG_STATE                    0x0082
-#define  GATT_DB_FULL                        0x0083
-#define  GATT_BUSY                           0x0084
-#define  GATT_ERROR                          0x0085
-#define  GATT_CMD_STARTED                    0x0086
-#define  GATT_PENDING                        0x0088
-#define  GATT_AUTH_FAIL                      0x0089
-#define  GATT_MORE                           0x008a
-#define  GATT_INVALID_CFG                    0x008b
-#define  GATT_SERVICE_STARTED                0x008c
+#define  GATT_SUCCESS                        0x00
+#define  GATT_INVALID_HANDLE                 0x01
+#define  GATT_READ_NOT_PERMIT                0x02
+#define  GATT_WRITE_NOT_PERMIT               0x03
+#define  GATT_INVALID_PDU                    0x04
+#define  GATT_INSUF_AUTHENTICATION           0x05
+#define  GATT_REQ_NOT_SUPPORTED              0x06
+#define  GATT_INVALID_OFFSET                 0x07
+#define  GATT_INSUF_AUTHORIZATION            0x08
+#define  GATT_PREPARE_Q_FULL                 0x09
+#define  GATT_NOT_FOUND                      0x0a
+#define  GATT_NOT_LONG                       0x0b
+#define  GATT_INSUF_KEY_SIZE                 0x0c
+#define  GATT_INVALID_ATTR_LEN               0x0d
+#define  GATT_ERR_UNLIKELY                   0x0e
+#define  GATT_INSUF_ENCRYPTION               0x0f
+#define  GATT_UNSUPPORT_GRP_TYPE             0x10
+#define  GATT_INSUF_RESOURCE                 0x11
+
+
+#define  GATT_ILLEGAL_PARAMETER              0x87
+#define  GATT_NO_RESOURCES                   0x80
+#define  GATT_INTERNAL_ERROR                 0x81
+#define  GATT_WRONG_STATE                    0x82
+#define  GATT_DB_FULL                        0x83
+#define  GATT_BUSY                           0x84
+#define  GATT_ERROR                          0x85
+#define  GATT_CMD_STARTED                    0x86
+#define  GATT_PENDING                        0x88
+#define  GATT_AUTH_FAIL                      0x89
+#define  GATT_MORE                           0x8a
+#define  GATT_INVALID_CFG                    0x8b
+#define  GATT_SERVICE_STARTED                0x8c
 #define  GATT_ENCRYPED_MITM                  GATT_SUCCESS
-#define  GATT_ENCRYPED_NO_MITM               0x008d
-#define  GATT_NOT_ENCRYPTED                  0x008e
-
+#define  GATT_ENCRYPED_NO_MITM               0x8d
+#define  GATT_NOT_ENCRYPTED                  0x8e
 
+                                             /* 0xE0 ~ 0xFC reserved for future use */
+#define  GATT_CCC_CFG_ERR                    0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
+#define  GATT_PRC_IN_PROGRESS                0xFE /* Procedure Already in progress */
+#define  GATT_OUT_OF_RANGE                   0xFF /* Attribute value out of range */
 typedef UINT8 tGATT_STATUS;
 
 
@@ -325,12 +328,9 @@ typedef union
 } tGATTS_RSP;
 
 /* Transports for the primary service  */
-enum
-{
-    GATT_TRANSPORT_LE,
-    GATT_TRANSPORT_BR_EDR,
-    GATT_TRANSPORT_LE_BR_EDR
-};
+#define GATT_TRANSPORT_LE           BT_TRANSPORT_LE
+#define GATT_TRANSPORT_BR_EDR       BT_TRANSPORT_BR_EDR
+#define GATT_TRANSPORT_LE_BR_EDR    (BT_TRANSPORT_LE|BT_TRANSPORT_BR_EDR)
 typedef UINT8 tGATT_TRANSPORT;
 
 #define GATT_PREP_WRITE_CANCEL   0x00
@@ -548,26 +548,30 @@ typedef struct
 
 
 typedef UINT8 tGATT_IF;
-#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP    0 /* start a idle timer for this duration when no application
-                                              need to use the link */
+#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP    0 /* start a idle timer for this duration
+                                                 when no application need to use the link */
 
 #define GATT_LINK_NO_IDLE_TIMEOUT            0xFFFF
 
 #define GATT_INVALID_ACL_HANDLE              0xFFFF
 /* discover result callback function */
-typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
+typedef void (tGATT_DISC_RES_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type,
+                                    tGATT_DISC_RES *p_data);
 
 /* discover complete callback function */
 typedef void (tGATT_DISC_CMPL_CB) (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
 
 /* Define a callback function for when read/write/disc/config operation is completed. */
-typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
+typedef void (tGATT_CMPL_CBACK) (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status,
+                tGATT_CL_COMPLETE *p_data);
 
 /* Define a callback function when an initialized connection is established. */
-typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+typedef void (tGATT_CONN_CBACK) (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+                                    tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
 
 /* attribute request callback for ATT server */
-typedef void  (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data);
+typedef void  (tGATT_REQ_CBACK )(UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type,
+                                tGATTS_DATA *p_data);
 
 /* Define a callback function when encryption is established. */
 typedef void (tGATT_ENC_CMPL_CB)(tGATT_IF gatt_if, BD_ADDR bda);
@@ -639,7 +643,8 @@ typedef struct
 /* Attibute server handle ranges NV storage callback functions
 */
 typedef void  (tGATTS_NV_SAVE_CBACK)(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
-typedef BOOLEAN  (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp);
+typedef BOOLEAN  (tGATTS_NV_SRV_CHG_CBACK)(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
+                                            tGATTS_SRV_CHG_RSP *p_rsp);
 
 typedef struct
 {
@@ -801,7 +806,8 @@ extern "C"
 ** Returns          TRUE if operation succeed, FALSE if handle block was not found.
 **
 *******************************************************************************/
-    GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_inst);
+    GATT_API extern BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
+                                                      UINT16 svc_inst);
 
 /*******************************************************************************
 **
@@ -998,11 +1004,13 @@ extern "C"
 **
 ** Parameter        bd_addr:   target device bd address.
 **                  idle_tout: timeout value in seconds.
+**                  transport: trasnport option.
 **
 ** Returns          void
 **
 *******************************************************************************/
-    GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout);
+    GATT_API extern void GATT_SetIdleTimeout (BD_ADDR bd_addr, UINT16 idle_tout,
+                                            tGATT_TRANSPORT transport);
 
 
 /*******************************************************************************
@@ -1058,11 +1066,13 @@ extern "C"
 ** Parameters       gatt_if: applicaiton interface
 **                  bd_addr: peer device address.
 **                  is_direct: is a direct conenection or a background auto connection
+**                  transport : Physical transport for GATT connection (BR/EDR or LE)
 **
 ** Returns          TRUE if connection started; FALSE if connection start failure.
 **
 *******************************************************************************/
-    GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct);
+    GATT_API extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr,
+                                          BOOLEAN is_direct, tBT_TRANSPORT transport);
 
 
 /*******************************************************************************
@@ -1080,7 +1090,8 @@ extern "C"
 ** Returns          TRUE if connection started; FALSE if connection start failure.
 **
 *******************************************************************************/
-    GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr, BOOLEAN is_direct);
+    GATT_API extern BOOLEAN GATT_CancelConnect (tGATT_IF gatt_if, BD_ADDR bd_addr,
+                                                BOOLEAN is_direct);
 
 /*******************************************************************************
 **
@@ -1108,11 +1119,13 @@ extern "C"
 ** Parameters        conn_id: connection id  (input)
 **                   p_gatt_if: applicaiton interface (output)
 **                   bd_addr: peer device address. (output)
+**                   transport :  physical transport of the GATT connection (BR/EDR or LE)
 **
 ** Returns          TRUE the ligical link information is found for conn_id
 **
 *******************************************************************************/
-    GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if, BD_ADDR bd_addr);
+    GATT_API extern BOOLEAN GATT_GetConnectionInfor(UINT16 conn_id, tGATT_IF *p_gatt_if,
+                                        BD_ADDR bd_addr, tBT_TRANSPORT *p_transport);
 
 
 /*******************************************************************************
@@ -1125,11 +1138,13 @@ extern "C"
 ** Parameters        gatt_if: applicaiton interface (input)
 **                   bd_addr: peer device address. (input)
 **                   p_conn_id: connection id  (output)
+**                   transport :  physical transport of the GATT connection (BR/EDR or LE)
 **
 ** Returns          TRUE the ligical link is connected
 **
 *******************************************************************************/
-    GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr, UINT16 *p_conn_id);
+    GATT_API extern BOOLEAN GATT_GetConnIdIfConnected(tGATT_IF gatt_if, BD_ADDR bd_addr,
+                                                      UINT16 *p_conn_id, tBT_TRANSPORT transport);
 
 
 /*******************************************************************************
index ad31d52..14ae893 100644 (file)
 #define HCI_SET_MWS_PATTERN_CONFIGURATION       (0x0073 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 
 /* ConnectionLess Broadcast */
-#define HCI_SET_RESERVED_LT_ADDR                (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_DELETE_RESERVED_LT_ADDR             (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_WRITE_CLB_DATA                      (0x0079 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_WRITE_SYNC_TRAIN_PARAM              (0x007A | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
-#define HCI_READ_SYNC_TRAIN_PARAM               (0x007B | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_SET_RESERVED_LT_ADDR                (0x0074 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_DELETE_RESERVED_LT_ADDR             (0x0075 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_CLB_DATA                      (0x0076 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_READ_SYNC_TRAIN_PARAM               (0x0077 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_WRITE_SYNC_TRAIN_PARAM              (0x0078 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
 
 #define HCI_CONT_BASEBAND_CMDS_FIRST    HCI_SET_EVENT_MASK
 #define HCI_CONT_BASEBAND_CMDS_LAST     HCI_READ_SYNC_TRAIN_PARAM
 #define HCI_BLE_LTK_REQ_REPLY           (0x001A | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_LTK_REQ_NEG_REPLY       (0x001B | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_READ_SUPPORTED_STATES   (0x001C | HCI_GRP_BLE_CMDS)
+                            /*0x001D, 0x001E and 0x001F are reserved*/
+
+#define HCI_BLE_RC_PARAM_REQ_REPLY      (0x0020 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_RC_PARAM_REQ_NEG_REPLY  (0x0021 | HCI_GRP_BLE_CMDS)
+
+
 /* BLE TEST COMMANDS */
 #define HCI_BLE_RECEIVER_TEST           (0x001D | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_TRANSMITTER_TEST        (0x001E | HCI_GRP_BLE_CMDS)
 #define HCI_BLE_TEST_END                (0x001F | HCI_GRP_BLE_CMDS)
 
-#define HCI_BLE_RESET                   (0x0020 | HCI_GRP_BLE_CMDS)
-
 /* LE supported states definition */
 #define HCI_LE_ADV_STATE          0x00000001
 #define HCI_LE_SCAN_STATE         0x00000002
 #define HCI_LE_SCAN_SL_STATE      0x00000400
 #define HCI_LE_INIT_MA_STATE      0x00000800
 
+/* LE Supported States */
+/* Non Connectable Adv state is supported. 0x0000000000000001 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK          0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF           0
+#define HCI_LE_STATES_NON_CONN_ADV_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASK)
+
+/*Scanneable Connectable Adv state  is supported. 0x0000000000000002 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASK          0x02
+#define HCI_SUPP_LE_STATESSCAN_ADV_OFF           0
+#define HCI_LE_STATES_SCAN_ADV_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATESSCAN_ADV_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASK)
+
+/* Connectable Adv state is supported. 0x0000000000000004 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASK          0x04
+#define HCI_SUPP_LE_STATES_CONN_ADV_OFF           0
+#define HCI_LE_STATES_CONN_ADV_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASK)
+
+/* Hi duty Cycle Directed Adv state is supported. 0x0000000000000008 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK          0x08
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF           0
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASK)
+
+/* Passive Scan state is supported. 0x0000000000000010 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASK          0x10
+#define HCI_SUPP_LE_STATES_PASS_SCAN_OFF           0
+#define HCI_LE_STATES_PASS_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASK)
+
+/* Active Scan state is supported. 0x0000000000000020 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK          0x20
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF           0
+#define HCI_LE_STATES_ACTIVE_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASK)
+
+/* Initiating state is supported. 0x0000000000000040 (or connection state in master role is also supported) */
+#define HCI_SUPP_LE_STATES_INIT_MASK          0x40
+#define HCI_SUPP_LE_STATES_INIT_OFF           0
+#define HCI_LE_STATES_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_INIT_OFF] & HCI_SUPP_LE_STATES_INIT_MASK)
+
+/*connection state in slave  role is also supported. 0x0000000000000080 */
+#define HCI_SUPP_LE_STATES_SLAVE_MASK          0x80
+#define HCI_SUPP_LE_STATES_SLAVE_OFF           0
+#define HCI_LE_STATES_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SLAVE_OFF] & HCI_SUPP_LE_STATES_SLAVE_MASK)
+
+/* Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000100 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK          0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF           1
+#define HCI_LE_STATES_NON_CONN_ADV_PASS_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_PASS_SCAN_MASK)
+
+/*Scannable Adv state and Passive Scanning State combination is supported. 0x0000000000000200 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK          0x02
+#define HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF           1
+#define HCI_LE_STATES_SCAN_ADV_PASS_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_PASS_SCAN_MASK)
+
+/*Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000000400 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK          0x04
+#define HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF           1
+#define HCI_LE_STATES_CONN_ADV_PASS_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_PASS_SCAN_MASK)
+
+/*High Duty Cycl Directed ADv and Passive Scanning State combination is supported. 0x0000000000000800 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK          0x08
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF           1
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_PASS_SCAN_OFF)
+
+/*Non Connectable Adv state and Passive Scanning State combination is supported. 0x0000000000001000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK          0x10
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF           1
+#define HCI_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_ACTIVE_SCAN_MASK)
+
+/*Scannable Adv state and Active Scanning State combination is supported. 0x0000000000002000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK          0x20
+#define HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF           1
+#define HCI_LE_STATES_SCAN_ADV_ACTIVE_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_ACTIVE_SCAN_MASK)
+
+/*Connectable Adv state and Active Scanning State combination is supported. 0x0000000000004000 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK          0x40
+#define HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF           1
+#define HCI_LE_STATES_CONN_ADV_ACTIVE_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_ACTIVE_SCAN_MASK)
+
+/*High Duty Cycl Directed ADv and ACtive Scanning State combination is supported. 0x0000000000008000 */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK          0x80
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF           1
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_MASK] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_ACTIVE_SCAN_OFF)
+
+/*Non-Connectable Adv state and Initiating State combination is supported. 0x0000000000010000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK          0x01
+#define HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF           2
+#define HCI_LE_STATES_NON_CONN_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_INIT_OFF] & HCI_SUPP_LE_STATES_NON_CONN_INIT_MASK)
+
+/* Scannable Adv state and Initiating State combination is supported. 0x0000000000020000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK          0x02
+#define HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF           2
+#define HCI_LE_STATES_SCAN_ADV_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_INIT_MASK)
+
+/* Non-Connectable Adv state and Master Role combination is supported. 0x0000000000040000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK          0x04
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF           2
+#define HCI_LE_STATES_NON_CONN_ADV_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_MASTER_MASK)
+
+/*Scannable Adv state and Master Role combination is supported. 0x0000000000040000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK          0x08
+#define HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF           2
+#define HCI_LE_STATES_SCAN_ADV_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_MASTER_MASK)
+
+/* Non-Connectable Adv and Slave Role combination is supported. 0x000000000100000 */
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK          0x10
+#define HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF           2
+#define HCI_LE_STATES_NON_CONN_ADV_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_NON_CONN_ADV_SLAVE_MASK)
+
+/*Scannable Adv and Slave Role combination is supported. 0x000000000200000 */
+#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK          0x20
+#define HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF           2
+#define HCI_LE_STATES_SCAN_ADV_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_SCAN_ADV_SLAVE_MASK)
+
+/*Passive Scan and Initiating State combination is supported. 0x000000000400000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK          0x40
+#define HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF           2
+#define HCI_LE_STATES_PASS_SCAN_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_INIT_MASK)
+
+/*Active Scan and Initiating State combination is supported. 0x000000000800000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK          0x80
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF           2
+#define HCI_LE_STATES_ACTIVE_SCAN_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_INIT_MASK)
+
+/*Passive Scan and Master Role combination is supported. 0x000000001000000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK          0x01
+#define HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF           3
+#define HCI_LE_STATES_PASS_SCAN_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_MASTER_MASK)
+
+/*Active Scan and Master Role combination is supported. 0x000000002000000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK          0x02
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF           3
+#define HCI_LE_STATES_ACTIVE_SCAN_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_MASTER_MASK)
+
+/*Passive Scan and Slave Role combination is supported. 0x000000004000000 */
+#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK          0x04
+#define HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF           3
+#define HCI_LE_STATES_PASS_SCAN_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_PASS_SCAN_SLAVE_MASK)
+
+/*Active Scan and Slave Role combination is supported. 0x000000008000000 */
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK          0x08
+#define HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF           3
+#define HCI_LE_STATES_ACTIVE_SCAN_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_OFF] & HCI_SUPP_LE_STATES_ACTIVE_SCAN_SLAVE_MASK)
+
+/*Link Layer Topology Added States Combo */
+/*Initiating State and Master Role combination supported.
+  Master Role and Master Role combination is also supported. 0x0000000010000000 */
+#define HCI_SUPP_LE_STATES_INIT_MASTER_MASK          0x10
+#define HCI_SUPP_LE_STATES_INIT_MASTER_OFF           3
+#define HCI_LE_STATES_INIT_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_MASK)
+
+/* Connectable Advertising State and Initiating State combination supported. 0x0000000100000000 */
+#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK          0x01
+#define HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF           4
+#define HCI_LE_STATES_CONN_ADV_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_INIT_MASK)
+
+/* High Duty Cycle Directed Advertising State and Initiating State combination supported. */
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK          0x02
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF           4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_INIT_MASK)
+
+/* Low Duty Cycle Directed Advertising State and Initiating State combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK          0x04
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF           4
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_INIT_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_INIT_MASK)
+
+/* Connectable Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK          0x08
+#define HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF           4
+#define HCI_LE_STATES_CONN_ADV_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_MASTER_MASK)
+
+/* High Duty Cycle Directed Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK          0x10
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF           4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_MASTER_MASK)
+
+/* Low Duty Cycle Directed Advertising State and Master Role combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK          0x20
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF           4
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_MASTER_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_MASTER_MASK)
+
+/* Connectable Advertising State and Slave Role combination supported. */
+#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK          0x40
+#define HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF           4
+#define HCI_LE_STATES_CONN_ADV_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_CONN_ADV_SLAVE_MASK)
+
+/* High Duty Cycle Directed Advertising State and slave Role combination supported.*/
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK          0x80
+#define HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF           4
+#define HCI_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_HI_DUTY_DIR_ADV_SLAVE_MASK)
+
+/* Low Duty Cycle Directed Advertising State and slave Role combination supported.*/
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK          0x01
+#define HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF           5
+#define HCI_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_OFF] & HCI_SUPP_LE_STATES_LO_DUTY_DIR_ADV_SLAVE_MASK)
+
+/* Initiating State and Slave Role combination supported.
+   Master Role and Slave Role combination also supported.
+ */
+#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK          0x02
+#define HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF           5
+#define HCI_LE_STATES_INIT_MASTER_SLAVE_SUPPORTED(x)      ((x)[HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_OFF] & HCI_SUPP_LE_STATES_INIT_MASTER_SLAVE_MASK)
+
+#define HCI_BRCM_ENABLE_WBS_MODIFIED        (0x0102 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* ConnectionLess Broadcast Stream VSC */
+#define HCI_BRCM_SET_CLB_STREAM             (0x0111 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_RECEIVE_CLB_STREAM         (0x0112 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_WRITE_CLB_STREAM_DATA      (0x0113 | HCI_GRP_VENDOR_SPECIFIC)
+#define HCI_BRCM_CLB_STREAM_FLUSH           (0x0114 | HCI_GRP_VENDOR_SPECIFIC)
+
 /*
 **  Definitions for HCI Events
 */
 #define HCI_NUM_COMPL_DATA_BLOCKS_EVT       0x48
 #define HCI_SHORT_RANGE_MODE_COMPLETE_EVT   0x4C
 #define HCI_AMP_STATUS_CHANGE_EVT           0x4D
+#define HCI_SET_TRIGGERED_CLOCK_CAPTURE_EVT 0x4E
 
 /* ULP HCI Event */
 #define HCI_BLE_EVENT                   0x03E
 #define HCI_BLE_LL_CONN_PARAM_UPD_EVT       0x03
 #define HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT   0x04
 #define HCI_BLE_LTK_REQ_EVT                 0x05
+#define HCI_BLE_RC_PARAM_REQ_EVT            0x06
+
+/* Definitions for LE Channel Map */
+#define HCI_BLE_CHNL_MAP_SIZE               5
 
-/* ConnectionLess Broadcast events */
-#define HCI_SYNC_TRAIN_COMP_EVT             0x4F
-#define HCI_SYNC_TRAIN_RECEIVED_EVT         0x50
-#define HCI_CLB_RX_DATA_EVT                 0x51
-#define HCI_CLB_RX_TIMEOUT_EVT              0x52
-#define HCI_TRUNCATED_PAGE_COMP_EVT         0x53
-#define HCI_SLAVE_PAGE_RESP_TIMEOUT_EVT     0x54
-#define HCI_CLB_CHANNEL_CHANGE_EVT          0x55
-#define HCI_INQUIRY_RESPONSE_NOTIF          0x56
 
 #define HCI_EVENT_RSP_FIRST                 HCI_INQUIRY_COMP_EVT
 #define HCI_EVENT_RSP_LAST                  HCI_CLB_CHANNEL_CHANGE_EVT
                                                  because conflict w/ TCI_EVT and per
                                                  specification compliant */
 
+/* the event mask for BLE event mask */
+#define HCI_BLE_EVENT_MASK_DEF               "\x00\x00\x00\x00\x00\x00\x00\x3f"
+
 
 
 /*
@@ -1583,6 +1794,10 @@ typedef struct
 #define HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF  0
 #define HCI_SIMUL_DUMO_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SIMUL_DUMO_HOST_OFF] & HCI_EXT_FEATURE_SIMUL_DUMO_HOST_MASK)
 
+#define HCI_EXT_FEATURE_SC_HOST_MASK 0x08
+#define HCI_EXT_FEATURE_SC_HOST_OFF  0
+#define HCI_SC_HOST_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_HOST_OFF] & HCI_EXT_FEATURE_SC_HOST_MASK)
+
 /*
 **   LMP features encoding - page 2
 */
@@ -1606,19 +1821,43 @@ typedef struct
 #define HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF      0
 #define HCI_INQ_RESP_NOTIF_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_INQ_RESP_NOTIF_OFF] & HCI_EXT_FEATURE_INQ_RESP_NOTIF_MASK)
 
+#define HCI_EXT_FEATURE_SC_CTRLR_MASK           0x01
+#define HCI_EXT_FEATURE_SC_CTRLR_OFF            1
+#define HCI_SC_CTRLR_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_SC_CTRLR_OFF] & HCI_EXT_FEATURE_SC_CTRLR_MASK)
+
+#define HCI_EXT_FEATURE_PING_MASK               0x02
+#define HCI_EXT_FEATURE_PING_OFF                1
+#define HCI_PING_SUPPORTED(x) ((x)[HCI_EXT_FEATURE_PING_OFF] & HCI_EXT_FEATURE_PING_MASK)
+
 /*
 **   LE features encoding - page 0 (the only page for now)
 */
+/* LE Encryption */
 #define HCI_LE_FEATURE_LE_ENCRYPTION_MASK       0x01
 #define HCI_LE_FEATURE_LE_ENCRYPTION_OFF        0
 #define HCI_LE_ENCRYPTION_SUPPORTED(x) ((x)[HCI_LE_FEATURE_LE_ENCRYPTION_OFF] & HCI_LE_FEATURE_LE_ENCRYPTION_MASK)
 
+/* Connection Parameters Request Procedure */
+#define HCI_LE_FEATURE_CONN_PARAM_REQ_MASK       0x02
+#define HCI_LE_FEATURE_CONN_PARAM_REQ_OFF        0
+#define HCI_LE_CONN_PARAM_REQ_SUPPORTED(x) ((x)[HCI_LE_FEATURE_CONN_PARAM_REQ_OFF] & HCI_LE_FEATURE_CONN_PARAM_REQ_MASK)
+
+/* Extended Reject Indication */
+#define HCI_LE_FEATURE_EXT_REJ_IND_MASK       0x04
+#define HCI_LE_FEATURE_EXT_REJ_IND_OFF        0
+#define HCI_LE_EXT_REJ_IND_SUPPORTED(x) ((x)[HCI_LE_FEATURE_EXT_REJ_IND_OFF] & HCI_LE_FEATURE_EXT_REJ_IND_MASK)
+
+/* Slave-initiated Features Exchange */
+#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK       0x08
+#define HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF        0
+#define HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(x) ((x)[HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_OFF] & HCI_LE_FEATURE_SLAVE_INIT_FEAT_EXC_MASK)
 
 /*
 **   Local Supported Commands encoding
 */
 #define HCI_NUM_SUPP_COMMANDS_BYTES           64
 
+/* Supported Commands Byte 0 */
 #define HCI_SUPP_COMMANDS_INQUIRY_MASK 0x01
 #define HCI_SUPP_COMMANDS_INQUIRY_OFF  0
 #define HCI_INQUIRY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_INQUIRY_OFF] & HCI_SUPP_COMMANDS_INQUIRY_MASK)
@@ -2398,8 +2637,42 @@ typedef struct
 #define HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF         32
 #define HCI_WRITE_SYNC_TRAIN_PARAM_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM_OFF] & HCI_SUPP_COMMANDS_WRITE_SYNC_TRAIN_PARAM)
 
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK   0x02
+#define HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF    32
+#define HCI_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_OFF] & HCI_SUPP_COMMANDS_REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK    0x04
+#define HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF     32
+#define HCI_READ_SECURE_CONNS_SUPPORT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_READ_SECURE_CONNS_SUPPORT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK   0x08
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF    32
+#define HCI_WRITE_SECURE_CONNS_SUPPORT_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNS_SUPPORT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK    0x10
+#define HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF     32
+#define HCI_READ_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_READ_AUTHENT_PAYLOAD_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK   0x20
+#define HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF    32
+#define HCI_WRITE_AUTHENT_PAYLOAD_TOUT_SUPPORTED(x)  ((x)[HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_OFF] & HCI_SUPP_COMMANDS_WRITE_AUTHENT_PAYLOAD_TOUT_MASK)
+
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK 0x40
+#define HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF  32
+#define HCI_READ_LOCAL_OOB_EXTENDED_DATA_SUPPORTED(x)   ((x)[HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_OFF] & HCI_SUPP_COMMANDS_READ_LOCAL_OOB_EXTENDED_DATA_MASK)
+
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK   0x80
+#define HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF    32
+#define HCI_WRITE_SECURE_CONNECTIONS_TEST_MODE_SUPPORTED(x) ((x)[HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_OFF] & HCI_SUPP_COMMANDS_WRITE_SECURE_CONNECTIONS_TEST_MODE_MASK)
 
+/* supported LE remote control connection parameter request reply */
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK          0x10
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF           33
+#define HCI_LE_RC_CONN_PARAM_UPD_RPY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_OFF] & HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_RPY_MASK)
 
+#define HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK          0x20
+#define HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF           33
+#define HCI_LE_RC_CONN_PARAM_UPD_NEG_RPY_SUPPORTED(x)      ((x)[HCI_SUPP_COMMANDS_LE_RC_CONN_PARAM_UPD_NEG_RPY_OFF] & HCI_SUPP_COMMANDS_RLE_RC_CONN_PARAM_UPD_NEG_RPY_MASK)
 
 /*
 Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator
index 318e748..3201f75 100644 (file)
@@ -1252,8 +1252,6 @@ HCI_API extern void btsnd_hcie_ext_inquiry_result(void *buffer, UINT8 num_resp,
 #define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA      31
 
 /* ULP HCI command */
-HCI_API extern BOOLEAN btsnd_hcic_ble_reset(void);
-
 HCI_API extern BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask);
 
 HCI_API extern BOOLEAN btsnd_hcic_ble_read_buffer_size (void);
@@ -1331,6 +1329,20 @@ HCI_API extern BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test
                                                            UINT8 payload);
 HCI_API extern BOOLEAN btsnd_hcic_ble_test_end(void);
 
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+
+#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY           14
+HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_reply(UINT16 handle,
+                                                        UINT16 conn_int_min, UINT16 conn_int_max,
+                                                        UINT16 conn_latency, UINT16 conn_timeout,
+                                                        UINT16 min_ce_len, UINT16 max_ce_len);
+
+#define HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY       3
+HCI_API extern BOOLEAN btsnd_hcic_ble_rc_param_req_neg_reply(UINT16 handle, UINT8 reason);
+
+#endif /* BLE_LLT_INCLUDED */
+
+
 #endif /* BLE_INCLUDED */
 
 #ifdef __cplusplus
index 0da7f79..54c7ddb 100644 (file)
@@ -919,8 +919,9 @@ L2C_API extern BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIO
 **      BD Address of remote
 **      TRUE if channel is connected, FALSE if disconnected
 **      Reason for connection failure
+**      transport : physical transport, BR/EDR or LE
 */
-typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16);
+typedef void (tL2CA_FIXED_CHNL_CB) (BD_ADDR, BOOLEAN, UINT16, tBT_TRANSPORT);
 
 /* Signalling data received. Parameters are
 **      BD Address of remote
@@ -1128,7 +1129,8 @@ L2C_API extern BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda);
 **  Return value:   TRUE if update started
 **
 *******************************************************************************/
-L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout);
+L2C_API extern BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bdRa, UINT16 min_int,
+                                                          UINT16 max_int, UINT16 latency, UINT16 timeout);
 
 /*******************************************************************************
 **
@@ -1146,18 +1148,6 @@ L2C_API extern BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN
 
 /*******************************************************************************
 **
-** Function         L2CA_HandleConnUpdateEvent
-**
-** Description      This function enables the connection update request from remote
-**                  after a successful connection update response is received.
-**
-** Returns          void
-**
-*******************************************************************************/
-L2C_API void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status);
-
-/*******************************************************************************
-**
 ** Function         L2CA_GetBleConnRole
 **
 ** Description      This function returns the connection role.
@@ -1173,10 +1163,13 @@ L2C_API extern UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr);
 **
 ** Description      This function returns the disconnect reason code.
 **
+**  Parameters:     BD Address of remote
+**                         Physical transport for the L2CAP connection (BR/EDR or LE)
+**
 ** Returns          disconnect reason
 **
 *******************************************************************************/
-L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda);
+L2C_API extern UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport);
 
 #endif /* (BLE_INCLUDED == TRUE) */
 
index 68c9ebf..e47cce3 100644 (file)
@@ -134,9 +134,9 @@ typedef struct
 
 typedef struct
 {
-    UINT8       reason;
-    UINT8       sec_level;
-    BOOLEAN     is_pair_cancel;
+    tSMP_STATUS     reason;
+    tSMP_SEC_LEVEL  sec_level;
+    BOOLEAN         is_pair_cancel;
 } tSMP_CMPL;
 
 typedef union
index 6a9a4ae..53cdccf 100644 (file)
@@ -105,231 +105,6 @@ typedef struct t_uipc_log_msg
 } tUIPC_LOG_MSG;
 #define UIPC_LOG_MSGLEN       (IPC_LOG_MSG_LEN + 4)
 
-/********************************
-
-    H5 Sync Message
-
-********************************/
-
-/* op_code */
-#define SLIP_SYNC_TO_LITE_REQ        0
-#define SLIP_SYNC_TO_LITE_RESP       1
-#define SLIP_SYNC_TO_FULL_REQ        2
-#define SLIP_SYNC_TO_FULL_RESP       3
-#define SLIP_SYNC_NOTIFY             4
-
-/* status */
-#define SLIP_SYNC_SUCCESS            0
-#define SLIP_SYNC_FAILURE            1
-
-typedef struct
-{
-    UINT8       op_code;
-    UINT8       status;
-    UINT16      acl_pkt_size;
-    UINT8       state;
-    UINT8       lp_state;           /* Low Power state */
-    UINT8       next_seqno;         /* next send seq */
-    UINT8       ack;                /* next ack seq, expected seq from peer */
-    UINT8       sent_ack;           /* last sent ack */
-    UINT8       sliding_window_size;/* window size */
-    BOOLEAN     oof_flow_control;   /* Out of Frame SW Flow Control */
-    BOOLEAN     data_integrity_type;/* Level of Data Integrity Check */
-    UINT8       rx_state;           /* rx state for incoming packet processing */
-} tSLIP_SYNC_INFO;
-
-/********************************
-
-    L2CAP Sync Message
-
-********************************/
-
-/* op_code */
-#define L2C_SYNC_TO_LITE_REQ        0
-#define L2C_SYNC_TO_LITE_RESP       1
-#define L2C_REMOVE_TO_LITE_REQ      2
-#define L2C_REMOVE_TO_LITE_RESP     3
-#define L2C_FLUSH_TO_FULL_IND       4
-
-/* status */
-#define L2C_SYNC_SUCCESS            0
-#define L2C_SYNC_FAILURE            1
-
-typedef struct t_l2c_stream_info
-{
-    UINT16  local_cid;          /* Local CID                        */
-    UINT16  remote_cid;         /* Remote CID                       */
-    UINT16  out_mtu;            /* Max MTU we will send             */
-    UINT16  handle;             /* The handle used with LM          */
-    UINT16  link_xmit_quota;    /* Num outstanding pkts allowed     */
-    BOOLEAN is_flushable;       /* TRUE if flushable channel        */
-} tL2C_STREAM_INFO;
-
-typedef struct t_l2c_sync_to_lite_req
-{
-    UINT8   op_code;                       /* L2C_SYNC_TO_LITE_REQ */
-    UINT16  light_xmit_quota;              /* Total quota for light stack    */
-    UINT16  acl_data_size;                 /* Max ACL data size across HCI transport    */
-    UINT16  non_flushable_pbf;             /* L2CAP_PKT_START_NON_FLUSHABLE if controller supports */
-                                           /* Otherwise, L2CAP_PKT_START */
-    UINT8   multi_av_data_cong_start;      /* Multi-AV queue size to start congestion */
-    UINT8   multi_av_data_cong_end;        /* Multi-AV queue size to end congestion */
-    UINT8   multi_av_data_cong_discard;    /* Multi-AV queue size to discard */
-    UINT8   num_stream;
-    tL2C_STREAM_INFO stream[BTM_SYNC_INFO_NUM_STR];
-} tL2C_SYNC_TO_LITE_REQ;
-
-typedef struct t_l2c_sync_to_lite_resp_stream
-{
-    UINT16  lcid;
-    UINT8   status;
-} tL2C_SYNC_TO_LITE_RESP_STREAM;
-
-typedef struct t_l2c_sync_to_lite_resp
-{
-    UINT8   op_code;                       /* L2C_SYNC_TO_LITE_RESP */
-    UINT16  light_xmit_unacked;            /* unacked packet more than quota in light stack    */
-    UINT8   num_stream;
-    tL2C_SYNC_TO_LITE_RESP_STREAM stream[BTM_SYNC_INFO_NUM_STR];
-} tL2C_SYNC_TO_LITE_RESP;
-
-typedef struct t_l2c_remove_to_lite_req
-{
-    UINT8   op_code;                       /* L2C_REMOVE_TO_LITE_REQ */
-    UINT16  light_xmit_quota;              /* Total quota for light stack    */
-    UINT8   num_stream;
-    UINT16  lcid[BTM_SYNC_INFO_NUM_STR];
-} tL2C_REMOVE_TO_LITE_REQ;
-
-typedef tL2C_SYNC_TO_LITE_RESP  tL2C_REMOVE_TO_LITE_RESP;
-typedef tL2C_REMOVE_TO_LITE_REQ tL2C_FLUSH_TO_FULL_IND;
-
-typedef union t_l2c_sync_msg
-{
-    UINT8                       op_code;
-    tL2C_SYNC_TO_LITE_REQ       sync_req;
-    tL2C_SYNC_TO_LITE_RESP      sync_resp;
-    tL2C_REMOVE_TO_LITE_REQ     remove_req;
-    tL2C_REMOVE_TO_LITE_RESP    remove_resp;
-    tL2C_FLUSH_TO_FULL_IND      flush_ind;
-} tL2C_SYNC_MSG;
-
-/********************************
-
-    AVDTP Sync Message
-
-********************************/
-
-/* op_code */
-#define AVDT_SYNC_TO_LITE_REQ        0
-#define AVDT_SYNC_TO_LITE_RESP       1
-#define AVDT_RESYNC_TO_LITE_REQ      2
-#define AVDT_RESYNC_TO_LITE_RESP     3
-#define AVDT_SYNC_TO_FULL_REQ        4
-#define AVDT_SYNC_TO_FULL_RESP       5
-#define AVDT_REMOVE_TO_LITE_REQ      6
-#define AVDT_REMOVE_TO_LITE_RESP     7
-#define AVDT_SYNC_TO_BTC_LITE_REQ    8
-#define AVDT_SYNC_TO_BTC_LITE_RESP   9
-
-/* status */
-#define AVDT_SYNC_SUCCESS            0
-#define AVDT_SYNC_FAILURE            1
-
-typedef struct
-{
-    UINT16  lcid;
-    UINT32  ssrc;
-} tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM;
-
-typedef struct
-{
-    UINT8   opcode;                     /* AVDT_SYNC_TO_BTC_LITE_REQ */
-    UINT8   num_stream;
-    tAVDT_SYNC_TO_BTC_LITE_REQ_STREAM  stream[BTM_SYNC_INFO_NUM_STR];
-} tAVDT_SYNC_TO_BTC_LITE_REQ;
-
-typedef struct
-{
-    UINT8   opcode;                     /* AVDT_SYNC_TO_BTC_LITE_RESP */
-    UINT8   status;
-} tAVDT_SYNC_TO_BTC_LITE_RESP;
-
-typedef struct t_avdt_scb_sync_info
-{
-    UINT8   handle;         /* SCB handle */
-    BD_ADDR peer_addr;      /* BD address of peer */
-    UINT16  local_cid;      /* Local CID                        */
-    UINT16  peer_mtu;       /* L2CAP mtu of the peer device */
-    UINT8   mux_tsid_media; /* TSID for media transport session */
-    UINT16  media_seq;      /* media packet sequence number */
-} tAVDT_SCB_SYNC_INFO;
-
-typedef struct t_avdt_sync_info
-{
-    UINT8   op_code;
-    UINT8   status;
-
-    tAVDT_SCB_SYNC_INFO scb_info[BTM_SYNC_INFO_NUM_STR];
-
-} tAVDT_SYNC_INFO;
-
-typedef union t_avdt_sync_msg
-{
-    UINT8                       op_code;
-    tAVDT_SYNC_INFO             sync_info;
-    tAVDT_SYNC_TO_BTC_LITE_REQ  btc_sync_req;
-    tAVDT_SYNC_TO_BTC_LITE_RESP btc_sync_resp;
-} tAVDT_SYNC_MSG;
-
-/********************************
-
-    BTA AV Sync Message
-
-********************************/
-
-/* op_code for MM light stack */
-#define BTA_AV_SYNC_TO_LITE_REQ             0
-#define BTA_AV_SYNC_TO_LITE_RESP            1
-#define BTA_AV_STR_START_TO_LITE_REQ        2
-#define BTA_AV_STR_START_TO_LITE_RESP       3
-#define BTA_AV_STR_STOP_TO_LITE_REQ         4
-#define BTA_AV_STR_STOP_TO_LITE_RESP        5
-#define BTA_AV_STR_CLEANUP_TO_LITE_REQ      6
-#define BTA_AV_STR_CLEANUP_TO_LITE_RESP     7
-#define BTA_AV_STR_SUSPEND_TO_LITE_REQ      8
-#define BTA_AV_STR_SUSPEND_TO_LITE_RESP     9
-#define BTA_AV_SYNC_ERROR_RESP              10
-
-/* op_code for BTC light stack */
-#define A2DP_START_REQ                      11
-#define A2DP_START_RESP                     12
-#define A2DP_STOP_REQ                       13
-#define A2DP_STOP_RESP                      14
-#define A2DP_CLEANUP_REQ                    15
-#define A2DP_CLEANUP_RESP                   16
-#define A2DP_SUSPEND_REQ                    17
-#define A2DP_SUSPEND_RESP                   18
-
-#define A2DP_JITTER_DONE_IND                41  /* For BTSNK */
-
-#define AUDIO_CODEC_CONFIG_REQ              19
-#define AUDIO_CODEC_CONFIG_RESP             20
-#define AUDIO_CODEC_SET_BITRATE_REQ         21
-#define AUDIO_CODEC_FLUSH_REQ               22
-#define AUDIO_ROUTE_CONFIG_REQ              23
-#define AUDIO_ROUTE_CONFIG_RESP             24
-#define AUDIO_MIX_CONFIG_REQ                25
-#define AUDIO_MIX_CONFIG_RESP               26
-#define AUDIO_BURST_FRAMES_IND              27
-#define AUDIO_BURST_END_IND                 28
-#define AUDIO_EQ_MODE_CONFIG_REQ            29
-#define AUDIO_SCALE_CONFIG_REQ              30
-
-/* For TIVO, only applicable for I2S -> DAC */
-#define AUDIO_SUB_ROUTE_REQ                 51
-#define AUDIO_SUB_ROUTE_RESP                52
-
 typedef struct
 {
     UINT8   opcode;     /* A2DP_START_REQ */
@@ -789,96 +564,5 @@ typedef struct
     tMIX_SCALE_CONFIG   mix_scale;
 } tAUDIO_SCALE_CONFIG_REQ;
 
-typedef UINT8 tBTA_AV_DUAL_STACK_EVT;
-
-typedef struct
-{
-    UINT8               avdt_handle;    /* AVDTP handle */
-    UINT8               chnl;           /* the channel: audio/video */
-    UINT8               codec_type;     /* codec type */
-    BOOLEAN             cong;           /* TRUE if AVDTP congested */
-    UINT8               hdi;            /* the index to SCB[] */
-    UINT8               hndl;           /* the handle: ((hdi + 1)|chnl) */
-    UINT8               l2c_bufs;       /* the number of buffers queued to L2CAP */
-    UINT16              l2c_cid;        /* L2CAP channel ID */
-    BD_ADDR             peer_addr;      /* peer BD address */
-}tBTA_AV_SYNC_INFO;
-
-typedef struct
-{
-    tBTA_AV_DUAL_STACK_EVT  event;
-    tBTA_AV_SYNC_INFO       sync_info;
-    UINT16                  curr_mtu;                 /* common mtu shared by all active streams */
-    UINT8                   multi_av_supported;       /* Whether multi-av is supported */
-}tBTA_AV_SYNC_INFO_REQ; /* SYNC_TO_LITE_REQ */
-
-/* Dual stack stream events */
-typedef struct
-{
-    tBTA_AV_DUAL_STACK_EVT          event;
-    UINT8                           scb_idx;
-}tBTA_AV_SCB_EVT;
-
-/* data type for the Audio Codec Information*/
-typedef struct
-{
-    UINT16  bit_rate;                   /* SBC encoder bit rate in kbps */
-    UINT16  bit_rate_busy;              /* SBC encoder bit rate in kbps */
-    UINT16  bit_rate_swampd;            /* SBC encoder bit rate in kbps */
-    UINT8   busy_level;                 /* Busy level indicating the bit-rate to be used */
-    UINT8   codec_info[AVDT_CODEC_SIZE];
-    UINT8   codec_type;                 /* Codec type */
-} tBTA_AV_AUDIO_CODEC_SYNC_INFO;
-
-/* Dual stack stream events */
-typedef struct
-{
-    tBTA_AV_DUAL_STACK_EVT          event;
-    UINT8                           scb_idx;
-    UINT8                           audio_open_cnt;
-    tBTA_AV_AUDIO_CODEC_SYNC_INFO   p_codec_cfg;
-    UINT8                           start_stop_flag;
-}tBTA_AV_SCB_REQ;
-
-typedef struct
-{
-    tBTA_AV_DUAL_STACK_EVT          event;
-    UINT8                           scb_idx;
-    UINT8                           audio_open_cnt;
-    UINT16                          curr_mtu;           /* common mtu shared by all active streams */
-}tBTA_AV_SCB_CLEANUP_REQ;
-
-/* Add request/response structures if needed ...
-typedef struct
-{
-    event;
-    data;
-}tBTA_AV_SYNC_*_REQ/RESP;
-*/
-
-typedef union
-{
-    /* MM light stack */
-    tBTA_AV_DUAL_STACK_EVT          event;
-    tBTA_AV_SYNC_INFO_REQ           sync_info_req;
-    tBTA_AV_SCB_EVT                 scb_evt;
-    tBTA_AV_SCB_REQ                 scb_req;
-    tBTA_AV_SCB_CLEANUP_REQ         scb_cleanup_req;
-
-    /* BTC light stack */
-    UINT8                           opcode;
-    tA2DP_START_REQ                 btc_start_req;
-    tA2DP_STOP_REQ                  btc_stop_req;
-    tA2DP_CLEANUP_REQ               btc_cleanup_req;
-    tA2DP_SUSPEND_REQ               btc_suspend_req;
-
-    tAUDIO_CODEC_CONFIG_REQ         codec_config_req;
-    tAUDIO_CODEC_SET_BITRATE_REQ    codec_bitrate_req;
-    tAUDIO_CODEC_FLUSH_REQ          codec_flush_req;
-    tAUDIO_ROUTE_CONFIG_REQ         route_config_req;
-    tAUDIO_MIX_CONFIG_REQ           mix_config_req;
-    tAUDIO_EQ_MODE_CONFIG_REQ       eq_mode_req;
-    tAUDIO_SCALE_CONFIG_REQ         scale_config_req;
-}tBTA_DUAL_STACK_MSG;
-
 #endif /* UIPC_MSG_H */
+
index 30249a4..338a7cd 100644 (file)
@@ -223,6 +223,10 @@ UINT16 L2CA_ConnectReq (UINT16 psm, BD_ADDR p_bd_addr)
 **                  connection establishment gets started. The callback function
 **                  will be invoked when connection establishes or fails.
 **
+**  Parameters:       PSM: L2CAP PSM for the connection
+**                    BD address of the peer
+**                   Enhaced retransmission mode configurations
+
 ** Returns          the CID of the connection, or 0 if it failed to start
 **
 *******************************************************************************/
@@ -232,10 +236,12 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
     tL2C_CCB        *p_ccb;
     tL2C_RCB        *p_rcb;
 
-    L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq()  PSM: 0x%04x  BDA: %08x%04x  p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm,
+    L2CAP_TRACE_API6 ("L2CA_ErtmConnectReq()  PSM: 0x%04x  BDA: %08x%04x  p_ertm_info"
+                      ": 0x%08x allowed:0x%x preferred:%d", psm,
                       (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
                       (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info,
-                      (p_ertm_info) ? p_ertm_info->allowed_modes : 0, (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
+                      (p_ertm_info) ? p_ertm_info->allowed_modes : 0,
+                      (p_ertm_info) ? p_ertm_info->preferred_mode : 0);
 
     /* Fail if we have not established communications with the controller */
     if (!BTM_IsDeviceUp())
@@ -251,13 +257,16 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
     }
 
     /* First, see if we already have a link to the remote */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+    /* assume all ERTM l2cap connection is going over BR/EDR for now */
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         /* No link. Get an LCB and start link establishment */
-        if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
-         ||  (l2cu_create_conn(p_lcb) == FALSE) )
+        if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
+             /* currently use BR/EDR for ERTM mode l2cap connection */
+         ||  (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) )
         {
-            L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x  p_lcb: 0x%08x", psm, p_lcb);
+            L2CAP_TRACE_WARNING2 ("L2CAP - conn not started for PSM: 0x%04x  p_lcb: 0x%08x",
+                                psm, p_lcb);
             return (0);
         }
     }
@@ -289,7 +298,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
         if (p_ccb->ertm_info.user_tx_pool_id == L2CAP_DEFAULT_ERM_POOL_ID)
             p_ccb->ertm_info.user_tx_pool_id = HCI_ACL_POOL_ID;
 
-        p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) - (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
+        p_ccb->max_rx_mtu = GKI_get_pool_bufsize (p_ertm_info->user_rx_pool_id) -
+            (L2CAP_MIN_OFFSET + L2CAP_SDU_LEN_OFFSET + L2CAP_FCS_LEN);
     }
 
     /* If link is up, start the L2CAP connection */
@@ -312,7 +322,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
         p_lcb->p_pending_ccb = p_ccb;
     }
 
-    L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x", psm, p_ccb->local_cid);
+    L2CAP_TRACE_API2 ("L2CAP - L2CA_conn_req(psm: 0x%04x) returned CID: 0x%04x",
+        psm, p_ccb->local_cid);
 
     /* Return the local CID as our handle */
     return (p_ccb->local_cid);
@@ -330,7 +341,8 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
 ** Returns          TRUE for success, FALSE for failure
 **
 *******************************************************************************/
-BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 result, UINT16 status)
+BOOLEAN L2CA_ConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid,
+                              UINT16 result, UINT16 status)
 {
     return L2CA_ErtmConnectRsp (p_bd_addr, id, lcid, result, status, NULL);
 }
@@ -353,13 +365,14 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re
     tL2C_LCB        *p_lcb;
     tL2C_CCB        *p_ccb;
 
-    L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp()  CID: 0x%04x  Result: %d  Status: %d  BDA: %08x%04x  p_ertm_info:0x%08x",
+    L2CAP_TRACE_API6 ("L2CA_ErtmConnectRsp()  CID: 0x%04x  Result: %d  Status: %d  BDA: %08x%04x"
+                       " p_ertm_info:0x%08x",
                       lcid, result, status,
                       (p_bd_addr[0]<<24)+(p_bd_addr[1]<<16)+(p_bd_addr[2]<<8)+p_bd_addr[3],
                       (p_bd_addr[4]<<8)+p_bd_addr[5], p_ertm_info);
 
     /* First, find the link control block */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         /* No link. Get an LCB and start link establishment */
         L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_rsp");
@@ -594,15 +607,15 @@ BOOLEAN  L2CA_Ping (BD_ADDR p_bd_addr, tL2CA_ECHO_RSP_CB *p_callback)
         return (FALSE);
 
     /* First, see if we already have a link to the remote */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         /* No link. Get an LCB and start link establishment */
-        if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
+        if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
         {
             L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_ping");
             return (FALSE);
         }
-        if (l2cu_create_conn(p_lcb) == FALSE)
+        if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE)
         {
             return (FALSE);
         }
@@ -670,7 +683,7 @@ BOOLEAN  L2CA_Echo (BD_ADDR p_bd_addr, BT_HDR *p_data, tL2CA_ECHO_DATA_CB *p_cal
     }
 
     /* We assume the upper layer will call this function only when the link is established. */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         L2CAP_TRACE_ERROR0 ("L2CA_Echo ERROR : link not established");
         return FALSE;
@@ -767,7 +780,7 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout)
 
     if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
     {
-        p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr );
+        p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, BT_TRANSPORT_BR_EDR);
         if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
             p_lcb->idle_timeout = timeout;
         else
@@ -880,7 +893,7 @@ UINT16 L2CA_LocalLoopbackReq (UINT16 psm, UINT16 handle, BD_ADDR p_bd_addr)
         return (0);
     }
 
-    if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE)) == NULL)
+    if ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_conn_req");
         return (0);
@@ -1129,7 +1142,7 @@ BOOLEAN L2CA_SetFlushTimeout (BD_ADDR bd_addr, UINT16 flush_tout)
 
     if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
     {
-        p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+        p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
 
         if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
         {
@@ -1195,7 +1208,7 @@ BOOLEAN L2CA_GetPeerFeatures (BD_ADDR bd_addr, UINT32 *p_ext_feat, UINT8 *p_chnl
     tL2C_LCB        *p_lcb;
 
     /* We must already have a link to the remote */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         L2CAP_TRACE_WARNING2 ("L2CA_GetPeerFeatures() No BDA: %08x%04x",
                               (bd_addr[0]<<24)+(bd_addr[1]<<16)+(bd_addr[2]<<8)+bd_addr[3],
@@ -1307,9 +1320,8 @@ BOOLEAN  L2CA_RegisterFixedChannel (UINT16 fixed_cid, tL2CAP_FIXED_CHNL_REG *p_f
 BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
 {
     tL2C_LCB        *p_lcb;
-#if BLE_INCLUDED == TRUE
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
     UINT16          reason;
-#endif
 
     L2CAP_TRACE_API3  ("L2CA_ConnectFixedChnl()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
                     (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
@@ -1329,39 +1341,58 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
         return (FALSE);
     }
 
+#if BLE_INCLUDED == TRUE
+    if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+        transport = BT_TRANSPORT_LE;
+#endif
+
     /* If we already have a link to the remote, check if it supports that CID */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) != NULL)
     {
         if (!(p_lcb->peer_chnl_mask[0] & (1 << fixed_cid)))
         {
-            L2CAP_TRACE_EVENT3  ("L2CA_ConnectFixedChnl()  CID: 0x%04x  BDA: %08x%04x not supported", fixed_cid,
-                                (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
+            L2CAP_TRACE_EVENT3  ("L2CA_ConnectFixedChnl() CID:0x%04x  BDA: %08x%04x not supported",
+                fixed_cid,(rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+                (rem_bda[4]<<8)+rem_bda[5]);
             return (FALSE);
         }
         /* Get a CCB and link the lcb to it */
-        if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+        if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid,
+            &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
         {
             L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - LCB but no CCB", fixed_cid);
             return (FALSE);
         }
+
+        /* racing with disconnecting, queue the connection request */
+        if (p_lcb->link_state == LST_DISCONNECTING)
+        {
+            L2CAP_TRACE_DEBUG0 ("L2CAP API - link disconnecting: RETRY LATER");
+            /* Save ccb so it can be started after disconnect is finished */
+            p_lcb->p_pending_ccb = p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL];
+            return (TRUE);
+        }
+
 #if BLE_INCLUDED == TRUE
-        reason = (p_lcb->is_ble_link) ? 1: 0;
-        (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
+        (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)
+        (p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
 #else
-        (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0);
+        (*l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedConn_Cb)
+        (p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
 #endif
         return (TRUE);
     }
 
     /* No link. Get an LCB and start link establishment */
-    if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL)
+    if ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, transport)) == NULL)
     {
         L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no LCB", fixed_cid);
         return (FALSE);
     }
 
     /* Get a CCB and link the lcb to it */
-    if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid, &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
+    if (!l2cu_initialize_fixed_ccb (p_lcb, fixed_cid,
+        &l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
     {
         p_lcb->disc_reason = L2CAP_CONN_NO_RESOURCES;
         L2CAP_TRACE_WARNING1 ("L2CA_ConnectFixedChnl(0x%04x) - no CCB", fixed_cid);
@@ -1369,7 +1400,7 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
         return (FALSE);
     }
 
-    return (l2cu_create_conn(p_lcb));
+    return (l2cu_create_conn(p_lcb, transport));
 }
 
 /*******************************************************************************
@@ -1389,10 +1420,16 @@ BOOLEAN L2CA_ConnectFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
 UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
 {
     tL2C_LCB        *p_lcb;
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
 
     L2CAP_TRACE_API3 ("L2CA_SendFixedChnlData()  CID: 0x%04x  BDA: %08x%04x", fixed_cid,
                      (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
 
+#if BLE_INCLUDED == TRUE
+    if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+        transport = BT_TRANSPORT_LE;
+#endif
+
     /* Check CID is valid and registered */
     if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
      ||  (l2cb.fixed_reg[fixed_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb == NULL) )
@@ -1409,7 +1446,9 @@ UINT16 L2CA_SendFixedChnlData (UINT16 fixed_cid, BD_ADDR rem_bda, BT_HDR *p_buf)
     }
 
     /* We need to have a link up */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport)) == NULL ||
+        /* if link is disconnecting, also report data sending failure */
+        p_lcb->link_state == LST_DISCONNECTING)
     {
         L2CAP_TRACE_WARNING1 ("L2CA_SendFixedChnlData(0x%04x) - no LCB", fixed_cid);
         return (L2CAP_DW_FAILED);
@@ -1463,6 +1502,7 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
 {
     tL2C_LCB    *p_lcb;
     tL2C_CCB    *p_ccb;
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
 
     /* Check CID is valid and registered */
     if ( (fixed_cid < L2CAP_FIRST_FIXED_CHNL) || (fixed_cid > L2CAP_LAST_FIXED_CHNL)
@@ -1472,8 +1512,14 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
         return (FALSE);
     }
 
+#if BLE_INCLUDED == TRUE
+    if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+        transport = BT_TRANSPORT_LE;
+#endif
+
     /* Is a fixed channel connected to the remote BDA ?*/
-    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
+
     if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
     {
         L2CAP_TRACE_WARNING3 ("L2CA_RemoveFixedChnl()  CID: 0x%04x  BDA: %08x%04x not connected", fixed_cid,
@@ -1491,7 +1537,14 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
     p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
 
 #if BLE_INCLUDED == TRUE
-    if (fixed_cid == L2CAP_ATT_CID && !p_lcb->ccb_queue.p_first_ccb)
+    /* retain the link for a few more seconds after SMP pairing is done, since Android
+    platformalways do service discovery after pairing complete. This way would avoid
+    the link down (pairing is complete) and an immediate reconnection for service
+    discovery. Some devices do not do auto advertising when link is dropped, thus fail
+    the second connection and service discovery.
+    BEFORE :if ((fixed_cid == L2CAP_ATT_CID || fixed_cid == L2CAP_SMP_CID)
+                       && !p_lcb->ccb_queue.p_first_ccb)*/
+    if ((fixed_cid == L2CAP_ATT_CID ) && !p_lcb->ccb_queue.p_first_ccb)
         p_lcb->idle_timeout = 0;
 #endif
 
@@ -1520,9 +1573,15 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
 BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle_tout)
 {
     tL2C_LCB        *p_lcb;
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
+
+#if BLE_INCLUDED == TRUE
+    if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID)
+        transport = BT_TRANSPORT_LE;
+#endif
 
     /* Is a fixed channel connected to the remote BDA ?*/
-    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, transport);
     if ( ((p_lcb) == NULL) || (!p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]) )
     {
         L2CAP_TRACE_WARNING3 ("L2CA_SetFixedChannelTout()  CID: 0x%04x  BDA: %08x%04x not connected", fixed_cid,
@@ -1614,7 +1673,7 @@ BOOLEAN L2CA_RegForNoCPEvt(tL2CA_NOCP_CB *p_cb, BD_ADDR p_bda)
     tL2C_LCB        *p_lcb;
 
     /* Find the link that is associated with this remote bdaddr */
-    p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
 
     /* If no link for this handle, nothing to do. */
     if (!p_lcb)
index ba0d7ec..0e6c73a 100644 (file)
@@ -32,6 +32,9 @@
 #include "hcimsgs.h"
 
 #if (BLE_INCLUDED == TRUE)
+#define L2CA_GET_UPD_ST(x)          ((x) & UPD_ST_MASK)
+#define L2CA_SET_UPD_ST(x, y)      x = (((x) & ~UPD_ST_MASK) | (y))
+
 
 /*******************************************************************************
 **
@@ -68,7 +71,7 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
     if (btsnd_hcic_ble_create_conn_cancel())
     {
 
-        if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) != NULL)
+        if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE)) != NULL)
         {
             p_lcb->disc_reason = L2CAP_CONN_CANCEL;
             l2cu_release_lcb (p_lcb);
@@ -84,57 +87,6 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda)
 
 /*******************************************************************************
 **
-**  Function        L2CA_InternalBleConnUpdate
-**
-**  Description     update BLE connection based on status
-**
-**  Parameters:     lcb
-**
-**  Return value:   none
-**
-*******************************************************************************/
-static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
-{
-    if (p_lcb->upd_status & L2C_BLE_UPDATE_PENDING) return;
-
-    if (p_lcb->upd_status & L2C_BLE_CONN_UPDATE_DISABLE)
-    {
-        /* application requests to disable parameters update.
-           If parameters are already updated, lets set them
-           up to what has been requested during connection establishement */
-        if (p_lcb->upd_status & L2C_BLE_NOT_DEFAULT_PARAM)
-        {
-            tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
-
-            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle,
-                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
-                         p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
-                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
-                         p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
-                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
-                         p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
-                (UINT16)((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
-                         p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
-                0, 0);
-            p_lcb->upd_status &= ~L2C_BLE_NOT_DEFAULT_PARAM;
-            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NEW_CONN_PARAM);
-        }
-    }
-    else
-    {
-        /* application allows to do update, if we were delaying one do it now */
-        if (p_lcb->upd_status & L2C_BLE_NEW_CONN_PARAM)
-        {
-            btsnd_hcic_ble_upd_ll_conn_params(p_lcb->handle, p_lcb->min_interval,
-                p_lcb->max_interval, p_lcb->latency, p_lcb->timeout, 0, 0);
-            p_lcb->upd_status &= ~L2C_BLE_NEW_CONN_PARAM;
-            p_lcb->upd_status |= (L2C_BLE_UPDATE_PENDING | L2C_BLE_NOT_DEFAULT_PARAM);
-        }
-    }
-}
-
-/*******************************************************************************
-**
 **  Function        L2CA_UpdateBleConnParams
 **
 **  Description     Update BLE connection parameters.
@@ -144,41 +96,54 @@ static void L2CA_InternalBleConnUpdate (tL2C_LCB *p_lcb)
 **  Return value:   TRUE if update started
 **
 *******************************************************************************/
-BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int, UINT16 latency, UINT16 timeout)
+BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_int,
+                                            UINT16 latency, UINT16 timeout)
 {
-    tL2C_LCB            *p_lcb;
-
-    /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+        tL2C_LCB            *p_lcb;
+        tACL_CONN           *p_acl_cb = btm_bda_to_acl(rem_bda, BT_TRANSPORT_LE);
 
-    /* If we don't have one, create one and accept the connection. */
-    if (!p_lcb)
-    {
-        L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
-                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
-        return(FALSE);
-    }
+        /* See if we have a link control block for the remote device */
+        p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
 
-    if (!p_lcb->is_ble_link)
-    {
-        L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
-                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
-        return(FALSE);
-    }
+        /* If we don't have one, create one and accept the connection. */
+        if (!p_lcb || !p_acl_cb)
+        {
+            L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - unknown BD_ADDR %08x%04x",
+                                  (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+                                  (rem_bda[4]<<8)+rem_bda[5]);
+            return(FALSE);
+        }
 
-    if (p_lcb->link_role == HCI_ROLE_MASTER)
-    {
-        p_lcb->min_interval = min_int;
-        p_lcb->max_interval = max_int;
-        p_lcb->latency = latency;
-        p_lcb->timeout = timeout;
-        p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
-        L2CA_InternalBleConnUpdate(p_lcb);
-    }
-    else
-        l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
+        if (p_lcb->transport != BT_TRANSPORT_LE)
+        {
+            L2CAP_TRACE_WARNING2 ("L2CA_UpdateBleConnParams - BD_ADDR %08x%04x not LE",
+                                  (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+                                  (rem_bda[4]<<8)+rem_bda[5]);
+            return(FALSE);
+        }
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+        /* if both 4.1 compliant */
+        if ((HCI_LE_CONN_PARAM_REQ_SUPPORTED(btm_cb.devcb.local_le_features) &&
+         HCI_LE_CONN_PARAM_REQ_SUPPORTED(p_acl_cb->peer_le_features)))
+        {
+            /* TODO: CE length selection ?? */
+            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
+            latency, timeout, 0, 0);
+        }
+        else
+        /* if either side does not support Connection Parameters Request
+        Link Layer Control Procedure,
+           use Link Layer Connection Update procedure */
+#endif
+        {
+            if (p_lcb->link_role == HCI_ROLE_MASTER)
+                btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_int, max_int,
+                latency, timeout, 0, 0);
+            else
+                l2cu_send_peer_ble_par_req (p_lcb, min_int, max_int, latency, timeout);
+        }
+        return(TRUE);
 
-    return(TRUE);
 }
 
 
@@ -198,77 +163,69 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
     tL2C_LCB            *p_lcb;
 
     /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE);
 
-    /* If we don't have one, create one and accept the connection. */
     if (!p_lcb)
     {
         L2CAP_TRACE_WARNING2 ("L2CA_EnableUpdateBleConnParams - unknown BD_ADDR %08x%04x",
-            (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5]);
+            (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+            (rem_bda[4]<<8)+rem_bda[5]);
         return (FALSE);
     }
 
-    L2CAP_TRACE_API4 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x enable %d upd state %d",
-        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5],
-        enable, p_lcb->upd_status);
+    L2CAP_TRACE_API5 ("%s - BD_ADDR %08x%04x enable %d current upd state 0x%02x",__FUNCTION__,
+        (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+        (rem_bda[4]<<8)+rem_bda[5], enable, p_lcb->conn_update_mask);
 
-    if (!p_lcb->is_ble_link || (p_lcb->link_role != HCI_ROLE_MASTER))
+    if (p_lcb->transport != BT_TRANSPORT_LE || (p_lcb->link_role != HCI_ROLE_MASTER))
     {
-        L2CAP_TRACE_WARNING3 ("L2CA_EnableUpdateBleConnParams - BD_ADDR %08x%04x not LE or not master %d",
-                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3], (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
+        L2CAP_TRACE_WARNING4 ("%s - BD_ADDR %08x%04x not LE or not master %d", __FUNCTION__,
+                              (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
+                              (rem_bda[4]<<8)+rem_bda[5], p_lcb->link_role);
         return (FALSE);
     }
 
     if (enable)
     {
-        p_lcb->upd_status &= ~L2C_BLE_CONN_UPDATE_DISABLE;
+        if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) == UPD_DISABLED)
+        {
+            p_lcb->conn_param_enb.param = (TIMER_PARAM_TYPE)p_lcb;
+            btu_start_timer (&p_lcb->conn_param_enb, BTU_TTYPE_L2CAP_END_CONN_UPD,
+                                                    L2CAP_BLE_ENB_CONN_PARAM_TOUT);
+            L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENB_TOUT);
+        }
     }
-    else
+    else if (L2CA_GET_UPD_ST (p_lcb->conn_update_mask) != UPD_DISABLED)
     {
-        p_lcb->upd_status |= L2C_BLE_CONN_UPDATE_DISABLE;
-    }
-
-    L2CA_InternalBleConnUpdate(p_lcb);
-
-    return (TRUE);
-}
-
-/*******************************************************************************
-**
-** Function         L2CA_HandleConnUpdateEvent
-**
-** Description      This function enables the connection update request from remote
-**                  after a successful connection update response is received.
-**
-** Returns          void
-**
-*******************************************************************************/
-void L2CA_HandleConnUpdateEvent (UINT16 handle, UINT8 status)
-{
-    tL2C_LCB *p_lcb;
-
-    L2CAP_TRACE_DEBUG0("L2CA_HandleConnUpdateEvent");
+        btu_stop_timer(&p_lcb->conn_param_enb);
 
-    /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_handle(handle);
-    if (!p_lcb)
-    {
-        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Invalid handle: %d", handle);
-        return;
-    }
+        if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+        {
 
-    p_lcb->upd_status &= ~L2C_BLE_UPDATE_PENDING;
+            /*
+            application requests to disable parameters update.If parameters are already updated,
+            lets set them   up to what has been requested during connection establishement
+            */
+            if ((p_lcb->conn_update_mask & UPD_REQUEST) != 0)
+            {
+                /* revert back to default */
+                btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
+                                                   BTM_BLE_CONN_INT_MIN_DEF,
+                                                   BTM_BLE_CONN_INT_MAX_DEF,
+                                                   BTM_BLE_CONN_SLAVE_LATENCY_DEF,
+                                                   BTM_BLE_CONN_TIMEOUT_DEF,
+                                                   0, 0);
+            }
+        }
+        L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_DISABLED);
 
-    if (status != HCI_SUCCESS)
-    {
-        L2CAP_TRACE_WARNING1("L2CA_EnableUpdateBleConnParams: Error status: %d", status);
     }
 
-    L2CA_InternalBleConnUpdate(p_lcb);
+    return (TRUE);
 
-    L2CAP_TRACE_DEBUG1("L2CA_HandleConnUpdateEvent: upd_status=%d", p_lcb->upd_status);
 }
 
+
 /*******************************************************************************
 **
 ** Function         L2CA_GetBleConnRole
@@ -284,7 +241,7 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
 
     tL2C_LCB *p_lcb;
 
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr)) != NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_LE)) != NULL)
         role = p_lcb->link_role;
 
     return role;
@@ -298,12 +255,12 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr)
 ** Returns          disconnect reason
 **
 *******************************************************************************/
-UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda)
+UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
 {
     tL2C_LCB            *p_lcb;
     UINT16              reason = 0;
 
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda)) != NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (remote_bda, transport)) != NULL)
         reason = p_lcb->disc_reason;
 
     L2CAP_TRACE_DEBUG1 ("L2CA_GetDisconnectReason=%d ",reason);
@@ -333,12 +290,12 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
     l2cb.is_ble_connecting = FALSE;
 
     /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
 
     /* If we don't have one, create one. this is auto connection complete. */
     if (!p_lcb)
     {
-        p_lcb = l2cu_allocate_lcb (bda, FALSE);
+        p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
         if (!p_lcb)
         {
             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
@@ -368,7 +325,7 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
     /* Connected OK. Change state to connected, we were scanning so we are master */
     p_lcb->link_state = LST_CONNECTED;
     p_lcb->link_role  = HCI_ROLE_MASTER;
-    p_lcb->is_ble_link = TRUE;
+    p_lcb->transport  = BT_TRANSPORT_LE;
 
     /* If there are any preferred connection parameters, set them now */
     if ( (p_dev_rec->conn_params.min_conn_int     >= BTM_BLE_CONN_INT_MIN ) &&
@@ -394,21 +351,16 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
                                            p_dev_rec->conn_params.slave_latency,
                                            p_dev_rec->conn_params.supervision_tout,
                                            0, 0);
-        p_lcb->upd_status |= L2C_BLE_UPDATE_PENDING;
     }
 
     /* Tell BTM Acl management about the link */
-    btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
-
-    if (p_lcb->p_echo_rsp_cb)
-    {
-        L2CAP_TRACE_ERROR0 ("l2cu_send_peer_echo_req");
-        l2cu_send_peer_echo_req (p_lcb, NULL, 0);
-    }
+    btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
 
     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
 
     l2cu_process_fixed_chnl_resp (p_lcb);
+
+    btm_ble_set_conn_st(BLE_CONN_IDLE);
 }
 
 
@@ -433,12 +385,12 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
     UNUSED(conn_timeout);
 
     /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
 
     /* If we don't have one, create one and accept the connection. */
     if (!p_lcb)
     {
-        p_lcb = l2cu_allocate_lcb (bda, FALSE);
+        p_lcb = l2cu_allocate_lcb (bda, FALSE, BT_TRANSPORT_LE);
         if (!p_lcb)
         {
             btm_sec_disconnect (handle, HCI_ERR_NO_CONNECTION);
@@ -462,16 +414,22 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
     /* Connected OK. Change state to connected, we were advertising, so we are slave */
     p_lcb->link_state = LST_CONNECTED;
     p_lcb->link_role  = HCI_ROLE_SLAVE;
-    p_lcb->is_ble_link = TRUE;
+    p_lcb->transport  = BT_TRANSPORT_LE;
 
     /* Tell BTM Acl management about the link */
     p_dev_rec = btm_find_or_alloc_dev (bda);
 
-    btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, TRUE);
+    btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
 
     p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
 
     l2cu_process_fixed_chnl_resp (p_lcb);
+
+    /* when adv and initiating are both active, cancel the direct connection */
+    if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
+    {
+        L2CA_CancelBleConnectReq(bda);
+    }
 }
 
 /*******************************************************************************
@@ -561,12 +519,22 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
 
                     l2cu_send_peer_ble_par_rsp (p_lcb, L2CAP_CFG_OK, id);
 
-                    p_lcb->min_interval = min_interval;
-                    p_lcb->max_interval = max_interval;
-                    p_lcb->latency = latency;
-                    p_lcb->timeout = timeout;
-                    p_lcb->upd_status |= L2C_BLE_NEW_CONN_PARAM;
-                    L2CA_InternalBleConnUpdate(p_lcb);
+                     p_lcb->min_interval = min_interval;
+                     p_lcb->max_interval = max_interval;
+                     p_lcb->latency = latency;
+                     p_lcb->timeout = timeout;
+                     p_lcb->conn_update_mask |= UPD_REQUEST;
+
+                     if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+                     {
+                         btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, min_interval, max_interval,
+                                                             latency, timeout, 0, 0);
+                     }
+                     else
+                     {
+                         L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
+                     }
+
                 }
             }
             else
@@ -583,8 +551,47 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             return;
     }
 }
+/*******************************************************************************
+**
+** Function         l2c_enable_conn_param_timeout
+**
+** Description      This function process the connection parameter enabling timeout
+**
+** Returns          None.
+**
+*******************************************************************************/
+void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb)
+{
+    tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
 
 
+    /* application allows to do update, if we were delaying one do it now, otherwise
+    just mark lcb that updates are enabled */
+    if (p_lcb->conn_update_mask & UPD_REQUEST)
+    {
+        btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle, p_lcb->min_interval, p_lcb->max_interval,
+                                           p_lcb->latency, p_lcb->timeout, 0, 0);
+    }
+    else
+    {
+        /* if preferred number has been set, set to preferred conn parameter */
+        if (p_dev_rec && p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF)
+        {
+            btsnd_hcic_ble_upd_ll_conn_params (p_lcb->handle,
+                (UINT16)((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF),
+                (UINT16)((p_dev_rec->conn_params.max_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
+                p_dev_rec->conn_params.max_conn_int : BTM_BLE_CONN_INT_MAX_DEF),
+                (UINT16)((p_dev_rec->conn_params.slave_latency != BTM_BLE_CONN_PARAM_UNDEF) ?
+                p_dev_rec->conn_params.slave_latency : BTM_BLE_CONN_SLAVE_LATENCY_DEF),
+                (UINT16) ((p_dev_rec->conn_params.supervision_tout != BTM_BLE_CONN_PARAM_UNDEF) ?
+                p_dev_rec->conn_params.supervision_tout : BTM_BLE_CONN_TIMEOUT_DEF),
+                0, 0);
+        }
+    }
+    L2CA_SET_UPD_ST( p_lcb->conn_update_mask, UPD_ENABLED);
+
+}
 /*******************************************************************************
 **
 ** Function         l2cble_init_direct_conn
@@ -606,7 +613,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
     /* There can be only one BLE connection request outstanding at a time */
     if (p_dev_rec == NULL)
     {
-        BTM_TRACE_WARNING0 ("unknown device, can not initate connection");
+        L2CAP_TRACE_WARNING0 ("unknown device, can not initate connection");
         return(FALSE);
     }
 
@@ -616,14 +623,23 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
     init_addr_type = p_lcb->ble_addr_type;
     memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
 
-#if BTM_BLE_PRIVACY_SPT == TRUE
+#if BLE_PRIVACY_SPT == TRUE
     if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
     {
         init_addr_type = BLE_ADDR_RANDOM;
         memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
     }
+    /* if privacy is on and current do not consider using reconnection address */
+    if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
+        own_addr_type = BLE_ADDR_RANDOM;
 #endif
 
+    if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
+    {
+        l2cu_release_lcb (p_lcb);
+        L2CAP_TRACE_ERROR0("initate direct connection fail, topology limitation");
+        return FALSE;
+    }
     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
                                         scan_win, /* UINT16 scan_win      */
                                         FALSE,                   /* UINT8 white_list     */
@@ -712,4 +728,47 @@ void l2c_link_processs_ble_num_bufs (UINT16 num_lm_ble_bufs)
     l2cb.num_lm_ble_bufs = l2cb.controller_le_xmit_window = num_lm_ble_bufs;
 }
 
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+/*******************************************************************************
+**
+** Function         l2cble_process_rc_param_request_evt
+**
+** Description      process LE Remote Connection Parameter Request Event.
+**
+** Returns          void
+**
+*******************************************************************************/
+void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
+                                     UINT16 latency, UINT16 timeout)
+{
+    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_handle (handle);
+
+    if (p_lcb != NULL)
+    {
+        p_lcb->min_interval = int_min;
+        p_lcb->max_interval = int_max;
+        p_lcb->latency = latency;
+        p_lcb->timeout = timeout;
+        p_lcb->conn_update_mask |= UPD_REQUEST;
+
+        /* TODO: revisit: if update is enabled, always accept connection parameter update */
+        if (L2CA_GET_UPD_ST(p_lcb->conn_update_mask) == UPD_ENABLED)
+        {
+            btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, 0, 0);
+        }
+        else
+        {
+            L2CAP_TRACE_EVENT0 ("L2CAP - LE - update currently disabled");
+            btsnd_hcic_ble_rc_param_req_neg_reply (handle,HCI_ERR_UNACCEPT_CONN_INTERVAL);
+        }
+
+    }
+    else
+    {
+        L2CAP_TRACE_WARNING0("No link to update connection parameter")
+    }
+}
+#endif
+
+
 #endif /* (BLE_INCLUDED == TRUE) */
index 9685f77..f2e72ad 100644 (file)
@@ -2246,7 +2246,7 @@ UINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
                 p_ccb->out_cfg_fcr_present = TRUE;
             }
 
-            if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE)
+            if (p_cfg->fcr.mode == L2CAP_FCR_ERTM_MODE || p_cfg->fcr.mode == L2CAP_FCR_STREAM_MODE)
             {
                 /* Always respond with FCR ERTM parameters */
                 p_ccb->out_cfg_fcr_present = TRUE;
index 72d5544..272d318 100644 (file)
@@ -52,6 +52,8 @@
 #define L2CAP_WAIT_UNPARK_TOUT       2            /* 2 seconds */
 #define L2CAP_LINK_INFO_RESP_TOUT    2            /* 2  seconds */
 #define L2CAP_BLE_LINK_CONNECT_TOUT  30           /* 30 seconds */
+#define L2CAP_BLE_CONN_PARAM_UPD_TOUT   30           /* 30 seconds */
+#define L2CAP_BLE_ENB_CONN_PARAM_TOUT   1           /* 1 seconds */
 
 /* quick timer uses millisecond unit */
 #define L2CAP_DEFAULT_RETRANS_TOUT   2000         /* 2000 milliseconds */
@@ -393,6 +395,7 @@ typedef struct t_l2c_linkcb
 
     UINT8               link_role;                  /* Master or slave                  */
     UINT8               id;
+    UINT8               cur_echo_id;                /* Current id value for echo request */
     tL2CA_ECHO_RSP_CB   *p_echo_rsp_cb;             /* Echo response callback           */
     UINT16              idle_timeout;               /* Idle timeout                     */
     BOOLEAN             is_bonding;                 /* True - link active only for bonding */
@@ -431,16 +434,17 @@ typedef struct t_l2c_linkcb
     UINT16              disc_reason;
 #endif
 
+    tBT_TRANSPORT       transport;
 #if (BLE_INCLUDED == TRUE)
-    BOOLEAN             is_ble_link;
     tBLE_ADDR_TYPE      ble_addr_type;
-
-#define L2C_BLE_CONN_UPDATE_DISABLE 0x1  /* disable update connection parameters */
-#define L2C_BLE_NEW_CONN_PARAM      0x2  /* new connection parameter to be set */
-#define L2C_BLE_UPDATE_PENDING      0x4  /* waiting for connection update finished */
-#define L2C_BLE_NOT_DEFAULT_PARAM   0x8  /* not using default connection parameters */
-    UINT8               upd_status;
-
+    TIMER_LIST_ENT      conn_param_enb;         /* Timer entry for enabling connection parameter update */
+
+#define UPD_ENABLED     0  /* If peer requests update, we will change params */
+#define UPD_DISABLED    1  /* application requested not to update */
+#define UPD_ENB_TOUT    2  /* while updates are disabled, peer requested new parameters */
+#define UPD_ST_MASK     0x0f
+#define UPD_REQUEST     0x10  /* remote device set preferred conn param */
+    UINT8               conn_update_mask;
     UINT16              min_interval; /* parameters as requested by peripheral */
     UINT16              max_interval;
     UINT16              latency;
@@ -578,14 +582,14 @@ extern void     l2c_process_held_packets (BOOLEAN timed_out);
 /* Functions provided by l2c_utils.c
 ************************************
 */
-extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
+extern tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport);
 extern BOOLEAN  l2cu_start_post_bond_timer (UINT16 handle);
 extern void     l2cu_release_lcb (tL2C_LCB *p_lcb);
-extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr);
+extern tL2C_LCB *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport);
 extern tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle);
 extern void     l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding);
 
-extern UINT8    l2cu_get_conn_role (BD_ADDR bd_addr);
+extern UINT8    l2cu_get_conn_role (tL2C_LCB *p_this_lcb);
 extern BOOLEAN  l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_after_rs);
 
 extern void     l2cu_enqueue_ccb (tL2C_CCB *p_ccb);
@@ -597,6 +601,7 @@ extern void     l2cu_release_ccb (tL2C_CCB *p_ccb);
 extern tL2C_CCB *l2cu_find_ccb_by_cid (tL2C_LCB *p_lcb, UINT16 local_cid);
 extern tL2C_CCB *l2cu_find_ccb_by_remote_cid (tL2C_LCB *p_lcb, UINT16 remote_cid);
 extern void     l2cu_adj_id (tL2C_LCB *p_lcb, UINT8 adj_mask);
+extern BOOLEAN  l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb);
 
 extern void     l2cu_send_peer_cmd_reject (tL2C_LCB *p_lcb, UINT16 reason,
                                            UINT8 rem_id,UINT16 p1, UINT16 p2);
@@ -676,7 +681,7 @@ extern void     l2cu_device_reset (void);
 extern tL2C_LCB *l2cu_find_lcb_by_state (tL2C_LINK_STATE state);
 extern BOOLEAN  l2cu_lcb_disconnecting (void);
 
-extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb);
+extern BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport);
 extern BOOLEAN l2cu_create_conn_after_switch (tL2C_LCB *p_lcb);
 extern BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb);
 extern void    l2cu_resubmit_pending_sec_req (BD_ADDR p_bda);
@@ -699,7 +704,7 @@ extern void     l2c_link_process_num_completed_blocks (UINT8 controller_id, UINT
 extern void     l2c_link_processs_num_bufs (UINT16 num_lm_acl_bufs);
 extern UINT8    l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles);
 extern void     l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status);
-extern void     l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status);
+extern void     l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT trasnport, void *p_ref_data, UINT8 status);
 extern void     l2c_link_segments_xmitted (BT_HDR *p_msg);
 extern void     l2c_pin_code_request (BD_ADDR bd_addr);
 extern void     l2c_link_adjust_chnl_allocation (void);
@@ -762,8 +767,13 @@ extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len);
 extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
                               UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout);
 extern BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb);
-
+extern void l2c_enable_conn_param_timeout(tL2C_LCB * p_lcb);
+#if (defined BLE_LLT_INCLUDED) && (BLE_LLT_INCLUDED == TRUE)
+extern void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 int_max,
+                                                        UINT16 latency, UINT16 timeout);
+#endif
 #endif
+extern void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb);
 
 #ifdef __cplusplus
 }
index fd38ca2..f5e8294 100644 (file)
@@ -65,12 +65,12 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr)
     BOOLEAN         no_links;
 
     /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+    p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
 
     /* If we don't have one, create one and accept the connection. */
     if (!p_lcb)
     {
-        p_lcb = l2cu_allocate_lcb (bd_addr, FALSE);
+        p_lcb = l2cu_allocate_lcb (bd_addr, FALSE, BT_TRANSPORT_BR_EDR);
         if (!p_lcb)
         {
             btsnd_hcic_reject_conn (bd_addr, HCI_ERR_HOST_REJECT_RESOURCES);
@@ -99,7 +99,7 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr)
             if (!btm_dev_support_switch (bd_addr))
                 p_lcb->link_role = HCI_ROLE_SLAVE;
             else
-                p_lcb->link_role = l2cu_get_conn_role(bd_addr);
+                p_lcb->link_role = l2cu_get_conn_role(p_lcb);
         }
 
         /* Tell the other side we accept the connection */
@@ -120,7 +120,7 @@ BOOLEAN l2c_link_hci_conn_req (BD_ADDR bd_addr)
         if (!btm_dev_support_switch (bd_addr))
             p_lcb->link_role = HCI_ROLE_SLAVE;
         else
-            p_lcb->link_role = l2cu_get_conn_role(bd_addr);
+            p_lcb->link_role = l2cu_get_conn_role(p_lcb);
 
         btsnd_hcic_accept_conn (bd_addr, p_lcb->link_role);
 
@@ -168,7 +168,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
     memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN);
 
     /* See if we have a link control block for the remote device */
-    p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr);
+    p_lcb = l2cu_find_lcb_by_bd_addr (ci.bd_addr, BT_TRANSPORT_BR_EDR);
 
     /* If we don't have one, this is an error */
     if (!p_lcb)
@@ -202,9 +202,9 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
         if ((p_dev_info = btm_find_dev (p_bda)) != NULL)
             btm_acl_created (ci.bd_addr, p_dev_info->dev_class,
                              p_dev_info->sec_bd_name, handle,
-                             p_lcb->link_role, FALSE);
+                             p_lcb->link_role, BT_TRANSPORT_BR_EDR);
         else
-            btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, FALSE);
+            btm_acl_created (ci.bd_addr, NULL, NULL, handle, p_lcb->link_role, BT_TRANSPORT_BR_EDR);
 
         BTM_SetLinkSuperTout (ci.bd_addr, btm_cb.btm_def_link_super_tout);
 
@@ -272,7 +272,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
             }
             else
             {
-                l2cu_create_conn(p_lcb);
+                l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
             }
         }
     }
@@ -290,7 +290,7 @@ BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda)
 ** Returns          void
 **
 *******************************************************************************/
-void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status)
+void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data, UINT8 status)
 {
     tL2C_CONN_INFO  ci;
     tL2C_LCB        *p_lcb;
@@ -298,6 +298,8 @@ void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status)
     tL2C_CCB        *p_next_ccb;
     UINT8           event;
 
+    UNUSED(transport);
+
     L2CAP_TRACE_DEBUG2 ("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data);
 
     if (status == BTM_SUCCESS_NO_SECURITY)
@@ -307,7 +309,7 @@ void l2c_link_sec_comp (BD_ADDR p_bda, void *p_ref_data, UINT8 status)
     ci.status       = status;
     memcpy (ci.bd_addr, p_bda, BD_ADDR_LEN);
 
-    p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+    p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
 
     /* If we don't have one, this is an error */
     if (!p_lcb)
@@ -361,6 +363,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
     tL2C_CCB    *p_ccb;
     BOOLEAN     status = TRUE;
     BOOLEAN     lcb_is_free = TRUE;
+    tBT_TRANSPORT   transport = BT_TRANSPORT_BR_EDR;
 
     /* See if we have a link control block for the connection */
     p_lcb = l2cu_find_lcb_by_handle (handle);
@@ -401,35 +404,53 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
             p_ccb = pn;
         }
 
-#if BTM_SCO_INCLUDED == TRUE
-        /* Tell SCO management to drop any SCOs on this ACL */
-        btm_sco_acl_removed (p_lcb->remote_bd_addr);
+#if (BTM_SCO_INCLUDED == TRUE)
+#if (BLE_INCLUDED == TRUE)
+        if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+#endif
+            /* Tell SCO management to drop any SCOs on this ACL */
+            btm_sco_acl_removed (p_lcb->remote_bd_addr);
 #endif
 
         /* If waiting for disconnect and reconnect is pending start the reconnect now
            race condition where layer above issued connect request on link that was
            disconnecting
          */
-        if (p_lcb->ccb_queue.p_first_ccb != NULL)
+        if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb)
         {
 #if (L2CAP_NUM_FIXED_CHNLS > 0)
             /* If we are going to re-use the LCB without dropping it, release all fixed channels here */
             int         xx;
-
             for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
             {
-                if (p_lcb->p_fixed_ccbs[xx])
+                if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
                 {
-                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+#if BLE_INCLUDED == TRUE
+                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+                                                             p_lcb->disc_reason, p_lcb->transport);
+#else
+                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
+                                                          p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
                     l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
 
                     p_lcb->p_fixed_ccbs[xx] = NULL;
                 }
+#if BLE_INCLUDED == TRUE
+                else if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] ==
+                                    p_lcb->p_pending_ccb)
+                {
+                    if (p_lcb->p_fixed_ccbs[xx]->local_cid >= L2CAP_ATT_CID &&
+                        p_lcb->p_fixed_ccbs[xx]->local_cid <= L2CAP_SMP_CID)
+                        transport = BT_TRANSPORT_LE;
+                }
+#endif
+
             }
 #endif
             L2CAP_TRACE_DEBUG0("l2c_link_hci_disc_comp: Restarting pending ACL request");
 
-            if (l2cu_create_conn(p_lcb))
+            if (l2cu_create_conn(p_lcb, transport))
                 lcb_is_free = FALSE; /* still using this lcb */
         }
 
@@ -444,7 +465,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
     if (lcb_is_free && ((p_lcb = l2cu_find_lcb_by_state(LST_CONNECT_HOLDING)) != NULL))
     {
         /* we found one-- create a connection */
-        l2cu_create_conn(p_lcb);
+        l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR);
     }
 
     return status;
@@ -576,6 +597,7 @@ void l2c_link_timeout (tL2C_LCB *p_lcb)
             }
             else if (rc == BTM_SUCCESS)
             {
+                l2cu_process_fixed_disc_cback(p_lcb);
                 /* BTM SEC will make sure that link is release (probably after pairing is done) */
                 p_lcb->link_state = LST_DISCONNECTING;
                 timeout = 0xFFFF;
@@ -588,6 +610,7 @@ void l2c_link_timeout (tL2C_LCB *p_lcb)
             else if ((p_lcb->is_bonding)
                   && (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)))
             {
+                l2cu_process_fixed_disc_cback(p_lcb);
                 p_lcb->link_state = LST_DISCONNECTING;
                 timeout = L2CAP_LINK_DISCONNECT_TOUT;
             }
@@ -977,7 +1000,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status)
     if (bd_addr)
     {
         /* If here came form hci role change event */
-        p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+        p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
         if (p_lcb)
         {
             p_lcb->link_role = new_role;
@@ -1013,7 +1036,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status)
 *******************************************************************************/
 void l2c_pin_code_request (BD_ADDR bd_addr)
 {
-    tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr);
+    tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bd_addr, BT_TRANSPORT_BR_EDR);
 
     if ( (p_lcb) && (!p_lcb->ccb_queue.p_first_ccb) )
     {
@@ -1129,11 +1152,11 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
             /* If controller window is full, nothing to do */
             if ( (l2cb.controller_xmit_window == 0
 #if (BLE_INCLUDED == TRUE)
-                  && !p_lcb->is_ble_link
+                  && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
 #endif
                 )
 #if (BLE_INCLUDED == TRUE)
-                || (p_lcb->is_ble_link && l2cb.controller_le_xmit_window == 0 )
+                || (p_lcb->transport == BT_TRANSPORT_LE && l2cb.controller_le_xmit_window == 0 )
 #endif
               || (l2cb.round_robin_unacked >= l2cb.round_robin_quota) )
                 break;
@@ -1168,8 +1191,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
 
         /* If we finished without using up our quota, no need for a safety check */
 #if (BLE_INCLUDED == TRUE)
-        if ( ((l2cb.controller_xmit_window > 0 && !p_lcb->is_ble_link) ||
-             (l2cb.controller_le_xmit_window > 0 && p_lcb->is_ble_link))
+        if ( ((l2cb.controller_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+             (l2cb.controller_le_xmit_window > 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
           && (l2cb.round_robin_unacked < l2cb.round_robin_quota) )
 #else
         if ( (l2cb.controller_xmit_window > 0)
@@ -1188,8 +1211,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
 
         /* See if we can send anything from the link queue */
 #if (BLE_INCLUDED == TRUE)
-        while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) ||
-                 (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link))
+        while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+                 (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
              && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
 #else
         while ( (l2cb.controller_xmit_window != 0)
@@ -1207,8 +1230,8 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
         {
             /* See if we can send anything for any channel */
 #if (BLE_INCLUDED == TRUE)
-            while ( ((l2cb.controller_xmit_window != 0 && !p_lcb->is_ble_link) ||
-                    (l2cb.controller_le_xmit_window != 0 && p_lcb->is_ble_link))
+            while ( ((l2cb.controller_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+                    (l2cb.controller_le_xmit_window != 0 && (p_lcb->transport == BT_TRANSPORT_LE)))
                     && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
 #else
             while ((l2cb.controller_xmit_window != 0) && (p_lcb->sent_not_acked < p_lcb->link_xmit_quota))
@@ -1245,12 +1268,14 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
     UINT16      num_segs;
     UINT16      xmit_window, acl_data_size;
 
+    if ((p_buf->len <= btu_cb.hcit_acl_pkt_size
 #if (BLE_INCLUDED == TRUE)
-    if ((!p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_acl_pkt_size)) ||
-        (p_lcb->is_ble_link && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size)))
+        && (p_lcb->transport == BT_TRANSPORT_BR_EDR)) ||
+        ((p_lcb->transport == BT_TRANSPORT_LE) && (p_buf->len <= btu_cb.hcit_ble_acl_pkt_size))
 #else
-    if (p_buf->len <= btu_cb.hcit_acl_pkt_size)
+        )
 #endif
+        )
     {
         if (p_lcb->link_xmit_quota == 0)
             l2cb.round_robin_unacked++;
@@ -1259,7 +1284,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
         p_buf->layer_specific = 0;
 
 #if (BLE_INCLUDED == TRUE)
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             l2cb.controller_le_xmit_window--;
             L2C_LINK_SEND_BLE_ACL_DATA (p_buf);
@@ -1274,7 +1299,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
     else
     {
 #if BLE_INCLUDED == TRUE
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             acl_data_size = btu_cb.hcit_ble_acl_data_size;
             xmit_window = l2cb.controller_le_xmit_window;
@@ -1313,7 +1338,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
 
         p_buf->layer_specific        = num_segs;
 #if BLE_INCLUDED == TRUE
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             l2cb.controller_le_xmit_window -= num_segs;
 
@@ -1327,7 +1352,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
 
         p_lcb->sent_not_acked += num_segs;
 #if BLE_INCLUDED == TRUE
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             L2C_LINK_SEND_BLE_ACL_DATA(p_buf);
         }
@@ -1340,7 +1365,7 @@ static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf)
 
 #if (L2CAP_HCI_FLOW_CONTROL_DEBUG == TRUE)
 #if (BLE_INCLUDED == TRUE)
-    if (p_lcb->is_ble_link)
+    if (p_lcb->transport == BT_TRANSPORT_LE)
     {
         L2CAP_TRACE_DEBUG6 ("TotalWin=%d,Hndl=0x%x,Quota=%d,Unack=%d,RRQuota=%d,RRUnack=%d",
                 l2cb.controller_le_xmit_window,
@@ -1400,11 +1425,9 @@ void l2c_link_process_num_completed_pkts (UINT8 *p)
         if (p_lcb)
         {
 #if (BLE_INCLUDED == TRUE)
-            if (p_lcb->is_ble_link)
-            {
-                l2cb.controller_le_xmit_window += num_sent;
-            }
-            else
+        if (p_lcb && (p_lcb->transport == BT_TRANSPORT_LE))
+            l2cb.controller_le_xmit_window += num_sent;
+        else
 #endif
             {
                 /* Maintain the total window to the controller */
@@ -1441,7 +1464,7 @@ void l2c_link_process_num_completed_pkts (UINT8 *p)
         if (p_lcb)
         {
 #if (BLE_INCLUDED == TRUE)
-            if (p_lcb->is_ble_link)
+            if (p_lcb->transport == BT_TRANSPORT_LE)
             {
                 L2CAP_TRACE_DEBUG5 ("TotalWin=%d,LinkUnack(0x%x)=%d,RRCheck=%d,RRUnack=%d",
                     l2cb.controller_le_xmit_window,
index 49dd811..2795d8c 100644 (file)
@@ -320,17 +320,29 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
     tL2CAP_CFG_INFO cfg_info;
     UINT16          rej_reason, rej_mtu, lcid, rcid, info_type;
     tL2C_CCB        *p_ccb;
-    tL2C_RCB        *p_rcb;
-    BOOLEAN         cfg_rej;
+    tL2C_RCB        *p_rcb, *p_rcb2;
+    BOOLEAN         cfg_rej, pkt_size_rej = FALSE;
     UINT16          cfg_rej_len, cmd_len;
     UINT16          result;
     tL2C_CONN_INFO  ci;
 
 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
     /* if l2cap command received in CID 1 on top of an LE link, ignore this command */
-    if (p_lcb->is_ble_link)
+    if (p_lcb->transport == BT_TRANSPORT_LE)
         return;
 #endif
+
+    /* Reject the packet if it exceeds the default Signalling Channel MTU */
+    if (pkt_len > L2CAP_DEFAULT_MTU)
+    {
+        /* Core Spec requires a single response to the first command found in a multi-command
+        ** L2cap packet.  If only responses in the packet, then it will be ignored.
+        ** Here we simply mark the bad packet and decide which cmd ID to reject later
+        */
+        pkt_size_rej = TRUE;
+        L2CAP_TRACE_ERROR1 ("L2CAP SIG MTU Pkt Len Exceeded (672) -> pkt_len: %d", pkt_len);
+    }
+
     p_next_cmd = p;
     p_pkt_end  = p + pkt_len;
 
@@ -355,6 +367,18 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
             break;
         }
 
+        L2CAP_TRACE_DEBUG3 ("cmd_code: %d, id:%d, cmd_len:%d", cmd_code, id, cmd_len);
+
+        /* Bad L2CAP packet length, look or cmd to reject */
+        if (pkt_size_rej)
+        {
+            /* If command found rejected it and we're done, otherwise keep looking */
+            if (l2c_is_cmd_rejected(cmd_code, id, p_lcb))
+                return;
+            else
+                continue; /* Look for next cmd/response in current packet */
+        }
+
         switch (cmd_code)
         {
         case L2CAP_CMD_REJECT:
@@ -911,6 +935,11 @@ void l2c_process_timeout (TIMER_LIST_ENT *p_tle)
         l2c_info_timeout((tL2C_LCB *)p_tle->param);
         break;
 
+#if (BLE_INCLUDED == TRUE)
+    case BTU_TTYPE_L2CAP_END_CONN_UPD:
+        l2c_enable_conn_param_timeout((tL2C_LCB *)p_tle->param);
+        break;
+#endif
     }
 }
 
index 4dfc804..4f907ad 100644 (file)
@@ -343,7 +343,7 @@ BOOLEAN L2CA_UcdDiscover ( UINT16 psm, BD_ADDR rem_bda, UINT8 info_type )
 
     /* First, see if we already have a link to the remote */
     /* then find the channel control block for UCD. */
-    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
       ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
     {
         if ( l2c_ucd_connect (rem_bda) == FALSE )
@@ -411,7 +411,7 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla
 
     /* First, see if we already have a link to the remote */
     /*  then find the channel control block for UCD */
-    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
       ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
     {
         if ( l2c_ucd_connect (rem_bda) == FALSE )
@@ -421,7 +421,7 @@ UINT16 L2CA_UcdDataWrite (UINT16 psm, BD_ADDR rem_bda, BT_HDR *p_buf, UINT16 fla
         }
 
         /* If we still don't have lcb and ccb after connect attempt, then can't proceed */
-        if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+        if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
             || ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
         {
             GKI_freebuf (p_buf);
@@ -490,7 +490,7 @@ BOOLEAN L2CA_UcdSetIdleTimeout ( BD_ADDR rem_bda, UINT16 timeout )
 
     /* First, see if we already have a link to the remote */
     /* then find the channel control block. */
-    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if (((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
       ||((p_ccb = l2cu_find_ccb_by_cid (p_lcb, L2CAP_CONNECTIONLESS_CID)) == NULL))
     {
         L2CAP_TRACE_WARNING0 ("L2CAP - no UCD channel");
@@ -521,7 +521,7 @@ BOOLEAN L2CA_UCDSetTxPriority ( BD_ADDR rem_bda, tL2CAP_CHNL_PRIORITY priority )
                       (rem_bda[0]<<24)+(rem_bda[1]<<16)+(rem_bda[2]<<8)+rem_bda[3],
                       (rem_bda[4]<<8)+rem_bda[5]);
 
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_UCDSetTxPriority");
         return (FALSE);
@@ -569,11 +569,11 @@ static BOOLEAN l2c_ucd_connect ( BD_ADDR rem_bda )
     }
 
     /* First, see if we already have a link to the remote */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         /* No link. Get an LCB and start link establishment */
-        if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE)) == NULL)
-         ||  (l2cu_create_conn(p_lcb) == FALSE) )
+        if ( ((p_lcb = l2cu_allocate_lcb (rem_bda, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
+         ||  (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) )
         {
             L2CAP_TRACE_WARNING0 ("L2CAP - conn not started l2c_ucd_connect");
             return (FALSE);
index 05d5e5d..23b7584 100644 (file)
@@ -37,6 +37,7 @@
 #include "btm_int.h"
 #include "hcidefs.h"
 #include "bd.h"
+#include "bt_utils.h"
 
 /*******************************************************************************
 **
@@ -47,7 +48,7 @@
 ** Returns          LCB address or NULL if none found
 **
 *******************************************************************************/
-tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
+tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding, tBT_TRANSPORT transport)
 {
     int         xx;
     tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
@@ -69,7 +70,9 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
             p_lcb->idle_timeout    = l2cb.idle_timeout;
             p_lcb->id              = 1;                     /* spec does not allow '0' */
             p_lcb->is_bonding      = is_bonding;
-
+#if BLE_INCLUDED == TRUE
+            p_lcb->transport       = transport;
+#endif
             l2cb.num_links_active++;
 
             l2c_link_adjust_allocation();
@@ -93,7 +96,7 @@ tL2C_LCB *l2cu_allocate_lcb (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
 *******************************************************************************/
 void l2cu_update_lcb_4_bonding (BD_ADDR p_bd_addr, BOOLEAN is_bonding)
 {
-    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr);
+    tL2C_LCB    *p_lcb = l2cu_find_lcb_by_bd_addr (p_bd_addr, BT_TRANSPORT_BR_EDR);
 
     if (p_lcb)
     {
@@ -133,14 +136,17 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
     }
 
 #if BTM_SCO_INCLUDED == TRUE
-    /* Release all SCO links */
-    btm_remove_sco_links(p_lcb->remote_bd_addr);
+#if (BLE_INCLUDED == TRUE)
+        if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+#endif
+        /* Release all SCO links */
+        btm_remove_sco_links(p_lcb->remote_bd_addr);
 #endif
 
     if (p_lcb->sent_not_acked > 0)
     {
 #if (BLE_INCLUDED == TRUE)
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             l2cb.controller_le_xmit_window += p_lcb->sent_not_acked;
             if (l2cb.controller_le_xmit_window > l2cb.num_lm_ble_bufs)
@@ -160,7 +166,6 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
     }
 
 #if (BLE_INCLUDED == TRUE)
-    p_lcb->is_ble_link = FALSE;
     l2cb.is_ble_connecting = FALSE;
 #endif
 
@@ -174,11 +179,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
             {
                 l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
                 p_lcb->p_fixed_ccbs[xx] = NULL;
-                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
             }
             else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
                    && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
-                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+                    (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
         }
     }
 #endif
@@ -191,8 +196,11 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
 
     /* Tell BTM Acl management the link was removed */
     if ((p_lcb->link_state == LST_CONNECTED) || (p_lcb->link_state == LST_DISCONNECTING))
-        btm_acl_removed (p_lcb->remote_bd_addr);
-
+#if (BLE_INCLUDED == TRUE)
+        btm_acl_removed (p_lcb->remote_bd_addr, p_lcb->transport);
+#else
+        btm_acl_removed (p_lcb->remote_bd_addr, BT_TRANSPORT_BR_EDR);
+#endif
     /* Release any held buffers */
     while (p_lcb->link_xmit_data_q.p_first)
         GKI_freebuf (GKI_dequeue (&p_lcb->link_xmit_data_q));
@@ -231,14 +239,18 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
 ** Returns          pointer to matched LCB, or NULL if no match
 **
 *******************************************************************************/
-tL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
+tL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr, tBT_TRANSPORT transport)
 {
     int         xx;
     tL2C_LCB    *p_lcb = &l2cb.lcb_pool[0];
 
     for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
     {
-        if ((p_lcb->in_use) && (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
+        if ((p_lcb->in_use) &&
+#if BLE_INCLUDED == TRUE
+            p_lcb->transport == transport &&
+#endif
+            (!memcmp (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN)))
         {
             return (p_lcb);
         }
@@ -253,8 +265,6 @@ tL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
 ** Function         l2cu_get_conn_role
 **
 ** Description      Determine the desired role (master or slave) of a link.
-**                  If it is the previous connected remote device, use the same
-**                  role as previous used role.
 **                  If already got a slave link, this one must be a master. If
 **                  already got at least 1 link where we are the master, make this
 **                  also a master.
@@ -262,12 +272,12 @@ tL2C_LCB  *l2cu_find_lcb_by_bd_addr (BD_ADDR p_bd_addr)
 ** Returns          HCI_ROLE_MASTER or HCI_ROLE_SLAVE
 **
 *******************************************************************************/
-UINT8 l2cu_get_conn_role (BD_ADDR bd_addr)
+UINT8 l2cu_get_conn_role (tL2C_LCB *p_this_lcb)
 {
     UINT8 i;
     for (i = 0; i < BTM_ROLE_DEVICE_NUM; i++) {
         if ((btm_cb.previous_connected_role[i] != BTM_ROLE_UNDEFINED) &&
-            (!bdcmp(bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
+            (!bdcmp(p_this_lcb->remote_bd_addr, btm_cb.previous_connected_remote_addr[i]))) {
             L2CAP_TRACE_WARNING1 ("l2cu_get_conn_role %d",
                                   btm_cb.previous_connected_role[i]);
             return btm_cb.previous_connected_role[i];
@@ -278,6 +288,39 @@ UINT8 l2cu_get_conn_role (BD_ADDR bd_addr)
 
 /*******************************************************************************
 **
+** Function         l2c_is_cmd_rejected
+**
+** Description      Checks if cmd_code is command or response
+**                  If a command it will be rejected per spec.
+**                  This function is used when a illegal packet length is detected
+**
+** Returns          BOOLEAN - TRUE if cmd_code is a command and it is rejected,
+**                            FALSE if response code. (command not rejected)
+**
+*******************************************************************************/
+BOOLEAN l2c_is_cmd_rejected (UINT8 cmd_code, UINT8 id, tL2C_LCB *p_lcb)
+{
+    switch(cmd_code)
+    {
+    case L2CAP_CMD_CONN_REQ:
+    case L2CAP_CMD_CONFIG_REQ:
+    case L2CAP_CMD_DISC_REQ:
+    case L2CAP_CMD_ECHO_REQ:
+    case L2CAP_CMD_INFO_REQ:
+    case L2CAP_CMD_AMP_CONN_REQ:
+    case L2CAP_CMD_AMP_MOVE_REQ:
+    case L2CAP_CMD_BLE_UPDATE_REQ:
+        l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, L2CAP_DEFAULT_MTU, 0);
+        L2CAP_TRACE_WARNING1 ("Dumping first Command (%d)", cmd_code);
+        return TRUE;
+
+    default:    /* Otherwise a response */
+        return FALSE;
+    }
+}
+
+/*******************************************************************************
+**
 ** Function         l2cu_build_header
 **
 ** Description      Builds the L2CAP command packet header
@@ -311,7 +354,7 @@ BT_HDR *l2cu_build_header (tL2C_LCB *p_lcb, UINT16 len, UINT8 cmd, UINT8 id)
     UINT16_TO_STREAM (p, len + L2CAP_CMD_OVERHEAD);
 
 #if (BLE_INCLUDED == TRUE)
-    if (p_lcb->is_ble_link)
+    if (p_lcb->transport == BT_TRANSPORT_LE)
     {
         UINT16_TO_STREAM (p, L2CAP_BLE_SIGNALLING_CID);
     }
@@ -717,11 +760,24 @@ void l2cu_send_peer_config_rsp (tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg)
 *******************************************************************************/
 void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len, UINT16 rej_len)
 {
-    BT_HDR  *p_buf = (BT_HDR *)GKI_getpoolbuf (L2CAP_CMD_POOL_ID);
-    UINT16  len, cfg_len;
+    BT_HDR  *p_buf;
+    UINT16  len, cfg_len, buf_space, len1;
     UINT8   *p, *p_hci_len, *p_data_end;
     UINT8   cfg_code;
 
+    L2CAP_TRACE_DEBUG2("l2cu_send_peer_config_rej: data_len=%d, rej_len=%d", data_len, rej_len);
+
+
+    len = BT_HDR_SIZE + HCI_DATA_PREAMBLE_SIZE + L2CAP_PKT_OVERHEAD + L2CAP_CMD_OVERHEAD + L2CAP_CONFIG_RSP_LEN;
+    len1 = 0xFFFF - len;
+    if (rej_len > len1)
+    {
+        L2CAP_TRACE_ERROR0 ("L2CAP - cfg_rej pkt size exceeds buffer design max limit.");
+        return;
+    }
+
+    p_buf = (BT_HDR *)GKI_getbuf (len + rej_len);
+
     if (!p_buf)
     {
         L2CAP_TRACE_ERROR0 ("L2CAP - no buffer for cfg_rej");
@@ -761,6 +817,8 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len,
     UINT16_TO_STREAM (p, 0);                    /* Flags = 0 (no continuation) */
     UINT16_TO_STREAM (p, L2CAP_CFG_UNKNOWN_OPTIONS);
 
+    buf_space = rej_len;
+
     /* Now, put the rejected options */
     p_data_end = p_data + data_len;
     while (p_data < p_data_end)
@@ -784,8 +842,18 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len,
                 {
                     if ((cfg_code & 0x80) == 0)
                     {
-                        memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
-                        p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
+                        if (buf_space >= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD))
+                        {
+                            memcpy(p, p_data, cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
+                            p += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
+                            buf_space -= (cfg_len + L2CAP_CFG_OPTION_OVERHEAD);
+                        }
+                        else
+                        {
+                            L2CAP_TRACE_WARNING0("L2CAP - cfg_rej exceeds allocated buffer");
+                            p_data = p_data_end; /* force loop exit */
+                            break;
+                        }
                     }
                     p_data += cfg_len + L2CAP_CFG_OPTION_OVERHEAD;
                 }
@@ -803,6 +871,9 @@ void l2cu_send_peer_config_rej (tL2C_CCB *p_ccb, UINT8 *p_data, UINT16 data_len,
 
     p_buf->len = len + 4;
 
+    L2CAP_TRACE_DEBUG2 ("L2CAP - cfg_rej pkt hci_len=%d, l2cap_len=%d",
+                        len, (L2CAP_CMD_OVERHEAD+L2CAP_CONFIG_RSP_LEN+rej_len));
+
     l2c_link_check_send_pkts (p_ccb->p_lcb, NULL, p_buf);
 }
 
@@ -941,6 +1012,21 @@ void l2cu_send_peer_echo_rsp (tL2C_LCB *p_lcb, UINT8 id, UINT8 *p_data, UINT16 d
     BT_HDR  *p_buf;
     UINT8   *p;
     UINT16   maxlen;
+    /* Filter out duplicate IDs or if available buffers are low (intruder checking) */
+    if (!id || id == p_lcb->cur_echo_id)
+    {
+        /* Dump this request since it is illegal */
+        L2CAP_TRACE_WARNING1 ("L2CAP ignoring duplicate echo request (%d)", id);
+        return;
+    }
+    else
+        p_lcb->cur_echo_id = id;
+     /* Don't respond if we more than 10% of our buffers are used */
+    if (GKI_poolutilization (L2CAP_CMD_POOL_ID) > 10)
+    {
+        L2CAP_TRACE_WARNING0 ("L2CAP gki pool used up to more than 10%%, ignore echo response");
+        return;
+    }
 
     /* Don't return data if it does not fit in ACL and L2CAP MTU */
     maxlen = (GKI_get_pool_bufsize(L2CAP_CMD_POOL_ID) > btu_cb.hcit_acl_pkt_size) ?
@@ -1069,7 +1155,7 @@ void l2cu_send_peer_info_rsp (tL2C_LCB *p_lcb, UINT8 remote_id, UINT16 info_type
     {
         UINT16_TO_STREAM (p, L2CAP_INFO_RESP_RESULT_SUCCESS);
 #if (BLE_INCLUDED == TRUE)
-        if (p_lcb->is_ble_link)
+        if (p_lcb->transport == BT_TRANSPORT_LE)
         {
             /* optional data are not added for now */
             UINT32_TO_STREAM (p, L2CAP_BLE_EXTFEA_MASK);
@@ -2104,7 +2190,7 @@ extern UINT16 tcs_wug_get_clk_offset( BD_ADDR addr ) ;
 ** Returns          TRUE if successful, FALSE if gki get buffer fails.
 **
 *******************************************************************************/
-BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
+BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb, tBT_TRANSPORT transport)
 {
     int             xx;
     tL2C_LCB        *p_lcb_cur = &l2cb.lcb_pool[0];
@@ -2116,15 +2202,16 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
     tBT_DEVICE_TYPE     dev_type;
     tBLE_ADDR_TYPE      addr_type;
 
+
     BTM_ReadDevInfo(p_lcb->remote_bd_addr, &dev_type, &addr_type);
 
-    if (dev_type == BT_DEVICE_TYPE_BLE)
+    if (transport == BT_TRANSPORT_LE)
     {
         if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
             return FALSE;
 
         p_lcb->ble_addr_type = addr_type;
-        p_lcb->is_ble_link   = TRUE;
+        p_lcb->transport = BT_TRANSPORT_LE;
 
         return (l2cble_create_conn(p_lcb));
     }
@@ -2154,7 +2241,7 @@ BOOLEAN l2cu_create_conn (tL2C_LCB *p_lcb)
             if (is_sco_active == TRUE)
                 continue; /* No Master Slave switch not allowed when SCO Active */
 #endif
-
+            /*4_1_TODO check  if btm_cb.devcb.local_features to be used instead */
             if (HCI_SWITCH_SUPPORTED(BTM_ReadLocalFeatures()))
             {
                 /* mark this lcb waiting for switch to be completed and
@@ -2394,7 +2481,7 @@ BOOLEAN l2cu_set_acl_priority (BD_ADDR bd_addr, UINT8 priority, BOOLEAN reset_af
     APPL_TRACE_EVENT1("SET ACL PRIORITY %d", priority);
 
     /* Find the link control block for the acl channel */
-    if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr)) == NULL)
+    if ((p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR)) == NULL)
     {
         L2CAP_TRACE_WARNING0 ("L2CAP - no LCB for L2CA_SetAclPriority");
         return (FALSE);
@@ -2468,7 +2555,7 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
     /* If we are called with a BDA, only resubmit for that BDA */
     if (p_bda)
     {
-        p_lcb = l2cu_find_lcb_by_bd_addr (p_bda);
+        p_lcb = l2cu_find_lcb_by_bd_addr (p_bda, BT_TRANSPORT_BR_EDR);
 
         /* If we don't have one, this is an error */
         if (p_lcb)
@@ -2663,11 +2750,13 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
         rc = btm_sec_disconnect (p_lcb->handle, HCI_ERR_PEER_USER);
         if (rc == BTM_CMD_STARTED)
         {
+            l2cu_process_fixed_disc_cback(p_lcb);
             p_lcb->link_state = LST_DISCONNECTING;
             timeout = L2CAP_LINK_DISCONNECT_TOUT;
         }
         else if (rc == BTM_SUCCESS)
         {
+            l2cu_process_fixed_disc_cback(p_lcb);
             /* BTM SEC will make sure that link is release (probably after pairing is done) */
             p_lcb->link_state = LST_DISCONNECTING;
             timeout = 0xFFFF;
@@ -2675,6 +2764,7 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
         else if ( (p_lcb->is_bonding)
             &&   (btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER)) )
         {
+            l2cu_process_fixed_disc_cback(p_lcb);
             p_lcb->link_state = LST_DISCONNECTING;
             timeout = L2CAP_LINK_DISCONNECT_TOUT;
         }
@@ -2709,27 +2799,43 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
 void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
 {
     int     xx;
-#if BLE_INCLUDED == TRUE
-    UINT16  reason = (p_lcb->is_ble_link ) ? 1 : 0;
-#else
-    UINT16 reason =0;
+#if (BLE_INCLUDED == TRUE)
+    /* always exclude LE fixed channel on BR/EDR fix channel capability */
+    if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+        p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \
+                                      L2CAP_FIXED_CHNL_BLE_SIG_BIT| \
+                                      L2CAP_FIXED_CHNL_SMP_BIT);
 #endif
 
     /* Tell all registered fixed channels about the connection */
     for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
     {
+#if BLE_INCLUDED == TRUE
+        /* skip sending LE fix channel callbacks on BR/EDR links */
+        if (p_lcb->transport == BT_TRANSPORT_BR_EDR &&
+            xx + L2CAP_FIRST_FIXED_CHNL >= L2CAP_ATT_CID &&
+            xx + L2CAP_FIRST_FIXED_CHNL <= L2CAP_SMP_CID)
+            continue;
+#endif
         if (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL)
         {
             if (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
             {
                 if (p_lcb->p_fixed_ccbs[xx])
                     p_lcb->p_fixed_ccbs[xx]->chnl_state = CST_OPEN;
-
-                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, reason);
+#if BLE_INCLUDED == TRUE
+                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, p_lcb->transport);
+#else
+                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, TRUE, 0, BT_TRANSPORT_BR_EDR);
+#endif
             }
             else
             {
-                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason);
+#if BLE_INCLUDED == TRUE
+                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+                (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
 
                 if (p_lcb->p_fixed_ccbs[xx])
                 {
@@ -2742,6 +2848,45 @@ void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
 }
 #endif
 
+
+/*******************************************************************************
+**
+** Function         l2cu_process_fixed_disc_cback
+**
+** Description      send l2cap fixed channel disconnection callback to application
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
+{
+#if (L2CAP_NUM_FIXED_CHNLS > 0)
+    int         xx;
+
+    for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
+    {
+        if (p_lcb->p_fixed_ccbs[xx])
+        {
+            l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
+            p_lcb->p_fixed_ccbs[xx] = NULL;
+#if BLE_INCLUDED == TRUE
+            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
+        }
+        else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
+               && (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
+#if BLE_INCLUDED == TRUE
+            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
+#else
+            (*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
+#endif
+    }
+#endif
+}
+
 #if (BLE_INCLUDED == TRUE)
 /*******************************************************************************
 **
@@ -3193,7 +3338,7 @@ void l2cu_set_acl_hci_header (BT_HDR *p_buf, tL2C_CCB *p_ccb)
     UINT16_TO_STREAM (p, p_ccb->p_lcb->handle | (L2CAP_PKT_START << L2CAP_PKT_TYPE_SHIFT));
 #endif
 #if (BLE_INCLUDED == TRUE)
-    if (p_ccb->p_lcb->is_ble_link)
+    if (p_ccb->p_lcb->transport == BT_TRANSPORT_LE)
     {
         /* The HCI transport will segment the buffers. */
         if (p_buf->len > btu_cb.hcit_ble_acl_data_size)
index bc6fe09..d792bfc 100644 (file)
@@ -70,12 +70,14 @@ const tL2CAP_FCR_OPTS mca_l2c_fcr_opts_def =
 ** Returns          void
 **
 *******************************************************************************/
-static void mca_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void mca_sec_check_complete_term (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tMCA_TC_TBL     *p_tbl = (tMCA_TC_TBL *)p_ref_data;
     tL2CAP_CFG_INFO cfg;
     tL2CAP_ERTM_INFO ertm_info;
 
+    UNUSED(transport);
+
     MCA_TRACE_DEBUG1("mca_sec_check_complete_term res: %d", res);
 
     if ( res == BTM_SUCCESS )
@@ -115,11 +117,12 @@ static void mca_sec_check_complete_term (BD_ADDR bd_addr, void *p_ref_data, UINT
 ** Returns          void
 **
 *******************************************************************************/
-static void mca_sec_check_complete_orig (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+static void mca_sec_check_complete_orig (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tMCA_TC_TBL     *p_tbl = (tMCA_TC_TBL *)p_ref_data;
     tL2CAP_CFG_INFO cfg;
     UNUSED(bd_addr);
+    UNUSED(transport);
 
     MCA_TRACE_DEBUG1("mca_sec_check_complete_orig res: %d", res);
 
index 83a63e3..302a8af 100644 (file)
@@ -315,7 +315,7 @@ tRFC_MCB  *rfc_find_lcid_mcb (UINT16 lcid);
 extern void      rfc_save_lcid_mcb (tRFC_MCB *p_rfc_mcb, UINT16 lcid);
 extern void      rfc_check_mcb_active (tRFC_MCB *p_mcb);
 extern void      rfc_port_closed (tPORT *p_port);
-extern void      rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res);
+extern void      rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport,void *p_ref_data, UINT8 res);
 extern void      rfc_inc_credit (tPORT *p_port, UINT8 credit);
 extern void      rfc_dec_credit (tPORT *p_port);
 extern void      rfc_check_send_cmd(tRFC_MCB *p_mcb, BT_HDR *p_buf);
index d2b02fc..47b093f 100644 (file)
@@ -350,10 +350,11 @@ void rfcomm_process_timeout (TIMER_LIST_ENT  *p_tle)
 ** Returns          void
 **
 *******************************************************************************/
-void rfc_sec_check_complete (BD_ADDR bd_addr, void *p_ref_data, UINT8 res)
+void rfc_sec_check_complete (BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, UINT8 res)
 {
     tPORT *p_port = (tPORT *)p_ref_data;
     UNUSED(bd_addr);
+    UNUSED(transport);
 
     /* Verify that PORT is still waiting for Security to complete */
     if (!p_port->in_use
index 65cddf5..d3d8ff6 100644 (file)
@@ -510,6 +510,7 @@ return_type aes_set_key( const unsigned char key[], length_type keylen, aes_cont
         keylen = 24;
         break;
     case 32:
+    /*    case 256:           length in bits (256 = 8*32) */ 
         keylen = 32;
         break;
     default:
index 47cd2c9..7543eb7 100644 (file)
@@ -26,6 +26,7 @@
     #include "l2c_api.h"
     #include "smp_int.h"
 
+#define MAX_KEY_DISTRIBUTION_TYPES   3
 
 const UINT8 smp_association_table[2][SMP_IO_CAP_MAX][SMP_IO_CAP_MAX] =
 {
@@ -108,6 +109,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
         {
             p_cb->loc_auth_req   = cb_data.io_req.auth_req;
             p_cb->loc_io_caps    = cb_data.io_req.io_cap;
+
 #if (defined(BLE_PERIPHERAL_DISPLAYONLY) && (BLE_PERIPHERAL_DISPLAYONLY == TRUE))
             if (p_cb->role == HCI_ROLE_SLAVE)
             {
@@ -165,7 +167,11 @@ void smp_send_pair_req(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
        some peripherals are not able to revert to fast connection parameters
        during the start of service discovery. Connection paramter updates
        get enabled again once service discovery completes. */
-    L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
+    if (L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE) == FALSE)
+    {
+        SMP_TRACE_ERROR0 ("smp pair failed...!");
+        return;
+    }
 #endif
 
     /* erase all keys when master sends pairing req*/
@@ -616,7 +622,7 @@ void smp_proc_sl_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 *******************************************************************************/
 void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 {
-    BOOLEAN cmd;
+    tBTM_STATUS cmd;
     UINT8 reason = SMP_ENC_FAIL;
 
     SMP_TRACE_DEBUG0 ("smp_start_enc ");
@@ -625,7 +631,7 @@ void smp_start_enc(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     else
         cmd = btm_ble_start_encrypt(p_cb->pairing_bda, FALSE, NULL);
 
-    if (!cmd)
+    if (cmd != BTM_CMD_STARTED && cmd != BTM_BUSY)
         smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
 
 }
@@ -729,7 +735,7 @@ void smp_key_pick_key(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
     UINT8   i = 0;
 
     SMP_TRACE_DEBUG1 ("smp_key_pick_key key_to_dist=0x%x", key_to_dist);
-    while (i < 3)
+    while (i < MAX_KEY_DISTRIBUTION_TYPES)
     {
         SMP_TRACE_DEBUG2("key to send = %02x, i = %d",  key_to_dist, i);
 
@@ -899,6 +905,7 @@ void smp_pairing_cmpl(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
 
     SMP_TRACE_DEBUG0 ("smp_pairing_cmpl ");
 
+    (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, TRUE);
     if ((p_cb->status == SMP_SUCCESS) ||
         (p_cb->status <= SMP_REPEATED_ATTEMPTS && p_cb->status != SMP_SUCCESS))
     {
@@ -960,6 +967,18 @@ void smp_idle_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
         smp_proc_pairing_cmpl(p_cb);
     }
 }
+
+/*******************************************************************************
+** Function     smp_fast_conn_param
+** Description  apply default connection parameter for pairing process
+*******************************************************************************/
+void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
+{
+    /* disable connection parameter update */
+    (void)L2CA_EnableUpdateBleConnParams(p_cb->pairing_bda, FALSE);
+}
+
+
 /*******************************************************************************
 **
 ** Function         smp_link_encrypted
index 51cdbb3..70c09a5 100644 (file)
@@ -202,6 +202,8 @@ typedef struct
     BD_ADDR         local_bda;
     BOOLEAN         is_pair_cancel;
     BOOLEAN         discard_sec_req;
+    UINT8           rcvd_cmd_code;
+    UINT8           rcvd_cmd_len;
 #if SMP_CONFORMANCE_TESTING == TRUE
     BOOLEAN         enable_test_confirm_val;
     BT_OCTET16      test_confirm;
@@ -288,6 +290,8 @@ extern void smp_key_distribution(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
 extern void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
 extern void smp_generate_csrk(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
 extern void smp_delay_terminate(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+extern void smp_fast_conn_param(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
+
 /* smp_l2c */
 extern void smp_l2cap_if_init (void);
 
@@ -314,6 +318,7 @@ extern void smp_genenrate_rand_cont(tSMP_CB *p_cb, tSMP_INT_DATA *p_data);
 /* smp main util */
 extern void smp_set_state(tSMP_STATE state);
 extern tSMP_STATE smp_get_state(void);
+extern void smp_reject_unexp_pair_req(BD_ADDR bd_addr);
 
 #endif /* SMP_INT_H */
 
index 54b78b4..02ec38e 100644 (file)
@@ -34,7 +34,7 @@
 
 
 
-static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason);
+static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason, tBT_TRANSPORT transport);
 static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf);
 
 /*******************************************************************************
@@ -73,13 +73,20 @@ void smp_l2cap_if_init (void)
 **                      connected (conn = TRUE)/disconnected (conn = FALSE).
 **
 *******************************************************************************/
-static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason)
+static void smp_connect_cback (BD_ADDR bd_addr, BOOLEAN connected, UINT16 reason,
+                                    tBT_TRANSPORT transport)
 {
     tSMP_CB   *p_cb = &smp_cb;
     tSMP_INT_DATA   int_data;
 
     SMP_TRACE_EVENT0 ("SMDBG l2c smp_connect_cback ");
 
+    if (transport == BT_TRANSPORT_BR_EDR)
+    {
+        SMP_TRACE_ERROR0 ("smp_connect_cback : Wrong transport");
+        return;
+    }
+
     if (memcmp(bd_addr, p_cb->pairing_bda, BD_ADDR_LEN) == 0)
     {
         SMP_TRACE_EVENT3 ("smp_connect_cback()  for pairing BDA: %08x%04x  Event: %s",
@@ -132,6 +139,13 @@ static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf)
 
     STREAM_TO_UINT8(cmd, p);
 
+    /* sanity check */
+    if ((SMP_OPCODE_MAX <= cmd) || (cmd == 0))
+    {
+        SMP_TRACE_WARNING1( "Ignore received command with RESERVED code 0x%02x", cmd);
+        GKI_freebuf (p_buf);
+        return;
+    }
 
     /* reject the pairing request if there is an on-going SMP pairing */
     if (SMP_OPCODE_PAIRING_REQ == cmd || SMP_OPCODE_SEC_REQ == cmd)
@@ -143,14 +157,21 @@ static void smp_data_ind (BD_ADDR bd_addr, BT_HDR *p_buf)
         }
         else if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN))
         {
-            p_cb->failure = SMP_PAIR_NOT_SUPPORT;
-            smp_send_cmd(SMP_OPCODE_PAIRING_FAILED, p_cb);
+            GKI_freebuf (p_buf);
+            smp_reject_unexp_pair_req(bd_addr);
+            return;
         }
+        /* else, out of state pairing request/security request received, passed into SM */
     }
 
     if (memcmp(&bd_addr[0], p_cb->pairing_bda, BD_ADDR_LEN) == 0)
     {
-        btu_stop_timer (&p_cb->rsp_timer_ent);
+        if (p_cb->state != SMP_ST_RELEASE_DELAY)
+        {
+            btu_stop_timer (&p_cb->rsp_timer_ent);
+        }
+        p_cb->rcvd_cmd_code = cmd;
+        p_cb->rcvd_cmd_len = (UINT8) p_buf->len;
         smp_sm_event(p_cb, cmd, p);
     }
 
index f8e450c..dd40a71 100644 (file)
@@ -114,6 +114,8 @@ enum
     SMP_PROC_REL_DELAY,
     SMP_PROC_REL_DELAY_TOUT,
     SMP_DELAY_TERMINATE,
+    SMP_IDLE_TERMINATE,
+    SMP_FAST_CONN_PARAM,
     SMP_SM_NO_ACTION
 };
 
@@ -156,6 +158,8 @@ static const tSMP_ACT smp_sm_action[] =
     smp_proc_release_delay,
     smp_proc_release_delay_tout,
     smp_delay_terminate,
+    smp_idle_terminate,
+    smp_fast_conn_param
 };
 /************ SMP Master FSM State/Event Indirection Table **************/
 static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
@@ -176,7 +180,7 @@ static const UINT8 smp_ma_entry_map[][SMP_ST_MAX] =
 /* KEY_READY          */{ 0,    3,     0,      3,     1,   0,    2,   1,    6,     0   },
 /* ENC_CMPL           */{ 0,    0,     0,      0,     0,   0,    0,   2,    0,     0   },
 /* L2C_CONN           */{ 1,    0,     0,      0,     0,   0,    0,   0,    0,     0   },
-/* L2C_DISC           */{ 0x83,        0x83,  0,      0x83,  0x83,0x83, 0x83,0x83, 0x83,  3   },
+/* L2C_DISC           */{ 3,   0x83,  0,      0x83,  0x83,0x83, 0x83,0x83, 0x83,  3   },
 /* IO_RSP             */{ 0,    2,     0,      0,     0,   0,    0,   0,    0,     0   },
 /* SEC_GRANT          */{ 0,    1,     0,      0,     0,   0,    0,   0,    0,     0   },
 /* TK_REQ             */{ 0,    0,     0,      2,     0,   0,    0,   0,    0,     0   },
@@ -198,15 +202,16 @@ static const UINT8 smp_all_table[][SMP_SM_NUM_COLS] = {
 static const UINT8 smp_ma_idle_table[][SMP_SM_NUM_COLS] = {
 /* Event       Action                   Next State */
 /* L2C_CONN */      {SMP_SEND_APP_CBACK,     SMP_SM_NO_ACTION,   SMP_ST_WAIT_APP_RSP},
-/* SEC_REQ  */      {SMP_PROC_SEC_REQ,       SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP}
+/* SEC_REQ  */      {SMP_PROC_SEC_REQ,       SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
+/* L2C_DISC  */     {SMP_IDLE_TERMINATE,     SMP_SM_NO_ACTION,      SMP_ST_IDLE}
 };
 
 static const UINT8 smp_ma_wait_app_rsp_table[][SMP_SM_NUM_COLS] = {
 /* Event                                                                Action          Next State */
 /* SEC_GRANT            */ { SMP_PROC_SEC_GRANT,   SMP_SEND_APP_CBACK, SMP_ST_WAIT_APP_RSP},
-/* IO_RSP               */ { SMP_SEND_PAIR_REQ,    SMP_SM_NO_ACTION,   SMP_ST_PAIR_REQ_RSP},
+/* IO_RSP               */ { SMP_SEND_PAIR_REQ,    SMP_FAST_CONN_PARAM,   SMP_ST_PAIR_REQ_RSP},
 /* KEY_READY            */ { SMP_GENERATE_CONFIRM, SMP_SM_NO_ACTION,   SMP_ST_WAIT_CONFIRM},/* TK ready */
-/* ENC_REQ              */ { SMP_START_ENC,        SMP_SM_NO_ACTION,   SMP_ST_ENC_PENDING},/* start enc mode setup */
+/* ENC_REQ              */ { SMP_START_ENC,        SMP_FAST_CONN_PARAM,   SMP_ST_ENC_PENDING},/* start enc mode setup */
 /* DISCARD_SEC_REQ      */ { SMP_PROC_DISCARD,     SMP_SM_NO_ACTION,   SMP_ST_IDLE}
 };
 
index dac0cc0..38b2be8 100644 (file)
@@ -621,6 +621,35 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
     smp_reset_control_value(p_cb);
 }
 
+/*******************************************************************************
+**
+** Function         smp_reject_unexp_pair_req
+**
+** Description      send pairing failure to an unexpected pairing request during
+**                  an active pairing process.
+**
+** Returns          void
+**
+*******************************************************************************/
+void smp_reject_unexp_pair_req(BD_ADDR bd_addr)
+{
+    BT_HDR *p_buf;
+    UINT8   *p;
+
+    if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR) + SMP_PAIR_FAIL_SIZE + L2CAP_MIN_OFFSET)) != NULL)
+    {
+        p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
+
+        UINT8_TO_STREAM (p, SMP_OPCODE_PAIRING_FAILED);
+        UINT8_TO_STREAM (p, SMP_PAIR_NOT_SUPPORT);
+
+        p_buf->offset = L2CAP_MIN_OFFSET;
+        p_buf->len = SMP_PAIR_FAIL_SIZE;
+
+        smp_send_msg_to_L2CAP(bd_addr, p_buf);
+    }
+}
+
 #if SMP_CONFORMANCE_TESTING == TRUE
 /*******************************************************************************
 **
index 90b4acd..7c4df0d 100644 (file)
@@ -443,14 +443,14 @@ BOOLEAN DIS_ReadDISInfo(BD_ADDR peer_bda, tDIS_READ_CBACK *p_cback)
                       (peer_bda[4]<<8)+peer_bda[5], dis_attr_uuid[dis_cb.dis_read_uuid_idx]);
 
 
-    GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id);
+    GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, BT_TRANSPORT_LE);
 
     /* need to enhance it as multiple service is needed */
     srvc_eng_request_channel(peer_bda, SRVC_ID_DIS);
 
     if (conn_id == GATT_INVALID_CONN_ID)
     {
-        return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE);
+        return GATT_Connect(srvc_eng_cb.gatt_if, peer_bda, TRUE, BT_TRANSPORT_LE);
     }
 
     return dis_gatt_c_read_dis_req(conn_id);
index 4598738..bf730aa 100644 (file)
@@ -30,7 +30,8 @@
 #include "srvc_battery_int.h"
 
 static void srvc_eng_s_request_cback (UINT16 conn_id, UINT32 trans_id, UINT8 op_code, tGATTS_DATA *p_data);
-static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected, tGATT_DISCONN_REASON reason);
+static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id, BOOLEAN connected,
+                                          tGATT_DISCONN_REASON reason, tBT_TRANSPORT transport);
 static void srvc_eng_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS status, tGATT_CL_COMPLETE *p_data);
 
 static tGATT_CBACK srvc_gatt_cback =
@@ -341,9 +342,10 @@ static void srvc_eng_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATU
 **
 *******************************************************************************/
 static void srvc_eng_connect_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
-                                        BOOLEAN connected, tGATT_DISCONN_REASON reason)
+                                        BOOLEAN connected, tGATT_DISCONN_REASON reason,  tBT_TRANSPORT transport)
 {
     UNUSED(gatt_if);
+    UNUSED (transport);
 
     GATT_TRACE_EVENT5 ("srvc_eng_connect_cback: from %08x%04x connected:%d conn_id=%d reason = 0x%04x",
                        (bda[0]<<24)+(bda[1]<<16)+(bda[2]<<8)+bda[3],