2018-01-15 19:47:23 +08:00
/*
2024-04-30 14:38:33 +08:00
* SPDX - FileCopyrightText : 2021 - 2024 Espressif Systems ( Shanghai ) CO LTD
2021-12-06 14:59:55 +08:00
*
* SPDX - License - Identifier : Unlicense OR CC0 - 1.0
*/
2016-11-18 00:30:35 +08:00
2017-07-20 21:33:03 +08:00
/****************************************************************************
*
2018-10-24 08:54:07 +05:30
* This demo showcases BLE GATT server . It can send adv data , be connected by client .
2017-07-20 21:33:03 +08:00
* Run the gatt_client demo , the client demo will automatically connect to the gatt_server demo .
2018-10-24 08:54:07 +05:30
* Client demo will enable gatt_server ' s notify after connection . The two devices will then exchange
2017-07-20 21:33:03 +08:00
* data .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-18 00:30:35 +08:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2022-12-08 11:03:04 +08:00
# include <inttypes.h>
2016-11-18 00:30:35 +08:00
# include "freertos/FreeRTOS.h"
# include "freertos/task.h"
# include "freertos/event_groups.h"
# include "esp_system.h"
# include "esp_log.h"
# include "nvs_flash.h"
2017-12-07 21:48:27 +08:00
# include "esp_bt.h"
2016-11-18 00:30:35 +08:00
# include "esp_gap_ble_api.h"
# include "esp_gatts_api.h"
# include "esp_bt_defs.h"
# include "esp_bt_main.h"
2017-08-24 19:54:41 +08:00
# include "esp_gatt_common_api.h"
2016-11-18 00:30:35 +08:00
2017-01-19 11:49:59 +08:00
# include "sdkconfig.h"
2017-01-03 15:53:06 +08:00
# define GATTS_TAG "GATTS_DEMO"
2017-07-20 21:33:03 +08:00
///Declare the static function
2016-12-19 17:12:43 +08:00
static void gatts_profile_a_event_handler ( esp_gatts_cb_event_t event , esp_gatt_if_t gatts_if , esp_ble_gatts_cb_param_t * param ) ;
static void gatts_profile_b_event_handler ( esp_gatts_cb_event_t event , esp_gatt_if_t gatts_if , esp_ble_gatts_cb_param_t * param ) ;
2016-12-11 16:36:47 +08:00
2016-12-19 17:12:43 +08:00
# define GATTS_SERVICE_UUID_TEST_A 0x00FF
# define GATTS_CHAR_UUID_TEST_A 0xFF01
# define GATTS_DESCR_UUID_TEST_A 0x3333
# define GATTS_NUM_HANDLE_TEST_A 4
# define GATTS_SERVICE_UUID_TEST_B 0x00EE
# define GATTS_CHAR_UUID_TEST_B 0xEE01
# define GATTS_DESCR_UUID_TEST_B 0x2222
# define GATTS_NUM_HANDLE_TEST_B 4
2016-11-25 02:10:15 +08:00
2016-12-19 17:12:43 +08:00
# define TEST_DEVICE_NAME "ESP_GATTS_DEMO"
2016-11-25 02:10:15 +08:00
# define TEST_MANUFACTURER_DATA_LEN 17
2016-12-23 11:28:47 -05:00
2017-02-10 11:02:10 +08:00
# define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
2016-12-23 11:28:47 -05:00
2017-05-31 17:20:29 +08:00
# define PREPARE_BUF_MAX_SIZE 1024
2018-10-24 08:54:07 +05:30
static uint8_t char1_str [ ] = { 0x11 , 0x22 , 0x33 } ;
static esp_gatt_char_prop_t a_property = 0 ;
static esp_gatt_char_prop_t b_property = 0 ;
2017-07-20 21:33:03 +08:00
2018-10-24 08:54:07 +05:30
static esp_attr_value_t gatts_demo_char1_val =
2016-12-23 11:28:47 -05:00
{
2017-02-10 11:02:10 +08:00
. attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX ,
. attr_len = sizeof ( char1_str ) ,
. attr_value = char1_str ,
2016-12-23 11:28:47 -05:00
} ;
2017-07-20 21:33:03 +08:00
static uint8_t adv_config_done = 0 ;
# define adv_config_flag (1 << 0)
# define scan_rsp_config_flag (1 << 1)
2017-01-19 11:49:59 +08:00
# ifdef CONFIG_SET_RAW_ADV_DATA
2017-02-10 11:02:10 +08:00
static uint8_t raw_adv_data [ ] = {
2024-08-09 21:26:19 +08:00
/* Flags */
0x02 , ESP_BLE_AD_TYPE_FLAG , 0x06 , // Length 2, Data Type ESP_BLE_AD_TYPE_FLAG, Data 1 (LE General Discoverable Mode, BR/EDR Not Supported)
/* TX Power Level */
0x02 , ESP_BLE_AD_TYPE_TX_PWR , 0xEB , // Length 2, Data Type ESP_BLE_AD_TYPE_TX_PWR, Data 2 (-21)
/* Complete 16-bit Service UUIDs */
0x03 , ESP_BLE_AD_TYPE_16SRV_CMPL , 0xAB , 0xCD // Length 3, Data Type ESP_BLE_AD_TYPE_16SRV_CMPL, Data 3 (UUID)
2017-02-10 11:02:10 +08:00
} ;
2024-08-09 21:26:19 +08:00
static uint8_t raw_scan_rsp_data [ ] = {
/* Complete Local Name */
0x0F , ESP_BLE_AD_TYPE_NAME_CMPL , ' E ' , ' S ' , ' P ' , ' _ ' , ' G ' , ' A ' , ' T ' , ' T ' , ' S ' , ' _ ' , ' D ' , ' E ' , ' M ' , ' O ' // Length 15, Data Type ESP_BLE_AD_TYPE_NAME_CMPL, Data (ESP_GATTS_DEMO)
2017-02-10 11:02:10 +08:00
} ;
2017-01-19 11:49:59 +08:00
# else
2017-07-20 21:33:03 +08:00
static uint8_t adv_service_uuid128 [ 32 ] = {
2016-11-25 02:10:15 +08:00
/* LSB <--------------------------------------------------------------------------------> MSB */
//first uuid, 16bit, [12],[13] is the value
2017-07-20 21:33:03 +08:00
0xfb , 0x34 , 0x9b , 0x5f , 0x80 , 0x00 , 0x00 , 0x80 , 0x00 , 0x10 , 0x00 , 0x00 , 0xEE , 0x00 , 0x00 , 0x00 ,
2016-11-25 02:10:15 +08:00
//second uuid, 32bit, [12], [13], [14], [15] is the value
2017-07-20 21:33:03 +08:00
0xfb , 0x34 , 0x9b , 0x5f , 0x80 , 0x00 , 0x00 , 0x80 , 0x00 , 0x10 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 ,
2016-11-25 02:10:15 +08:00
} ;
2016-11-18 00:30:35 +08:00
2017-07-20 21:33:03 +08:00
// The length of adv data must be less than 31 bytes
2016-12-07 20:04:44 +08:00
//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56};
2017-07-20 21:33:03 +08:00
//adv data
static esp_ble_adv_data_t adv_data = {
2016-11-25 02:10:15 +08:00
. set_scan_rsp = false ,
. include_name = true ,
2019-04-26 17:24:34 +08:00
. include_txpower = false ,
2018-09-29 16:22:24 +08:00
. min_interval = 0x0006 , //slave connection min interval, Time = min_interval * 1.25 msec
. max_interval = 0x0010 , //slave connection max interval, Time = max_interval * 1.25 msec
2016-11-25 02:10:15 +08:00
. appearance = 0x00 ,
. manufacturer_len = 0 , //TEST_MANUFACTURER_DATA_LEN,
. p_manufacturer_data = NULL , //&test_manufacturer[0],
. service_data_len = 0 ,
. p_service_data = NULL ,
2018-10-24 08:54:07 +05:30
. service_uuid_len = sizeof ( adv_service_uuid128 ) ,
2017-07-20 21:33:03 +08:00
. p_service_uuid = adv_service_uuid128 ,
2017-01-05 15:24:09 +08:00
. flag = ( ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT ) ,
2016-11-18 00:30:35 +08:00
} ;
2017-07-20 21:33:03 +08:00
// scan response data
static esp_ble_adv_data_t scan_rsp_data = {
. set_scan_rsp = true ,
. include_name = true ,
. include_txpower = true ,
2019-04-26 17:24:34 +08:00
//.min_interval = 0x0006,
//.max_interval = 0x0010,
2017-07-20 21:33:03 +08:00
. appearance = 0x00 ,
. manufacturer_len = 0 , //TEST_MANUFACTURER_DATA_LEN,
. p_manufacturer_data = NULL , //&test_manufacturer[0],
. service_data_len = 0 ,
. p_service_data = NULL ,
2018-10-24 08:54:07 +05:30
. service_uuid_len = sizeof ( adv_service_uuid128 ) ,
2017-07-20 21:33:03 +08:00
. p_service_uuid = adv_service_uuid128 ,
. flag = ( ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT ) ,
} ;
2017-01-19 11:49:59 +08:00
# endif /* CONFIG_SET_RAW_ADV_DATA */
2016-11-18 00:30:35 +08:00
2017-07-20 21:33:03 +08:00
static esp_ble_adv_params_t adv_params = {
2016-11-25 02:10:15 +08:00
. adv_int_min = 0x20 ,
. adv_int_max = 0x40 ,
. adv_type = ADV_TYPE_IND ,
. own_addr_type = BLE_ADDR_TYPE_PUBLIC ,
//.peer_addr =
//.peer_addr_type =
. channel_map = ADV_CHNL_ALL ,
. adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY ,
2016-11-18 00:30:35 +08:00
} ;
2016-12-11 16:36:47 +08:00
# define PROFILE_NUM 2
# define PROFILE_A_APP_ID 0
# define PROFILE_B_APP_ID 1
struct gatts_profile_inst {
esp_gatts_cb_t gatts_cb ;
uint16_t gatts_if ;
2016-11-25 02:10:15 +08:00
uint16_t app_id ;
uint16_t conn_id ;
uint16_t service_handle ;
esp_gatt_srvc_id_t service_id ;
uint16_t char_handle ;
esp_bt_uuid_t char_uuid ;
esp_gatt_perm_t perm ;
esp_gatt_char_prop_t property ;
uint16_t descr_handle ;
esp_bt_uuid_t descr_uuid ;
2016-11-18 00:30:35 +08:00
} ;
2016-12-11 16:36:47 +08:00
/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
static struct gatts_profile_inst gl_profile_tab [ PROFILE_NUM ] = {
[ PROFILE_A_APP_ID ] = {
. gatts_cb = gatts_profile_a_event_handler ,
. gatts_if = ESP_GATT_IF_NONE , /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
} ,
[ PROFILE_B_APP_ID ] = {
2016-12-19 17:12:43 +08:00
. gatts_cb = gatts_profile_b_event_handler , /* This demo does not implement, similar as profile A */
2016-12-11 16:36:47 +08:00
. gatts_if = ESP_GATT_IF_NONE , /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
} ,
} ;
2017-05-31 17:20:29 +08:00
typedef struct {
uint8_t * prepare_buf ;
int prepare_len ;
} prepare_type_env_t ;
static prepare_type_env_t a_prepare_write_env ;
static prepare_type_env_t b_prepare_write_env ;
void example_write_event_env ( esp_gatt_if_t gatts_if , prepare_type_env_t * prepare_write_env , esp_ble_gatts_cb_param_t * param ) ;
void example_exec_write_event_env ( prepare_type_env_t * prepare_write_env , esp_ble_gatts_cb_param_t * param ) ;
2016-12-11 16:36:47 +08:00
static void gap_event_handler ( esp_gap_ble_cb_event_t event , esp_ble_gap_cb_param_t * param )
2016-11-18 00:30:35 +08:00
{
2016-11-25 02:10:15 +08:00
switch ( event ) {
2017-07-20 21:33:03 +08:00
# ifdef CONFIG_SET_RAW_ADV_DATA
2017-01-19 11:49:59 +08:00
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT :
2017-07-20 21:33:03 +08:00
adv_config_done & = ( ~ adv_config_flag ) ;
if ( adv_config_done = = 0 ) {
esp_ble_gap_start_advertising ( & adv_params ) ;
}
2017-01-19 11:49:59 +08:00
break ;
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT :
2017-07-20 21:33:03 +08:00
adv_config_done & = ( ~ scan_rsp_config_flag ) ;
if ( adv_config_done = = 0 ) {
esp_ble_gap_start_advertising ( & adv_params ) ;
}
2017-01-19 11:49:59 +08:00
break ;
2017-07-20 21:33:03 +08:00
# else
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT :
adv_config_done & = ( ~ adv_config_flag ) ;
if ( adv_config_done = = 0 ) {
esp_ble_gap_start_advertising ( & adv_params ) ;
}
break ;
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT :
adv_config_done & = ( ~ scan_rsp_config_flag ) ;
if ( adv_config_done = = 0 ) {
esp_ble_gap_start_advertising ( & adv_params ) ;
}
break ;
# endif
2017-02-23 17:32:46 +08:00
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT :
//advertising start complete event to indicate advertising start successfully or failed
if ( param - > adv_start_cmpl . status ! = ESP_BT_STATUS_SUCCESS ) {
ESP_LOGE ( GATTS_TAG , " Advertising start failed \n " ) ;
}
2017-05-07 20:01:45 +08:00
break ;
2017-03-29 16:51:21 +08:00
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT :
if ( param - > adv_stop_cmpl . status ! = ESP_BT_STATUS_SUCCESS ) {
ESP_LOGE ( GATTS_TAG , " Advertising stop failed \n " ) ;
2018-10-24 08:54:07 +05:30
} else {
2017-03-29 16:51:21 +08:00
ESP_LOGI ( GATTS_TAG , " Stop adv successfully \n " ) ;
}
2017-02-23 17:32:46 +08:00
break ;
2017-06-02 01:09:23 -04:00
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT :
2024-08-05 20:19:13 +08:00
ESP_LOGI ( GATTS_TAG , " update connection params status = %d, conn_int = %d, latency = %d, timeout = %d " ,
2017-06-19 03:22:25 -04:00
param - > update_conn_params . status ,
2017-06-02 01:09:23 -04:00
param - > update_conn_params . conn_int ,
param - > update_conn_params . latency ,
param - > update_conn_params . timeout ) ;
break ;
2024-04-30 14:38:33 +08:00
case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT :
ESP_LOGI ( GATTS_TAG , " packet length updated: rx = %d, tx = %d, status = %d " ,
param - > pkt_data_length_cmpl . params . rx_len ,
param - > pkt_data_length_cmpl . params . tx_len ,
param - > pkt_data_length_cmpl . status ) ;
break ;
2016-11-25 02:10:15 +08:00
default :
break ;
}
2016-11-18 00:30:35 +08:00
}
2017-05-31 17:20:29 +08:00
void example_write_event_env ( esp_gatt_if_t gatts_if , prepare_type_env_t * prepare_write_env , esp_ble_gatts_cb_param_t * param ) {
esp_gatt_status_t status = ESP_GATT_OK ;
if ( param - > write . need_rsp ) {
2023-12-21 10:51:31 +08:00
if ( param - > write . is_prep ) {
if ( param - > write . offset > PREPARE_BUF_MAX_SIZE ) {
status = ESP_GATT_INVALID_OFFSET ;
} else if ( ( param - > write . offset + param - > write . len ) > PREPARE_BUF_MAX_SIZE ) {
status = ESP_GATT_INVALID_ATTR_LEN ;
}
if ( status = = ESP_GATT_OK & & prepare_write_env - > prepare_buf = = NULL ) {
2017-05-31 17:20:29 +08:00
prepare_write_env - > prepare_buf = ( uint8_t * ) malloc ( PREPARE_BUF_MAX_SIZE * sizeof ( uint8_t ) ) ;
prepare_write_env - > prepare_len = 0 ;
if ( prepare_write_env - > prepare_buf = = NULL ) {
2017-07-20 21:33:03 +08:00
ESP_LOGE ( GATTS_TAG , " Gatt_server prep no mem \n " ) ;
2017-05-31 17:20:29 +08:00
status = ESP_GATT_NO_RESOURCES ;
}
}
esp_gatt_rsp_t * gatt_rsp = ( esp_gatt_rsp_t * ) malloc ( sizeof ( esp_gatt_rsp_t ) ) ;
gatt_rsp - > attr_value . len = param - > write . len ;
gatt_rsp - > attr_value . handle = param - > write . handle ;
gatt_rsp - > attr_value . offset = param - > write . offset ;
gatt_rsp - > attr_value . auth_req = ESP_GATT_AUTH_REQ_NONE ;
memcpy ( gatt_rsp - > attr_value . value , param - > write . value , param - > write . len ) ;
esp_err_t response_err = esp_ble_gatts_send_response ( gatts_if , param - > write . conn_id , param - > write . trans_id , status , gatt_rsp ) ;
if ( response_err ! = ESP_OK ) {
2017-07-20 21:33:03 +08:00
ESP_LOGE ( GATTS_TAG , " Send response error \n " ) ;
2017-05-31 17:20:29 +08:00
}
free ( gatt_rsp ) ;
if ( status ! = ESP_GATT_OK ) {
return ;
}
memcpy ( prepare_write_env - > prepare_buf + param - > write . offset ,
param - > write . value ,
param - > write . len ) ;
prepare_write_env - > prepare_len + = param - > write . len ;
} else {
esp_ble_gatts_send_response ( gatts_if , param - > write . conn_id , param - > write . trans_id , status , NULL ) ;
}
}
}
void example_exec_write_event_env ( prepare_type_env_t * prepare_write_env , esp_ble_gatts_cb_param_t * param ) {
if ( param - > exec_write . exec_write_flag = = ESP_GATT_PREP_WRITE_EXEC ) {
2017-06-11 21:59:49 +08:00
esp_log_buffer_hex ( GATTS_TAG , prepare_write_env - > prepare_buf , prepare_write_env - > prepare_len ) ;
2017-05-31 17:20:29 +08:00
} else {
ESP_LOGI ( GATTS_TAG , " ESP_GATT_PREP_WRITE_CANCEL " ) ;
}
if ( prepare_write_env - > prepare_buf ) {
free ( prepare_write_env - > prepare_buf ) ;
prepare_write_env - > prepare_buf = NULL ;
}
prepare_write_env - > prepare_len = 0 ;
}
2016-12-11 16:36:47 +08:00
static void gatts_profile_a_event_handler ( esp_gatts_cb_event_t event , esp_gatt_if_t gatts_if , esp_ble_gatts_cb_param_t * param ) {
2016-11-25 02:10:15 +08:00
switch ( event ) {
case ESP_GATTS_REG_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " REGISTER_APP_EVT, status %d, app_id %d \n " , param - > reg . status , param - > reg . app_id ) ;
2016-12-11 16:36:47 +08:00
gl_profile_tab [ PROFILE_A_APP_ID ] . service_id . is_primary = true ;
gl_profile_tab [ PROFILE_A_APP_ID ] . service_id . id . inst_id = 0x00 ;
gl_profile_tab [ PROFILE_A_APP_ID ] . service_id . id . uuid . len = ESP_UUID_LEN_16 ;
2016-12-19 17:12:43 +08:00
gl_profile_tab [ PROFILE_A_APP_ID ] . service_id . id . uuid . uuid . uuid16 = GATTS_SERVICE_UUID_TEST_A ;
2017-10-27 14:07:47 +08:00
esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name ( TEST_DEVICE_NAME ) ;
if ( set_dev_name_ret ) {
ESP_LOGE ( GATTS_TAG , " set device name failed, error code = %x " , set_dev_name_ret ) ;
}
2017-01-19 11:49:59 +08:00
# ifdef CONFIG_SET_RAW_ADV_DATA
2017-07-20 21:33:03 +08:00
esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw ( raw_adv_data , sizeof ( raw_adv_data ) ) ;
if ( raw_adv_ret ) {
ESP_LOGE ( GATTS_TAG , " config raw adv data failed, error code = %x " , raw_adv_ret ) ;
}
adv_config_done | = adv_config_flag ;
esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw ( raw_scan_rsp_data , sizeof ( raw_scan_rsp_data ) ) ;
if ( raw_scan_ret ) {
ESP_LOGE ( GATTS_TAG , " config raw scan rsp data failed, error code = %x " , raw_scan_ret ) ;
}
adv_config_done | = scan_rsp_config_flag ;
2017-01-19 11:49:59 +08:00
# else
2017-07-20 21:33:03 +08:00
//config adv data
esp_err_t ret = esp_ble_gap_config_adv_data ( & adv_data ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " config adv data failed, error code = %x " , ret ) ;
}
adv_config_done | = adv_config_flag ;
//config scan response data
ret = esp_ble_gap_config_adv_data ( & scan_rsp_data ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " config scan response data failed, error code = %x " , ret ) ;
}
adv_config_done | = scan_rsp_config_flag ;
2017-01-19 11:49:59 +08:00
# endif
2016-12-19 17:12:43 +08:00
esp_ble_gatts_create_service ( gatts_if , & gl_profile_tab [ PROFILE_A_APP_ID ] . service_id , GATTS_NUM_HANDLE_TEST_A ) ;
break ;
case ESP_GATTS_READ_EVT : {
2022-12-08 11:03:04 +08:00
ESP_LOGI ( GATTS_TAG , " GATT_READ_EVT, conn_id %d, trans_id % " PRIu32 " , handle %d \n " , param - > read . conn_id , param - > read . trans_id , param - > read . handle ) ;
2016-12-19 17:12:43 +08:00
esp_gatt_rsp_t rsp ;
memset ( & rsp , 0 , sizeof ( esp_gatt_rsp_t ) ) ;
rsp . attr_value . handle = param - > read . handle ;
rsp . attr_value . len = 4 ;
rsp . attr_value . value [ 0 ] = 0xde ;
rsp . attr_value . value [ 1 ] = 0xed ;
rsp . attr_value . value [ 2 ] = 0xbe ;
rsp . attr_value . value [ 3 ] = 0xef ;
esp_ble_gatts_send_response ( gatts_if , param - > read . conn_id , param - > read . trans_id ,
ESP_GATT_OK , & rsp ) ;
break ;
}
case ESP_GATTS_WRITE_EVT : {
2022-12-08 11:03:04 +08:00
ESP_LOGI ( GATTS_TAG , " GATT_WRITE_EVT, conn_id %d, trans_id % " PRIu32 " , handle %d " , param - > write . conn_id , param - > write . trans_id , param - > write . handle ) ;
2017-07-20 21:33:03 +08:00
if ( ! param - > write . is_prep ) {
ESP_LOGI ( GATTS_TAG , " GATT_WRITE_EVT, value len %d, value : " , param - > write . len ) ;
esp_log_buffer_hex ( GATTS_TAG , param - > write . value , param - > write . len ) ;
if ( gl_profile_tab [ PROFILE_A_APP_ID ] . descr_handle = = param - > write . handle & & param - > write . len = = 2 ) {
uint16_t descr_value = param - > write . value [ 1 ] < < 8 | param - > write . value [ 0 ] ;
if ( descr_value = = 0x0001 ) {
if ( a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY ) {
ESP_LOGI ( GATTS_TAG , " notify enable " ) ;
uint8_t notify_data [ 15 ] ;
for ( int i = 0 ; i < sizeof ( notify_data ) ; + + i )
{
notify_data [ i ] = i % 0xff ;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate ( gatts_if , param - > write . conn_id , gl_profile_tab [ PROFILE_A_APP_ID ] . char_handle ,
sizeof ( notify_data ) , notify_data , false ) ;
}
} else if ( descr_value = = 0x0002 ) {
if ( a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE ) {
ESP_LOGI ( GATTS_TAG , " indicate enable " ) ;
uint8_t indicate_data [ 15 ] ;
for ( int i = 0 ; i < sizeof ( indicate_data ) ; + + i )
{
indicate_data [ i ] = i % 0xff ;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate ( gatts_if , param - > write . conn_id , gl_profile_tab [ PROFILE_A_APP_ID ] . char_handle ,
sizeof ( indicate_data ) , indicate_data , true ) ;
}
}
else if ( descr_value = = 0x0000 ) {
ESP_LOGI ( GATTS_TAG , " notify/indicate disable " ) ;
} else {
ESP_LOGE ( GATTS_TAG , " unknown descr value " ) ;
esp_log_buffer_hex ( GATTS_TAG , param - > write . value , param - > write . len ) ;
}
}
}
2017-05-31 17:20:29 +08:00
example_write_event_env ( gatts_if , & a_prepare_write_env , param ) ;
2016-12-19 17:12:43 +08:00
break ;
}
case ESP_GATTS_EXEC_WRITE_EVT :
2017-05-31 17:20:29 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_EXEC_WRITE_EVT " ) ;
esp_ble_gatts_send_response ( gatts_if , param - > write . conn_id , param - > write . trans_id , ESP_GATT_OK , NULL ) ;
example_exec_write_event_env ( & a_prepare_write_env , param ) ;
break ;
2016-12-19 17:12:43 +08:00
case ESP_GATTS_MTU_EVT :
2017-07-20 21:33:03 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_MTU_EVT, MTU %d " , param - > mtu . mtu ) ;
break ;
2016-12-19 17:12:43 +08:00
case ESP_GATTS_UNREG_EVT :
break ;
case ESP_GATTS_CREATE_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " CREATE_SERVICE_EVT, status %d, service_handle %d \n " , param - > create . status , param - > create . service_handle ) ;
2016-12-19 17:12:43 +08:00
gl_profile_tab [ PROFILE_A_APP_ID ] . service_handle = param - > create . service_handle ;
gl_profile_tab [ PROFILE_A_APP_ID ] . char_uuid . len = ESP_UUID_LEN_16 ;
gl_profile_tab [ PROFILE_A_APP_ID ] . char_uuid . uuid . uuid16 = GATTS_CHAR_UUID_TEST_A ;
esp_ble_gatts_start_service ( gl_profile_tab [ PROFILE_A_APP_ID ] . service_handle ) ;
2017-07-20 21:33:03 +08:00
a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY ;
esp_err_t add_char_ret = esp_ble_gatts_add_char ( gl_profile_tab [ PROFILE_A_APP_ID ] . service_handle , & gl_profile_tab [ PROFILE_A_APP_ID ] . char_uuid ,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE ,
a_property ,
& gatts_demo_char1_val , NULL ) ;
if ( add_char_ret ) {
ESP_LOGE ( GATTS_TAG , " add char failed, error code =%x " , add_char_ret ) ;
}
2016-12-19 17:12:43 +08:00
break ;
case ESP_GATTS_ADD_INCL_SRVC_EVT :
break ;
2016-12-23 11:28:47 -05:00
case ESP_GATTS_ADD_CHAR_EVT : {
2017-02-10 11:02:10 +08:00
uint16_t length = 0 ;
2016-12-23 11:28:47 -05:00
const uint8_t * prf_char ;
2016-12-19 17:12:43 +08:00
2016-12-23 11:28:47 -05:00
ESP_LOGI ( GATTS_TAG , " ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d \n " ,
param - > add_char . status , param - > add_char . attr_handle , param - > add_char . service_handle ) ;
2016-12-19 17:12:43 +08:00
gl_profile_tab [ PROFILE_A_APP_ID ] . char_handle = param - > add_char . attr_handle ;
gl_profile_tab [ PROFILE_A_APP_ID ] . descr_uuid . len = ESP_UUID_LEN_16 ;
gl_profile_tab [ PROFILE_A_APP_ID ] . descr_uuid . uuid . uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG ;
2017-07-20 21:33:03 +08:00
esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value ( param - > add_char . attr_handle , & length , & prf_char ) ;
if ( get_attr_ret = = ESP_FAIL ) {
ESP_LOGE ( GATTS_TAG , " ILLEGAL HANDLE " ) ;
}
2016-12-23 11:28:47 -05:00
ESP_LOGI ( GATTS_TAG , " the gatts demo char length = %x \n " , length ) ;
for ( int i = 0 ; i < length ; i + + ) {
ESP_LOGI ( GATTS_TAG , " prf_char[%x] =%x \n " , i , prf_char [ i ] ) ;
}
2017-07-20 21:33:03 +08:00
esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr ( gl_profile_tab [ PROFILE_A_APP_ID ] . service_handle , & gl_profile_tab [ PROFILE_A_APP_ID ] . descr_uuid ,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE , NULL , NULL ) ;
if ( add_descr_ret ) {
ESP_LOGE ( GATTS_TAG , " add char descr failed, error code =%x " , add_descr_ret ) ;
}
2016-12-19 17:12:43 +08:00
break ;
2016-12-23 11:28:47 -05:00
}
2016-12-19 17:12:43 +08:00
case ESP_GATTS_ADD_CHAR_DESCR_EVT :
2017-09-12 10:57:45 +10:00
gl_profile_tab [ PROFILE_A_APP_ID ] . descr_handle = param - > add_char_descr . attr_handle ;
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d \n " ,
2017-07-01 13:12:22 +03:00
param - > add_char_descr . status , param - > add_char_descr . attr_handle , param - > add_char_descr . service_handle ) ;
2016-12-19 17:12:43 +08:00
break ;
case ESP_GATTS_DELETE_EVT :
break ;
case ESP_GATTS_START_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " SERVICE_START_EVT, status %d, service_handle %d \n " ,
2016-12-19 17:12:43 +08:00
param - > start . status , param - > start . service_handle ) ;
break ;
case ESP_GATTS_STOP_EVT :
break ;
2017-06-02 01:09:23 -04:00
case ESP_GATTS_CONNECT_EVT : {
esp_ble_conn_update_params_t conn_params = { 0 } ;
memcpy ( conn_params . bda , param - > connect . remote_bda , sizeof ( esp_bd_addr_t ) ) ;
2017-06-19 03:22:25 -04:00
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
2017-06-02 01:09:23 -04:00
conn_params . latency = 0 ;
2017-08-24 20:46:03 +08:00
conn_params . max_int = 0x20 ; // max_int = 0x20*1.25ms = 40ms
conn_params . min_int = 0x10 ; // min_int = 0x10*1.25ms = 20ms
2017-06-02 01:09:23 -04:00
conn_params . timeout = 400 ; // timeout = 400*10ms = 4000ms
2017-10-16 16:27:38 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x: " ,
2016-12-19 17:12:43 +08:00
param - > connect . conn_id ,
param - > connect . remote_bda [ 0 ] , param - > connect . remote_bda [ 1 ] , param - > connect . remote_bda [ 2 ] ,
2017-10-16 16:27:38 +08:00
param - > connect . remote_bda [ 3 ] , param - > connect . remote_bda [ 4 ] , param - > connect . remote_bda [ 5 ] ) ;
2016-12-19 17:12:43 +08:00
gl_profile_tab [ PROFILE_A_APP_ID ] . conn_id = param - > connect . conn_id ;
2017-06-02 01:09:23 -04:00
//start sent the update connection parameters to the peer device.
esp_ble_gap_update_conn_params ( & conn_params ) ;
2016-12-19 17:12:43 +08:00
break ;
2017-06-02 01:09:23 -04:00
}
2016-12-19 17:12:43 +08:00
case ESP_GATTS_DISCONNECT_EVT :
2018-09-27 16:22:31 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x " , param - > disconnect . reason ) ;
2017-07-20 21:33:03 +08:00
esp_ble_gap_start_advertising ( & adv_params ) ;
2017-01-11 16:40:37 -08:00
break ;
2017-10-26 14:39:49 +08:00
case ESP_GATTS_CONF_EVT :
2018-10-16 14:38:49 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_CONF_EVT, status %d attr_handle %d " , param - > conf . status , param - > conf . handle ) ;
2017-10-26 14:39:49 +08:00
if ( param - > conf . status ! = ESP_GATT_OK ) {
esp_log_buffer_hex ( GATTS_TAG , param - > conf . value , param - > conf . len ) ;
}
break ;
2016-12-19 17:12:43 +08:00
case ESP_GATTS_OPEN_EVT :
case ESP_GATTS_CANCEL_OPEN_EVT :
case ESP_GATTS_CLOSE_EVT :
case ESP_GATTS_LISTEN_EVT :
case ESP_GATTS_CONGEST_EVT :
default :
break ;
}
}
static void gatts_profile_b_event_handler ( esp_gatts_cb_event_t event , esp_gatt_if_t gatts_if , esp_ble_gatts_cb_param_t * param ) {
switch ( event ) {
case ESP_GATTS_REG_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " REGISTER_APP_EVT, status %d, app_id %d \n " , param - > reg . status , param - > reg . app_id ) ;
2017-01-17 20:13:25 +08:00
gl_profile_tab [ PROFILE_B_APP_ID ] . service_id . is_primary = true ;
gl_profile_tab [ PROFILE_B_APP_ID ] . service_id . id . inst_id = 0x00 ;
gl_profile_tab [ PROFILE_B_APP_ID ] . service_id . id . uuid . len = ESP_UUID_LEN_16 ;
gl_profile_tab [ PROFILE_B_APP_ID ] . service_id . id . uuid . uuid . uuid16 = GATTS_SERVICE_UUID_TEST_B ;
2016-11-25 02:10:15 +08:00
2017-01-17 20:13:25 +08:00
esp_ble_gatts_create_service ( gatts_if , & gl_profile_tab [ PROFILE_B_APP_ID ] . service_id , GATTS_NUM_HANDLE_TEST_B ) ;
2016-11-25 02:10:15 +08:00
break ;
case ESP_GATTS_READ_EVT : {
2022-12-08 11:03:04 +08:00
ESP_LOGI ( GATTS_TAG , " GATT_READ_EVT, conn_id %d, trans_id % " PRIu32 " , handle %d \n " , param - > read . conn_id , param - > read . trans_id , param - > read . handle ) ;
2016-11-25 02:10:15 +08:00
esp_gatt_rsp_t rsp ;
memset ( & rsp , 0 , sizeof ( esp_gatt_rsp_t ) ) ;
2016-12-11 16:36:47 +08:00
rsp . attr_value . handle = param - > read . handle ;
2016-11-25 02:10:15 +08:00
rsp . attr_value . len = 4 ;
rsp . attr_value . value [ 0 ] = 0xde ;
2016-11-18 00:30:35 +08:00
rsp . attr_value . value [ 1 ] = 0xed ;
rsp . attr_value . value [ 2 ] = 0xbe ;
rsp . attr_value . value [ 3 ] = 0xef ;
2016-12-11 16:36:47 +08:00
esp_ble_gatts_send_response ( gatts_if , param - > read . conn_id , param - > read . trans_id ,
2016-11-25 02:10:15 +08:00
ESP_GATT_OK , & rsp ) ;
break ;
}
case ESP_GATTS_WRITE_EVT : {
2022-12-08 11:03:04 +08:00
ESP_LOGI ( GATTS_TAG , " GATT_WRITE_EVT, conn_id %d, trans_id % " PRIu32 " , handle %d \n " , param - > write . conn_id , param - > write . trans_id , param - > write . handle ) ;
2017-07-20 21:33:03 +08:00
if ( ! param - > write . is_prep ) {
ESP_LOGI ( GATTS_TAG , " GATT_WRITE_EVT, value len %d, value : " , param - > write . len ) ;
esp_log_buffer_hex ( GATTS_TAG , param - > write . value , param - > write . len ) ;
if ( gl_profile_tab [ PROFILE_B_APP_ID ] . descr_handle = = param - > write . handle & & param - > write . len = = 2 ) {
uint16_t descr_value = param - > write . value [ 1 ] < < 8 | param - > write . value [ 0 ] ;
if ( descr_value = = 0x0001 ) {
if ( b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY ) {
ESP_LOGI ( GATTS_TAG , " notify enable " ) ;
uint8_t notify_data [ 15 ] ;
for ( int i = 0 ; i < sizeof ( notify_data ) ; + + i )
{
notify_data [ i ] = i % 0xff ;
}
//the size of notify_data[] need less than MTU size
esp_ble_gatts_send_indicate ( gatts_if , param - > write . conn_id , gl_profile_tab [ PROFILE_B_APP_ID ] . char_handle ,
sizeof ( notify_data ) , notify_data , false ) ;
}
} else if ( descr_value = = 0x0002 ) {
if ( b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE ) {
ESP_LOGI ( GATTS_TAG , " indicate enable " ) ;
uint8_t indicate_data [ 15 ] ;
for ( int i = 0 ; i < sizeof ( indicate_data ) ; + + i )
{
indicate_data [ i ] = i % 0xff ;
}
//the size of indicate_data[] need less than MTU size
esp_ble_gatts_send_indicate ( gatts_if , param - > write . conn_id , gl_profile_tab [ PROFILE_B_APP_ID ] . char_handle ,
sizeof ( indicate_data ) , indicate_data , true ) ;
}
}
else if ( descr_value = = 0x0000 ) {
ESP_LOGI ( GATTS_TAG , " notify/indicate disable " ) ;
} else {
ESP_LOGE ( GATTS_TAG , " unknown value " ) ;
}
}
}
2017-05-31 17:20:29 +08:00
example_write_event_env ( gatts_if , & b_prepare_write_env , param ) ;
2016-11-25 02:10:15 +08:00
break ;
}
case ESP_GATTS_EXEC_WRITE_EVT :
2017-05-31 17:20:29 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_EXEC_WRITE_EVT " ) ;
esp_ble_gatts_send_response ( gatts_if , param - > write . conn_id , param - > write . trans_id , ESP_GATT_OK , NULL ) ;
example_exec_write_event_env ( & b_prepare_write_env , param ) ;
break ;
2016-11-25 02:10:15 +08:00
case ESP_GATTS_MTU_EVT :
2017-07-20 21:33:03 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_MTU_EVT, MTU %d " , param - > mtu . mtu ) ;
break ;
2016-11-25 02:10:15 +08:00
case ESP_GATTS_UNREG_EVT :
break ;
case ESP_GATTS_CREATE_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " CREATE_SERVICE_EVT, status %d, service_handle %d \n " , param - > create . status , param - > create . service_handle ) ;
2017-01-17 20:13:25 +08:00
gl_profile_tab [ PROFILE_B_APP_ID ] . service_handle = param - > create . service_handle ;
gl_profile_tab [ PROFILE_B_APP_ID ] . char_uuid . len = ESP_UUID_LEN_16 ;
gl_profile_tab [ PROFILE_B_APP_ID ] . char_uuid . uuid . uuid16 = GATTS_CHAR_UUID_TEST_B ;
2016-11-25 02:10:15 +08:00
2017-01-17 20:13:25 +08:00
esp_ble_gatts_start_service ( gl_profile_tab [ PROFILE_B_APP_ID ] . service_handle ) ;
2017-07-20 21:33:03 +08:00
b_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY ;
esp_err_t add_char_ret = esp_ble_gatts_add_char ( gl_profile_tab [ PROFILE_B_APP_ID ] . service_handle , & gl_profile_tab [ PROFILE_B_APP_ID ] . char_uuid ,
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE ,
b_property ,
NULL , NULL ) ;
if ( add_char_ret ) {
ESP_LOGE ( GATTS_TAG , " add char failed, error code =%x " , add_char_ret ) ;
}
2016-11-25 02:10:15 +08:00
break ;
case ESP_GATTS_ADD_INCL_SRVC_EVT :
break ;
case ESP_GATTS_ADD_CHAR_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d \n " ,
2016-12-11 16:36:47 +08:00
param - > add_char . status , param - > add_char . attr_handle , param - > add_char . service_handle ) ;
2016-11-25 02:10:15 +08:00
2017-01-17 20:13:25 +08:00
gl_profile_tab [ PROFILE_B_APP_ID ] . char_handle = param - > add_char . attr_handle ;
gl_profile_tab [ PROFILE_B_APP_ID ] . descr_uuid . len = ESP_UUID_LEN_16 ;
gl_profile_tab [ PROFILE_B_APP_ID ] . descr_uuid . uuid . uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG ;
esp_ble_gatts_add_char_descr ( gl_profile_tab [ PROFILE_B_APP_ID ] . service_handle , & gl_profile_tab [ PROFILE_B_APP_ID ] . descr_uuid ,
2016-12-23 11:28:47 -05:00
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE ,
NULL , NULL ) ;
2016-11-25 02:10:15 +08:00
break ;
case ESP_GATTS_ADD_CHAR_DESCR_EVT :
2017-09-12 10:57:45 +10:00
gl_profile_tab [ PROFILE_B_APP_ID ] . descr_handle = param - > add_char_descr . attr_handle ;
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d \n " ,
2017-07-01 13:12:22 +03:00
param - > add_char_descr . status , param - > add_char_descr . attr_handle , param - > add_char_descr . service_handle ) ;
2016-11-25 02:10:15 +08:00
break ;
2016-11-28 22:40:30 +08:00
case ESP_GATTS_DELETE_EVT :
2016-11-25 02:10:15 +08:00
break ;
case ESP_GATTS_START_EVT :
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " SERVICE_START_EVT, status %d, service_handle %d \n " ,
2016-12-11 16:36:47 +08:00
param - > start . status , param - > start . service_handle ) ;
2016-11-25 02:10:15 +08:00
break ;
case ESP_GATTS_STOP_EVT :
break ;
case ESP_GATTS_CONNECT_EVT :
2017-10-16 16:27:38 +08:00
ESP_LOGI ( GATTS_TAG , " CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x: " ,
2016-12-11 16:36:47 +08:00
param - > connect . conn_id ,
param - > connect . remote_bda [ 0 ] , param - > connect . remote_bda [ 1 ] , param - > connect . remote_bda [ 2 ] ,
2017-10-16 16:27:38 +08:00
param - > connect . remote_bda [ 3 ] , param - > connect . remote_bda [ 4 ] , param - > connect . remote_bda [ 5 ] ) ;
2017-01-17 20:13:25 +08:00
gl_profile_tab [ PROFILE_B_APP_ID ] . conn_id = param - > connect . conn_id ;
2016-11-25 02:10:15 +08:00
break ;
2017-10-26 14:39:49 +08:00
case ESP_GATTS_CONF_EVT :
2018-10-16 14:38:49 +08:00
ESP_LOGI ( GATTS_TAG , " ESP_GATTS_CONF_EVT status %d attr_handle %d " , param - > conf . status , param - > conf . handle ) ;
2017-10-26 14:39:49 +08:00
if ( param - > conf . status ! = ESP_GATT_OK ) {
esp_log_buffer_hex ( GATTS_TAG , param - > conf . value , param - > conf . len ) ;
}
break ;
2016-11-25 02:10:15 +08:00
case ESP_GATTS_DISCONNECT_EVT :
case ESP_GATTS_OPEN_EVT :
case ESP_GATTS_CANCEL_OPEN_EVT :
case ESP_GATTS_CLOSE_EVT :
case ESP_GATTS_LISTEN_EVT :
case ESP_GATTS_CONGEST_EVT :
default :
break ;
}
2016-11-18 00:30:35 +08:00
}
2016-12-11 16:36:47 +08:00
static void gatts_event_handler ( esp_gatts_cb_event_t event , esp_gatt_if_t gatts_if , esp_ble_gatts_cb_param_t * param )
{
/* If event is register event, store the gatts_if for each profile */
if ( event = = ESP_GATTS_REG_EVT ) {
if ( param - > reg . status = = ESP_GATT_OK ) {
gl_profile_tab [ param - > reg . app_id ] . gatts_if = gatts_if ;
} else {
2017-01-03 15:53:06 +08:00
ESP_LOGI ( GATTS_TAG , " Reg app failed, app_id %04x, status %d \n " ,
2017-07-20 21:33:03 +08:00
param - > reg . app_id ,
2016-12-11 16:36:47 +08:00
param - > reg . status ) ;
return ;
}
}
/* If the gatts_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 ( gatts_if = = ESP_GATT_IF_NONE | | /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
gatts_if = = gl_profile_tab [ idx ] . gatts_if ) {
if ( gl_profile_tab [ idx ] . gatts_cb ) {
gl_profile_tab [ idx ] . gatts_cb ( event , gatts_if , param ) ;
}
}
}
} while ( 0 ) ;
}
2019-07-16 16:33:30 +07:00
void app_main ( void )
2016-11-18 00:30:35 +08:00
{
2016-11-25 02:10:15 +08:00
esp_err_t ret ;
2016-11-18 00:30:35 +08:00
2017-07-13 23:46:19 +08:00
// Initialize NVS.
ret = nvs_flash_init ( ) ;
2018-07-25 20:41:09 +05:30
if ( ret = = ESP_ERR_NVS_NO_FREE_PAGES | | ret = = ESP_ERR_NVS_NEW_VERSION_FOUND ) {
2017-07-13 23:46:19 +08:00
ESP_ERROR_CHECK ( nvs_flash_erase ( ) ) ;
ret = nvs_flash_init ( ) ;
}
ESP_ERROR_CHECK ( ret ) ;
2017-12-12 15:24:43 +08:00
ESP_ERROR_CHECK ( esp_bt_controller_mem_release ( ESP_BT_MODE_CLASSIC_BT ) ) ;
2017-04-05 21:19:15 +08: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 14:48:53 +01:00
ESP_LOGE ( GATTS_TAG , " %s initialize controller failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-04-05 21:19:15 +08:00
return ;
}
2017-01-03 15:53:06 +08:00
2017-12-12 15:24:43 +08:00
ret = esp_bt_controller_enable ( ESP_BT_MODE_BLE ) ;
2017-02-17 19:24:58 +08:00
if ( ret ) {
2018-02-22 14:48:53 +01:00
ESP_LOGE ( GATTS_TAG , " %s enable controller failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2017-02-17 19:24:58 +08:00
return ;
}
2017-01-03 15:53:06 +08:00
ret = esp_bluedroid_init ( ) ;
2016-11-25 02:10:15 +08:00
if ( ret ) {
2018-02-22 14:48:53 +01:00
ESP_LOGE ( GATTS_TAG , " %s init bluetooth failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2016-11-25 02:10:15 +08:00
return ;
}
2017-01-03 15:53:06 +08:00
ret = esp_bluedroid_enable ( ) ;
2016-11-25 02:10:15 +08:00
if ( ret ) {
2018-02-22 14:48:53 +01:00
ESP_LOGE ( GATTS_TAG , " %s enable bluetooth failed: %s \n " , __func__ , esp_err_to_name ( ret ) ) ;
2016-11-25 02:10:15 +08:00
return ;
}
2016-11-18 00:30:35 +08:00
2017-07-20 21:33:03 +08:00
ret = esp_ble_gatts_register_callback ( gatts_event_handler ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " gatts register error, error code = %x " , ret ) ;
return ;
}
ret = esp_ble_gap_register_callback ( gap_event_handler ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " gap register error, error code = %x " , ret ) ;
return ;
}
ret = esp_ble_gatts_app_register ( PROFILE_A_APP_ID ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " gatts app register error, error code = %x " , ret ) ;
return ;
}
ret = esp_ble_gatts_app_register ( PROFILE_B_APP_ID ) ;
if ( ret ) {
ESP_LOGE ( GATTS_TAG , " gatts app register error, error code = %x " , ret ) ;
return ;
}
2017-08-24 19:54:41 +08:00
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu ( 500 ) ;
if ( local_mtu_ret ) {
ESP_LOGE ( GATTS_TAG , " set local MTU failed, error code = %x " , local_mtu_ret ) ;
}
2016-11-18 00:30:35 +08:00
2016-11-25 02:10:15 +08:00
return ;
2016-11-18 00:30:35 +08:00
}