Explorar o código

Added reporting for ACL link related events to application

jincheng %!s(int64=3) %!d(string=hai) anos
pai
achega
228bf596dc

+ 66 - 0
components/bt/host/bluedroid/api/include/api/esp_bt_defs.h

@@ -19,6 +19,7 @@ extern "C" {
         return ESP_ERR_INVALID_STATE;                \
     }
 
+#define ESP_BT_STATUS_BASE_FOR_HCI_ERR  0X0100  /* base for coverting HCI error code to ESP status */
 
 /* relate to BT_STATUS_xxx in bt_def.h */
 /// Status Return Value
@@ -45,6 +46,71 @@ typedef enum {
     ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT,    /* relate to HCI_ERR_ILLEGAL_PARAMETER_FMT in stack/hcidefs.h */
     ESP_BT_STATUS_MEMORY_FULL   = 20,           /* relate to BT_STATUS_MEMORY_FULL in bt_def.h */
     ESP_BT_STATUS_EIR_TOO_LARGE,                /* relate to BT_STATUS_EIR_TOO_LARGE in bt_def.h */
+    ESP_BT_STATUS_HCI_SUCCESS   = ESP_BT_STATUS_BASE_FOR_HCI_ERR,
+    ESP_BT_STATUS_HCI_PENDING,
+    ESP_BT_STATUS_HCI_ILLEGAL_COMMAND,
+    ESP_BT_STATUS_HCI_NO_CONNECTION,
+    ESP_BT_STATUS_HCI_HW_FAILURE,
+    ESP_BT_STATUS_HCI_PAGE_TIMEOUT,
+    ESP_BT_STATUS_HCI_AUTH_FAILURE,
+    ESP_BT_STATUS_HCI_KEY_MISSING,
+    ESP_BT_STATUS_HCI_MEMORY_FULL,
+    ESP_BT_STATUS_HCI_CONNECTION_TOUT,
+    ESP_BT_STATUS_HCI_MAX_NUM_OF_CONNECTIONS,
+    ESP_BT_STATUS_HCI_MAX_NUM_OF_SCOS,
+    ESP_BT_STATUS_HCI_CONNECTION_EXISTS,
+    ESP_BT_STATUS_HCI_COMMAND_DISALLOWED,
+    ESP_BT_STATUS_HCI_HOST_REJECT_RESOURCES,
+    ESP_BT_STATUS_HCI_HOST_REJECT_SECURITY,
+    ESP_BT_STATUS_HCI_HOST_REJECT_DEVICE,
+    ESP_BT_STATUS_HCI_HOST_TIMEOUT,
+    ESP_BT_STATUS_HCI_UNSUPPORTED_VALUE,
+    ESP_BT_STATUS_HCI_ILLEGAL_PARAMETER_FMT,
+    ESP_BT_STATUS_HCI_PEER_USER,
+    ESP_BT_STATUS_HCI_PEER_LOW_RESOURCES,
+    ESP_BT_STATUS_HCI_PEER_POWER_OFF,
+    ESP_BT_STATUS_HCI_CONN_CAUSE_LOCAL_HOST,
+    ESP_BT_STATUS_HCI_REPEATED_ATTEMPTS,
+    ESP_BT_STATUS_HCI_PAIRING_NOT_ALLOWED,
+    ESP_BT_STATUS_HCI_UNKNOWN_LMP_PDU,
+    ESP_BT_STATUS_HCI_UNSUPPORTED_REM_FEATURE,
+    ESP_BT_STATUS_HCI_SCO_OFFSET_REJECTED,
+    ESP_BT_STATUS_HCI_SCO_INTERVAL_REJECTED,
+    ESP_BT_STATUS_HCI_SCO_AIR_MODE,
+    ESP_BT_STATUS_HCI_INVALID_LMP_PARAM,
+    ESP_BT_STATUS_HCI_UNSPECIFIED,
+    ESP_BT_STATUS_HCI_UNSUPPORTED_LMP_PARAMETERS,
+    ESP_BT_STATUS_HCI_ROLE_CHANGE_NOT_ALLOWED,
+    ESP_BT_STATUS_HCI_LMP_RESPONSE_TIMEOUT,
+    ESP_BT_STATUS_HCI_LMP_ERR_TRANS_COLLISION,
+    ESP_BT_STATUS_HCI_LMP_PDU_NOT_ALLOWED,
+    ESP_BT_STATUS_HCI_ENCRY_MODE_NOT_ACCEPTABLE,
+    ESP_BT_STATUS_HCI_UNIT_KEY_USED,
+    ESP_BT_STATUS_HCI_QOS_NOT_SUPPORTED,
+    ESP_BT_STATUS_HCI_INSTANT_PASSED,
+    ESP_BT_STATUS_HCI_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED,
+    ESP_BT_STATUS_HCI_DIFF_TRANSACTION_COLLISION,
+    ESP_BT_STATUS_HCI_UNDEFINED_0x2B,
+    ESP_BT_STATUS_HCI_QOS_UNACCEPTABLE_PARAM,
+    ESP_BT_STATUS_HCI_QOS_REJECTED,
+    ESP_BT_STATUS_HCI_CHAN_CLASSIF_NOT_SUPPORTED,
+    ESP_BT_STATUS_HCI_INSUFFCIENT_SECURITY,
+    ESP_BT_STATUS_HCI_PARAM_OUT_OF_RANGE,
+    ESP_BT_STATUS_HCI_UNDEFINED_0x31,
+    ESP_BT_STATUS_HCI_ROLE_SWITCH_PENDING,
+    ESP_BT_STATUS_HCI_UNDEFINED_0x33,
+    ESP_BT_STATUS_HCI_RESERVED_SLOT_VIOLATION,
+    ESP_BT_STATUS_HCI_ROLE_SWITCH_FAILED,
+    ESP_BT_STATUS_HCI_INQ_RSP_DATA_TOO_LARGE,
+    ESP_BT_STATUS_HCI_SIMPLE_PAIRING_NOT_SUPPORTED,
+    ESP_BT_STATUS_HCI_HOST_BUSY_PAIRING,
+    ESP_BT_STATUS_HCI_REJ_NO_SUITABLE_CHANNEL,
+    ESP_BT_STATUS_HCI_CONTROLLER_BUSY,
+    ESP_BT_STATUS_HCI_UNACCEPT_CONN_INTERVAL,
+    ESP_BT_STATUS_HCI_DIRECTED_ADVERTISING_TIMEOUT,
+    ESP_BT_STATUS_HCI_CONN_TOUT_DUE_TO_MIC_FAILURE,
+    ESP_BT_STATUS_HCI_CONN_FAILED_ESTABLISHMENT,
+    ESP_BT_STATUS_HCI_MAC_CONNECTION_FAILED,
 } esp_bt_status_t;
 
 

