Merge branch 'bugfix/btdm_optimize_gatt_security_server_demo' into 'master'

component/bt: optimize gatt security server demo

See merge request !1047
This commit is contained in:
Jiang Jiang Jian 2017-09-01 20:13:13 +08:00
commit 73473ad351

View file

@ -1,11 +1,16 @@
/* BLE Security example_ble_security_gatts_demo example // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2 //
3 This example code is in the Public Domain (or CC0 licensed, at your option.) // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 Unless required by applicable law or agreed to in writing, this // You may obtain a copy of the License at
6 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7 CONDITIONS OF ANY KIND, either express or implied. // http://www.apache.org/licenses/LICENSE-2.0
8 */ //
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@ -14,7 +19,6 @@
#include "esp_log.h" #include "esp_log.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "bt.h" #include "bt.h"
#include "bta_api.h"
#include "esp_gap_ble_api.h" #include "esp_gap_ble_api.h"
#include "esp_gatts_api.h" #include "esp_gatts_api.h"
@ -33,6 +37,11 @@
#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40 #define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
#define ADV_CONFIG_FLAG (1 << 0)
#define SCAN_RSP_CONFIG_FLAG (1 << 1)
static uint8_t adv_config_done = 0;
uint8_t heart_str[] = {0x11,0x22,0x33}; uint8_t heart_str[] = {0x11,0x22,0x33};
uint16_t heart_rate_handle_table[HRS_IDX_NB]; uint16_t heart_rate_handle_table[HRS_IDX_NB];
@ -43,7 +52,7 @@ esp_attr_value_t gatts_demo_char1_val =
.attr_len = sizeof(heart_str), .attr_len = sizeof(heart_str),
.attr_value = heart_str, .attr_value = heart_str,
}; };
static uint8_t test_manufacturer[3]={'E', 'S', 'P'};
static uint8_t sec_service_uuid[16] = { static uint8_t sec_service_uuid[16] = {
/* LSB <--------------------------------------------------------------------------------> MSB */ /* LSB <--------------------------------------------------------------------------------> MSB */
@ -51,10 +60,9 @@ static uint8_t sec_service_uuid[16] = {
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x18, 0x0D, 0x00, 0x00, 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x18, 0x0D, 0x00, 0x00,
}; };
// config adv data
static esp_ble_adv_data_t heart_rate_adv_config = { static esp_ble_adv_data_t heart_rate_adv_config = {
.set_scan_rsp = false, .set_scan_rsp = false,
.include_name = true,
.include_txpower = true, .include_txpower = true,
.min_interval = 0x100, .min_interval = 0x100,
.max_interval = 0x100, .max_interval = 0x100,
@ -67,12 +75,19 @@ static esp_ble_adv_data_t heart_rate_adv_config = {
.p_service_uuid = sec_service_uuid, .p_service_uuid = sec_service_uuid,
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
}; };
// config scan response data
static esp_ble_adv_data_t heart_rate_scan_rsp_config = {
.set_scan_rsp = true,
.include_name = true,
.manufacturer_len = sizeof(test_manufacturer),
.p_manufacturer_data = test_manufacturer,
};
static esp_ble_adv_params_t heart_rate_adv_params = { static esp_ble_adv_params_t heart_rate_adv_params = {
.adv_int_min = 0x100, .adv_int_min = 0x100,
.adv_int_max = 0x100, .adv_int_max = 0x100,
.adv_type = ADV_TYPE_IND, .adv_type = ADV_TYPE_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC, .own_addr_type = BLE_ADDR_TYPE_RANDOM,
.channel_map = ADV_CHNL_ALL, .channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
}; };
@ -104,12 +119,6 @@ static struct gatts_profile_inst heart_rate_profile_tab[HEART_PROFILE_NUM] = {
}; };
/*
* HTPT PROFILE ATTRIBUTES
****************************************************************************************
*/
/* /*
* Heart Rate PROFILE ATTRIBUTES * Heart Rate PROFILE ATTRIBUTES
**************************************************************************************** ****************************************************************************************
@ -229,14 +238,25 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
ESP_LOGV(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); ESP_LOGV(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event);
switch (event) { switch (event) {
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT: 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(&heart_rate_adv_params); esp_ble_gap_start_advertising(&heart_rate_adv_params);
}
break;
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(&heart_rate_adv_params);
}
break; break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
//advertising start complete event to indicate advertising start successfully or failed //advertising start complete event to indicate advertising start successfully or failed
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) {
ESP_LOGE(GATTS_TABLE_TAG, "Advertising start failed\n"); ESP_LOGE(GATTS_TABLE_TAG, "advertising start failed, error status = %x", param->adv_start_cmpl.status);
break;
} }
ESP_LOGI(GATTS_TABLE_TAG, "advertising start success");
break; break;
case ESP_GAP_BLE_SEC_REQ_EVT: case ESP_GAP_BLE_SEC_REQ_EVT:
/* send the positive(true) security response to the peer device to accept the security request. /* send the positive(true) security response to the peer device to accept the security request.
@ -262,22 +282,43 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
break; break;
} }
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: { case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status); ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
break; break;
} }
case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: { case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status); ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status);
break; break;
} }
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: { case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num); ESP_LOGI(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num);
esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev; esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev;
for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) { for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) {
ESP_LOGD(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask); ESP_LOGI(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask);
esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t)); esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t));
} }
break; break;
} }
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
if (param->local_privacy_cmpl.status != ESP_BT_STATUS_SUCCESS){
ESP_LOGE(GATTS_TABLE_TAG, "config local privacy failed, error status = %x", param->local_privacy_cmpl.status);
break;
}
esp_err_t ret = esp_ble_gap_config_adv_data(&heart_rate_adv_config);
if (ret){
ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret);
}else{
adv_config_done |= ADV_CONFIG_FLAG;
}
ret = esp_ble_gap_config_adv_data(&heart_rate_scan_rsp_config);
if (ret){
ESP_LOGE(GATTS_TABLE_TAG, "config adv data failed, error code = %x", ret);
}else{
adv_config_done |= SCAN_RSP_CONFIG_FLAG;
}
break;
default: default:
break; break;
} }
@ -289,17 +330,13 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
ESP_LOGV(GATTS_TABLE_TAG, "event = %x\n",event); ESP_LOGV(GATTS_TABLE_TAG, "event = %x\n",event);
switch (event) { switch (event) {
case ESP_GATTS_REG_EVT: case ESP_GATTS_REG_EVT:
ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__);
esp_ble_gap_set_device_name(EXCAMPLE_DEVICE_NAME); esp_ble_gap_set_device_name(EXCAMPLE_DEVICE_NAME);
ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); //generate a resolvable random address
esp_ble_gap_config_adv_data(&heart_rate_adv_config); esp_ble_gap_config_local_privacy(true);
ESP_LOGD(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__);
esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if, esp_ble_gatts_create_attr_tab(heart_rate_gatt_db, gatts_if,
HRS_IDX_NB, HEART_RATE_SVC_INST_ID); HRS_IDX_NB, HEART_RATE_SVC_INST_ID);
break; break;
case ESP_GATTS_READ_EVT: case ESP_GATTS_READ_EVT:
break; break;
case ESP_GATTS_WRITE_EVT: case ESP_GATTS_WRITE_EVT:
break; break;
@ -318,10 +355,12 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
case ESP_GATTS_STOP_EVT: case ESP_GATTS_STOP_EVT:
break; break;
case ESP_GATTS_CONNECT_EVT: case ESP_GATTS_CONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_CONNECT_EVT");
//start security connect with peer device when receive the connect event sent by the master. //start security connect with peer device when receive the connect event sent by the master.
esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM); esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
break; break;
case ESP_GATTS_DISCONNECT_EVT: case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_DISCONNECT_EVT");
///start advertising again when missing the connect. ///start advertising again when missing the connect.
esp_ble_gap_start_advertising(&heart_rate_adv_params); esp_ble_gap_start_advertising(&heart_rate_adv_params);
break; break;
@ -336,13 +375,19 @@ static void gatts_profile_event_handler(esp_gatts_cb_event_t event,
case ESP_GATTS_CONGEST_EVT: case ESP_GATTS_CONGEST_EVT:
break; break;
case ESP_GATTS_CREAT_ATTR_TAB_EVT: { case ESP_GATTS_CREAT_ATTR_TAB_EVT: {
ESP_LOGD(GATTS_TABLE_TAG, "The number handle =%x\n",param->add_attr_tab.num_handle); ESP_LOGI(GATTS_TABLE_TAG, "The number handle = %x",param->add_attr_tab.num_handle);
if (param->create.status == ESP_GATT_OK){
if(param->add_attr_tab.num_handle == HRS_IDX_NB) { if(param->add_attr_tab.num_handle == HRS_IDX_NB) {
memcpy(heart_rate_handle_table, param->add_attr_tab.handles, memcpy(heart_rate_handle_table, param->add_attr_tab.handles,
sizeof(heart_rate_handle_table)); sizeof(heart_rate_handle_table));
esp_ble_gatts_start_service(heart_rate_handle_table[HRS_IDX_SVC]); esp_ble_gatts_start_service(heart_rate_handle_table[HRS_IDX_SVC]);
}else{
ESP_LOGE(GATTS_TABLE_TAG, "Create attribute table abnormally, num_handle (%d) doesn't equal to HRS_IDX_NB(%d)",
param->add_attr_tab.num_handle, HRS_IDX_NB);
}
}else{
ESP_LOGE(GATTS_TABLE_TAG, " Create attribute table failed, error code = %x", param->create.status);
} }
break; break;
} }
@ -416,9 +461,21 @@ void app_main()
return; return;
} }
esp_ble_gatts_register_callback(gatts_event_handler); ret = esp_ble_gatts_register_callback(gatts_event_handler);
esp_ble_gap_register_callback(gap_event_handler); if (ret){
esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID); ESP_LOGE(GATTS_TABLE_TAG, "gatts register error, error code = %x", ret);
return;
}
ret = esp_ble_gap_register_callback(gap_event_handler);
if (ret){
ESP_LOGE(GATTS_TABLE_TAG, "gap register error, error code = %x", ret);
return;
}
ret = esp_ble_gatts_app_register(ESP_HEART_RATE_APP_ID);
if (ret){
ESP_LOGE(GATTS_TABLE_TAG, "gatts app register error, error code = %x", ret);
return;
}
/* set the security iocap & auth_req & key size & init key response key parameters to the stack*/ /* set the security iocap & auth_req & key size & init key response key parameters to the stack*/
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND; //bonding with peer device after authentication
@ -429,6 +486,10 @@ void app_main()
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_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_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t)); esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
/* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribut to you,
and the response key means which key you can distribut 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 distribut to you,
and the init key means which key you can distribut to the slave. */
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_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t)); esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));