]> granicus.if.org Git - esp-idf/commitdiff
component/bt: Add Secure Simple Pairing
authorbaohongde <baohongde@espressif.com>
Tue, 10 Jul 2018 03:18:52 +0000 (11:18 +0800)
committerbaohongde <baohongde@espressif.com>
Tue, 10 Jul 2018 03:18:52 +0000 (11:18 +0800)
22 files changed:
components/bt/Kconfig
components/bt/bluedroid/api/esp_gap_bt_api.c
components/bt/bluedroid/api/include/api/esp_gap_bt_api.h
components/bt/bluedroid/bta/dm/bta_dm_act.c
components/bt/bluedroid/bta/dm/bta_dm_api.c
components/bt/bluedroid/bta/dm/bta_dm_co.c
components/bt/bluedroid/bta/dm/bta_dm_main.c
components/bt/bluedroid/bta/dm/include/bta_dm_int.h
components/bt/bluedroid/bta/include/bta/bta_api.h
components/bt/bluedroid/bta/include/bta/bta_dm_co.h
components/bt/bluedroid/btc/core/btc_dm.c
components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c
components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h
components/bt/bluedroid/common/include/common/bt_target.h
components/bt/bluedroid/common/include/common/bte_appl.h
components/bt/bluedroid/stack/btm/btm_sec.c
examples/bluetooth/a2dp_sink/main/main.c
examples/bluetooth/a2dp_source/main/main.c
examples/bluetooth/bt_spp_acceptor/main/example_spp_acceptor_demo.c
examples/bluetooth/bt_spp_initiator/main/example_spp_initiator_demo.c
examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c
examples/bluetooth/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c

index 7f5c0b3a7dafa06a83a92ca014dfa8e9256f6a28..f9589a9142864eb1655d73420d2f4a7f7b1ebb68 100644 (file)
@@ -155,6 +155,11 @@ config CLASSIC_BT_ENABLED
     help
         For now this option needs "SMP_ENABLE" to be set to yes
 
+config BT_SSP_ENABLE
+   bool "Enable Secure Simple Pairing"
+   depends on CLASSIC_BT_ENABLED
+   default CLASSIC_BT_ENABLED
+
 config A2DP_ENABLE
     bool "A2DP"
     depends on CLASSIC_BT_ENABLED
index ebe3d5bfc0350fe78459ee94eea07e28f8bab240..6be94bd0f594e6404d7018dddfcfcc52baf0448f 100644 (file)
@@ -240,4 +240,65 @@ esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list)
     return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
 }
 
+#if (BT_SSP_INCLUDED == TRUE)
+esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
+        void *value, uint8_t len)
+{
+    btc_msg_t msg;
+    btc_gap_bt_args_t arg;
+
+    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_ACT_SET_SECURITY_PARAM;
+    arg.set_security_param.param_type = param_type;
+    arg.set_security_param.len = len;
+    arg.set_security_param.value = value;
+
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
+{
+    btc_msg_t msg;
+    btc_gap_bt_args_t arg;
+
+    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_ACT_PASSKEY_REPLY;
+    arg.passkey_reply.accept = accept;
+    arg.passkey_reply.passkey = passkey;
+    memcpy(arg.passkey_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
+{
+    btc_msg_t msg;
+    btc_gap_bt_args_t arg;
+
+    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
+        return ESP_ERR_INVALID_STATE;
+    }
+
+    msg.sig = BTC_SIG_API_CALL;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_ACT_CONFIRM_REPLY;
+    arg.confirm_reply.accept = accept;
+    memcpy(arg.confirm_reply.bda.address, bd_addr, sizeof(esp_bd_addr_t));
+    return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), btc_gap_bt_arg_deep_copy)
+            == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
+
+#endif /*(BT_SSP_INCLUDED == TRUE)*/
+
 #endif /* #if BTC_GAP_BT_INCLUDED == TRUE */
index d30767e72fedef3a7a223f5a0790267c4ccb4c17..69dc0e437433a3582525255753fa837e6c9f3a3c 100644 (file)
@@ -102,6 +102,19 @@ typedef enum {
     ESP_BT_COD_SRVC_INFORMATION              = 0x400,    /*!< Information, e.g., WEB-server, WAP-server */
 } esp_bt_cod_srvc_t;
 
+
+typedef enum {
+    ESP_BT_SP_IOCAP_MODE = 0,                            /*!< Set IO mode */
+    //ESP_BT_SP_OOB_DATA, //TODO                         /*!< Set OOB data */
+} esp_bt_sp_param_t;
+
+/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
+#define ESP_BT_IO_CAP_OUT                      0        /*!< DisplayOnly */         /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
+#define ESP_BT_IO_CAP_IO                       1        /*!< DisplayYesNo */        /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
+#define ESP_BT_IO_CAP_IN                       2        /*!< KeyboardOnly */        /* relate to BTM_IO_CAP_IN in stack/btm_api.h */
+#define ESP_BT_IO_CAP_NONE                     3        /*!< NoInputNoOutput */     /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */
+typedef uint8_t esp_bt_io_cap_t;                        /*!< combination of the io capability */
+
 /// Bits of major service class field
 #define ESP_BT_COD_SRVC_BIT_MASK              (0xffe000) /*!< Major service bit mask */
 #define ESP_BT_COD_SRVC_BIT_OFFSET            (13)       /*!< Major service bit offset */
@@ -149,6 +162,9 @@ typedef enum {
     ESP_BT_GAP_RMT_SRVCS_EVT,                       /*!< get remote services event */
     ESP_BT_GAP_RMT_SRVC_REC_EVT,                    /*!< get remote service record event */
     ESP_BT_GAP_AUTH_CMPL_EVT,                       /*!< AUTH complete event */
+    ESP_BT_GAP_CFM_REQ_EVT,                         /*!< Simple Pairing User Confirmation request. */
+    ESP_BT_GAP_KEY_NOTIF_EVT,                       /*!< Simple Pairing Passkey Notification */
+    ESP_BT_GAP_KEY_REQ_EVT,                         /*!< Simple Pairing Passkey request */
     ESP_BT_GAP_READ_RSSI_DELTA_EVT,                 /*!< read rssi event */
     ESP_BT_GAP_EVT_MAX,
 } esp_bt_gap_cb_event_t;
@@ -216,6 +232,29 @@ typedef union {
         esp_bt_status_t stat;                  /*!< authentication complete status */
         uint8_t device_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; /*!< device name */
     } auth_cmpl;                               /*!< authentication complete parameter struct */
+
+    /**
+     * @brief ESP_BT_GAP_CFM_REQ_EVT
+     */
+    struct cfm_req_param {
+        esp_bd_addr_t bda;                     /*!< remote bluetooth device address*/
+        uint32_t num_val;                      /*!< the numeric value for comparison. */
+    } cfm_req;                                 /*!< confirm request parameter struct */
+
+    /**
+     * @brief ESP_BT_GAP_KEY_NOTIF_EVT
+     */
+    struct key_notif_param {
+        esp_bd_addr_t bda;                     /*!< remote bluetooth device address*/
+        uint32_t passkey;                      /*!< the numeric value for passkey entry. */
+    } key_notif;                               /*!< passkey notif parameter struct */
+
+    /**
+     * @brief ESP_BT_GAP_KEY_REQ_EVT
+     */
+    struct key_req_param {
+        esp_bd_addr_t bda;                     /*!< remote bluetooth device address*/
+    } key_req;                                 /*!< passkey request parameter struct */
 } esp_bt_gap_cb_param_t;
 
 /**
@@ -447,6 +486,53 @@ int esp_bt_gap_get_bond_device_num(void);
 */
 esp_err_t esp_bt_gap_get_bond_device_list(int *dev_num, esp_bd_addr_t *dev_list);
 