+ 20 - 0
components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h

@@ -215,6 +215,8 @@ typedef enum {
     ESP_BT_GAP_MODE_CHG_EVT,
     ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT,         /*!< remove bond device complete event */
     ESP_BT_GAP_QOS_CMPL_EVT,                        /*!< QOS complete event */
+    ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT,              /*!< ACL connection complete status event */
+    ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT,           /*!< ACL disconnection complete status event */
     ESP_BT_GAP_EVT_MAX,
 } esp_bt_gap_cb_event_t;
 
@@ -368,6 +370,24 @@ typedef union {
                                                     which from the master to a particular slave on the ACL
                                                     logical transport. unit is 0.625ms. */
     } qos_cmpl;                                /*!< QoS complete parameter struct */
+
+    /**
+     * @brief ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT
+     */
+    struct acl_conn_cmpl_stat_param {
+        esp_bt_status_t stat;                  /*!< ACL connection status */
+        uint16_t handle;                       /*!< ACL connection handle */
+        esp_bd_addr_t bda;                     /*!< remote bluetooth device address */
+    } acl_conn_cmpl_stat;                      /*!< ACL connection complete status parameter struct */
+
+    /**
+     * @brief ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT
+     */
+    struct acl_disconn_cmpl_stat_param {
+        esp_bt_status_t reason;                /*!< ACL disconnection reason */
+        uint16_t handle;                       /*!< ACL connection handle */
+        esp_bd_addr_t bda;                     /*!< remote bluetooth device address */
+    } acl_disconn_cmpl_stat;                   /*!< ACL disconnection complete status parameter struct */
 } esp_bt_gap_cb_param_t;
 
 /**

+ 41 - 0
components/bt/host/bluedroid/bta/dm/bta_dm_act.c

@@ -71,6 +71,7 @@ static BOOLEAN bta_dm_check_av(UINT16 event);
 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
 
 
+static void bta_dm_acl_link_stat_cback(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data);
 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
 
 /* Extended Inquiry Response */
