2018-01-15 11:47:23 +00:00
/*
This example code is in the Public Domain ( or CC0 licensed , at your option . )
2017-07-24 08:22:08 +00:00
2018-01-15 11:47:23 +00:00
Unless required by applicable law or agreed to in writing , this
software is distributed on an " AS IS " BASIS , WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND , either express or implied .
*/
2017-07-24 08:22:08 +00:00
/****************************************************************************
*
* This file is for gatt_security_client demo . It can scan ble device , connect one device that needs to be encrypted .
* run gatt_security_server demo , the gatt_security_client demo will automatically connect the gatt_security_server ,
* then paring and bonding .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <stdint.h>
# include <string.h>
# include <stdbool.h>
# include <stdio.h>
# include "nvs.h"
# include "nvs_flash.h"
2017-12-07 13:48:27 +00:00
# include "esp_bt.h"
2017-07-24 08:22:08 +00:00
# include "esp_gap_ble_api.h"
# include "esp_gattc_api.h"
# include "esp_gatt_defs.h"
# include "esp_bt_main.h"
2017-08-24 11:54:41 +00:00
# include "esp_gatt_common_api.h"
2018-04-08 04:10:50 +00:00
# include "esp_log.h"
# include "freertos/FreeRTOS.h"
2017-07-24 08:22:08 +00:00
# define GATTC_TAG "SEC_GATTC_DEMO"
2018-06-25 08:04:20 +00:00
# define REMOTE_SERVICE_UUID ESP_GATT_UUID_HEART_RATE_SVC
2017-07-24 08:22:08 +00:00
# define REMOTE_NOTIFY_UUID 0x2A37
2017-08-24 06:24:04 +00:00
static esp_gattc_char_elem_t * char_elem_result = NULL ;
static esp_gattc_descr_elem_t * descr_elem_result = NULL ;
2017-07-24 08:22:08 +00:00
///Declare static functions
static void esp_gap_cb ( esp_gap_ble_cb_event_t event , esp_ble_gap_cb_param_t * param ) ;
static void esp_gattc_cb ( esp_gattc_cb_event_t event , esp_gatt_if_t gattc_if , esp_ble_gattc_cb_param_t * param ) ;
static void gattc_profile_event_handler ( esp_gattc_cb_event_t event , esp_gatt_if_t gattc_if , esp_ble_gattc_cb_param_t * param ) ;
static esp_bt_uuid_t remote_filter_service_uuid = {
. len = ESP_UUID_LEN_16 ,
. uuid = { . uuid16 = REMOTE_SERVICE_UUID , } ,
} ;
static bool connect = false ;
static bool get_service = false ;
static const char remote_device_name [ ] = " ESP_BLE_SECURITY " ;
static esp_ble_scan_params_t ble_scan_params = {
. scan_type = BLE_SCAN_TYPE_ACTIVE ,
. own_addr_type = BLE_ADDR_TYPE_RANDOM ,
. scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL ,
. scan_interval = 0x50 ,
2018-05-03 12:22:08 +00:00
. scan_window = 0x30 ,
. scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE
2017-07-24 08:22:08 +00:00
} ;
# define PROFILE_NUM 1
# define PROFILE_A_APP_ID 0
2017-08-24 06:24:04 +00:00
# define INVALID_HANDLE 0
2017-07-24 08:22:08 +00:00
struct gattc_profile_inst {
esp_gattc_cb_t gattc_cb ;
uint16_t gattc_if ;
uint16_t app_id ;
uint16_t conn_id ;
2017-08-24 06:24:04 +00:00
uint16_t service_start_handle ;
uint16_t service_end_handle ;
uint16_t notify_char_handle ;
2017-07-24 08:22:08 +00:00
esp_bd_addr_t remote_bda ;
} ;
/* One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT */
static struct gattc_profile_inst gl_profile_tab [ PROFILE_NUM ] = {
[ PROFILE_A_APP_ID ] = {
. gattc_cb = gattc_profile_event_handler ,
. gattc_if = ESP_GATT_IF_NONE , /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
} ,
} ;
2018-04-09 10:58:35 +00:00
static const char * esp_key_type_to_str ( esp_ble_key_type_t key_type )
2017-07-24 08:22:08 +00:00
{
2018-04-09 10:58:35 +00:00
const char * key_str = NULL ;
2017-07-24 08:22:08 +00:00
switch ( key_type ) {
case ESP_LE_KEY_NONE :
key_str = " ESP_LE_KEY_NONE " ;
break ;
case ESP_LE_KEY_PENC :
key_str = " ESP_LE_KEY_PENC " ;
break ;
case ESP_LE_KEY_PID :
key_str = " ESP_LE_KEY_PID " ;
break ;
case ESP_LE_KEY_PCSRK :
key_str = " ESP_LE_KEY_PCSRK " ;
break ;
case ESP_LE_KEY_PLK :
key_str = " ESP_LE_KEY_PLK " ;
break ;
case ESP_LE_KEY_LLK :
key_str = " ESP_LE_KEY_LLK " ;
break ;
case ESP_LE_KEY_LENC :
key_str = " ESP_LE_KEY_LENC " ;
break ;
case ESP_LE_KEY_LID :
key_str = " ESP_LE_KEY_LID " ;
break ;
case ESP_LE_KEY_LCSRK :
key_str = " ESP_LE_KEY_LCSRK " ;
break ;
default :
key_str = " INVALID BLE KEY TYPE " ;
break ;
}
return key_str ;
}
2018-09-27 08:22:31 +00:00
static char * esp_auth_req_to_str ( esp_ble_auth_req_t auth_req )
{
char * auth_str = NULL ;
switch ( auth_req ) {
case ESP_LE_AUTH_NO_BOND :
auth_str = " ESP_LE_AUTH_NO_BOND " ;
break ;
case ESP_LE_AUTH_BOND :
auth_str = " ESP_LE_AUTH_BOND " ;
break ;
case ESP_LE_AUTH_REQ_MITM :
auth_str = " ESP_LE_AUTH_REQ_MITM " ;
break ;
2018-10-16 09:56:07 +00:00
case ESP_LE_AUTH_REQ_BOND_MITM :
auth_str = " ESP_LE_AUTH_REQ_BOND_MITM " ;
break ;
2018-09-27 08:22:31 +00:00
case ESP_LE_AUTH_REQ_SC_ONLY :
auth_str = " ESP_LE_AUTH_REQ_SC_ONLY " ;
break ;
case ESP_LE_AUTH_REQ_SC_BOND :
auth_str = " ESP_LE_AUTH_REQ_SC_BOND " ;
break ;
case ESP_LE_AUTH_REQ_SC_MITM :
auth_str = " ESP_LE_AUTH_REQ_SC_MITM " ;
break ;
case ESP_LE_AUTH_REQ_SC_MITM_BOND :
auth_str = " ESP_LE_AUTH_REQ_SC_MITM_BOND " ;
break ;
default :
auth_str = " INVALID BLE AUTH REQ " ;
break ;
}
return auth_str ;
}
2017-07-24 08:22:08 +00:00
static void gattc_profile_event_handler ( esp_gattc_cb_event_t event , esp_gatt_if_t gattc_if , esp_ble_gattc_cb_param_t * param )
{
esp_ble_gattc_cb_param_t * p_data = ( esp_ble_gattc_cb_param_t * ) param ;
switch ( event ) {
case ESP_GATTC_REG_EVT :
ESP_LOGI ( GATTC_TAG , " REG_EVT " ) ;
esp_ble_gap_config_local_privacy ( true ) ;
break ;
case ESP_GATTC_OPEN_EVT :
if ( param - > open . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " open failed, error status = %x " , p_data - > open . status ) ;
break ;
}
ESP_LOGI ( GATTC_TAG , " open success " ) ;
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id = p_data - > open . conn_id ;
memcpy ( gl_profile_tab [ PROFILE_A_APP_ID ] . remote_bda , p_data - > open . remote_bda , sizeof ( esp_bd_addr_t ) ) ;
ESP_LOGI ( GATTC_TAG , " REMOTE BDA: " ) ;
esp_log_buffer_hex ( GATTC_TAG , gl_profile_tab [ PROFILE_A_APP_ID ] . remote_bda , sizeof ( esp_bd_addr_t ) ) ;
2017-08-24 06:24:04 +00:00
esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req ( gattc_if , p_data - > open . conn_id ) ;
2017-07-24 08:22:08 +00:00
if ( mtu_ret ) {
ESP_LOGE ( GATTC_TAG , " config MTU error, error code = %x " , mtu_ret ) ;
}
break ;
case ESP_GATTC_CFG_MTU_EVT :
if ( param - > cfg_mtu . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " config mtu failed, error status = %x " , param - > cfg_mtu . status ) ;
}
ESP_LOGI ( GATTC_TAG , " ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d " , param - > cfg_mtu . status , param - > cfg_mtu . mtu , param - > cfg_mtu . conn_id ) ;
esp_ble_gattc_search_service ( gattc_if , param - > cfg_mtu . conn_id , & remote_filter_service_uuid ) ;
break ;
case ESP_GATTC_SEARCH_RES_EVT : {
2018-03-20 11:27:50 +00:00
ESP_LOGI ( GATTC_TAG , " SEARCH RES: conn_id = %x is primary service %d " , p_data - > search_res . conn_id , p_data - > search_res . is_primary ) ;
2018-07-30 06:34:07 +00:00
ESP_LOGI ( GATTC_TAG , " start handle %d end handle %d current handle value %d " , p_data - > search_res . start_handle , p_data - > search_res . end_handle , p_data - > search_res . srvc_id . inst_id ) ;
2018-03-20 11:27:50 +00:00
if ( p_data - > search_res . srvc_id . uuid . len = = ESP_UUID_LEN_16 & & p_data - > search_res . srvc_id . uuid . uuid . uuid16 = = REMOTE_SERVICE_UUID ) {
ESP_LOGI ( GATTC_TAG , " UUID16: %x " , p_data - > search_res . srvc_id . uuid . uuid . uuid16 ) ;
2017-07-24 08:22:08 +00:00
get_service = true ;
2017-08-24 06:24:04 +00:00
gl_profile_tab [ PROFILE_A_APP_ID ] . service_start_handle = p_data - > search_res . start_handle ;
gl_profile_tab [ PROFILE_A_APP_ID ] . service_end_handle = p_data - > search_res . end_handle ;
2017-07-24 08:22:08 +00:00
}
break ;
}
case ESP_GATTC_SEARCH_CMPL_EVT :
if ( p_data - > search_cmpl . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " search service failed, error status = %x " , p_data - > search_cmpl . status ) ;
break ;
}
2018-09-28 06:12:32 +00:00
if ( p_data - > search_cmpl . searched_service_source = = ESP_GATT_SERVICE_FROM_REMOTE_DEVICE ) {
ESP_LOGI ( GATTC_TAG , " Get service information from remote device " ) ;
} else if ( p_data - > search_cmpl . searched_service_source = = ESP_GATT_SERVICE_FROM_NVS_FLASH ) {
ESP_LOGI ( GATTC_TAG , " Get service information from flash " ) ;
} else {
ESP_LOGI ( GATTC_TAG , " unknown service source " ) ;
}
2017-07-24 08:22:08 +00:00
if ( get_service ) {
2017-08-24 06:24:04 +00:00
uint16_t count = 0 ;
uint16_t offset = 0 ;
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id ,
ESP_GATT_DB_CHARACTERISTIC ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_start_handle ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_end_handle ,
INVALID_HANDLE ,
& count ) ;
if ( ret_status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " esp_ble_gattc_get_attr_count error, %d " , __LINE__ ) ;
}
if ( count > 0 ) {
2017-10-23 03:07:03 +00:00
char_elem_result = ( esp_gattc_char_elem_t * ) malloc ( sizeof ( esp_gattc_char_elem_t ) * count ) ;
2017-08-24 06:24:04 +00:00
if ( ! char_elem_result ) {
ESP_LOGE ( GATTC_TAG , " gattc no mem " ) ;
} else {
ret_status = esp_ble_gattc_get_all_char ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_start_handle ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_end_handle ,
char_elem_result ,
& count ,
offset ) ;
if ( ret_status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " esp_ble_gattc_get_all_char error, %d " , __LINE__ ) ;
}
if ( count > 0 ) {
2017-07-24 08:22:08 +00:00
2017-08-24 06:24:04 +00:00
for ( int i = 0 ; i < count ; + + i )
{
if ( char_elem_result [ i ] . uuid . len = = ESP_UUID_LEN_16 & & char_elem_result [ i ] . uuid . uuid . uuid16 = = REMOTE_NOTIFY_UUID & & ( char_elem_result [ i ] . properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY ) )
{
gl_profile_tab [ PROFILE_A_APP_ID ] . notify_char_handle = char_elem_result [ i ] . char_handle ;
esp_ble_gattc_register_for_notify ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . remote_bda ,
char_elem_result [ i ] . char_handle ) ;
break ;
}
}
}
}
free ( char_elem_result ) ;
}
2017-07-24 08:22:08 +00:00
}
break ;
case ESP_GATTC_REG_FOR_NOTIFY_EVT : {
if ( p_data - > reg_for_notify . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " reg for notify failed, error status = %x " , p_data - > reg_for_notify . status ) ;
break ;
}
2017-08-24 06:24:04 +00:00
uint16_t count = 0 ;
uint16_t offset = 0 ;
uint16_t notify_en = 1 ;
esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id ,
ESP_GATT_DB_DESCRIPTOR ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_start_handle ,
gl_profile_tab [ PROFILE_A_APP_ID ] . service_end_handle ,
p_data - > reg_for_notify . handle ,
& count ) ;
if ( ret_status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " esp_ble_gattc_get_attr_count error, %d " , __LINE__ ) ;
}
if ( count > 0 ) {
2017-10-23 03:07:03 +00:00
descr_elem_result = malloc ( sizeof ( esp_gattc_descr_elem_t ) * count ) ;
2017-08-24 06:24:04 +00:00
if ( ! descr_elem_result ) {
ESP_LOGE ( GATTC_TAG , " malloc error, gattc no mem " ) ;
} else {
ret_status = esp_ble_gattc_get_all_descr ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id ,
p_data - > reg_for_notify . handle ,
descr_elem_result ,
& count ,
offset ) ;
if ( ret_status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " esp_ble_gattc_get_all_descr error, %d " , __LINE__ ) ;
}
for ( int i = 0 ; i < count ; + + i )
{
if ( descr_elem_result [ i ] . uuid . len = = ESP_UUID_LEN_16 & & descr_elem_result [ i ] . uuid . uuid . uuid16 = = ESP_GATT_UUID_CHAR_CLIENT_CONFIG )
{
esp_ble_gattc_write_char_descr ( gattc_if ,
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id ,
descr_elem_result [ i ] . handle ,
sizeof ( notify_en ) ,
( uint8_t * ) & notify_en ,
ESP_GATT_WRITE_TYPE_RSP ,
ESP_GATT_AUTH_REQ_NONE ) ;
break ;
}
}
}
free ( descr_elem_result ) ;
}
2017-07-24 08:22:08 +00:00
break ;
}
case ESP_GATTC_NOTIFY_EVT :
ESP_LOGI ( GATTC_TAG , " ESP_GATTC_NOTIFY_EVT, receive notify value: " ) ;
esp_log_buffer_hex ( GATTC_TAG , p_data - > notify . value , p_data - > notify . value_len ) ;
break ;
case ESP_GATTC_WRITE_DESCR_EVT :
if ( p_data - > write . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " write descr failed, error status = %x " , p_data - > write . status ) ;
break ;
}
ESP_LOGI ( GATTC_TAG , " write descr success " ) ;
break ;
case ESP_GATTC_SRVC_CHG_EVT : {
esp_bd_addr_t bda ;
memcpy ( bda , p_data - > srvc_chg . remote_bda , sizeof ( esp_bd_addr_t ) ) ;
ESP_LOGI ( GATTC_TAG , " ESP_GATTC_SRVC_CHG_EVT, bd_addr: " ) ;
esp_log_buffer_hex ( GATTC_TAG , bda , sizeof ( esp_bd_addr_t ) ) ;
break ;
}
case ESP_GATTC_WRITE_CHAR_EVT :
if ( p_data - > write . status ! = ESP_GATT_OK ) {
ESP_LOGE ( GATTC_TAG , " write char failed, error status = %x " , p_data - > write . status ) ;
break ;
}
ESP_LOGI ( GATTC_TAG , " Write char success " ) ;
break ;
case ESP_GATTC_DISCONNECT_EVT :
2018-09-27 08:22:31 +00:00
ESP_LOGI ( GATTC_TAG , " ESP_GATTC_DISCONNECT_EVT, reason = 0x%x " , p_data - > disconnect . reason ) ;
2017-07-24 08:22:08 +00:00
connect = false ;
get_service = false ;
break ;
default :
break ;
}
}
static void esp_gap_cb ( esp_gap_ble_cb_event_t event , esp_ble_gap_cb_param_t * param )
{
uint8_t * adv_name = NULL ;
uint8_t adv_name_len = 0 ;
switch ( event ) {
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT :
if ( param - > local_privacy_cmpl . status ! = ESP_BT_STATUS_SUCCESS ) {
ESP_LOGE ( GATTC_TAG , " config local privacy failed, error code =%x " , param - > local_privacy_cmpl . status ) ;
break ;
}
esp_err_t scan_ret = esp_ble_gap_set_scan_params ( & ble_scan_params ) ;
if ( scan_ret ) {
ESP_LOGE ( GATTC_TAG , " set scan params error, error code = %x " , scan_ret ) ;
}
break ;
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT : {
//the unit of the duration is second
uint32_t duration = 30 ;
esp_ble_gap_start_scanning ( duration ) ;
break ;
}
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT :
//scan start complete event to indicate scan start successfully or failed
if ( param - > scan_start_cmpl . status ! = ESP_BT_STATUS_SUCCESS ) {
ESP_LOGE ( GATTC_TAG , " scan start failed, error status = %x " , param - > scan_start_cmpl . status ) ;
break ;
}
ESP_LOGI ( GATTC_TAG , " Scan start success " ) ;
break ;
2017-11-02 09:49:48 +00:00
case ESP_GAP_BLE_PASSKEY_REQ_EVT : /* passkey request event */
2018-10-17 08:55:11 +00:00
/* Call the following function to input the passkey which is displayed on the remote device */
2017-11-02 09:49:48 +00:00
//esp_ble_passkey_reply(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, true, 0x00);
ESP_LOGI ( GATTC_TAG , " ESP_GAP_BLE_PASSKEY_REQ_EVT " ) ;
break ;
2018-10-16 09:56:07 +00:00
case ESP_GAP_BLE_OOB_REQ_EVT : {
2017-11-02 09:49:48 +00:00
ESP_LOGI ( GATTC_TAG , " ESP_GAP_BLE_OOB_REQ_EVT " ) ;
2018-10-16 09:56:07 +00:00
uint8_t tk [ 16 ] = { 1 } ; //If you paired with OOB, both devices need to use the same tk
esp_ble_oob_req_reply ( param - > ble_security . ble_req . bd_addr , tk , sizeof ( tk ) ) ;
2017-11-02 09:49:48 +00:00
break ;
2018-10-16 09:56:07 +00:00
}
2017-11-02 09:49:48 +00:00
case ESP_GAP_BLE_LOCAL_IR_EVT : /* BLE local IR event */
ESP_LOGI ( GATTC_TAG , " ESP_GAP_BLE_LOCAL_IR_EVT " ) ;
break ;
case ESP_GAP_BLE_LOCAL_ER_EVT : /* BLE local ER event */
ESP_LOGI ( GATTC_TAG , " ESP_GAP_BLE_LOCAL_ER_EVT " ) ;
break ;
2017-07-24 08:22:08 +00:00
case ESP_GAP_BLE_SEC_REQ_EVT :
/* send the positive(true) security response to the peer device to accept the security request.
2018-11-21 11:41:27 +00:00
If not accept the security request , should send the security response with negative ( false ) accept value */
2017-07-24 08:22:08 +00:00
esp_ble_gap_security_rsp ( param - > ble_security . ble_req . bd_addr , true ) ;
break ;
2018-02-13 08:03:48 +00:00
case ESP_GAP_BLE_NC_REQ_EVT :
/* The app will receive this evt when the IO has DisplayYesNO capability and the peer device IO also has DisplayYesNo capability.
2018-10-17 08:55:11 +00:00
show the passkey number to the user to confirm it with the number displayed by peer device . */
esp_ble_confirm_reply ( param - > ble_security . ble_req . bd_addr , true ) ;
2018-02-13 08:03:48 +00:00
ESP_LOGI ( GATTC_TAG , " ESP_GAP_BLE_NC_REQ_EVT, the passkey Notify number:%d " , param - > ble_security . key_notif . passkey ) ;
break ;
2017-07-24 08:22:08 +00:00
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT : ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
2018-11-21 11:41:27 +00:00
///show the passkey number to the user to input it in the peer device.
2018-08-29 04:03:55 +00:00
ESP_LOGI ( GATTC_TAG , " The passkey Notify number:%06d " , param - > ble_security . key_notif . passkey ) ;
2017-07-24 08:22:08 +00:00
break ;
case ESP_GAP_BLE_KEY_EVT :
//shows the ble key info share with peer device to the user.
ESP_LOGI ( GATTC_TAG , " key type = %s " , esp_key_type_to_str ( param - > ble_security . ble_key . key_type ) ) ;
break ;
case ESP_GAP_BLE_AUTH_CMPL_EVT : {
esp_bd_addr_t bd_addr ;
memcpy ( bd_addr , param - > ble_security . auth_cmpl . bd_addr , sizeof ( esp_bd_addr_t ) ) ;
ESP_LOGI ( GATTC_TAG , " remote BD_ADDR: %08x%04x " , \
( bd_addr [ 0 ] < < 24 ) + ( bd_addr [ 1 ] < < 16 ) + ( bd_addr [ 2 ] < < 8 ) + bd_addr [ 3 ] ,
( bd_addr [ 4 ] < < 8 ) + bd_addr [ 5 ] ) ;
ESP_LOGI ( GATTC_TAG , " address type = %d " , param - > ble_security . auth_cmpl . addr_type ) ;
ESP_LOGI ( GATTC_TAG , " pair status = %s " , param - > ble_security . auth_cmpl . success ? " success " : " fail " ) ;
2018-09-27 08:22:31 +00:00
if ( ! param - > ble_security . auth_cmpl . success ) {
ESP_LOGI ( GATTC_TAG , " fail reason = 0x%x " , param - > ble_security . auth_cmpl . fail_reason ) ;
} else {
ESP_LOGI ( GATTC_TAG , " auth mode = %s " , esp_auth_req_to_str ( param - > ble_security . auth_cmpl . auth_mode ) ) ;
}
2017-07-24 08:22:08 +00:00
break ;
}
case ESP_GAP_BLE_SCAN_RESULT_EVT : {
esp_ble_gap_cb_param_t * scan_result = ( esp_ble_gap_cb_param_t * ) param ;
switch ( scan_result - > scan_rst . search_evt ) {
case ESP_GAP_SEARCH_INQ_RES_EVT :
esp_log_buffer_hex ( GATTC_TAG , scan_result - > scan_rst . bda , 6 ) ;
ESP_LOGI ( GATTC_TAG , " Searched Adv Data Len %d, Scan Response Len %d " , scan_result - > scan_rst . adv_data_len , scan_result - > scan_rst . scan_rsp_len ) ;
adv_name = esp_ble_resolve_adv_data ( scan_result - > scan_rst . ble_adv ,
ESP_BLE_AD_TYPE_NAME_CMPL , & adv_name_len ) ;
ESP_LOGI ( GATTC_TAG , " Searched Device Name Len %d " , adv_name_len ) ;
esp_log_buffer_char ( GATTC_TAG , adv_name , adv_name_len ) ;
ESP_LOGI ( GATTC_TAG , " \n " ) ;
if ( adv_name ! = NULL ) {
if ( strlen ( remote_device_name ) = = adv_name_len & & strncmp ( ( char * ) adv_name , remote_device_name , adv_name_len ) = = 0 ) {
ESP_LOGI ( GATTC_TAG , " searched device %s \n " , remote_device_name ) ;
if ( connect = = false ) {
connect = true ;
ESP_LOGI ( GATTC_TAG , " connect to the remote device. " ) ;
esp_ble_gap_stop_scanning ( ) ;
2018-03-23 03:08:03 +00:00
esp_ble_gattc_open ( gl_profile_tab [ PROFILE_A_APP_ID ] . gattc_if , scan_result - > scan_rst . bda , scan_result - > scan_rst . ble_addr_type , true ) ;
2017-07-24 08:22:08 +00:00
}
}
}
break ;
case ESP_GAP_SEARCH_INQ_CMPL_EVT :
break ;
default :
break ;
}
break ;
}
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT :
if ( param - > scan_stop_cmpl . status ! = ESP_BT_STATUS_SUCCESS ) {
ESP_LOGE ( GATTC_TAG , " Scan stop failed, error status = %x " , param - > scan_stop_cmpl . status ) ;
break ;
}
ESP_LOGI ( GATTC_TAG , " Stop scan successfully " ) ;
break ;
default :
break ;
}
}
static void esp_gattc_cb ( esp_gattc_cb_event_t event , esp_gatt_if_t gattc_if , esp_ble_gattc_cb_param_t * param )
{
ESP_LOGI ( GATTC_TAG , " EVT %d, gattc if %d " , event , gattc_if ) ;
/* If event is register event, store the gattc_if for each profile */
if ( event = = ESP_GATTC_REG_EVT ) {
if ( param - > reg . status = = ESP_GATT_OK ) {
gl_profile_tab [ param - > reg . app_id ] . gattc_if = gattc_if ;
} else {
ESP_LOGI ( GATTC_TAG , " Reg app failed, app_id %04x, status %d " ,
param - > reg . app_id ,
param - > reg . status ) ;
return ;
}
}
/* If the gattc_if equal to profile A, call profile A cb handler,
* so here call each profile ' s callback */
do {
int idx ;
for ( idx = 0 ; idx < PROFILE_NUM ; idx + + ) {
if ( gattc_if = = ESP_GATT_IF_NONE | | /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
gattc_if = = gl_profile_tab [ idx ] . gattc_if ) {
if ( gl_profile_tab [ idx ] . gattc_cb ) {
gl_profile_tab [ idx ] . gattc_cb ( event , gattc_if , param ) ;
}
}
}
} while ( 0 ) ;
}
void app_main ( )
{
// Initialize NVS.
esp_err_t ret = nvs_flash_init ( ) ;
2018-07-25 15:11:09 +00:00
if ( ret = = ESP_ERR_NVS_NO_FREE_PAGES | | ret = = ESP_ERR_NVS_NEW_VERSION_FOUND ) {
2017-07-24 08:22:08 +00:00
ESP_ERROR_CHECK ( nvs_flash_erase ( ) ) ;
ret = nvs_flash_init ( ) ;
}
ESP_ERROR_CHECK ( ret ) ;
2017-12-12 07:24:43 +00:00
ESP_ERROR_CHECK ( esp_bt_controller_mem_release ( ESP_BT_MODE_CLASSIC_BT ) ) ;
2017-07-24 08:22:08 +00:00
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT ( ) ;
ret = esp_bt_controller_init ( & bt_cfg ) ;
if ( ret ) {
2018-02-22 13:48:53 +00:00
ESP_LOGE ( GATTC_TAG , " %s initialize controller failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-07-24 08:22:08 +00:00
return ;
}
2017-12-12 07:24:43 +00:00
ret = esp_bt_controller_enable ( ESP_BT_MODE_BLE ) ;
2017-07-24 08:22:08 +00:00
if ( ret ) {
2018-02-22 13:48:53 +00:00
ESP_LOGE ( GATTC_TAG , " %s enable controller failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-07-24 08:22:08 +00:00
return ;
}
ret = esp_bluedroid_init ( ) ;
if ( ret ) {
2018-02-22 13:48:53 +00:00
ESP_LOGE ( GATTC_TAG , " %s init bluetooth failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-07-24 08:22:08 +00:00
return ;
}
ret = esp_bluedroid_enable ( ) ;
if ( ret ) {
2018-02-22 13:48:53 +00:00
ESP_LOGE ( GATTC_TAG , " %s enable bluetooth failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-07-24 08:22:08 +00:00
return ;
}
//register the callback function to the gap module
ret = esp_ble_gap_register_callback ( esp_gap_cb ) ;
if ( ret ) {
ESP_LOGE ( GATTC_TAG , " %s gap register error, error code = %x \n " , __func__ , ret ) ;
return ;
}
//register the callback function to the gattc module
ret = esp_ble_gattc_register_callback ( esp_gattc_cb ) ;
if ( ret ) {
ESP_LOGE ( GATTC_TAG , " %s gattc register error, error code = %x \n " , __func__ , ret ) ;
return ;
}
ret = esp_ble_gattc_app_register ( PROFILE_A_APP_ID ) ;
if ( ret ) {
ESP_LOGE ( GATTC_TAG , " %s gattc app register error, error code = %x \n " , __func__ , ret ) ;
}
2017-11-02 09:49:48 +00:00
2017-08-24 11:54:41 +00:00
ret = esp_ble_gatt_set_local_mtu ( 200 ) ;
if ( ret ) {
ESP_LOGE ( GATTC_TAG , " set local MTU failed, error code = %x " , ret ) ;
}
2017-07-24 08:22:08 +00:00
2017-11-02 09:49:48 +00:00
/* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
2018-10-16 09:56:07 +00:00
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND ; //bonding with peer device after authentication
2017-11-02 09:49:48 +00:00
esp_ble_io_cap_t iocap = ESP_IO_CAP_NONE ; //set the IO capability to No output No input
uint8_t key_size = 16 ; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK ;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK ;
2018-10-16 09:56:07 +00:00
uint8_t oob_support = ESP_BLE_OOB_DISABLE ;
2017-11-02 09:49:48 +00:00
esp_ble_gap_set_security_param ( ESP_BLE_SM_AUTHEN_REQ_MODE , & auth_req , sizeof ( uint8_t ) ) ;
esp_ble_gap_set_security_param ( ESP_BLE_SM_IOCAP_MODE , & iocap , sizeof ( uint8_t ) ) ;
esp_ble_gap_set_security_param ( ESP_BLE_SM_MAX_KEY_SIZE , & key_size , sizeof ( uint8_t ) ) ;
2018-10-16 09:56:07 +00:00
esp_ble_gap_set_security_param ( ESP_BLE_SM_OOB_SUPPORT , & oob_support , sizeof ( uint8_t ) ) ;
2018-11-21 11:41:27 +00:00
/* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
and the response key means which key you can distribute to the Master ;
If your BLE device act as a master , the response key means you hope which types of key of the slave should distribute to you ,
and the init key means which key you can distribute to the slave . */
2017-11-02 09:49:48 +00:00
esp_ble_gap_set_security_param ( ESP_BLE_SM_SET_INIT_KEY , & init_key , sizeof ( uint8_t ) ) ;
esp_ble_gap_set_security_param ( ESP_BLE_SM_SET_RSP_KEY , & rsp_key , sizeof ( uint8_t ) ) ;
2017-07-24 08:22:08 +00:00
}