mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
feat(bt/bluedroid): Added throughput mode for BLE SPP example
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
menu "Example 'SPP CLIENT' Config"
|
||||
|
||||
choice EXAMPLE_SPP_CLIENT
|
||||
prompt "SPP TRANSPORT mode"
|
||||
default EXAMPLE_SPP_THROUGHPUT
|
||||
help
|
||||
Define SPP TRANSPORT mode
|
||||
|
||||
config EXAMPLE_SPP_THROUGHPUT
|
||||
bool "Throughput"
|
||||
config EXAMPLE_SPP_RELIABLE
|
||||
bool "Reliable"
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
@@ -27,14 +27,18 @@
|
||||
#include "esp_gatt_common_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_timer.h"
|
||||
|
||||
#define GATTC_TAG "GATTC_SPP_DEMO"
|
||||
#define PROFILE_NUM 1
|
||||
#define PROFILE_APP_ID 0
|
||||
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define BT_BD_ADDR_HEX(addr) addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]
|
||||
#define ESP_GATT_SPP_SERVICE_UUID 0xABF0
|
||||
#define SCAN_ALL_THE_TIME 0
|
||||
#define SPP_GATT_MTU_SIZE (512)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
struct gattc_profile_inst {
|
||||
esp_gattc_cb_t gattc_cb;
|
||||
@@ -98,14 +102,18 @@ static uint16_t cmd = 0;
|
||||
static uint16_t spp_srv_start_handle = 0;
|
||||
static uint16_t spp_srv_end_handle = 0;
|
||||
static uint16_t spp_gattc_if = 0xff;
|
||||
static uint16_t count = SPP_IDX_NB;
|
||||
static esp_gattc_db_elem_t *db = NULL;
|
||||
static QueueHandle_t cmd_reg_queue = NULL;
|
||||
QueueHandle_t spp_uart_queue = NULL;
|
||||
static bool connect = false;
|
||||
static char * notify_value_p = NULL;
|
||||
static int notify_value_offset = 0;
|
||||
static int notify_value_count = 0;
|
||||
static uint16_t count = SPP_IDX_NB;
|
||||
static esp_gattc_db_elem_t *db = NULL;
|
||||
static esp_ble_gap_cb_param_t scan_rst;
|
||||
static QueueHandle_t cmd_reg_queue = NULL;
|
||||
QueueHandle_t spp_uart_queue = NULL;
|
||||
static bool start = false;
|
||||
static uint64_t notify_len = 0;
|
||||
static uint64_t start_time = 0;
|
||||
static uint64_t current_time = 0;
|
||||
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
static uint8_t heartbeat_s[9] = {'E','s','p','r','e','s','s','i','f'};
|
||||
@@ -121,40 +129,33 @@ static void notify_event_handler(esp_ble_gattc_cb_param_t * p_data)
|
||||
{
|
||||
uint8_t handle = 0;
|
||||
|
||||
if(p_data->notify.is_notify == true){
|
||||
ESP_LOGI(GATTC_TAG,"+NOTIFY:handle = %d,length = %d ", p_data->notify.handle, p_data->notify.value_len);
|
||||
}else{
|
||||
ESP_LOGI(GATTC_TAG,"+INDICATE:handle = %d,length = %d ", p_data->notify.handle, p_data->notify.value_len);
|
||||
}
|
||||
handle = p_data->notify.handle;
|
||||
if(db == NULL) {
|
||||
if (db == NULL) {
|
||||
ESP_LOGE(GATTC_TAG, " %s db is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
if(handle == db[SPP_IDX_SPP_DATA_NTY_VAL].attribute_handle){
|
||||
#ifdef SPP_DEBUG_MODE
|
||||
ESP_LOG_BUFFER_CHAR(GATTC_TAG, (char *)p_data->notify.value, p_data->notify.value_len);
|
||||
#else
|
||||
if((p_data->notify.value[0] == '#')&&(p_data->notify.value[1] == '#')){
|
||||
if((++notify_value_count) != p_data->notify.value[3]){
|
||||
|
||||
if (handle == db[SPP_IDX_SPP_DATA_NTY_VAL].attribute_handle) {
|
||||
if ((p_data->notify.value[0] == '#') && (p_data->notify.value[1] == '#')) {
|
||||
if ((++notify_value_count) != p_data->notify.value[3]) {
|
||||
if(notify_value_p != NULL){
|
||||
free(notify_value_p);
|
||||
}
|
||||
notify_value_count = 0;
|
||||
notify_value_p = NULL;
|
||||
notify_value_offset = 0;
|
||||
ESP_LOGE(GATTC_TAG,"notify value count is not continuous,%s",__func__);
|
||||
ESP_LOGE(GATTC_TAG,"notify value count is not continuous, %s", __func__);
|
||||
return;
|
||||
}
|
||||
if(p_data->notify.value[3] == 1){
|
||||
if (p_data->notify.value[3] == 1) {
|
||||
notify_value_p = (char *)malloc(((spp_mtu_size-7)*(p_data->notify.value[2]))*sizeof(char));
|
||||
if(notify_value_p == NULL){
|
||||
ESP_LOGE(GATTC_TAG, "malloc failed,%s L#%d",__func__,__LINE__);
|
||||
if (notify_value_p == NULL) {
|
||||
ESP_LOGE(GATTC_TAG, "malloc failed, %s L#%d", __func__, __LINE__);
|
||||
notify_value_count = 0;
|
||||
return;
|
||||
}
|
||||
memcpy((notify_value_p + notify_value_offset),(p_data->notify.value + 4),(p_data->notify.value_len - 4));
|
||||
if(p_data->notify.value[2] == p_data->notify.value[3]){
|
||||
memcpy((notify_value_p + notify_value_offset), (p_data->notify.value + 4), (p_data->notify.value_len - 4));
|
||||
if (p_data->notify.value[2] == p_data->notify.value[3]) {
|
||||
uart_write_bytes(UART_NUM_0, (char *)(notify_value_p), (p_data->notify.value_len - 4 + notify_value_offset));
|
||||
free(notify_value_p);
|
||||
notify_value_p = NULL;
|
||||
@@ -162,9 +163,9 @@ static void notify_event_handler(esp_ble_gattc_cb_param_t * p_data)
|
||||
return;
|
||||
}
|
||||
notify_value_offset += (p_data->notify.value_len - 4);
|
||||
}else if(p_data->notify.value[3] <= p_data->notify.value[2]){
|
||||
memcpy((notify_value_p + notify_value_offset),(p_data->notify.value + 4),(p_data->notify.value_len - 4));
|
||||
if(p_data->notify.value[3] == p_data->notify.value[2]){
|
||||
} else if (p_data->notify.value[3] <= p_data->notify.value[2]) {
|
||||
memcpy((notify_value_p + notify_value_offset), (p_data->notify.value + 4), (p_data->notify.value_len - 4));
|
||||
if (p_data->notify.value[3] == p_data->notify.value[2]) {
|
||||
uart_write_bytes(UART_NUM_0, (char *)(notify_value_p), (p_data->notify.value_len - 4 + notify_value_offset));
|
||||
free(notify_value_p);
|
||||
notify_value_count = 0;
|
||||
@@ -174,14 +175,13 @@ static void notify_event_handler(esp_ble_gattc_cb_param_t * p_data)
|
||||
}
|
||||
notify_value_offset += (p_data->notify.value_len - 4);
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
uart_write_bytes(UART_NUM_0, (char *)(p_data->notify.value), p_data->notify.value_len);
|
||||
}
|
||||
#endif
|
||||
}else if(handle == ((db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle)){
|
||||
} else if (handle == ((db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle)) {
|
||||
ESP_LOG_BUFFER_CHAR(GATTC_TAG, (char *)p_data->notify.value, p_data->notify.value_len);
|
||||
//TODO:server notify status characteristic
|
||||
}else{
|
||||
} else {
|
||||
ESP_LOG_BUFFER_CHAR(GATTC_TAG, (char *)p_data->notify.value, p_data->notify.value_len);
|
||||
}
|
||||
}
|
||||
@@ -189,6 +189,7 @@ static void notify_event_handler(esp_ble_gattc_cb_param_t * p_data)
|
||||
static void free_gattc_srv_db(void)
|
||||
{
|
||||
is_connect = false;
|
||||
connect = false;
|
||||
spp_gattc_if = 0xff;
|
||||
spp_conn_id = 0;
|
||||
spp_mtu_size = 23;
|
||||
@@ -198,7 +199,7 @@ static void free_gattc_srv_db(void)
|
||||
notify_value_p = NULL;
|
||||
notify_value_offset = 0;
|
||||
notify_value_count = 0;
|
||||
if(db){
|
||||
if (db) {
|
||||
free(db);
|
||||
db = NULL;
|
||||
}
|
||||
@@ -210,7 +211,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
|
||||
uint8_t adv_name_len = 0;
|
||||
esp_err_t err;
|
||||
|
||||
switch(event){
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: {
|
||||
if((err = param->scan_param_cmpl.status) != ESP_BT_STATUS_SUCCESS){
|
||||
ESP_LOGE(GATTC_TAG, "Scan param set failed: %s", esp_err_to_name(err));
|
||||
@@ -224,51 +225,52 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
|
||||
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
|
||||
//scan start complete event to indicate scan start successfully or failed
|
||||
if ((err = param->scan_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGE(GATTC_TAG, "Scan start failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGE(GATTC_TAG, "Scanning start failed, err %s", esp_err_to_name(err));
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(GATTC_TAG, "Scan start successfully");
|
||||
ESP_LOGI(GATTC_TAG, "Scanning start successfully");
|
||||
break;
|
||||
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
|
||||
if ((err = param->scan_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGE(GATTC_TAG, "Scan stop failed: %s", esp_err_to_name(err));
|
||||
ESP_LOGE(GATTC_TAG, "Scanning stop failed, err %s", esp_err_to_name(err));
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(GATTC_TAG, "Scan stop successfully");
|
||||
if (is_connect == false) {
|
||||
ESP_LOGI(GATTC_TAG, "Connect to the remote device.");
|
||||
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||
memcpy(&creat_conn_params.remote_bda, scan_rst.scan_rst.bda,ESP_BD_ADDR_LEN);
|
||||
creat_conn_params.remote_addr_type = scan_rst.scan_rst.ble_addr_type;
|
||||
creat_conn_params.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
|
||||
creat_conn_params.is_direct = true;
|
||||
creat_conn_params.is_aux = false;
|
||||
creat_conn_params.phy_mask = 0x0;
|
||||
esp_ble_gattc_enh_open(gl_profile_tab[PROFILE_APP_ID].gattc_if,
|
||||
&creat_conn_params);
|
||||
}
|
||||
ESP_LOGI(GATTC_TAG, "Scanning stop successfully");
|
||||
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_by_type(scan_result->scan_rst.ble_adv,
|
||||
scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len,
|
||||
ESP_BLE_AD_TYPE_NAME_CMPL,
|
||||
&adv_name_len);
|
||||
ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len);
|
||||
scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len,
|
||||
ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
|
||||
ESP_LOGI(GATTC_TAG, "Scan result, device "ESP_BD_ADDR_STR", name len %u", ESP_BD_ADDR_HEX(scan_result->scan_rst.bda), adv_name_len);
|
||||
ESP_LOG_BUFFER_CHAR(GATTC_TAG, adv_name, adv_name_len);
|
||||
ESP_LOGI(GATTC_TAG, " ");
|
||||
if (adv_name != NULL) {
|
||||
if ( strncmp((char *)adv_name, device_name, adv_name_len) == 0) {
|
||||
memcpy(&(scan_rst), scan_result, sizeof(esp_ble_gap_cb_param_t));
|
||||
if (adv_name != NULL && strncmp((char *)adv_name, device_name, adv_name_len) == 0) {
|
||||
if (connect == false) {
|
||||
connect = true;
|
||||
esp_ble_gap_stop_scanning();
|
||||
ESP_LOGI(GATTC_TAG, "Connect to the remote device.");
|
||||
esp_ble_conn_params_t phy_1m_conn_params = {0};
|
||||
phy_1m_conn_params.interval_max = 32;
|
||||
phy_1m_conn_params.interval_min = 32;
|
||||
phy_1m_conn_params.latency = 0;
|
||||
phy_1m_conn_params.supervision_timeout = 600;
|
||||
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||
memcpy(&creat_conn_params.remote_bda, scan_result->scan_rst.bda,ESP_BD_ADDR_LEN);
|
||||
creat_conn_params.remote_addr_type = scan_result->scan_rst.ble_addr_type;
|
||||
creat_conn_params.own_addr_type = BLE_ADDR_TYPE_PUBLIC;
|
||||
creat_conn_params.is_direct = true;
|
||||
creat_conn_params.is_aux = false;
|
||||
creat_conn_params.phy_mask = ESP_BLE_PHY_1M_PREF_MASK;
|
||||
creat_conn_params.phy_1m_conn_params = &phy_1m_conn_params;
|
||||
esp_ble_gattc_enh_open(gl_profile_tab[PROFILE_APP_ID].gattc_if,
|
||||
&creat_conn_params);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_SEARCH_INQ_CMPL_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "Scan complete");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -276,12 +278,19 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
|
||||
break;
|
||||
}
|
||||
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
|
||||
if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS){
|
||||
ESP_LOGE(GATTC_TAG, "Adv stop failed: %s", esp_err_to_name(err));
|
||||
}else {
|
||||
ESP_LOGI(GATTC_TAG, "Stop adv successfully");
|
||||
if ((err = param->adv_stop_cmpl.status) != ESP_BT_STATUS_SUCCESS) {
|
||||
ESP_LOGE(GATTC_TAG, "Advertising stop failed, err %s", esp_err_to_name(err));
|
||||
} else {
|
||||
ESP_LOGI(GATTC_TAG, "Advertising stop successfully");
|
||||
}
|
||||
break;
|
||||
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "Connection params update, status %d, conn_int %d, latency %d, timeout %d",
|
||||
param->update_conn_params.status,
|
||||
param->update_conn_params.conn_int,
|
||||
param->update_conn_params.latency,
|
||||
param->update_conn_params.timeout);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -289,7 +298,6 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
|
||||
|
||||
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) {
|
||||
@@ -321,40 +329,56 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
|
||||
switch (event) {
|
||||
case ESP_GATTC_REG_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "REG EVT, set scan params");
|
||||
ESP_LOGI(GATTC_TAG, "GATT client register, status %d, app_id %d, gattc_if %d", param->reg.status, param->reg.app_id, gattc_if);
|
||||
esp_ble_gap_set_scan_params(&ble_scan_params);
|
||||
break;
|
||||
case ESP_GATTC_CONNECT_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT: conn_id=%d, gatt_if = %d", spp_conn_id, gattc_if);
|
||||
ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
|
||||
ESP_LOG_BUFFER_HEX(GATTC_TAG, gl_profile_tab[PROFILE_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
|
||||
ESP_LOGI(GATTC_TAG, "Connected, conn_id %d, remote "ESP_BD_ADDR_STR"", p_data->connect.conn_id,
|
||||
ESP_BD_ADDR_HEX(p_data->connect.remote_bda));
|
||||
memcpy(gl_profile_tab[PROFILE_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
|
||||
spp_gattc_if = gattc_if;
|
||||
is_connect = true;
|
||||
spp_conn_id = p_data->connect.conn_id;
|
||||
memcpy(gl_profile_tab[PROFILE_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
|
||||
esp_ble_gattc_search_service(spp_gattc_if, spp_conn_id, &spp_service_uuid);
|
||||
break;
|
||||
case ESP_GATTC_OPEN_EVT:
|
||||
if (param->open.status != ESP_GATT_OK){
|
||||
ESP_LOGE(GATTC_TAG, "Open failed, status %d", p_data->open.status);
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(GATTC_TAG, "Open successfully, MTU %u", p_data->open.mtu);
|
||||
break;
|
||||
case ESP_GATTC_DISCONNECT_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "disconnect");
|
||||
ESP_LOGI(GATTC_TAG, "Disconnected, remote "ESP_BD_ADDR_STR", reason 0x%02x",
|
||||
ESP_BD_ADDR_HEX(p_data->disconnect.remote_bda), p_data->disconnect.reason);
|
||||
free_gattc_srv_db();
|
||||
start = false;
|
||||
start_time = 0;
|
||||
current_time = 0;
|
||||
notify_len = 0;
|
||||
esp_ble_gap_start_scanning(SCAN_ALL_THE_TIME);
|
||||
break;
|
||||
case ESP_GATTC_SEARCH_RES_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_RES_EVT: start_handle = %d, end_handle = %d, UUID:0x%04x",p_data->search_res.start_handle,p_data->search_res.end_handle,p_data->search_res.srvc_id.uuid.uuid.uuid16);
|
||||
ESP_LOGI(GATTC_TAG, "Service search result, start_handle %d, end_handle %d, UUID:0x%04x",
|
||||
p_data->search_res.start_handle, p_data->search_res.end_handle, p_data->search_res.srvc_id.uuid.uuid.uuid16);
|
||||
spp_srv_start_handle = p_data->search_res.start_handle;
|
||||
spp_srv_end_handle = p_data->search_res.end_handle;
|
||||
break;
|
||||
case ESP_GATTC_SEARCH_CMPL_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "SEARCH_CMPL: conn_id = %x, status %d", spp_conn_id, p_data->search_cmpl.status);
|
||||
ESP_LOGI(GATTC_TAG, "Service search complete, conn_id %x, status %d", spp_conn_id, p_data->search_cmpl.status);
|
||||
esp_ble_gattc_send_mtu_req(gattc_if, spp_conn_id);
|
||||
break;
|
||||
case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
|
||||
ESP_LOGI(GATTC_TAG,"Index = %d,status = %d,handle = %d",cmd, p_data->reg_for_notify.status, p_data->reg_for_notify.handle);
|
||||
if(p_data->reg_for_notify.status != ESP_GATT_OK){
|
||||
ESP_LOGE(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT, status = %d", p_data->reg_for_notify.status);
|
||||
ESP_LOGI(GATTC_TAG,"Notification register, index %d, status %d, handle %d", cmd, p_data->reg_for_notify.status, p_data->reg_for_notify.handle);
|
||||
if (p_data->reg_for_notify.status != ESP_GATT_OK) {
|
||||
break;
|
||||
}
|
||||
uint16_t notify_en = 1;
|
||||
uint16_t notify_en = 0x01;
|
||||
#ifdef CONFIG_EXAMPLE_SPP_RELIABLE
|
||||
if (cmd == SPP_IDX_SPP_DATA_NTY_VAL) {
|
||||
notify_en = 0x02;
|
||||
}
|
||||
#endif
|
||||
esp_ble_gattc_write_char_descr(
|
||||
spp_gattc_if,
|
||||
spp_conn_id,
|
||||
@@ -363,31 +387,33 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
(uint8_t *)¬ify_en,
|
||||
ESP_GATT_WRITE_TYPE_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
|
||||
break;
|
||||
}
|
||||
case ESP_GATTC_NOTIFY_EVT:
|
||||
ESP_LOGI(GATTC_TAG,"ESP_GATTC_NOTIFY_EVT");
|
||||
if (p_data->notify.is_notify){
|
||||
// ESP_LOGI(GATTC_TAG, "Notification received, handle %d", param->notify.handle);
|
||||
}else{
|
||||
// ESP_LOGI(GATTC_TAG, "Indication received, handle %d", param->notify.handle);
|
||||
}
|
||||
notify_event_handler(p_data);
|
||||
break;
|
||||
case ESP_GATTC_READ_CHAR_EVT:
|
||||
ESP_LOGI(GATTC_TAG,"ESP_GATTC_READ_CHAR_EVT");
|
||||
ESP_LOGI(GATTC_TAG,"Characteristic read");
|
||||
break;
|
||||
case ESP_GATTC_WRITE_CHAR_EVT:
|
||||
ESP_LOGI(GATTC_TAG,"ESP_GATTC_WRITE_CHAR_EVT:status = %d,handle = %d", param->write.status, param->write.handle);
|
||||
if(param->write.status != ESP_GATT_OK){
|
||||
ESP_LOGE(GATTC_TAG, "ESP_GATTC_WRITE_CHAR_EVT, error status = %d", p_data->write.status);
|
||||
break;
|
||||
if (param->write.status) {
|
||||
ESP_LOGI(GATTC_TAG,"Characteristic write, status %d, handle %d", param->write.status, param->write.handle);
|
||||
}
|
||||
break;
|
||||
case ESP_GATTC_PREP_WRITE_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "Prepare write");
|
||||
break;
|
||||
case ESP_GATTC_EXEC_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "Execute write %d", param->exec_cmpl.status);
|
||||
break;
|
||||
case ESP_GATTC_WRITE_DESCR_EVT:
|
||||
ESP_LOGI(GATTC_TAG,"ESP_GATTC_WRITE_DESCR_EVT: status =%d,handle = %d", p_data->write.status, p_data->write.handle);
|
||||
ESP_LOGI(GATTC_TAG,"Descriptor write, status %d, handle %d", p_data->write.status, p_data->write.handle);
|
||||
if(p_data->write.status != ESP_GATT_OK){
|
||||
ESP_LOGE(GATTC_TAG, "ESP_GATTC_WRITE_DESCR_EVT, error status = %d", p_data->write.status);
|
||||
break;
|
||||
}
|
||||
switch(cmd){
|
||||
@@ -396,64 +422,64 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
xQueueSend(cmd_reg_queue, &cmd,10/portTICK_PERIOD_MS);
|
||||
break;
|
||||
case SPP_IDX_SPP_STATUS_VAL:
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
cmd = SPP_IDX_SPP_HEARTBEAT_VAL;
|
||||
xQueueSend(cmd_reg_queue, &cmd, 10/portTICK_PERIOD_MS);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
case SPP_IDX_SPP_HEARTBEAT_VAL:
|
||||
xQueueSend(cmd_heartbeat_queue, &cmd, 10/portTICK_PERIOD_MS);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
};
|
||||
break;
|
||||
case ESP_GATTC_CFG_MTU_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "MTU exchange, status %d, MTU %d", param->cfg_mtu.status, param->cfg_mtu.mtu);
|
||||
if(p_data->cfg_mtu.status != ESP_OK){
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(GATTC_TAG,"+MTU:%d", p_data->cfg_mtu.mtu);
|
||||
spp_mtu_size = p_data->cfg_mtu.mtu;
|
||||
|
||||
db = (esp_gattc_db_elem_t *)malloc(count*sizeof(esp_gattc_db_elem_t));
|
||||
if(db == NULL){
|
||||
ESP_LOGE(GATTC_TAG,"%s:malloc db failed",__func__);
|
||||
ESP_LOGE(GATTC_TAG, "Malloc db failed");
|
||||
break;
|
||||
}
|
||||
if(esp_ble_gattc_get_db(spp_gattc_if, spp_conn_id, spp_srv_start_handle, spp_srv_end_handle, db, &count) != ESP_GATT_OK){
|
||||
ESP_LOGE(GATTC_TAG,"%s:get db failed",__func__);
|
||||
ESP_LOGE(GATTC_TAG, "Get db failed");
|
||||
break;
|
||||
}
|
||||
if(count != SPP_IDX_NB){
|
||||
ESP_LOGE(GATTC_TAG,"%s:get db count != SPP_IDX_NB, count = %d, SPP_IDX_NB = %d",__func__,count,SPP_IDX_NB);
|
||||
ESP_LOGE(GATTC_TAG, "Get db count != SPP_IDX_NB, count = %d, SPP_IDX_NB = %d", count, SPP_IDX_NB);
|
||||
break;
|
||||
}
|
||||
for(int i = 0;i < SPP_IDX_NB;i++){
|
||||
switch((db+i)->type){
|
||||
case ESP_GATT_DB_PRIMARY_SERVICE:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = PRIMARY_SERVICE,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "PRIMARY_SERVICE, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
case ESP_GATT_DB_SECONDARY_SERVICE:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = SECONDARY_SERVICE,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "SECONDARY_SERVICE, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
case ESP_GATT_DB_CHARACTERISTIC:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = CHARACTERISTIC,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "CHARACTERISTIC, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
case ESP_GATT_DB_DESCRIPTOR:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = DESCRIPTOR,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "DESCRIPTOR, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
case ESP_GATT_DB_INCLUDED_SERVICE:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = INCLUDED_SERVICE,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "INCLUDED_SERVICE, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
case ESP_GATT_DB_ALL:
|
||||
ESP_LOGI(GATTC_TAG,"attr_type = ESP_GATT_DB_ALL,attribute_handle=%d,start_handle=%d,end_handle=%d,properties=0x%x,uuid=0x%04x",\
|
||||
ESP_LOGI(GATTC_TAG, "GATT_DB_ALL, attribute_handle %d, start_handle %d, end_handle %d, properties 0x%x, uuid 0x%04x",
|
||||
(db+i)->attribute_handle, (db+i)->start_handle, (db+i)->end_handle, (db+i)->properties, (db+i)->uuid.uuid.uuid16);
|
||||
break;
|
||||
default:
|
||||
@@ -464,6 +490,7 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
xQueueSend(cmd_reg_queue, &cmd, 10/portTICK_PERIOD_MS);
|
||||
break;
|
||||
case ESP_GATTC_SRVC_CHG_EVT:
|
||||
ESP_LOGI(GATTC_TAG, "Service change from "ESP_BD_ADDR_STR"", ESP_BD_ADDR_HEX(p_data->srvc_chg.remote_bda));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -473,20 +500,20 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
void spp_client_reg_task(void* arg)
|
||||
{
|
||||
uint16_t cmd_id;
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
if(xQueueReceive(cmd_reg_queue, &cmd_id, portMAX_DELAY)) {
|
||||
if(db != NULL) {
|
||||
if(cmd_id == SPP_IDX_SPP_DATA_NTY_VAL){
|
||||
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d", cmd_id, (db+SPP_IDX_SPP_DATA_NTY_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_DATA_NTY_VAL)->attribute_handle);
|
||||
if (xQueueReceive(cmd_reg_queue, &cmd_id, portMAX_DELAY)) {
|
||||
if (db != NULL) {
|
||||
if (cmd_id == SPP_IDX_SPP_DATA_NTY_VAL) {
|
||||
ESP_LOGI(GATTC_TAG,"Index %d, UUID 0x%04x, handle %d", cmd_id, (db+SPP_IDX_SPP_DATA_NTY_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_DATA_NTY_VAL)->attribute_handle);
|
||||
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_DATA_NTY_VAL)->attribute_handle);
|
||||
}else if(cmd_id == SPP_IDX_SPP_STATUS_VAL){
|
||||
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d", cmd_id, (db+SPP_IDX_SPP_STATUS_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle);
|
||||
} else if(cmd_id == SPP_IDX_SPP_STATUS_VAL) {
|
||||
ESP_LOGI(GATTC_TAG,"Index %d, UUID 0x%04x, handle %d", cmd_id, (db+SPP_IDX_SPP_STATUS_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle);
|
||||
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle);
|
||||
}
|
||||
#ifdef SUPPORT_HEARTBEAT
|
||||
else if(cmd_id == SPP_IDX_SPP_HEARTBEAT_VAL){
|
||||
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d", cmd_id, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle);
|
||||
else if (cmd_id == SPP_IDX_SPP_HEARTBEAT_VAL) {
|
||||
ESP_LOGI(GATTC_TAG,"Index %d, UUID 0x%04x, handle %d", cmd_id, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle);
|
||||
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle);
|
||||
}
|
||||
#endif
|
||||
@@ -500,11 +527,11 @@ void spp_heart_beat_task(void * arg)
|
||||
{
|
||||
uint16_t cmd_id;
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
if(xQueueReceive(cmd_heartbeat_queue, &cmd_id, portMAX_DELAY)) {
|
||||
if (xQueueReceive(cmd_heartbeat_queue, &cmd_id, portMAX_DELAY)) {
|
||||
while(1){
|
||||
if((is_connect == true) && (db != NULL) && ((db+SPP_IDX_SPP_HEARTBEAT_VAL)->properties & (ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_WRITE))){
|
||||
if ((is_connect == true) && (db != NULL) && ((db+SPP_IDX_SPP_HEARTBEAT_VAL)->properties & (ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_WRITE))) {
|
||||
esp_ble_gattc_write_char( spp_gattc_if,
|
||||
spp_conn_id,
|
||||
(db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle,
|
||||
@@ -513,7 +540,7 @@ void spp_heart_beat_task(void * arg)
|
||||
ESP_GATT_WRITE_TYPE_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
}else{
|
||||
} else {
|
||||
ESP_LOGI(GATTC_TAG,"disconnect");
|
||||
break;
|
||||
}
|
||||
@@ -540,10 +567,8 @@ void ble_client_appRegister(void)
|
||||
ESP_LOGE(GATTC_TAG, "gattc register error: %s", esp_err_to_name_r(status, err_msg, sizeof(err_msg)));
|
||||
return;
|
||||
}
|
||||
esp_ble_gattc_app_register(PROFILE_APP_ID);
|
||||
|
||||
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(200);
|
||||
if (local_mtu_ret){
|
||||
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(SPP_GATT_MTU_SIZE);
|
||||
if (local_mtu_ret) {
|
||||
ESP_LOGE(GATTC_TAG, "set local MTU failed: %s", esp_err_to_name_r(local_mtu_ret, err_msg, sizeof(err_msg)));
|
||||
}
|
||||
|
||||
@@ -554,6 +579,7 @@ void ble_client_appRegister(void)
|
||||
cmd_heartbeat_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||
xTaskCreate(spp_heart_beat_task, "spp_heart_beat_task", 2048, NULL, 10, NULL);
|
||||
#endif
|
||||
esp_ble_gattc_app_register(PROFILE_APP_ID);
|
||||
}
|
||||
|
||||
void uart_task(void *pvParameters)
|
||||
@@ -567,20 +593,40 @@ void uart_task(void *pvParameters)
|
||||
case UART_DATA:
|
||||
if (event.size && (is_connect == true) && (db != NULL) && ((db+SPP_IDX_SPP_DATA_RECV_VAL)->properties & (ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_WRITE))) {
|
||||
uint8_t * temp = NULL;
|
||||
size_t offset = 0;
|
||||
size_t send_len = 0;
|
||||
temp = (uint8_t *)malloc(sizeof(uint8_t)*event.size);
|
||||
if(temp == NULL){
|
||||
ESP_LOGE(GATTC_TAG, "malloc failed,%s L#%d", __func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
memset(temp, 0x0, event.size);
|
||||
uart_read_bytes(UART_NUM_0,temp,event.size,portMAX_DELAY);
|
||||
esp_ble_gattc_write_char( spp_gattc_if,
|
||||
spp_conn_id,
|
||||
(db+SPP_IDX_SPP_DATA_RECV_VAL)->attribute_handle,
|
||||
event.size,
|
||||
temp,
|
||||
ESP_GATT_WRITE_TYPE_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
uart_read_bytes(UART_NUM_0, temp, event.size, portMAX_DELAY);
|
||||
while (offset < event.size) {
|
||||
send_len = MIN(spp_mtu_size - 3, event.size - offset);
|
||||
#ifdef CONFIG_EXAMPLE_SPP_THROUGHPUT
|
||||
if (esp_ble_get_cur_sendable_packets_num(spp_conn_id) > 0) {
|
||||
esp_ble_gattc_write_char(spp_gattc_if,
|
||||
spp_conn_id,
|
||||
(db+SPP_IDX_SPP_DATA_RECV_VAL)->attribute_handle,
|
||||
send_len,
|
||||
temp + offset,
|
||||
ESP_GATT_WRITE_TYPE_NO_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
} else {
|
||||
//Add the vTaskDelay to prevent this task from consuming the CPU all the time, causing low-priority tasks to not be executed at all.
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
#else
|
||||
esp_ble_gattc_write_char(spp_gattc_if,
|
||||
spp_conn_id,
|
||||
(db+SPP_IDX_SPP_DATA_RECV_VAL)->attribute_handle,
|
||||
send_len,
|
||||
temp + offset,
|
||||
ESP_GATT_WRITE_TYPE_RSP,
|
||||
ESP_GATT_AUTH_REQ_NONE);
|
||||
#endif
|
||||
offset += send_len;
|
||||
}
|
||||
free(temp);
|
||||
}
|
||||
break;
|
||||
@@ -600,7 +646,7 @@ static void spp_uart_init(void)
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_RTS,
|
||||
.rx_flow_ctrl_thresh = 122,
|
||||
.rx_flow_ctrl_thresh = 124,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
|
||||
@@ -610,18 +656,21 @@ static void spp_uart_init(void)
|
||||
uart_param_config(UART_NUM_0, &uart_config);
|
||||
//Set UART pins
|
||||
uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
xTaskCreate(uart_task, "uTask", 2048, (void*)UART_NUM_0, 8, NULL);
|
||||
xTaskCreate(uart_task, "uTask", 4096, (void*)UART_NUM_0, 8, NULL);
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
spp_uart_init();
|
||||
|
||||
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
|
||||
nvs_flash_init();
|
||||
|
||||
ret = esp_bt_controller_init(&bt_cfg);
|
||||
if (ret) {
|
||||
ESP_LOGE(GATTC_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
|
||||
@@ -648,5 +697,4 @@ void app_main(void)
|
||||
}
|
||||
|
||||
ble_client_appRegister();
|
||||
spp_uart_init();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user