+#if (BT_SSP_INCLUDED == TRUE)
+/**
+* @brief            Set a GAP security parameter value. Overrides the default value.
+*
+* @param[in]        param_type : the type of the param which is to be set
+* @param[in]        value  : the param value
+* @param[in]        len : the length of the param value
+*
+* @return           - ESP_OK : success
+*                   - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+*                   - other  : failed
+*
+*/
+esp_err_t esp_bt_gap_set_security_param(esp_bt_sp_param_t param_type,
+                                        void *value, uint8_t len);
+
+/**
+* @brief            Reply the key value to the peer device in the legacy connection stage.
+*
+* @param[in]        bd_addr : BD address of the peer
+* @param[in]        accept : passkey entry sucessful or declined.
+* @param[in]        passkey : passkey value, must be a 6 digit number,
+*                                     can be lead by 0.
+*
+* @return           - ESP_OK : success
+*                   - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+*                   - other  : failed
+*
+*/
+esp_err_t esp_bt_gap_ssp_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey);
+
+
+/**
+* @brief            Reply the confirm value to the peer device in the legacy connection stage.
+*
+* @param[in]        bd_addr : BD address of the peer device
+* @param[in]        accept : numbers to compare are the same or different.
+*
+* @return           - ESP_OK : success
+*                   - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
+*                   - other  : failed
+*
+*/
+esp_err_t esp_bt_gap_ssp_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
+
+#endif /*(BT_SSP_INCLUDED == TRUE)*/
+
 #ifdef __cplusplus
 }
 #endif
index d16418cd3a14bdee1d90fd1ab2fccbe4cd13d04b..5b79e9b8a4039fcf88bcad26847de7bb8ec4205b 100644 (file)
@@ -72,9 +72,9 @@ static void bta_dm_bl_change_cback (tBTM_BL_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 */
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
-#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
+#endif /* (BT_SSP_INCLUDED == TRUE) */
 
 static void bta_dm_set_eir (char *local_name);
 #if (SDP_INCLUDED == TRUE)
@@ -218,7 +218,7 @@ const tBTM_APPL_INFO bta_security = {
     &bta_dm_new_link_key_cback,
     &bta_dm_authentication_complete_cback,
     &bta_dm_bond_cancel_complete_cback,
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
     &bta_dm_sp_cback,
 #else
     NULL,
@@ -1094,6 +1094,28 @@ void bta_dm_confirm(tBTA_DM_MSG *p_data)
 }
 #endif  ///SMP_INCLUDED == TRUE
 
+/*******************************************************************************
+**
+** Function         bta_dm_key_req
+**
+** Description      Send the user passkey request reply in response to a
+**                  request from BTM
+**
+** Returns          void
+**
+*******************************************************************************/
+#if (SMP_INCLUDED == TRUE && BT_SSP_INCLUDED)
+void bta_dm_key_req(tBTA_DM_MSG *p_data)
+{
+    tBTM_STATUS res = BTM_NOT_AUTHORIZED;
+
+    if (p_data->key_req.accept == TRUE) {
+        res = BTM_SUCCESS;
+    }
+    BTM_PasskeyReqReply(res, p_data->key_req.bd_addr, p_data->key_req.passkey);
+}
+#endif  ///SMP_INCLUDED == TRUE && BT_SSP_INCLUDED
+
 /*******************************************************************************
 **
 ** Function         bta_dm_loc_oob
@@ -2814,7 +2836,7 @@ static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev
     return BTM_SUCCESS;
 }
 
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
 /*******************************************************************************
 **
 ** Function         bta_dm_sp_cback
@@ -2838,7 +2860,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
     /* TODO_SP */
     switch (event) {
     case BTM_SP_IO_REQ_EVT:
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
         /* translate auth_req */
         bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
                          &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
@@ -2850,7 +2872,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
         APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
         break;
     case BTM_SP_IO_RSP_EVT:
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
         bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
                          p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
 #endif
@@ -2865,10 +2887,10 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
         sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
 
         /* continue to next case */
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
     /* Passkey entry mode, mobile device with output capability is very
         unlikely to receive key request, so skip this event */
-    /*case BTM_SP_KEY_REQ_EVT: */
+    case BTM_SP_KEY_REQ_EVT:
     case BTM_SP_KEY_NOTIF_EVT:
 #endif
         if (BTM_SP_CFM_REQ_EVT == event) {
@@ -2916,6 +2938,27 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
             }
         }
 
+        if (BTM_SP_KEY_REQ_EVT == event) {
+            pin_evt = BTA_DM_SP_KEY_REQ_EVT;
+            /* 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_WARNING(" 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;
+            }
+        }
         bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
 
         break;
@@ -2969,7 +3012,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
     APPL_TRACE_EVENT("dm status: %d", status);
     return status;
 }
-#endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
+#endif /* (BT_SSP_INCLUDED == TRUE) */
 
 #endif  ///SMP_INCLUDED == TRUE
 
@@ -4234,7 +4277,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
     switch (event) {
     case BTM_LE_IO_REQ_EVT:
-        // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+        // #if (BT_SSP_INCLUDED == TRUE)
 
         bta_dm_co_ble_io_req(bda,
                              &p_data->io_req.io_cap,
index c00a2e1d5ec43b2f05b145b7fbdc5ef9a9f8ed8d..10610fd6f0d28f23e54e7eb4b6d0c7e5e4bdd195 100644 (file)
@@ -511,6 +511,29 @@ void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept)
     }
 }
 
+/*******************************************************************************
+**
+** Function         BTA_DmPasskeyReqReply
+**
+** Description      This function is called to provide the passkey for
+**                  Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
+**
+** Returns          void
+**
+*******************************************************************************/
+#if (BT_SSP_INCLUDED == TRUE)
+void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey)
+{
+    tBTA_DM_API_KEY_REQ    *p_msg;
+    if ((p_msg = (tBTA_DM_API_KEY_REQ *) osi_malloc(sizeof(tBTA_DM_API_KEY_REQ))) != NULL) {
+        p_msg->hdr.event = BTA_DM_API_KEY_REQ_EVT;
+        bdcpy(p_msg->bd_addr, bd_addr);
+        p_msg->accept = accept;
+        p_msg->passkey = passkey;
+        bta_sys_sendmsg(p_msg);
+    }
+}
+#endif ///BT_SSP_INCLUDED == TRUE
 /*******************************************************************************
 **
 ** Function         BTA_DmAddDevice
index dbfabc3b7a74f256ae8d8f835cfe378464b15809..01641ba9c70653759f0a87b7e7280097822eb67e 100644 (file)
@@ -44,6 +44,16 @@ tBTE_APPL_CFG bte_appl_cfg = {
 };
 #endif
 
+#if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
+#include "common/bte_appl.h"
+#include "btm_int.h"
+tBTE_BT_APPL_CFG bte_bt_appl_cfg = {
+  0,                    //Todo, Authentication requirements
+  BTM_LOCAL_IO_CAPS,
+  NULL,                 //Todo, OOB data
+};
+#endif
+
 /*******************************************************************************
 **
 ** Function         bta_dm_co_get_compress_memory
@@ -65,6 +75,34 @@ BOOLEAN bta_dm_co_get_compress_memory(tBTA_SYS_ID id, UINT8 **memory_p, UINT32 *
     return TRUE;
 }
 
+/*******************************************************************************
+**
+** Function         bta_dm_co_bt_set_io_cap
+**
+** Description      This function is used to set IO capabilities
+**
+** Parameters       bt_io_cap  - IO capabilities
+**
+** @return          - ESP_BT_STATUS_SUCCESS : success
+**                  - other  : failed
+**
+*******************************************************************************/
+esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap)
+{
+    esp_err_t ret = ESP_BT_STATUS_SUCCESS;
+#if (BT_SSP_INCLUDED == TRUE)
+    if(bt_io_cap < BTM_IO_CAP_MAX ) {
+        bte_bt_appl_cfg.bt_io_cap = bt_io_cap;
+        btm_cb.devcb.loc_io_caps = bt_io_cap;
+        ret = ESP_BT_STATUS_SUCCESS;
+    } else {
+        ret = ESP_BT_STATUS_FAIL;
+        APPL_TRACE_ERROR("%s error:Invalid io cap value.",__func__);
+    }
+#endif  ///BT_SSP_INCLUDED == TRUE
+    return ret;
+}
+
 /*******************************************************************************
 **
 ** Function         bta_dm_co_io_req
index 25977e7a4911d1becafd6128ab09f61e6c94c4f4..40c41617addbde4c747a01b9aae91b84b362098a 100644 (file)
@@ -74,12 +74,15 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
     /* simple pairing events */
 #if (SMP_INCLUDED == TRUE)
     bta_dm_confirm,                         /* 18 BTA_DM_API_CONFIRM_EVT */