@@ -511,6 +512,7 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
         BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
 #endif
         BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK);
+        BTM_RegAclLinkStatNotif (bta_dm_acl_link_stat_cback);
 
 #if BLE_VND_INCLUDED == TRUE
         BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
@@ -3317,6 +3319,45 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
 
 }
 
+/*******************************************************************************
+**
+** Function         bta_dm_acl_link_stat_cback
+**
+** Description      Callback from btm to report acl link status
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bta_dm_acl_link_stat_cback(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data)
+{
+    tBTA_DM_SEC sec_event;
+    memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
+    sec_event.acl_link_stat.event = p_data->event;
+
+    switch (sec_event.acl_link_stat.event) {
+    case BTA_ACL_LINK_STAT_CONN_CMPL: {
+        sec_event.acl_link_stat.link_act.conn_cmpl.status = p_data->link_act.conn_cmpl.status;
+        sec_event.acl_link_stat.link_act.conn_cmpl.handle = p_data->link_act.conn_cmpl.handle;
+        bdcpy(sec_event.acl_link_stat.link_act.conn_cmpl.bd_addr, p_data->link_act.conn_cmpl.bd_addr);
+        break;
+    }
+    case BTA_ACL_LINK_STAT_DISCONN_CMPL: {
+        sec_event.acl_link_stat.link_act.disconn_cmpl.reason = p_data->link_act.disconn_cmpl.reason;
+        sec_event.acl_link_stat.link_act.disconn_cmpl.handle = p_data->link_act.disconn_cmpl.handle;
+        bdcpy(sec_event.acl_link_stat.link_act.disconn_cmpl.bd_addr, p_data->link_act.disconn_cmpl.bd_addr);
+        break;
+    }
+    default: {
+        APPL_TRACE_WARNING("bta_dm_acl_link_stat: invalid event %d", sec_event.acl_link_stat.event);
+        return;
+    }
+    }
+
+    if (bta_dm_cb.p_sec_cback) {
+        (*bta_dm_cb.p_sec_cback)(BTA_DM_ACL_LINK_STAT_EVT, &sec_event);
+    }
+}
+
 /*******************************************************************************
 **
 ** Function         bta_dm_rs_cback

+ 29 - 0
components/bt/host/bluedroid/bta/include/bta/bta_api.h

@@ -656,6 +656,7 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
 #define BTA_DM_BLE_DEV_UNPAIRED_EVT     29      /* BLE unpair event */
 #define BTA_DM_SP_KEY_REQ_EVT           30      /* Simple Pairing Passkey request */
 #define BTA_DM_PM_MODE_CHG_EVT          31      /* Mode changed event */
+#define BTA_DM_ACL_LINK_STAT_EVT        32      /* ACL connection status report event */
 
 typedef UINT8 tBTA_DM_SEC_EVT;
 
@@ -819,6 +820,33 @@ typedef struct {
 #endif
 } tBTA_DM_LINK_DOWN;
 
