diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 7f5c0b3a7d..f9589a9142 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -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 diff --git a/components/bt/bluedroid/api/esp_gap_bt_api.c b/components/bt/bluedroid/api/esp_gap_bt_api.c index ebe3d5bfc0..6be94bd0f5 100644 --- a/components/bt/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/bluedroid/api/esp_gap_bt_api.c @@ -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 */ diff --git a/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h index d30767e72f..69dc0e4374 100644 --- a/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/bluedroid/api/include/api/esp_gap_bt_api.h @@ -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 diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index d16418cd3a..5b79e9b8a4 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -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, diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c index c00a2e1d5e..10610fd6f0 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c @@ -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 diff --git a/components/bt/bluedroid/bta/dm/bta_dm_co.c b/components/bt/bluedroid/bta/dm/bta_dm_co.c index dbfabc3b7a..01641ba9c7 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_co.c @@ -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 diff --git a/components/bt/bluedroid/bta/dm/bta_dm_main.c b/components/bt/bluedroid/bta/dm/bta_dm_main.c index 25977e7a49..40c41617ad 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_main.c @@ -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 */ diff --git a/components/bt/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/bluedroid/bta/dm/include/bta_dm_int.h index 62fdd13d6e..588886d302 100644 --- a/components/bt/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/bluedroid/bta/dm/include/bta_dm_int.h @@ -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); diff --git a/components/bt/bluedroid/bta/include/bta/bta_api.h b/components/bt/bluedroid/bta/include/bta/bta_api.h index fe53790939..00205addc2 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/bluedroid/bta/include/bta/bta_api.h @@ -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 diff --git a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h index 1f1f648a9f..3d49a6987b 100644 --- a/components/bt/bluedroid/bta/include/bta/bta_dm_co.h +++ b/components/bt/bluedroid/bta/include/bta/bta_dm_co.h @@ -30,6 +30,20 @@ ** 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 diff --git a/components/bt/bluedroid/btc/core/btc_dm.c b/components/bt/bluedroid/btc/core/btc_dm.c index cfd093af51..8876f8c172 100644 --- a/components/bt/bluedroid/btc/core/btc_dm.c +++ b/components/bt/bluedroid/btc/core/btc_dm.c @@ -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, ¶m, + 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, ¶m, + 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, ¶m, + 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: - case BTA_DM_SP_CFM_REQ_EVT: - case BTA_DM_SP_KEY_NOTIF_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; diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c index 1730bf8b3e..2e35eea18d 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -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; } +#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; diff --git a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h index 41674956cb..166b3e248e 100644 --- a/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h +++ b/components/bt/bluedroid/btc/profile/std/include/btc_gap_bt.h @@ -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); diff --git a/components/bt/bluedroid/common/include/common/bt_target.h b/components/bt/bluedroid/common/include/common/bt_target.h index a5bb49b6c8..202174c310 100644 --- a/components/bt/bluedroid/common/include/common/bt_target.h +++ b/components/bt/bluedroid/common/include/common/bt_target.h @@ -127,7 +127,13 @@ #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 @@ -729,7 +735,7 @@ /* 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 */ @@ -1145,6 +1151,20 @@ #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 diff --git a/components/bt/bluedroid/common/include/common/bte_appl.h b/components/bt/bluedroid/common/include/common/bte_appl.h index 4850250b8a..47a0184b7f 100644 --- a/components/bt/bluedroid/common/include/common/bte_appl.h +++ b/components/bt/bluedroid/common/include/common/bte_appl.h @@ -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 diff --git a/components/bt/bluedroid/stack/btm/btm_sec.c b/components/bt/bluedroid/stack/btm/btm_sec.c index 7b7f28ef44..0b71a3f1f5 100644 --- a/components/bt/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/bluedroid/stack/btm/btm_sec.c @@ -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); */ diff --git a/examples/bluetooth/a2dp_sink/main/main.c b/examples/bluetooth/a2dp_sink/main/main.c index 6fc554fa43..1e634dfe76 100644 --- a/examples/bluetooth/a2dp_sink/main/main.c +++ b/examples/bluetooth/a2dp_sink/main/main.c @@ -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); diff --git a/examples/bluetooth/a2dp_source/main/main.c b/examples/bluetooth/a2dp_source/main/main.c index eb63362301..31de9b9988 100644 --- a/examples/bluetooth/a2dp_source/main/main.c +++ b/examples/bluetooth/a2dp_source/main/main.c @@ -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; diff --git a/examples/bluetooth/bt_spp_acceptor/main/example_spp_acceptor_demo.c b/examples/bluetooth/bt_spp_acceptor/main/example_spp_acceptor_demo.c index 3d9d95a5f6..53513f08ee 100644 --- a/examples/bluetooth/bt_spp_acceptor/main/example_spp_acceptor_demo.c +++ b/examples/bluetooth/bt_spp_acceptor/main/example_spp_acceptor_demo.c @@ -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 } diff --git a/examples/bluetooth/bt_spp_initiator/main/example_spp_initiator_demo.c b/examples/bluetooth/bt_spp_initiator/main/example_spp_initiator_demo.c index f4d81a14f2..19e8e72391 100644 --- a/examples/bluetooth/bt_spp_initiator/main/example_spp_initiator_demo.c +++ b/examples/bluetooth/bt_spp_initiator/main/example_spp_initiator_demo.c @@ -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 } diff --git a/examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c b/examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c index 76b74552c1..deb1cfee45 100644 --- a/examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c +++ b/examples/bluetooth/bt_spp_vfs_acceptor/main/example_spp_vfs_acceptor_demo.c @@ -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 } diff --git a/examples/bluetooth/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c b/examples/bluetooth/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c index 47089bf0cb..dedb17f839 100644 --- a/examples/bluetooth/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c +++ b/examples/bluetooth/bt_spp_vfs_initiator/main/example_spp_vfs_initiator_demo.c @@ -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 }