+#if (BT_SSP_INCLUDED == TRUE)
+    bta_dm_key_req,                         /* 19 BTA_DM_API_KEY_REQ_EVT */
+#endif ///BT_SSP_INCLUDED == TRUE
     bta_dm_set_encryption,                  /* BTA_DM_API_SET_ENCRYPTION_EVT */
 #endif  ///SMP_INCLUDED == TRUE
 #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
-    bta_dm_loc_oob,                         /* 20 BTA_DM_API_LOC_OOB_EVT */
-    bta_dm_ci_io_req_act,                   /* 21 BTA_DM_CI_IO_REQ_EVT */
-    bta_dm_ci_rmt_oob_act,                  /* 22 BTA_DM_CI_RMT_OOB_EVT */
+    bta_dm_loc_oob,                         /* 21 BTA_DM_API_LOC_OOB_EVT */
+    bta_dm_ci_io_req_act,                   /* 22 BTA_DM_CI_IO_REQ_EVT */
+    bta_dm_ci_rmt_oob_act,                  /* 23 BTA_DM_CI_RMT_OOB_EVT */
 #endif /* BTM_OOB_INCLUDED */
 
 
@@ -119,7 +122,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
        data to HCI */
     bta_dm_ble_set_adv_config_raw,          /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */
     bta_dm_ble_set_scan_rsp,                /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
-    /* New function to allow set raw scan 
+    /* New function to allow set raw scan
        response data to HCI */
     bta_dm_ble_set_scan_rsp_raw,            /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
     bta_dm_ble_broadcast,                   /* BTA_DM_API_BLE_BROADCAST_EVT */