+enum {
+    BTA_ACL_LINK_STAT_CONN_CMPL,
+    BTA_ACL_LINK_STAT_DISCONN_CMPL
+};
+typedef UINT8 tBTA_ACL_LINK_STAT_EVT;
+
+typedef struct {
+    UINT8      status;             /* ACL link connection status */
+    UINT16     handle;             /* ACL connection handle */
+    BD_ADDR    bd_addr;            /* peer bluetooth address */
+} tBTA_DM_ACL_CONN_CMPL_STAT;
+
+typedef struct {
+    UINT8     reason;             /* ACL link disconnection reason */
+    UINT16    handle;             /* ACL connection handle */
+    BD_ADDR   bd_addr;            /* peer bluetooth address */
+} tBTA_DM_ACL_DISCONN_CMPL_STAT;
+
+/* Structure associated with BTA_DM_ACL_LINK_STAT_EVT */
+typedef struct {
+    tBTA_ACL_LINK_STAT_EVT            event;       /* ACL link event */
+    union {
+        tBTA_DM_ACL_CONN_CMPL_STAT     conn_cmpl;
+        tBTA_DM_ACL_DISCONN_CMPL_STAT  disconn_cmpl;
+    } link_act;
+} tBTA_DM_ACL_LINK_STAT;
+
 /* Structure associated with BTA_DM_ROLE_CHG_EVT */
 typedef struct {
     BD_ADDR         bd_addr;            /* BD address peer device. */
@@ -957,6 +985,7 @@ typedef union {
     tBTA_DM_AUTHORIZE           authorize;          /* Authorization request. */
     tBTA_DM_LINK_UP             link_up;            /* ACL connection up event */
     tBTA_DM_LINK_DOWN           link_down;          /* ACL connection down event */
+    tBTA_DM_ACL_LINK_STAT       acl_link_stat;      /* ACL link status event */
     tBTA_DM_BUSY_LEVEL          busy_level;         /* System busy level */
     tBTA_DM_SP_CFM_REQ          cfm_req;            /* user confirm request */
     tBTA_DM_SP_KEY_REQ          key_req;            /* user passkey request */

+ 38 - 0
components/bt/host/bluedroid/btc/core/btc_dm.c

@@ -677,6 +677,40 @@ bt_status_t btc_dm_disable_service(tBTA_SERVICE_ID service_id)
     return BT_STATUS_SUCCESS;
 }
 
+static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat)
+{
+#if (BTC_GAP_BT_INCLUDED == TRUE)
+    esp_bt_gap_cb_param_t param;
+    esp_bt_gap_cb_event_t event = ESP_BT_GAP_EVT_MAX;
+
+    switch (p_acl_link_stat->event) {
+    case BTA_ACL_LINK_STAT_CONN_CMPL: {
+        event = ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT;
+        param.acl_conn_cmpl_stat.stat = p_acl_link_stat->link_act.conn_cmpl.status | ESP_BT_STATUS_BASE_FOR_HCI_ERR;
+        param.acl_conn_cmpl_stat.handle = p_acl_link_stat->link_act.conn_cmpl.handle;
+        memcpy(param.acl_conn_cmpl_stat.bda, p_acl_link_stat->link_act.conn_cmpl.bd_addr, ESP_BD_ADDR_LEN);
+        break;
+    }
+    case BTA_ACL_LINK_STAT_DISCONN_CMPL: {
+        event = ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT;
+        param.acl_disconn_cmpl_stat.reason = p_acl_link_stat->link_act.disconn_cmpl.reason | ESP_BT_STATUS_BASE_FOR_HCI_ERR;
+        param.acl_disconn_cmpl_stat.handle = p_acl_link_stat->link_act.disconn_cmpl.handle;
+        memcpy(param.acl_disconn_cmpl_stat.bda, p_acl_link_stat->link_act.disconn_cmpl.bd_addr, ESP_BD_ADDR_LEN);
+        break;
+    }
+    default: {
+        BTC_TRACE_WARNING("%s: invalid event %x", __FUNCTION__, event);
+        return;
+    }
+    }
+
+    esp_bt_gap_cb_t cb = (esp_bt_gap_cb_t)btc_profile_cb_get(BTC_PID_GAP_BT);
+    if (cb) {
+        cb(event, &param);
+    }
+#endif
+}
+
 void btc_dm_sec_cb_handler(btc_msg_t *msg)
 {
     btc_dm_sec_args_t *arg = (btc_dm_sec_args_t *)(msg->arg);
@@ -755,6 +789,10 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
         break;
 #endif ///BT_SSP_INCLUDED == TRUE
 
+    case BTA_DM_ACL_LINK_STAT_EVT: {
+        btc_dm_acl_link_stat(&p_data->acl_link_stat);
+        break;
+    }
     case BTA_DM_DEV_UNPAIRED_EVT: {
         btc_dm_dev_unpaired_evt(&p_data->link_down);
         break;

+ 116 - 0
components/bt/host/bluedroid/stack/btm/btm_acl.c

@@ -43,7 +43,9 @@
 #include "stack/btu.h"
 #include "stack/btm_api.h"
 #include "btm_int.h"
+#include "stack/acl_hci_link_interface.h"
 #include "l2c_int.h"
+#include "stack/l2cap_hci_link_interface.h"
 #include "stack/hcidefs.h"
 //#include "bt_utils.h"
 #include "osi/list.h"
@@ -581,6 +583,26 @@ void btm_acl_update_busy_level (tBTM_BLI_EVENT event)
     }
 }
 
