Merge branch 'feature/support_ble_write_and_notify_throughput_test_at_the_same_time_v5.0' into 'release/v5.0'

support ble write and notify throughput test at the same time (backport v5.0)

See merge request espressif/esp-idf!22143
This commit is contained in:
Wang Meng Yang 2023-03-09 11:38:15 +08:00
commit e9092c2d2d
4 changed files with 97 additions and 63 deletions

View File

@ -78,6 +78,7 @@ typedef enum {
ESP_BLUFI_DATA_FORMAT_ERROR,
ESP_BLUFI_CALC_MD5_ERROR,
ESP_BLUFI_WIFI_SCAN_FAIL,
ESP_BLUFI_MSG_STATE_ERROR,
} esp_blufi_error_state_t;
/**

View File

@ -136,6 +136,16 @@ void btc_blufi_recv_handler(uint8_t *data, int len)
if (BLUFI_FC_IS_FRAG(hdr->fc)) {
if (blufi_env.offset == 0) {
/*
blufi_env.aggr_buf should be NULL if blufi_env.offset is 0.
It is possible that the process of sending fragment packet
has not been completed
*/
if (blufi_env.aggr_buf) {
BTC_TRACE_ERROR("%s msg error, blufi_env.aggr_buf is not freed\n", __func__);
btc_blufi_report_error(ESP_BLUFI_MSG_STATE_ERROR);
return;
}
blufi_env.total_len = hdr->data[0] | (((uint16_t) hdr->data[1]) << 8);
blufi_env.aggr_buf = osi_malloc(blufi_env.total_len);
if (blufi_env.aggr_buf == NULL) {
@ -155,6 +165,18 @@ void btc_blufi_recv_handler(uint8_t *data, int len)
} else {
if (blufi_env.offset > 0) { /* if previous pkt is frag */
/* blufi_env.aggr_buf should not be NULL */
if (blufi_env.aggr_buf == NULL) {
BTC_TRACE_ERROR("%s buffer is NULL\n", __func__);
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
return;
}
/* payload length should be equal to total_len */
if ((blufi_env.offset + hdr->data_len) != blufi_env.total_len) {
BTC_TRACE_ERROR("%s payload is longer than packet length, len %d \n", __func__, blufi_env.total_len);
btc_blufi_report_error(ESP_BLUFI_DATA_FORMAT_ERROR);
return;
}
memcpy(blufi_env.aggr_buf + blufi_env.offset, hdr->data, hdr->data_len);
btc_blufi_protocol_handler(hdr->type, blufi_env.aggr_buf, blufi_env.total_len);

View File

@ -60,7 +60,7 @@ static uint64_t current_time = 0;
#endif /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
#define GATTC_WRITE_LEN 490
#define GATTC_WRITE_LEN 495
static bool can_send_write = false;
static SemaphoreHandle_t gattc_semaphore;
@ -150,7 +150,6 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
}
break;
case ESP_GATTC_CONNECT_EVT: {
is_connect = true;
ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d", p_data->connect.conn_id, gattc_if);
gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
@ -173,6 +172,7 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (param->cfg_mtu.status != ESP_GATT_OK){
ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status);
}
is_connect = true;
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;
@ -309,8 +309,6 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
break;
}
#else /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */
esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
#endif /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */
break;
}
@ -337,7 +335,6 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
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:
is_connect = false;
@ -402,7 +399,12 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par
if (connect == false) {
connect = true;
ESP_LOGI(GATTC_TAG, "connect to the remote device.");
#if(CONFIG_GATTC_WRITE_THROUGHPUT && CONFIG_GATTS_NOTIFY_THROUGHPUT)
esp_ble_gap_set_prefer_conn_params(scan_result->scan_rst.bda, 34, 34, 0, 600);
#else
esp_ble_gap_set_prefer_conn_params(scan_result->scan_rst.bda, 32, 32, 0, 600);
#endif
esp_ble_gap_stop_scanning();
esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, BLE_ADDR_TYPE_PUBLIC, true);
}
@ -475,30 +477,15 @@ static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp
} while (0);
}
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
static void throughput_client_task(void *param)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
uint8_t sum = check_sum(write_data, sizeof(write_data) - 1);
write_data[GATTC_WRITE_LEN - 1] = sum;
#endif /* #if (CONFIG_GATTC_WRITE_THROUGHPUT) */
while(1) {
#if (CONFIG_GATTS_NOTIFY_THROUGHPUT)
vTaskDelay(2000 / portTICK_PERIOD_MS);
if(is_connect){
uint32_t bit_rate = 0;
if (start_time) {
current_time = esp_timer_get_time();
bit_rate = notify_len * SECOND_TO_USECOND / (current_time - start_time);
ESP_LOGI(GATTC_TAG, "Notify Bit rate = %" PRIu32 " Byte/s, = %" PRIu32 " bit/s, time = %ds",
bit_rate, bit_rate<<3, (int)((current_time - start_time) / SECOND_TO_USECOND));
} else {
ESP_LOGI(GATTC_TAG, "Notify Bit rate = 0 Byte/s, = 0 bit/s");
}
}
#endif /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
if (!can_send_write) {
int res = xSemaphoreTake(gattc_semaphore, portMAX_DELAY);
assert(res == pdTRUE);
@ -519,12 +506,36 @@ static void throughput_client_task(void *param)
} 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 {
vTaskDelay(300 / portTICK_PERIOD_MS );
}
}
#endif /* #if (CONFIG_GATTC_WRITE_THROUGHPUT) */
}
}
#endif /* #if (CONFIG_GATTC_WRITE_THROUGHPUT) */
#if (CONFIG_GATTS_NOTIFY_THROUGHPUT)
static void throughput_cal_task(void *param)
{
while (1)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
if(is_connect){
uint32_t bit_rate = 0;
if (start_time) {
current_time = esp_timer_get_time();
bit_rate = notify_len * SECOND_TO_USECOND / (current_time - start_time);
ESP_LOGI(GATTC_TAG, "Notify Bit rate = %" PRIu32 " Byte/s, = %" PRIu32 " bit/s, time = %ds",
bit_rate, bit_rate<<3, (int)((current_time - start_time) / SECOND_TO_USECOND));
} else {
ESP_LOGI(GATTC_TAG, "Notify Bit rate = 0 Byte/s, = 0 bit/s");
}
}
}
}
#endif /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */
void app_main(void)
{
@ -586,9 +597,15 @@ void app_main(void)
if (local_mtu_ret){
ESP_LOGE(GATTC_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
}
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
// The task is only created on the CPU core that Bluetooth is working on,
// preventing the sending task from using the un-updated Bluetooth state on another CPU.
xTaskCreatePinnedToCore(&throughput_client_task, "throughput_client_task", 4096, NULL, 10, NULL, BLUETOOTH_TASK_PINNED_TO_CORE);
#endif
#if (CONFIG_GATTS_NOTIFY_THROUGHPUT)
xTaskCreatePinnedToCore(&throughput_cal_task, "throughput_cal_task", 4096, NULL, 9, NULL, BLUETOOTH_TASK_PINNED_TO_CORE);
#endif
#if (CONFIG_GATTC_WRITE_THROUGHPUT)
gattc_semaphore = xSemaphoreCreateBinary();

View File

@ -46,7 +46,7 @@
#define GATTS_TAG "GATTS_DEMO"
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
#define GATTS_NOTIFY_LEN 490
#define GATTS_NOTIFY_LEN 495
static SemaphoreHandle_t gatts_semaphore;
static bool can_send_notify = false;
static uint8_t indicate_data[GATTS_NOTIFY_LEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a};
@ -323,9 +323,7 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare
}
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){
esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
}else{
if (param->exec_write.exec_write_flag != ESP_GATT_PREP_WRITE_EXEC){
ESP_LOGI(GATTS_TAG,"ESP_GATT_PREP_WRITE_CANCEL");
}
if (prepare_write_env->prepare_buf) {
@ -392,10 +390,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
}
case ESP_GATTS_WRITE_EVT: {
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
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);
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){
@ -468,6 +463,7 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
break;
case ESP_GATTS_MTU_EVT:
ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
is_connect = true;
break;
case ESP_GATTS_UNREG_EVT:
break;
@ -529,21 +525,11 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
case ESP_GATTS_STOP_EVT:
break;
case ESP_GATTS_CONNECT_EVT: {
is_connect = true;
esp_ble_conn_update_params_t conn_params = {0};
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
conn_params.latency = 0;
conn_params.max_int = 0x20; // max_int = 0x20*1.25ms = 40ms
conn_params.min_int = 0x10; // min_int = 0x10*1.25ms = 20ms
conn_params.timeout = 400; // timeout = 400*10ms = 4000ms
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
param->connect.conn_id,
param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id;
//start sent the update connection parameters to the peer device.
//esp_ble_gap_update_conn_params(&conn_params);
break;
}
case ESP_GATTS_DISCONNECT_EVT:
@ -552,12 +538,6 @@ static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_i
esp_ble_gap_start_advertising(&adv_params);
break;
case ESP_GATTS_CONF_EVT:
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT, status %d", param->conf.status);
#if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT)
start_time = false;
current_time = 0;
write_len = 0;
#endif /* #if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT) */
break;
case ESP_GATTS_OPEN_EVT:
case ESP_GATTS_CANCEL_OPEN_EVT:
@ -608,17 +588,15 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
} while (0);
}
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
void throughput_server_task(void *param)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
uint8_t sum = check_sum(indicate_data, sizeof(indicate_data) - 1);
// Added the check sum in the last data value.
indicate_data[GATTS_NOTIFY_LEN - 1] = sum;
#endif /* #if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT) */
while(1) {
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
if (!can_send_notify) {
int res = xSemaphoreTake(gatts_semaphore, portMAX_DELAY);
assert(res == pdTRUE);
@ -634,25 +612,33 @@ void throughput_server_task(void *param)
} 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 {
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
#endif /* #if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT) */
#if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT)
uint32_t bit_rate = 0;
vTaskDelay(2000 / portTICK_PERIOD_MS);
if (start_time) {
current_time = esp_timer_get_time();
bit_rate = write_len * SECOND_TO_USECOND / (current_time - start_time);
ESP_LOGI(GATTS_TAG, "GATTC write Bit rate = %d Byte/s, = %d bit/s, time = %ds",
bit_rate, bit_rate<<3, (int)((current_time - start_time) / SECOND_TO_USECOND));
} else {
ESP_LOGI(GATTS_TAG, "GATTC write Bit rate = 0 Byte/s, = 0 bit/s");
}
#endif /* #if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT) */
}
}
#endif
#if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT)
void throughput_cal_task(void *param)
{
while (1)
{
uint32_t bit_rate = 0;
vTaskDelay(2000 / portTICK_PERIOD_MS);
if (is_connect && start_time) {
current_time = esp_timer_get_time();
bit_rate = write_len * SECOND_TO_USECOND / (current_time - start_time);
ESP_LOGI(GATTS_TAG, "GATTC write Bit rate = %" PRIu32 " Byte/s, = %" PRIu32 " bit/s, time %d",
bit_rate, bit_rate<<3, (int)((current_time - start_time) / SECOND_TO_USECOND));
}
}
}
#endif /* #if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT) */
void app_main(void)
{
@ -711,9 +697,17 @@ void app_main(void)
if (local_mtu_ret){
ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
}
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
// The task is only created on the CPU core that Bluetooth is working on,
// preventing the sending task from using the un-updated Bluetooth state on another CPU.
xTaskCreatePinnedToCore(&throughput_server_task, "throughput_server_task", 4096, NULL, 15, NULL, BLUETOOTH_TASK_PINNED_TO_CORE);
#endif
#if (CONFIG_EXAMPLE_GATTC_WRITE_THROUGHPUT)
xTaskCreatePinnedToCore(&throughput_cal_task, "throughput_cal_task", 4096, NULL, 14, NULL, BLUETOOTH_TASK_PINNED_TO_CORE);
#endif
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT)
gatts_semaphore = xSemaphoreCreateBinary();
if (!gatts_semaphore) {