index 62fdd13d6e2324e89d3285881a13be4d5c9f6a3e..588886d302a4c30554723ff816150e1ced279992 100644 (file)
@@ -71,7 +71,9 @@ enum {
 #if (SMP_INCLUDED == TRUE)
     /* simple pairing events */
     BTA_DM_API_CONFIRM_EVT,
-
+#if (BT_SSP_INCLUDED == TRUE)
+    BTA_DM_API_KEY_REQ_EVT,
+#endif ///BT_SSP_INCLUDED == TRUE
     BTA_DM_API_SET_ENCRYPTION_EVT,
 #endif  ///SMP_INCLUDED == TRUE
 #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
@@ -292,6 +294,14 @@ typedef struct {
     BOOLEAN     accept;
 } tBTA_DM_API_CONFIRM;
 
+/* data type for BTA_DM_API_KEY_REQ_EVT */
+typedef struct {
+    BT_HDR      hdr;
+    BD_ADDR     bd_addr;
+    BOOLEAN     accept;
+    UINT32      passkey;
+} tBTA_DM_API_KEY_REQ;
+
 /* data type for BTA_DM_CI_IO_REQ_EVT */
 typedef struct {
     BT_HDR          hdr;
@@ -748,6 +758,7 @@ typedef union {
 
     tBTA_DM_API_LOC_OOB     loc_oob;
     tBTA_DM_API_CONFIRM     confirm;
+    tBTA_DM_API_KEY_REQ     key_req;
     tBTA_DM_CI_IO_REQ       ci_io_req;
     tBTA_DM_CI_RMT_OOB      ci_rmt_oob;
 
@@ -1225,6 +1236,7 @@ extern void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data);
 #endif
 extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
 extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
+extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
 #if (BTM_OOB_INCLUDED == TRUE)
 extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
 extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data);
index fe53790939e37c8635ca0060e2c190cbbd70e082..00205addc23939c692e2967f302e43fe4dcac11c 100644 (file)
@@ -636,6 +636,8 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK;
 #define BTA_DM_LE_FEATURES_READ         27      /* Cotroller specific LE features are read */
 #define BTA_DM_ENER_INFO_READ           28      /* Energy info read */
 #define BTA_DM_BLE_DEV_UNPAIRED_EVT     29      /* BLE unpair event */
+#define BTA_DM_SP_KEY_REQ_EVT           30      /* Simple Pairing Passkey request */
+
 typedef UINT8 tBTA_DM_SEC_EVT;
 
 /* Structure associated with BTA_DM_ENABLE_EVT */
@@ -868,6 +870,13 @@ typedef struct {
     tBTA_AUTH_REQ   rmt_io_caps;    /* IO Capabilities of remote device */
 } tBTA_DM_SP_CFM_REQ;
 
+/* Structure associated with tBTA_DM_SP_KEY_REQ */
+typedef struct {
+    BD_ADDR         bd_addr;        /* peer address */
+    DEV_CLASS       dev_class;      /* peer CoD */
+    BD_NAME         bd_name;        /* peer device name */
+} tBTA_DM_SP_KEY_REQ;
+
 enum {
     BTA_SP_KEY_STARTED,         /* passkey entry started */
     BTA_SP_KEY_ENTERED,         /* passkey digit entered */
@@ -907,23 +916,24 @@ typedef struct {
 
 /* Union of all security callback structures */
 typedef union {
-    tBTA_DM_ENABLE      enable;         /* BTA enabled */
-    tBTA_DM_PIN_REQ     pin_req;        /* PIN request. */
-    tBTA_DM_AUTH_CMPL   auth_cmpl;      /* Authentication complete indication. */
-    tBTA_DM_AUTHORIZE   authorize;      /* Authorization request. */
-    tBTA_DM_LINK_UP     link_up;       /* ACL connection down event */
-    tBTA_DM_LINK_DOWN   link_down;       /* ACL connection down event */
-    tBTA_DM_BUSY_LEVEL  busy_level;     /* System busy level */
-    tBTA_DM_SP_CFM_REQ  cfm_req;        /* user confirm request */
-    tBTA_DM_SP_KEY_NOTIF key_notif;     /* passkey notification */
-    tBTA_DM_SP_RMT_OOB  rmt_oob;        /* remote oob */
-    tBTA_DM_BOND_CANCEL_CMPL bond_cancel_cmpl; /* Bond Cancel Complete indication */
-    tBTA_DM_SP_KEY_PRESS   key_press;   /* key press notification event */
-    tBTA_DM_ROLE_CHG     role_chg;       /* role change event */
-    tBTA_DM_BLE_SEC_REQ  ble_req;        /* BLE SMP related request */
-    tBTA_DM_BLE_KEY      ble_key;        /* BLE SMP keys used when pairing */
-    tBTA_BLE_LOCAL_ID_KEYS  ble_id_keys;  /* IR event */
-    BT_OCTET16              ble_er;       /* ER event data */
+    tBTA_DM_ENABLE              enable;             /* BTA enabled */
+    tBTA_DM_PIN_REQ             pin_req;            /* PIN request. */
+    tBTA_DM_AUTH_CMPL           auth_cmpl;          /* Authentication complete indication. */
+    tBTA_DM_AUTHORIZE           authorize;          /* Authorization request. */
+    tBTA_DM_LINK_UP             link_up;            /* ACL connection down event */
+    tBTA_DM_LINK_DOWN           link_down;          /* ACL connection down 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 */
+    tBTA_DM_SP_KEY_NOTIF        key_notif;          /* passkey notification */
+    tBTA_DM_SP_RMT_OOB          rmt_oob;            /* remote oob */
+    tBTA_DM_BOND_CANCEL_CMPL    bond_cancel_cmpl;   /* Bond Cancel Complete indication */
+    tBTA_DM_SP_KEY_PRESS        key_press;          /* key press notification event */
+    tBTA_DM_ROLE_CHG            role_chg;           /* role change event */
+    tBTA_DM_BLE_SEC_REQ         ble_req;            /* BLE SMP related request */
+    tBTA_DM_BLE_KEY             ble_key;            /* BLE SMP keys used when pairing */
+    tBTA_BLE_LOCAL_ID_KEYS      ble_id_keys;        /* IR event */
+    BT_OCTET16                  ble_er;             /* ER event data */
 } tBTA_DM_SEC;
 
 /* Security callback */
@@ -1602,6 +1612,18 @@ extern void BTA_DmLocalOob(void);
 *******************************************************************************/
 extern void BTA_DmConfirm(BD_ADDR bd_addr, BOOLEAN accept);
 
+/*******************************************************************************
+**
+** Function         BTA_DmPasskeyReqReply
+**
+** Description      This function is called to provide the passkey for
+**                  Simple Pairing in response to BTA_DM_SP_KEY_REQ_EVT
+**
+** Returns          void
+**
+*******************************************************************************/
+extern void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey);
+
 /*******************************************************************************
 **
 ** Function         BTA_DmAddDevice
index 1f1f648a9fe0bf496f420bc88caa89916e3ae41b..3d49a6987b4f0fc6e6452c8415efe8eb38cc437f 100644 (file)
 **  Function Declarations
 *****************************************************************************/
 
+/*******************************************************************************
+**
+** Function         bta_dm_co_bt_set_io_cap
+**
+** Description      This function is used to set IO capabilities
+**
+** Parameters       bt_io_cap  - IO capabilities
+**
+** @return          - ESP_BT_STATUS_SUCCESS : success
+**                  - other  : failed
+**
+*******************************************************************************/
+extern esp_err_t bta_dm_co_bt_set_io_cap(UINT8 bt_io_cap);
+
 /*******************************************************************************
 **
 ** Function         bta_dm_co_io_req
index cfd093af51063b7f8f822aaa84215e0dd4f5f811..8876f8c1728ed3bf3d992d14e4bf1a54a075bc4c 100644 (file)
@@ -344,7 +344,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
         case HCI_ERR_INSUFFCIENT_SECURITY:
         case HCI_ERR_PEER_USER:
         case HCI_ERR_UNSPECIFIED:
-            BTC_TRACE_DEBUG(" %s() Authentication fail reason %d",
+            BTC_TRACE_ERROR(" %s() Authentication fail reason %d",
                       __FUNCTION__, p_auth_cmpl->fail_reason);
             /* if autopair attempts are more than 1, or not attempted */
             status =  BT_STATUS_AUTH_FAILURE;
@@ -353,7 +353,7 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
             status =  BT_STATUS_FAIL;
         }
     }
-#if (BTC_GAP_BT_INCLUDED == TRUE)
+#if (BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE)
     esp_bt_gap_cb_param_t param;
     bt_status_t ret;
     btc_msg_t msg;
@@ -368,13 +368,80 @@ static void btc_dm_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
                                sizeof(esp_bt_gap_cb_param_t), NULL);
 
     if (ret != BT_STATUS_SUCCESS) {
-        BTC_TRACE_DEBUG("%s btc_transfer_context failed\n", __func__);
+        BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
     }
 
-#endif /* BTC_GAP_BT_INCLUDED == TRUE */
+#endif /// BTC_GAP_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE
     (void) status;
 }
 
+#if (BT_SSP_INCLUDED == TRUE)
+static void btc_dm_sp_cfm_req_evt(tBTA_DM_SP_CFM_REQ *p_cfm_req)
+{
+    if (p_cfm_req->just_works) {
+        // just work, not show to users.
+        BTA_DmConfirm(p_cfm_req->bd_addr, true);
+        return;
+    }
+
+    esp_bt_gap_cb_param_t param;
+    bt_status_t ret;
+    btc_msg_t msg;
+    msg.sig = BTC_SIG_API_CB;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_CFM_REQ_EVT;
+    param.cfm_req.num_val = p_cfm_req->num_val;
+    memcpy(param.cfm_req.bda, p_cfm_req->bd_addr, ESP_BD_ADDR_LEN);
+
+    ret = btc_transfer_context(&msg, &param,
+                               sizeof(esp_bt_gap_cb_param_t), NULL);
+
+    if (ret != BT_STATUS_SUCCESS) {
+        BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+    }
+
+}
+
+static void btc_dm_sp_key_notif_evt(tBTA_DM_SP_KEY_NOTIF *p_key_notif)
+{
+    esp_bt_gap_cb_param_t param;
+    bt_status_t ret;
+    btc_msg_t msg;
+    msg.sig = BTC_SIG_API_CB;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_KEY_NOTIF_EVT;
+    param.key_notif.passkey = p_key_notif->passkey;
+    memcpy(param.key_notif.bda, p_key_notif->bd_addr, ESP_BD_ADDR_LEN);
+
+    ret = btc_transfer_context(&msg, &param,
+                               sizeof(esp_bt_gap_cb_param_t), NULL);
+
+    if (ret != BT_STATUS_SUCCESS) {
+        BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+    }
+
+}
+
+static void btc_dm_sp_key_req_evt(tBTA_DM_SP_KEY_REQ *p_key_req)
+{
+    esp_bt_gap_cb_param_t param;
+    bt_status_t ret;
+    btc_msg_t msg;
+    msg.sig = BTC_SIG_API_CB;
+    msg.pid = BTC_PID_GAP_BT;
+    msg.act = BTC_GAP_BT_KEY_REQ_EVT;
+    memcpy(param.key_req.bda, p_key_req->bd_addr, ESP_BD_ADDR_LEN);
+
+    ret = btc_transfer_context(&msg, &param,
+                               sizeof(esp_bt_gap_cb_param_t), NULL);
+
+    if (ret != BT_STATUS_SUCCESS) {
+        BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
+    }
+}
+#endif ///BT_SSP_INCLUDED == TRUE
+
+
 tBTA_SERVICE_MASK btc_get_enabled_services_mask(void)
 {
     return btc_enabled_services;
@@ -484,14 +551,32 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
         break;
     }
     case BTA_DM_PIN_REQ_EVT:
+        BTC_TRACE_DEBUG("BTA_DM_PIN_REQ_EVT");
         break;
     case BTA_DM_AUTH_CMPL_EVT:
         btc_dm_auth_cmpl_evt(&p_data->auth_cmpl);
         break;
     case BTA_DM_BOND_CANCEL_CMPL_EVT:
+        BTC_TRACE_DEBUG("BTA_DM_BOND_CANCEL_CMPL_EVT");
+        break;
+#if (BT_SSP_INCLUDED == TRUE)
     case BTA_DM_SP_CFM_REQ_EVT:
+        btc_dm_sp_cfm_req_evt(&p_data->cfm_req);
+        break;
     case BTA_DM_SP_KEY_NOTIF_EVT:
+        btc_dm_sp_key_notif_evt(&p_data->key_notif);
+        break;
+    case BTA_DM_SP_KEY_REQ_EVT:
+        btc_dm_sp_key_req_evt(&p_data->key_req);
         break;
+    case BTA_DM_SP_RMT_OOB_EVT:
+        BTC_TRACE_DEBUG("BTA_DM_SP_RMT_OOB_EVT");
+        break;
+    case BTA_DM_SP_KEYPRESS_EVT:
+        BTC_TRACE_DEBUG("BTA_DM_SP_KEYPRESS_EVT");
+        break;
+#endif ///BT_SSP_INCLUDED == TRUE
+
     case BTA_DM_DEV_UNPAIRED_EVT: {
 #if (SMP_INCLUDED == TRUE)
         bt_bdaddr_t bd_addr;
@@ -688,8 +773,6 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
 
     case BTA_DM_AUTHORIZE_EVT:
     case BTA_DM_SIG_STRENGTH_EVT:
-    case BTA_DM_SP_RMT_OOB_EVT:
-    case BTA_DM_SP_KEYPRESS_EVT:
     case BTA_DM_ROLE_CHG_EVT:
         BTC_TRACE_DEBUG( "btc_dm_sec_cback : unhandled event (%d)\n", msg->act );
         break;
index 1730bf8b3e1f0db7240dd4fec41693d0779341f0..2e35eea18d6212e1974e415e684cd2c0dadb97a7 100644 (file)
@@ -23,6 +23,7 @@
 #include "btc/btc_manage.h"
 #include "btc/btc_util.h"
 #include "osi/allocator.h"
+#include "bta/bta_dm_co.h"
 
 #if (BTC_GAP_BT_INCLUDED == TRUE)
 
@@ -635,7 +636,7 @@ static void btc_gap_bt_read_rssi_delta(btc_gap_bt_args_t *arg)
     BTA_DmBleReadRSSI(arg->read_rssi_delta.bda.address, BTA_TRANSPORT_BR_EDR, btc_gap_bt_read_rssi_delta_cmpl_callback);
 }
 
-esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
+static esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
 {
     BD_ADDR bd_addr;
     memcpy(bd_addr, arg->rm_bond_device.bda.address, sizeof(BD_ADDR));
@@ -645,6 +646,103 @@ esp_err_t btc_gap_bt_remove_bond_device(btc_gap_bt_args_t *arg)
     return ESP_BT_STATUS_FAIL;
 }
 
+#if (BT_SSP_INCLUDED == TRUE)
+static esp_err_t btc_gap_bt_set_security_param(btc_gap_bt_args_t *arg)
+{
+    esp_err_t ret;
+    switch(arg->set_security_param.param_type) {
+    case ESP_BT_SP_IOCAP_MODE:{
+        uint8_t iocap = 0;
+        uint8_t *p = arg->set_security_param.value;
+        STREAM_TO_UINT8(iocap, p);
+        ret = bta_dm_co_bt_set_io_cap(iocap);
+        break;
+    }
+    default:
+        ret = ESP_BT_STATUS_FAIL;
+        break;
+    }
+    return ret;
+}
+
+static void btc_gap_bt_ssp_passkey_reply(btc_gap_bt_args_t *arg)
+{
+    BTA_DmPasskeyReqReply(arg->passkey_reply.accept, arg->passkey_reply.bda.address, arg->passkey_reply.passkey);
+}
+
+static void btc_gap_bt_ssp_confirm(btc_gap_bt_args_t *arg)
+{
+    BTA_DmConfirm(arg->confirm_reply.bda.address, arg->confirm_reply.accept);
+
+}
+
+#endif ///BT_SSP_INCLUDED == TRUE
+
+void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+    switch (msg->act) {
+    case BTC_GAP_BT_ACT_SET_SCAN_MODE:
+    case BTC_GAP_BT_ACT_START_DISCOVERY:
+    case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
+    case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
+    case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
+    case BTC_GAP_BT_ACT_SET_COD:
+    case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
+    case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
+        break;
+#if (BT_SSP_INCLUDED == TRUE)
+    case BTC_GAP_BT_ACT_PASSKEY_REPLY:
+    case BTC_GAP_BT_ACT_CONFIRM_REPLY:
+        break;
+    case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
+        btc_gap_bt_args_t *src = (btc_gap_bt_args_t *)p_src;
+        btc_gap_bt_args_t  *dst = (btc_gap_bt_args_t *) p_dest;
+        uint8_t length = 0;
+        if (src->set_security_param.value) {
+            length = dst->set_security_param.len;
+            dst->set_security_param.value = osi_malloc(length);
+            if (dst->set_security_param.value != NULL) {
+                memcpy(dst->set_security_param.value, src->set_security_param.value, length);
+            } else {
+                BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
+            }
+        }
+        break;
+    }
+#endif ///BT_SSP_INCLUDED == TRUE
+    default:
+        BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+        break;
+    }
+}
+
+void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
+{
+    btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
+    switch (msg->act) {
+    case BTC_GAP_BT_ACT_SET_SCAN_MODE:
+    case BTC_GAP_BT_ACT_START_DISCOVERY:
+    case BTC_GAP_BT_ACT_CANCEL_DISCOVERY:
+    case BTC_GAP_BT_ACT_GET_REMOTE_SERVICES:
+    case BTC_GAP_BT_ACT_GET_REMOTE_SERVICE_RECORD:
+    case BTC_GAP_BT_ACT_SET_COD:
+    case BTC_GAP_BT_ACT_READ_RSSI_DELTA:
+    case BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE:
+        break;
+#if (BT_SSP_INCLUDED == TRUE)
+    case BTC_GAP_BT_ACT_PASSKEY_REPLY:
+    case BTC_GAP_BT_ACT_CONFIRM_REPLY:
+        break;
+    case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:
+        osi_free(arg->set_security_param.value);
+        break;
+#endif ///BT_SSP_INCLUDED == TRUE
+    default:
+        BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
+        break;
+    }
+}
+
 void btc_gap_bt_call_handler(btc_msg_t *msg)
 {
     btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg;
@@ -682,10 +780,25 @@ void btc_gap_bt_call_handler(btc_msg_t *msg)
         btc_gap_bt_remove_bond_device(msg->arg);
         break;
     }