+/*******************************************************************************
+**
+** Function         btm_acl_link_stat_report
+**
+** Description      This function is called when the ACL link related
+                    events are received from controller. It reports the ACL
+                    link status to upper layer.
+
+** Returns          void
+**
+*******************************************************************************/
+void btm_acl_link_stat_report(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data)
+{
+    BTM_TRACE_DEBUG ("btm_acl_link_stat_report\n");
+
+    if (btm_cb.p_acl_link_stat_cb) {
+        (*btm_cb.p_acl_link_stat_cb)(p_data);
+    }
+}
+
 /*******************************************************************************
 **
 ** Function         BTM_GetRole
@@ -1830,6 +1852,22 @@ tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level,
     return (BTM_SUCCESS);
 }
 
+
+tBTM_STATUS BTM_RegAclLinkStatNotif(tBTM_ACL_LINK_STAT_CB *p_cb)
+{
+    BTM_TRACE_DEBUG ("BTM_RegAclLinkStatNotif\n");
+
+    if (!p_cb) {
+        btm_cb.p_acl_link_stat_cb = NULL;
+    } else if (btm_cb.p_acl_link_stat_cb) {
+        return BTM_BUSY;
+    } else {
+        btm_cb.p_acl_link_stat_cb = p_cb;
+    }
+
+    return BTM_SUCCESS;
+}
+
 /*******************************************************************************
 **
 ** Function         BTM_SetQoS
@@ -2569,3 +2607,81 @@ void btm_acl_free(void)
     list_free(btm_cb.p_acl_db_list);
     list_free(btm_cb.p_pm_mode_db_list);
 }
+
+/*******************************************************************************
+**
+** Function         btm_acl_connected
+**
+** Description      Handle ACL connection complete event
+**
+*******************************************************************************/
+void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mode, UINT8 status)
+{
+#if BTM_SCO_INCLUDED == TRUE
+    tBTM_ESCO_DATA  esco_data;
+#endif
+
+    if (link_type == HCI_LINK_TYPE_ACL) {
+#if SMP_INCLUDED == TRUE
+        btm_sec_connected (bda, handle, status, enc_mode);
+#endif  /* SMP_INCLUDED == TRUE */
+        /* report acl connection result to upper layer */
+        do {
+            tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = {
+                .event = BTM_ACL_CONN_CMPL_EVT,
+                .link_act.conn_cmpl.status = status,
+                .link_act.conn_cmpl.handle = handle,
+            };
+            bdcpy(evt_data.link_act.conn_cmpl.bd_addr, bda);
+            btm_acl_link_stat_report(&evt_data);
+        } while (0);
+
+        l2c_link_hci_conn_comp(status, handle, bda);
+    }
+#if BTM_SCO_INCLUDED == TRUE
+    else {
+        memset(&esco_data, 0, sizeof(tBTM_ESCO_DATA));
+        esco_data.link_type = HCI_LINK_TYPE_SCO;
+        memcpy (esco_data.bd_addr, bda, BD_ADDR_LEN);
+        btm_sco_connected(status, bda, handle, &esco_data);
+    }
+#endif /* BTM_SCO_INCLUDED == TRUE */
+}
+
+/*******************************************************************************
+**
+** Function         btm_acl_disconnected
+**
+** Description      Handle ACL disconnection complete event
+**
+*******************************************************************************/
+void btm_acl_disconnected(UINT16 handle, UINT8 reason)
+{
+#if BTM_SCO_INCLUDED == TRUE
+    /* If L2CAP doesn't know about it, send it to SCO */
+    if (!l2c_link_hci_disc_comp (handle, reason)) {
+        btm_sco_removed (handle, reason);
+    }
+#else
+    /* Report BR/EDR ACL disconnection result to upper layer */
+    tACL_CONN *conn = btm_handle_to_acl(handle);
+#if BLE_INCLUDED == TRUE
+    if (conn->transport == BT_TRANSPORT_BR_EDR)
+#endif
+    {
+        tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = {
+            .event = BTM_ACL_DISCONN_CMPL_EVT,
+            .link_act.disconn_cmpl.reason = reason,
+            .link_act.disconn_cmpl.handle = handle,
+        };
+        bdcpy(evt_data.link_act.disconn_cmpl.bd_addr, conn->remote_addr);
+        btm_acl_link_stat_report(&evt_data);
+    }
+
+    l2c_link_hci_disc_comp(handle, reason);
+#endif /* BTM_SCO_INCLUDED */
+#if (SMP_INCLUDED == TRUE)
+    /* Notify security manager */
+    btm_sec_disconnected(handle, reason);
+#endif  /* SMP_INCLUDED == TRUE */
+}