-    default:
+#if (BT_SSP_INCLUDED == TRUE)
+    case BTC_GAP_BT_ACT_SET_SECURITY_PARAM:{
+        btc_gap_bt_set_security_param(arg);
         break;
     }
+    case BTC_GAP_BT_ACT_PASSKEY_REPLY:{
+        btc_gap_bt_ssp_passkey_reply(arg);
+        break;
+    }
+    case BTC_GAP_BT_ACT_CONFIRM_REPLY:{
+        btc_gap_bt_ssp_confirm(arg);
+        break;
+    }
+#endif ///BT_SSP_INCLUDED == TRUE
 
+    default:
+        break;
+    }
+    btc_gap_bt_arg_deep_free(msg);
     return;
 }
 
@@ -714,7 +827,12 @@ void btc_gap_bt_cb_deep_free(btc_msg_t *msg)
         osi_free(((tBTA_DM_SEARCH_PARAM *) (msg->arg)) ->p_data);
         break;
     case BTC_GAP_BT_READ_RSSI_DELTA_EVT:
+#if (BT_SSP_INCLUDED == TRUE)
     case BTC_GAP_BT_AUTH_CMPL_EVT:
+    case BTC_GAP_BT_CFM_REQ_EVT:
+    case BTC_GAP_BT_KEY_NOTIF_EVT:
+    case BTC_GAP_BT_KEY_REQ_EVT:
+#endif ///BT_SSP_INCLUDED == TRUE
         break;
     default:
         BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
@@ -741,10 +859,24 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg)
         btc_gap_bt_cb_to_app(ESP_BT_GAP_READ_RSSI_DELTA_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
         break;
     }
+#if (BT_SSP_INCLUDED == TRUE)
     case BTC_GAP_BT_AUTH_CMPL_EVT:{
         btc_gap_bt_cb_to_app(ESP_BT_GAP_AUTH_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
         break;
     }
+    case BTC_GAP_BT_CFM_REQ_EVT:{
+        btc_gap_bt_cb_to_app(ESP_BT_GAP_CFM_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+        break;
+    }
+    case BTC_GAP_BT_KEY_NOTIF_EVT:{
+        btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_NOTIF_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+        break;
+    }
+    case BTC_GAP_BT_KEY_REQ_EVT:{
+        btc_gap_bt_cb_to_app(ESP_BT_GAP_KEY_REQ_EVT, (esp_bt_gap_cb_param_t *)msg->arg);
+        break;
+    }
+#endif ///BT_SSP_INCLUDED == TRUE
     default:
         BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act);
         break;
index 41674956cb6b657cf7f07f034369af0078c75d2d..166b3e248ea1f1bad9260eb45d4ed8ce25145e8e 100644 (file)
@@ -26,8 +26,11 @@ typedef enum {
     BTC_GAP_BT_SEARCH_DEVICES_EVT = 0,
     BTC_GAP_BT_SEARCH_SERVICES_EVT,
     BTC_GAP_BT_SEARCH_SERVICE_RECORD_EVT,
-    BTC_GAP_BT_READ_RSSI_DELTA_EVT,
     BTC_GAP_BT_AUTH_CMPL_EVT,
+    BTC_GAP_BT_CFM_REQ_EVT,
+    BTC_GAP_BT_KEY_NOTIF_EVT,
+    BTC_GAP_BT_KEY_REQ_EVT,
+    BTC_GAP_BT_READ_RSSI_DELTA_EVT,
 }btc_gap_bt_evt_t;
 
 typedef enum {
@@ -39,6 +42,9 @@ typedef enum {
     BTC_GAP_BT_ACT_SET_COD,
     BTC_GAP_BT_ACT_READ_RSSI_DELTA,
     BTC_GAP_BT_ACT_REMOVE_BOND_DEVICE,
+    BTC_GAP_BT_ACT_SET_SECURITY_PARAM,
+    BTC_GAP_BT_ACT_PASSKEY_REPLY,
+    BTC_GAP_BT_ACT_CONFIRM_REPLY,
 } btc_gap_bt_act_t;
 
 /* btc_bt_gap_args_t */
@@ -79,11 +85,31 @@ typedef union {
     struct rm_bond_device_args {
        bt_bdaddr_t bda;
     } rm_bond_device;
+
+    // BTC_GAP_BT_ACT_SET_SECURITY_PARAM
+    struct set_sec_param_args {
+        esp_bt_sp_param_t param_type;
+        uint8_t len;
+        uint8_t *value;
+    } set_security_param;
+
+    // BTC_GAP_BT_ACT_PASSKEY_REPLY
+    struct passkey_reply_args {
+       bt_bdaddr_t bda;
+       bool accept;
+       uint32_t passkey;
+    } passkey_reply;
+
+    // BTC_GAP_BT_ACT_CONFIRM_REPLY
+    struct confirm_reply_args {
+       bt_bdaddr_t bda;
+       bool accept;
+    } confirm_reply;
 } btc_gap_bt_args_t;
 
 void btc_gap_bt_call_handler(btc_msg_t *msg);
 void btc_gap_bt_cb_handler(btc_msg_t *msg);
-
+void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
 void btc_gap_bt_busy_level_updated(uint8_t bl_flags);
 
 esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod);
index a5bb49b6c8ef677e9681d246ecf015b0f18d3054..202174c310947f959affe855393cd9f521de758b 100644 (file)
 #else
 #define SMP_INCLUDED              FALSE
 #define BLE_PRIVACY_SPT           FALSE
-#endif  /* CONFIG_GATTC_ENABLE */
+#endif  /* CONFIG_SMP_ENABLE */
+
+#if (CONFIG_BT_SSP_ENABLE)
+#define BT_SSP_INCLUDED              TRUE
+#else
+#define BT_SSP_INCLUDED              FALSE
+#endif  /* CONFIG_BT_SSP_ENABLE */
 
 #if (CONFIG_BT_ACL_CONNECTIONS)
 #define MAX_ACL_CONNECTIONS  CONFIG_BT_ACL_CONNECTIONS
 
 /* Include Out-of-Band implementation for Simple Pairing */
 #ifndef BTM_OOB_INCLUDED
-#define BTM_OOB_INCLUDED                TRUE
+#define BTM_OOB_INCLUDED                FALSE//TRUE
 #endif
 
 /* TRUE to include Sniff Subrating */
 #define SMP_LINK_TOUT_MIN               2
 #endif
 #endif
+
+/******************************************************************************
+**
+** BT_SSP
+**
+******************************************************************************/
+#ifndef BT_SSP_INCLUDED
+#define BT_SSP_INCLUDED         FALSE
+#endif
+
+#if BT_SSP_INCLUDED == TRUE && CLASSIC_BT_INCLUDED == FALSE
+#error "Can't have SSP without CLASSIC BT"
+#endif
+
 /******************************************************************************
 **
 ** SDP
index 4850250b8aceb7eeac9debcfa897be9ee6b9dfaa..47a0184b7fb0ad2c4d21525431512552453c3d98 100644 (file)
@@ -32,6 +32,18 @@ typedef struct {
     UINT8   ble_resp_key;
     UINT8   ble_max_key_size;
 #endif
+
 } tBTE_APPL_CFG;
 
 extern tBTE_APPL_CFG bte_appl_cfg;
+
+
+typedef struct {
+#if ((CLASSIC_BT_INCLUDED == TRUE) && (BT_SSP_INCLUDED == TRUE))
+    UINT8   bt_auth_req;
+    UINT8   bt_io_cap;
+    UINT8   *bt_oob_auth_data;
+#endif
+} tBTE_BT_APPL_CFG;
+
+extern tBTE_BT_APPL_CFG bte_bt_appl_cfg;
\ No newline at end of file
index 7b7f28ef441654778d93981f21c36039eb499bf6..0b71a3f1f54233559c90edd8d121fa74f4609738 100644 (file)
@@ -1524,7 +1524,7 @@ void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr)
 **                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
 **
 *******************************************************************************/
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
 void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
 {
 #if (BT_USE_TRACES == TRUE && SMP_INCLUDED == TRUE)
@@ -1572,7 +1572,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
         btsnd_hcic_user_passkey_reply (bd_addr, passkey);
     }
 }