+ 3 - 0
components/bt/host/bluedroid/stack/btm/include/btm_int.h

@@ -834,6 +834,8 @@ typedef struct {
     UINT16      btm_def_link_policy;
     UINT16      btm_def_link_super_tout;
 
+    tBTM_ACL_LINK_STAT_CB *p_acl_link_stat_cb; /* Callback for when ACL link related events came */
+
     tBTM_BL_EVENT_MASK     bl_evt_mask;
     tBTM_BL_CHANGE_CB     *p_bl_changed_cb;    /* Callback for when Busy Level changed */
 
@@ -1028,6 +1030,7 @@ void         btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_B
 void         btm_acl_removed (BD_ADDR bda, tBT_TRANSPORT transport);
 void         btm_acl_device_down (void);
 void         btm_acl_update_busy_level (tBTM_BLI_EVENT event);
+void         btm_acl_link_stat_report(tBTM_ACL_LINK_STAT_EVENT_DATA *p_data);
 
 void         btm_cont_rswitch (tACL_CONN *p,
                                tBTM_SEC_DEV_REC *p_dev_rec,

+ 6 - 34
components/bt/host/bluedroid/stack/btu/btu_hcif.c

@@ -36,6 +36,7 @@
 #include "l2c_int.h"
 #include "stack/btm_api.h"
 #include "btm_int.h"
+#include "stack/acl_hci_link_interface.h"
 //#include "bt_utils.h"
 #include "device/controller.h"
 #include "osi/osi.h"
@@ -642,36 +643,18 @@ static void btu_hcif_connection_comp_evt (UINT8 *p)
     UINT16      handle;
     BD_ADDR     bda;
     UINT8       link_type;
-#if SMP_INCLUDED == TRUE
     UINT8       enc_mode;
-#endif  ///SMP_INCLUDED == TRUE
-#if BTM_SCO_INCLUDED == TRUE
-    tBTM_ESCO_DATA  esco_data;
-#endif
 
     STREAM_TO_UINT8    (status, p);
     STREAM_TO_UINT16   (handle, p);
     STREAM_TO_BDADDR   (bda, p);
     STREAM_TO_UINT8    (link_type, p);
-#if (SMP_INCLUDED == TRUE)
     STREAM_TO_UINT8    (enc_mode, p);
-#endif  ///SMP_INCLUDED == TRUE
+
     handle = HCID_GET_HANDLE (handle);
 
-    if (link_type == HCI_LINK_TYPE_ACL) {
-#if (SMP_INCLUDED == TRUE)
-        btm_sec_connected (bda, handle, status, enc_mode);
-#endif  ///SMP_INCLUDED == TRUE
-        l2c_link_hci_conn_comp (status, handle, bda);
-    }
-#if BTM_SCO_INCLUDED == TRUE
-    else {
-        memset(&esco_data, 0, sizeof(tBTM_ESCO_DATA));
-        /* esco_data.link_type = HCI_LINK_TYPE_SCO; already zero */
-        memcpy (esco_data.bd_addr, bda, BD_ADDR_LEN);
-        btm_sco_connected (status, bda, handle, &esco_data);
-    }
-#endif /* BTM_SCO_INCLUDED */
+    btm_acl_connected(bda, handle, link_type, enc_mode, status);
+
     HCI_TRACE_WARNING("hcif conn complete: hdl 0x%x, st 0x%x", handle, status);
 }
 
@@ -729,20 +712,9 @@ static void btu_hcif_disconnection_comp_evt (UINT8 *p)
 
     handle = HCID_GET_HANDLE (handle);
 
-    HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason);
+    btm_acl_disconnected(handle, reason);
 