-#endif  ///BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE
+#endif  ///BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE
 
 /*******************************************************************************
 **
@@ -1588,7 +1588,7 @@ void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
 **                  type - notification type
 **
 *******************************************************************************/
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
+#if (BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
 void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
 {
     /* This API only make sense between PASSKEY_REQ and SP complete */
@@ -1596,7 +1596,7 @@ void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
         btsnd_hcic_send_keypress_notif (bd_addr, type);
     }
 }
-#endif  ///BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE
+#endif  ///BT_SSP_INCLUDED == TRUE && SMP_INCLUDED == TRUE
 
 #if BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE
 /*******************************************************************************
@@ -3504,7 +3504,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
             evt_data.cfm_req.just_works = TRUE;
 
             /* process user confirm req in association with the auth_req param */
-#if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
+// #if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
             if ( (p_dev_rec->rmt_io_caps == BTM_IO_CAP_IO)
                     &&  (btm_cb.devcb.loc_io_caps == BTM_IO_CAP_IO)
                     &&  ((p_dev_rec->rmt_auth_req & BTM_AUTH_SP_YES) || (btm_cb.devcb.loc_auth_req & BTM_AUTH_SP_YES)) ) {
@@ -3512,7 +3512,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
                    -> use authenticated link key */
                 evt_data.cfm_req.just_works = FALSE;
             }
-#endif
+// #endif
             BTM_TRACE_DEBUG ("btm_proc_sp_req_evt()  just_works:%d, io loc:%d, rmt:%d, auth loc:%d, rmt:%d\n",
                              evt_data.cfm_req.just_works, btm_cb.devcb.loc_io_caps, p_dev_rec->rmt_io_caps,
                              btm_cb.devcb.loc_auth_req, p_dev_rec->rmt_auth_req);
@@ -3532,7 +3532,7 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
             break;
 
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
         case BTM_SP_KEY_REQ_EVT:
             /* HCI_USER_PASSKEY_REQUEST_EVT */
             btm_sec_change_pairing_state (BTM_PAIR_STATE_KEY_ENTRY);
@@ -3555,14 +3555,13 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
             BTM_TRACE_DEBUG ("calling BTM_ConfirmReqReply with status: %d\n", status);
             BTM_ConfirmReqReply (status, p_bda);
         }
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
         else if (event == BTM_SP_KEY_REQ_EVT) {
             BTM_PasskeyReqReply(status, p_bda, 0);
         }
 #endif
         return;
     }
-
     /* Something bad. we can only fail this connection */
     btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
 
@@ -3579,7 +3578,8 @@ void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
             btm_sec_disconnect (p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE);
         }
     }
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+
+#if (BT_SSP_INCLUDED == TRUE)
     else {
         btsnd_hcic_user_passkey_neg_reply(p_bda);
     }
@@ -4849,7 +4849,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
         /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
         break;
 
-#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
+#if (BT_SSP_INCLUDED == TRUE)
     case BTM_PAIR_STATE_KEY_ENTRY:
         btsnd_hcic_user_passkey_neg_reply(p_cb->pairing_bda);
         /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
index 6fc554fa430977212cce4476b420892a88a72be2..1e634dfe7658831ed4077a54361a7a39f5e96271 100644 (file)
@@ -59,7 +59,7 @@ void app_main()
         .mode = I2S_MODE_MASTER | I2S_MODE_TX,                                  // Only TX
 #endif
         .sample_rate = 44100,
-        .bits_per_sample = 16,                                              
+        .bits_per_sample = 16,
         .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
         .communication_format = I2S_COMM_FORMAT_I2S_MSB,
         .dma_buf_count = 6,
@@ -113,9 +113,45 @@ void app_main()
 
     /* Bluetooth device name, connection mode and profile set up */
     bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
-}
 
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
+}
 
+void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
+{
+    switch (event) {
+#if (BT_SPP_INCLUDED)
+    case ESP_BT_GAP_AUTH_CMPL_EVT:{
+        if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
+            ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name);
+            esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
+        } else {
+            ESP_LOGE(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+        }
+        break;
+    }
+    case ESP_BT_GAP_CFM_REQ_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+        esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+        break;
+    case ESP_BT_GAP_KEY_NOTIF_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+        break;
+    case ESP_BT_GAP_KEY_REQ_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+        break;
+#endif ///BT_SPP_INCLUDED
+    default: {
+        ESP_LOGI(BT_AV_TAG, "event: %d", event);
+        break;
+    }
+    }
+    return;
+}
 static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
 {
     ESP_LOGD(BT_AV_TAG, "%s evt %d", __func__, event);
@@ -125,6 +161,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
         char *dev_name = "ESP_SPEAKER";
         esp_bt_dev_set_device_name(dev_name);
 
+        esp_bt_gap_register_callback(bt_app_gap_cb);
         /* initialize A2DP sink */
         esp_a2d_register_callback(&bt_app_a2d_cb);
         esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb);
index eb633623014f656c43482dd4b424ad42c1444ccf..31de9b99887c73c1e20a1d32c9a45d918f21f6e0 100644 (file)
@@ -133,6 +133,12 @@ void app_main()
 
     /* Bluetooth device name, connection mode and profile set up */
     bt_app_work_dispatch(bt_av_hdl_stack_evt, BT_APP_EVT_STACK_UP, NULL, 0, NULL);
+
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
 }
 
 static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len)