-#if BTM_SCO_INCLUDED == TRUE
-    /* If L2CAP doesn't know about it, send it to SCO */
-    if (!l2c_link_hci_disc_comp (handle, reason)) {
-        btm_sco_removed (handle, reason);
-    }
-#else
-    l2c_link_hci_disc_comp (handle, reason);
-#endif /* BTM_SCO_INCLUDED */
-#if (SMP_INCLUDED == TRUE)
-    /* Notify security manager */
-    btm_sec_disconnected (handle, reason);
-#endif  ///SMP_INCLUDED == TRUE
+    HCI_TRACE_WARNING("hcif disc complete: hdl 0x%x, rsn 0x%x", handle, reason);
 }
 
 /*******************************************************************************

+ 15 - 0
components/bt/host/bluedroid/stack/include/stack/acl_hci_link_interface.h

@@ -0,0 +1,15 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ACL_HCI_LINK_INTERFACE_H
+#define ACL_HCI_LINK_INTERFACE_H
+
+#include "bt_common.h"
+
+void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mode, UINT8 status);
+void btm_acl_disconnected(UINT16 handle, UINT8 reason);
+
+#endif /* ACL_HCI_LINK_INTERFACE_H */

+ 43 - 0
components/bt/host/bluedroid/stack/include/stack/btm_api.h

@@ -825,6 +825,37 @@ typedef struct {
     INT8        tx_power;
 } tBTM_INQ_TXPWR_RESULTS;
 
+
+enum {
+    BTM_ACL_CONN_CMPL_EVT,
+    BTM_ACL_DISCONN_CMPL_EVT
+};
+typedef UINT8 tBTM_ACL_LINK_STAT_EVENT;
+
+typedef struct {
+    UINT8                   status;   /* The status of ACL connection complete */
+    UINT16                  handle;   /* The ACL connection handle */
+    BD_ADDR                 bd_addr;  /* Peer Bluetooth device address */
+} tBTM_ACL_CONN_CMPL_DATA;
+
+typedef struct {
+    UINT8                   reason;   /* The reason for ACL disconnection complete */
+    UINT16                  handle;   /* The ACL connection handle */
+    BD_ADDR                 bd_addr;  /* Peer Bluetooth device address */
+} tBTM_ACL_DISCONN_CMPL_DATA;
+
+typedef struct {
+    tBTM_ACL_LINK_STAT_EVENT       event;          /* The event reported */
+    union {
+        tBTM_ACL_CONN_CMPL_DATA     conn_cmpl;     /* The data associated with BTM_ACL_CONN_CMPL_EVT */
+        tBTM_ACL_DISCONN_CMPL_DATA  disconn_cmpl;  /* The data associated with BTM_ACL_DISCONN_CMPL_EVT */
+    } link_act;
+} tBTM_ACL_LINK_STAT_EVENT_DATA;
+
+/* Callback function for reporting ACL link related events to upper
+*/
+typedef void (tBTM_ACL_LINK_STAT_CB) (tBTM_ACL_LINK_STAT_EVENT_DATA *p_data);
+
 enum {
     BTM_BL_CONN_EVT,
     BTM_BL_DISCN_EVT,
@@ -2909,6 +2940,18 @@ tBTM_STATUS BTM_ReadLinkQuality (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb);
 tBTM_STATUS BTM_RegBusyLevelNotif (tBTM_BL_CHANGE_CB *p_cb, UINT8 *p_level,
                                    tBTM_BL_EVENT_MASK evt_mask);
 
+/*******************************************************************************
+**
+** Function         BTM_RegAclLinkStatNotif
+**
+** Description      This function is called to register a callback to receive
+**                  ACL link related events.
+**
+** Returns          BTM_SUCCESS if successfully registered, otherwise error
+**
+*******************************************************************************/
+tBTM_STATUS BTM_RegAclLinkStatNotif(tBTM_ACL_LINK_STAT_CB *p_cb);
+
 /*******************************************************************************
 **
 ** Function         BTM_AclRegisterForChanges

+ 15 - 0
components/bt/host/bluedroid/stack/include/stack/l2cap_hci_link_interface.h

@@ -0,0 +1,15 @@
+/*
+ * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef L2CAP_HCI_LINK_INTERFACE_H
+#define L2CAP_HCI_LINK_INTERFACE_H
+
+#include "bt_common.h"
+
+extern BOOLEAN l2c_link_hci_conn_comp (UINT8 status, UINT16 handle, BD_ADDR p_bda);
+extern BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason);
+
+#endif /* L2CAP_HCI_LINK_INTERFACE_H */