@@ -245,15 +251,27 @@ void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
     case ESP_BT_GAP_RMT_SRVCS_EVT:
     case ESP_BT_GAP_RMT_SRVC_REC_EVT:
         break;
+#if (BT_SPP_INCLUDED)
     case ESP_BT_GAP_AUTH_CMPL_EVT:{
         if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
             ESP_LOGI(BT_AV_TAG, "authentication success: %s", param->auth_cmpl.device_name);
             esp_log_buffer_hex(BT_AV_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
         } else {
-            ESP_LOGI(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+            ESP_LOGE(BT_AV_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
         }
+        break;
     }
-
+    case ESP_BT_GAP_CFM_REQ_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+        esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+        break;
+    case ESP_BT_GAP_KEY_NOTIF_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+        break;
+    case ESP_BT_GAP_KEY_REQ_EVT:
+        ESP_LOGI(BT_AV_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+        break;
+#endif ///BT_SPP_INCLUDED
     default: {
         ESP_LOGI(BT_AV_TAG, "event: %d", event);
         break;
index 3d9d95a5f6fb2f48ff11388a1cc4ca8275294934..53513f08ee48ef492206ff61b3f9446c2c4043bf 100644 (file)
@@ -36,7 +36,7 @@ static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
 static struct timeval time_new, time_old;
 static long data_num = 0;
 
-static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
+static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
 
 static void print_speed(void)
@@ -103,7 +103,37 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
     }
 }
 
-
+void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
+{
+    switch (event) {
+#if (BT_SPP_INCLUDED)
+    case ESP_BT_GAP_AUTH_CMPL_EVT:{
+        if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
+            ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
+            esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
+        } else {
+            ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+        }
+        break;
+    }
+    case ESP_BT_GAP_CFM_REQ_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+        esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+        break;
+    case ESP_BT_GAP_KEY_NOTIF_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+        break;
+    case ESP_BT_GAP_KEY_REQ_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+        break;
+#endif ///BT_SPP_INCLUDED
+    default: {
+        ESP_LOGI(SPP_TAG, "event: %d", event);
+        break;
+    }
+    }
+    return;
+}
 
 void app_main()
 {
@@ -136,6 +166,11 @@ void app_main()
         return;
     }
 
+    if ((ret = esp_bt_gap_register_callback(esp_bt_gap_cb)) != ESP_OK) {
+        ESP_LOGE(SPP_TAG, "%s gap register failed: %s\n", __func__, esp_err_to_name(ret));
+        return;
+    }
+
     if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
         return;
@@ -145,5 +180,11 @@ void app_main()
         ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
         return;
     }
+
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
 }
 
index f4d81a14f21922b320f8c4127d25f73539003051..19e8e72391b174e23f590144035397e9c637d0d8 100644 (file)
@@ -36,7 +36,7 @@ static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
 static struct timeval time_new, time_old;
 static long data_num = 0;
 
-static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
+static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
 
 static esp_bd_addr_t peer_bd_addr;
@@ -190,6 +190,27 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
         case ESP_BT_GAP_RMT_SRVC_REC_EVT:
             ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT");
             break;
+#if (BT_SPP_INCLUDED)
+        case ESP_BT_GAP_AUTH_CMPL_EVT:{
+            if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
+                ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
+                esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
+            } else {
+                ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+            }
+            break;
+        }
+        case ESP_BT_GAP_CFM_REQ_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+            esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+            break;
+        case ESP_BT_GAP_KEY_NOTIF_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+            break;
+        case ESP_BT_GAP_KEY_REQ_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+            break;
+#endif ///BT_SPP_INCLUDED
         default:
             break;
     }
@@ -244,5 +265,11 @@ void app_main()
         ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
         return;
     }
+
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
 }
 
index 76b74552c1048ff910fef83d1a688d98de27d3be..deb1cfee453c5edc5fed6a43c056284aab9764b2 100644 (file)
@@ -42,7 +42,7 @@
 
 static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_VFS;
 
-static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
+static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
 
 #define SPP_DATA_LEN 100
@@ -105,6 +105,38 @@ static void esp_spp_stack_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param
     spp_task_work_dispatch((spp_task_cb_t)esp_spp_cb, event, param, sizeof(esp_spp_cb_param_t), NULL);
 }
 
+void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
+{
+    switch (event) {
+#if (BT_SPP_INCLUDED)
+    case ESP_BT_GAP_AUTH_CMPL_EVT:{
+        if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
+            ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
+            esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
+        } else {
+            ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+        }
+        break;
+    }
+    case ESP_BT_GAP_CFM_REQ_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+        esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+        break;
+    case ESP_BT_GAP_KEY_NOTIF_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+        break;
+    case ESP_BT_GAP_KEY_REQ_EVT:
+        ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+        break;
+#endif ///BT_SPP_INCLUDED
+    default: {
+        ESP_LOGI(SPP_TAG, "event: %d", event);
+        break;
+    }
+    }
+    return;
+}
+
 void app_main()
 {
     esp_err_t ret = nvs_flash_init();
@@ -135,6 +167,11 @@ void app_main()
         return;
     }
 
+    if (esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) {
+        ESP_LOGE(SPP_TAG, "%s gap register failed: %s\n", __func__, esp_err_to_name(ret));
+        return;
+    }
+
     if (esp_spp_register_callback(esp_spp_stack_cb) != ESP_OK) {
         ESP_LOGE(SPP_TAG, "%s spp register failed", __func__);
         return;
@@ -146,5 +183,11 @@ void app_main()
         ESP_LOGE(SPP_TAG, "%s spp init failed", __func__);
         return;
     }
+
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
 }
 
index 47089bf0cb365720b926b6c766405438f5f37b4f..dedb17f839da4433b8a1ddceb97e4bfebd38a018 100644 (file)
@@ -41,7 +41,7 @@
 
 static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_VFS;
 
-static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
+static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE;
 static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER;
 
 static esp_bd_addr_t peer_bd_addr;
@@ -170,6 +170,27 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
         case ESP_BT_GAP_RMT_SRVC_REC_EVT:
             ESP_LOGI(SPP_TAG, "ESP_BT_GAP_RMT_SRVC_REC_EVT");
             break;
+#if (BT_SPP_INCLUDED)
+        case ESP_BT_GAP_AUTH_CMPL_EVT:{
+            if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
+                ESP_LOGI(SPP_TAG, "authentication success: %s", param->auth_cmpl.device_name);
+                esp_log_buffer_hex(SPP_TAG, param->auth_cmpl.bda, ESP_BD_ADDR_LEN);
+            } else {
+                ESP_LOGE(SPP_TAG, "authentication failed, status:%d", param->auth_cmpl.stat);
+            }
+            break;
+        }
+        case ESP_BT_GAP_CFM_REQ_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
+            esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+            break;
+        case ESP_BT_GAP_KEY_NOTIF_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
+            break;
+        case ESP_BT_GAP_KEY_REQ_EVT:
+            ESP_LOGI(SPP_TAG, "ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+            break;
+#endif ///BT_SPP_INCLUDED
         default:
             break;
     }
@@ -230,5 +251,11 @@ void app_main()
         ESP_LOGE(SPP_TAG, "%s spp init failed", __func__);
         return;
     }
+
+#if (BT_SPP_INCLUDED)
+    esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
+    esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+    esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
+#endif ///BT_SPP_INCLUDED
 }