From a662b6c3e7b19c39b82ea2e7a00ff68105c9a5f8 Mon Sep 17 00:00:00 2001 From: zwsd Date: Thu, 21 Jul 2022 16:44:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E6=9E=90=E6=95=B0=E6=8D=AE=E5=B0=81?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- main/CMakeLists.txt | 1 + main/ble_parse_data.c | 137 ++++++ main/ble_parse_data.h | 46 ++ main/ble_spp_server_demo.c | 1091 +++++++++++++++++++++----------------------- main/ble_spp_server_demo.h | 52 +-- main/main.c | 135 +----- 7 files changed, 715 insertions(+), 750 deletions(-) create mode 100644 main/ble_parse_data.c create mode 100644 main/ble_parse_data.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 8421d8e..5b18e0d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ "esp_bt_main.h": "c", "esp_gatts_api.h": "c", "freertos.h": "c", - "regex": "c" + "regex": "c", + "ble_parse_data.h": "c" }, } \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 8d456ce..128a99e 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -3,6 +3,7 @@ idf_component_register(SRCS # "ble_spp_server_demo.c" "main.c" "timer_u.c" + "ble_parse_data.c" INCLUDE_DIRS # "../dep/" ".") diff --git a/main/ble_parse_data.c b/main/ble_parse_data.c new file mode 100644 index 0000000..e7cd666 --- /dev/null +++ b/main/ble_parse_data.c @@ -0,0 +1,137 @@ +#include "ble_parse_data.h" + +#define GATTS_TABLE_TAG "GATTS_SPP_DEMO" + +#define cmd_length_set_position 5 +#define cmd_length_get_status 2 + +static bluetooth_processer_t *parse_bluetooth_processer; +uint8_t bluetooth_rx_buffer_len = 0; + +bool test_flag; + +void constructor_bluetooth_processer(bluetooth_processer_t *bluetooth_processer) { parse_bluetooth_processer = bluetooth_processer; } + +void bluetooth_gatts_try_process_data() { + cJSON *json_tmp; + // cJSON *ch; + //开始接收 + if (parse_bluetooth_processer->bluetooth_rx_buffer_start_receving) { + //开启定时器 + parse_bluetooth_processer->port_delay_ms(parse_bluetooth_processer->bluetooth_baundrate_one_packet_delay_ms); + // port_timer_delay_ms(kbluetooth_baundrate_one_packet_delay_ms); + parse_bluetooth_processer->bluetooth_rx_buffer_processing = true; + + //打印输出 + // ESP_LOGI(GATTS_TABLE_TAG, "%s", parse_bluetooth_processer->bluetooth_processer_rx_buf); + + //验证解析数据是否正确 + if (parse_rxbuffer_and_validation_data(&json_tmp)) { + // JSON解析到结构体,如果order更改表示有指令传输进来,并且更改指令标志位(cmd_flag)为true + if (parse_json_to_struct(json_tmp->child)) { + ESP_LOGI(GATTS_TABLE_TAG, "order:%s ,index:%d speedLevel:%d position:%f direction:%d", parse_bluetooth_processer->order, parse_bluetooth_processer->index, + parse_bluetooth_processer->speedLevel, parse_bluetooth_processer->position, parse_bluetooth_processer->direction); + if (strcmp(parse_bluetooth_processer->order, set_position) == 0) { + ESP_LOGI(GATTS_TABLE_TAG, set_position); + // motor_cmd_set_position(parse_bluetooth_processer->speedLevel, parse_bluetooth_processer->position, parse_bluetooth_processer->direction); + // receipt_json_set_position(); + } + if (strcmp(parse_bluetooth_processer->order, get_status) == 0) { + ESP_LOGI(GATTS_TABLE_TAG, get_status); + test_flag = true; + // receipt_json_get_status(); + } + // if (strcmp(parse_bluetooth_processer->order, "deviceStatusReport") == 0) + // { + // ESP_LOGI(GATTS_TABLE_TAG, "deviceStatusReport"); + // } + parse_bluetooth_processer->actively_report_flag = true; + } + } + + //释放空间 + cJSON_Delete(json_tmp); + // buffer置0 + buffer_all_init(); + //未在处理数据 + parse_bluetooth_processer->cmd_flag = false; + parse_bluetooth_processer->bluetooth_rx_buffer_start_receving = false; + parse_bluetooth_processer->bluetooth_rx_buffer_processing = false; + } +} + +void start_receive_data_to_buffer(uint16_t length, uint8_t *value) { + parse_bluetooth_processer->bluetooth_rx_buffer_start_receving = true; + timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); + //判断是否buffer越界 + if ((length + bluetooth_rx_buffer_len) > profile_b_buffer_size) { + return; + } + + if (!parse_bluetooth_processer->bluetooth_rx_buffer_processing) { + //写入到buffer + for (int i = 0; i < length; i++) { + parse_bluetooth_processer->bluetooth_processer_rx_buf[bluetooth_rx_buffer_len++] = value[i]; + } + } +} + +void buffer_all_init() { + bluetooth_rx_buffer_len = 0; + memset(parse_bluetooth_processer->bluetooth_processer_rx_buf, 0, profile_b_buffer_size); +} + +bool parse_rxbuffer_and_validation_data(cJSON **json_tmp) { + *json_tmp = cJSON_Parse(parse_bluetooth_processer->bluetooth_processer_rx_buf); + if (*json_tmp == NULL) { + ESP_LOGE(GATTS_TABLE_TAG, "parse rxbuffer null or redundant symbol ',','{' "); + return false; + } + return true; +} +bool parse_json_to_struct(cJSON *ch) { + uint8_t cmd_length = 0; + while (ch != NULL) { + // ESP_LOGI(GATTS_TABLE_TAG, "%s", ch->string); + if (strcmp(ch->string, "order") == 0) { + parse_bluetooth_processer->order = ch->valuestring; + + if (strcmp(ch->valuestring, set_position) == 0) { + cmd_length = cmd_length_set_position; + } + if (strcmp(ch->valuestring, get_status) == 0) { + cmd_length = cmd_length_get_status; + } + // if (strcmp(ch->valuestring, "deviceStatusReport") == 0) + // { + // cmd_length = cmd_length_device_status_report; + // } + cmd_length--; + } + if (strcmp(ch->string, "index") == 0) { + parse_bluetooth_processer->index = ch->valueint; + cmd_length--; + } + if (strcmp(ch->string, "speedLevel") == 0) { + parse_bluetooth_processer->speedLevel = ch->valueint; + cmd_length--; + } + if (strcmp(ch->string, "position") == 0) { + parse_bluetooth_processer->position = ch->valuedouble; + cmd_length--; + } + if (strcmp(ch->string, "direction") == 0) { + parse_bluetooth_processer->direction = ch->valueint; + cmd_length--; + } + ch = ch->next; + } + + if (cmd_length == 0) { + parse_bluetooth_processer->cmd_flag = true; + } else { + ESP_LOGE(GATTS_TABLE_TAG, "JSON directive missing or exceeded"); + } + + return parse_bluetooth_processer->cmd_flag; +} \ No newline at end of file diff --git a/main/ble_parse_data.h b/main/ble_parse_data.h new file mode 100644 index 0000000..fcf10ef --- /dev/null +++ b/main/ble_parse_data.h @@ -0,0 +1,46 @@ +#include +#include +#include + +#include "cJSON.h" +#include "cJSON_Utils.h" +#include "driver/timer.h" +#include "esp_log.h" + +#define profile_b_buffer_size 128 + +#define set_position "setPosition" +#define get_status "getStatus" + +typedef struct bluetooth_processer { + char *bluetooth_processer_rx_buf; + uint8_t bluetooth_processer_rx_buf_size; // + + int bluetooth_baundrate_one_packet_delay_ms; + void (*port_delay_ms)(uint64_t us); + + bool bluetooth_rx_buffer_start_receving; + bool bluetooth_rx_buffer_processing; + + char *order; //指令名称 + int index; // + int speedLevel; // + double position; //角度 + int direction; //旋转方向 + int code; //错误码 + char *info; //错误码信息 + char *deviceState; //设备状态 + int deviceException; //设备异常编号 + char *deviceExceptionInfo; //设备异常信息 + + bool cmd_flag; + bool actively_report_flag; + +} bluetooth_processer_t; + +void constructor_bluetooth_processer(bluetooth_processer_t *bluetooth_processer); +void bluetooth_gatts_try_process_data(); +void start_receive_data_to_buffer(uint16_t length, uint8_t *value); +void buffer_all_init(); +bool parse_rxbuffer_and_validation_data(cJSON **json_tmp); +bool parse_json_to_struct(cJSON *ch); \ No newline at end of file diff --git a/main/ble_spp_server_demo.c b/main/ble_spp_server_demo.c index b012f9b..2c6e254 100644 --- a/main/ble_spp_server_demo.c +++ b/main/ble_spp_server_demo.c @@ -6,56 +6,41 @@ CONDITIONS OF ANY KIND, either express or implied. */ - -#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" -#include "esp_bt.h" -#include "driver/uart.h" -#include "string.h" - -#include "esp_gap_ble_api.h" -#include "esp_gatts_api.h" -#include "esp_bt_defs.h" -#include "esp_bt_main.h" #include "ble_spp_server_demo.h" +#define GATTS_TABLE_TAG "GATTS_SPP_DEMO" + static uint16_t *hid_conn_id; static esp_gatt_if_t *hid_gatts_if; static short unsigned int *hid_handle; -uint8_t bluetooth_rx_buffer_len = 0; static bluetooth_processer_t *g_bluetooth_processer; -#define SPP_PROFILE_NUM 1 -#define SPP_PROFILE_APP_IDX 0 -#define ESP_SPP_APP_ID 0x56 -#define SAMPLE_DEVICE_NAME "yimei_ble" //The Device Name Characteristics in GAP -#define SPP_SVC_INST_ID 0 +#define SPP_PROFILE_NUM 1 +#define SPP_PROFILE_APP_IDX 0 +#define ESP_SPP_APP_ID 0x56 +#define SAMPLE_DEVICE_NAME "yimei_ble" // The Device Name Characteristics in GAP +#define SPP_SVC_INST_ID 0 /// SPP Service // static const uint16_t spp_service_uuid = 0xABF0; /// Characteristic UUID -#define ESP_GATT_UUID_SPP_DATA_RECEIVE 0xABF1 -#define ESP_GATT_UUID_SPP_DATA_NOTIFY 0xABF2 -#define ESP_GATT_UUID_SPP_COMMAND_RECEIVE 0xABF3 -#define ESP_GATT_UUID_SPP_COMMAND_NOTIFY 0xABF4 +#define ESP_GATT_UUID_SPP_DATA_RECEIVE 0xABF1 +#define ESP_GATT_UUID_SPP_DATA_NOTIFY 0xABF2 +#define ESP_GATT_UUID_SPP_COMMAND_RECEIVE 0xABF3 +#define ESP_GATT_UUID_SPP_COMMAND_NOTIFY 0xABF4 #ifdef SUPPORT_HEARTBEAT -#define ESP_GATT_UUID_SPP_HEARTBEAT 0xABF5 +#define ESP_GATT_UUID_SPP_HEARTBEAT 0xABF5 #endif static const uint8_t spp_adv_data[23] = { /* Flags */ - 0x02,0x01,0x06, + 0x02, 0x01, 0x06, /* Complete List of 16-bit Service Class UUIDs */ - 0x03,0x03,0xF0,0xAB, + 0x03, 0x03, 0xF0, 0xAB, /* Complete Local Name in advertising */ - 0x0A,0x09, 'y', 'i', 'm', 'e', 'i', '_', 'b', 'l', 'e' -}; + 0x0A, 0x09, 'y', 'i', 'm', 'e', 'i', '_', 'b', 'l', 'e'}; static uint16_t spp_mtu_size = 23; static uint16_t spp_conn_id = 0xffff; @@ -65,70 +50,68 @@ static xQueueHandle cmd_cmd_queue = NULL; #ifdef SUPPORT_HEARTBEAT static xQueueHandle cmd_heartbeat_queue = NULL; -static uint8_t heartbeat_s[9] = {'E','s','p','r','e','s','s','i','f'}; +static uint8_t heartbeat_s[9] = {'E', 's', 'p', 'r', 'e', 's', 's', 'i', 'f'}; static bool enable_heart_ntf = false; static uint8_t heartbeat_count_num = 0; #endif static bool enable_data_ntf = false; static bool is_connected = false; -static esp_bd_addr_t spp_remote_bda = {0x0,}; +static esp_bd_addr_t spp_remote_bda = { + 0x0, +}; static uint16_t spp_handle_table[SPP_IDX_NB]; static esp_ble_adv_params_t spp_adv_params = { - .adv_int_min = 0x20, - .adv_int_max = 0x40, - .adv_type = ADV_TYPE_IND, - .own_addr_type = BLE_ADDR_TYPE_PUBLIC, - .channel_map = ADV_CHNL_ALL, - .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, + .adv_int_min = 0x20, + .adv_int_max = 0x40, + .adv_type = ADV_TYPE_IND, + .own_addr_type = BLE_ADDR_TYPE_PUBLIC, + .channel_map = ADV_CHNL_ALL, + .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; struct gatts_profile_inst { - esp_gatts_cb_t gatts_cb; - uint16_t gatts_if; - 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; + esp_gatts_cb_t gatts_cb; + uint16_t gatts_if; + 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; }; -typedef struct spp_receive_data_node{ - int32_t len; - uint8_t * node_buff; - struct spp_receive_data_node * next_node; -}spp_receive_data_node_t; - -static spp_receive_data_node_t * temp_spp_recv_data_node_p1 = NULL; -static spp_receive_data_node_t * temp_spp_recv_data_node_p2 = NULL; - -typedef struct spp_receive_data_buff{ - int32_t node_num; - int32_t buff_size; - spp_receive_data_node_t * first_node; -}spp_receive_data_buff_t; - -static spp_receive_data_buff_t SppRecvDataBuff = { - .node_num = 0, - .buff_size = 0, - .first_node = NULL -}; +typedef struct spp_receive_data_node { + int32_t len; + uint8_t *node_buff; + struct spp_receive_data_node *next_node; +} spp_receive_data_node_t; + +static spp_receive_data_node_t *temp_spp_recv_data_node_p1 = NULL; +static spp_receive_data_node_t *temp_spp_recv_data_node_p2 = NULL; + +typedef struct spp_receive_data_buff { + int32_t node_num; + int32_t buff_size; + spp_receive_data_node_t *first_node; +} spp_receive_data_buff_t; + +static spp_receive_data_buff_t SppRecvDataBuff = {.node_num = 0, .buff_size = 0, .first_node = NULL}; static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); /* 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 spp_profile_tab[SPP_PROFILE_NUM] = { - [SPP_PROFILE_APP_IDX] = { - .gatts_cb = gatts_profile_event_handler, - .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ - }, + [SPP_PROFILE_APP_IDX] = + { + .gatts_cb = gatts_profile_event_handler, .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */ + }, }; /* @@ -136,626 +119,578 @@ static struct gatts_profile_inst spp_profile_tab[SPP_PROFILE_NUM] = { **************************************************************************************** */ -#define CHAR_DECLARATION_SIZE (sizeof(uint8_t)) +#define CHAR_DECLARATION_SIZE (sizeof(uint8_t)) static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE; static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE; static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; -static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_NOTIFY; +static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_NOTIFY; static const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE_NR; #ifdef SUPPORT_HEARTBEAT -static const uint8_t char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_WRITE_NR|ESP_GATT_CHAR_PROP_BIT_NOTIFY; +static const uint8_t char_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_NOTIFY; #endif -///SPP Service - data receive characteristic, read&write without response +/// SPP Service - data receive characteristic, read&write without response // static const uint16_t spp_data_receive_uuid = ESP_GATT_UUID_SPP_DATA_RECEIVE; -static const uint8_t spp_data_receive_val[128] = {0x00}; +static const uint8_t spp_data_receive_val[128] = {0x00}; -///SPP Service - data notify characteristic, notify&read +/// SPP Service - data notify characteristic, notify&read // static const uint16_t spp_data_notify_uuid = ESP_GATT_UUID_SPP_DATA_NOTIFY; -static const uint8_t spp_data_notify_val[20] = {0x00}; -static const uint8_t spp_data_notify_ccc[2] = {0x00, 0x00}; +static const uint8_t spp_data_notify_val[20] = {0x00}; +static const uint8_t spp_data_notify_ccc[2] = {0x00, 0x00}; -///SPP Service - command characteristic, read&write without response +/// SPP Service - command characteristic, read&write without response // static const uint16_t spp_command_uuid = ESP_GATT_UUID_SPP_COMMAND_RECEIVE; // static const uint8_t spp_command_val[10] = {0x00}; -///SPP Service - status characteristic, notify&read +/// SPP Service - status characteristic, notify&read // static const uint16_t spp_status_uuid = ESP_GATT_UUID_SPP_COMMAND_NOTIFY; // static const uint8_t spp_status_val[10] = {0x00}; // static const uint8_t spp_status_ccc[2] = {0x00, 0x00}; #ifdef SUPPORT_HEARTBEAT -///SPP Server - Heart beat characteristic, notify&write&read +/// SPP Server - Heart beat characteristic, notify&write&read static const uint16_t spp_heart_beat_uuid = ESP_GATT_UUID_SPP_HEARTBEAT; -static const uint8_t spp_heart_beat_val[2] = {0x00, 0x00}; -static const uint8_t spp_heart_beat_ccc[2] = {0x00, 0x00}; +static const uint8_t spp_heart_beat_val[2] = {0x00, 0x00}; +static const uint8_t spp_heart_beat_ccc[2] = {0x00, 0x00}; #endif static const uint8_t spp_service_uuid128[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ - 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E, // + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E, // }; static const uint8_t spp_char_uuid128_rx[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ - 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E, // + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E, // }; static const uint8_t spp_char_uuid128_tx[16] = { /* LSB <--------------------------------------------------------------------------------> MSB */ - 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E, // + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E, // }; -///Full HRS Database Description - Used to add attributes into the database -static const esp_gatts_attr_db_t spp_gatt_db[SPP_IDX_NB] = -{ - //SPP - Service Declaration - [SPP_IDX_SVC] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, - sizeof(spp_service_uuid128), sizeof(spp_service_uuid128), (uint8_t *)&spp_service_uuid128}}, +/// Full HRS Database Description - Used to add attributes into the database +static const esp_gatts_attr_db_t spp_gatt_db[SPP_IDX_NB] = { + // SPP - Service Declaration + [SPP_IDX_SVC] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ, sizeof(spp_service_uuid128), sizeof(spp_service_uuid128), (uint8_t *)&spp_service_uuid128}}, - //SPP - data notify characteristic Declaration - [SPP_IDX_SPP_DATA_NOTIFY_CHAR] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, - CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}}, + // SPP - data notify characteristic Declaration + [SPP_IDX_SPP_DATA_NOTIFY_CHAR] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}}, - //SPP - data notify characteristic Value - [SPP_IDX_SPP_DATA_NTY_VAL] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&spp_char_uuid128_rx, ESP_GATT_PERM_READ, - SPP_DATA_MAX_LEN, sizeof(spp_data_notify_val), (uint8_t *)spp_data_notify_val}}, + // SPP - data notify characteristic Value + [SPP_IDX_SPP_DATA_NTY_VAL] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_128, (uint8_t *)&spp_char_uuid128_rx, ESP_GATT_PERM_READ, SPP_DATA_MAX_LEN, sizeof(spp_data_notify_val), (uint8_t *)spp_data_notify_val}}, // SPP - data notify characteristic - Client Characteristic Configuration Descriptor - [SPP_IDX_SPP_DATA_NTF_CFG] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, - sizeof(uint16_t),sizeof(spp_data_notify_ccc), (uint8_t *)spp_data_notify_ccc}}, - - //SPP - data receive characteristic Declaration - [SPP_IDX_SPP_DATA_RECV_CHAR] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_WRITE, - CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}}, - - //SPP - data receive characteristic Value - [SPP_IDX_SPP_DATA_RECV_VAL] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&spp_char_uuid128_tx, ESP_GATT_PERM_WRITE, - SPP_DATA_MAX_LEN,sizeof(spp_data_receive_val), (uint8_t *)spp_data_receive_val}}, - - // //SPP - command characteristic Declaration - // [SPP_IDX_SPP_COMMAND_CHAR] = - // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, - // CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}}, - - // //SPP - command characteristic Value - // [SPP_IDX_SPP_COMMAND_VAL] = - // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_command_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, - // SPP_CMD_MAX_LEN,sizeof(spp_command_val), (uint8_t *)spp_command_val}}, - - // //SPP - status characteristic Declaration - // [SPP_IDX_SPP_STATUS_CHAR] = - // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, - // CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}}, - - // //SPP - status characteristic Value - // [SPP_IDX_SPP_STATUS_VAL] = - // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_status_uuid, ESP_GATT_PERM_READ, - // SPP_STATUS_MAX_LEN,sizeof(spp_status_val), (uint8_t *)spp_status_val}}, - - // //SPP - status characteristic - Client Characteristic Configuration Descriptor - // [SPP_IDX_SPP_STATUS_CFG] = - // {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, - // sizeof(uint16_t),sizeof(spp_status_ccc), (uint8_t *)spp_status_ccc}}, + [SPP_IDX_SPP_DATA_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, sizeof(uint16_t), sizeof(spp_data_notify_ccc), + (uint8_t *)spp_data_notify_ccc}}, + + // SPP - data receive characteristic Declaration + [SPP_IDX_SPP_DATA_RECV_CHAR] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_WRITE, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}}, + + // SPP - data receive characteristic Value + [SPP_IDX_SPP_DATA_RECV_VAL] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_128, (uint8_t *)&spp_char_uuid128_tx, ESP_GATT_PERM_WRITE, SPP_DATA_MAX_LEN, sizeof(spp_data_receive_val), (uint8_t *)spp_data_receive_val}}, + +// //SPP - command characteristic Declaration +// [SPP_IDX_SPP_COMMAND_CHAR] = +// {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, +// CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}}, + +// //SPP - command characteristic Value +// [SPP_IDX_SPP_COMMAND_VAL] = +// {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_command_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, +// SPP_CMD_MAX_LEN,sizeof(spp_command_val), (uint8_t *)spp_command_val}}, + +// //SPP - status characteristic Declaration +// [SPP_IDX_SPP_STATUS_CHAR] = +// {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, +// CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}}, + +// //SPP - status characteristic Value +// [SPP_IDX_SPP_STATUS_VAL] = +// {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_status_uuid, ESP_GATT_PERM_READ, +// SPP_STATUS_MAX_LEN,sizeof(spp_status_val), (uint8_t *)spp_status_val}}, + +// //SPP - status characteristic - Client Characteristic Configuration Descriptor +// [SPP_IDX_SPP_STATUS_CFG] = +// {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, +// sizeof(uint16_t),sizeof(spp_status_ccc), (uint8_t *)spp_status_ccc}}, #ifdef SUPPORT_HEARTBEAT - //SPP - Heart beat characteristic Declaration - [SPP_IDX_SPP_HEARTBEAT_CHAR] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, - CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}}, - - //SPP - Heart beat characteristic Value - [SPP_IDX_SPP_HEARTBEAT_VAL] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_heart_beat_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, - sizeof(spp_heart_beat_val), sizeof(spp_heart_beat_val), (uint8_t *)spp_heart_beat_val}}, - - //SPP - Heart beat characteristic - Client Characteristic Configuration Descriptor - [SPP_IDX_SPP_HEARTBEAT_CFG] = - {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE, - sizeof(uint16_t),sizeof(spp_data_notify_ccc), (uint8_t *)spp_heart_beat_ccc}}, + // SPP - Heart beat characteristic Declaration + [SPP_IDX_SPP_HEARTBEAT_CHAR] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, + (uint8_t *)&char_prop_read_write_notify}}, + + // SPP - Heart beat characteristic Value + [SPP_IDX_SPP_HEARTBEAT_VAL] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&spp_heart_beat_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, sizeof(spp_heart_beat_val), sizeof(spp_heart_beat_val), + (uint8_t *)spp_heart_beat_val}}, + + // SPP - Heart beat characteristic - Client Characteristic Configuration Descriptor + [SPP_IDX_SPP_HEARTBEAT_CFG] = {{ESP_GATT_AUTO_RSP}, + {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, sizeof(uint16_t), sizeof(spp_data_notify_ccc), + (uint8_t *)spp_heart_beat_ccc}}, #endif }; -static uint8_t find_char_and_desr_index(uint16_t handle) -{ - uint8_t error = 0xff; +static uint8_t find_char_and_desr_index(uint16_t handle) { + uint8_t error = 0xff; - for(int i = 0; i < SPP_IDX_NB ; i++){ - if(handle == spp_handle_table[i]){ - return i; - } + for (int i = 0; i < SPP_IDX_NB; i++) { + if (handle == spp_handle_table[i]) { + return i; } + } - return error; + return error; } -static bool store_wr_buffer(esp_ble_gatts_cb_param_t *p_data) -{ - temp_spp_recv_data_node_p1 = (spp_receive_data_node_t *)malloc(sizeof(spp_receive_data_node_t)); - - if(temp_spp_recv_data_node_p1 == NULL){ - ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d\n", __func__, __LINE__); - return false; - } - if(temp_spp_recv_data_node_p2 != NULL){ - temp_spp_recv_data_node_p2->next_node = temp_spp_recv_data_node_p1; - } - temp_spp_recv_data_node_p1->len = p_data->write.len; - SppRecvDataBuff.buff_size += p_data->write.len; - temp_spp_recv_data_node_p1->next_node = NULL; - temp_spp_recv_data_node_p1->node_buff = (uint8_t *)malloc(p_data->write.len); - temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1; - memcpy(temp_spp_recv_data_node_p1->node_buff,p_data->write.value,p_data->write.len); - if(SppRecvDataBuff.node_num == 0){ - SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1; - SppRecvDataBuff.node_num++; - }else{ - SppRecvDataBuff.node_num++; - } - - return true; +static bool store_wr_buffer(esp_ble_gatts_cb_param_t *p_data) { + temp_spp_recv_data_node_p1 = (spp_receive_data_node_t *)malloc(sizeof(spp_receive_data_node_t)); + + if (temp_spp_recv_data_node_p1 == NULL) { + ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d\n", __func__, __LINE__); + return false; + } + if (temp_spp_recv_data_node_p2 != NULL) { + temp_spp_recv_data_node_p2->next_node = temp_spp_recv_data_node_p1; + } + temp_spp_recv_data_node_p1->len = p_data->write.len; + SppRecvDataBuff.buff_size += p_data->write.len; + temp_spp_recv_data_node_p1->next_node = NULL; + temp_spp_recv_data_node_p1->node_buff = (uint8_t *)malloc(p_data->write.len); + temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1; + memcpy(temp_spp_recv_data_node_p1->node_buff, p_data->write.value, p_data->write.len); + if (SppRecvDataBuff.node_num == 0) { + SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1; + SppRecvDataBuff.node_num++; + } else { + SppRecvDataBuff.node_num++; + } + + return true; } -static void free_write_buffer(void) -{ - temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node; +static void free_write_buffer(void) { + temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node; - while(temp_spp_recv_data_node_p1 != NULL){ - temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1->next_node; - free(temp_spp_recv_data_node_p1->node_buff); - free(temp_spp_recv_data_node_p1); - temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p2; - } + while (temp_spp_recv_data_node_p1 != NULL) { + temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1->next_node; + free(temp_spp_recv_data_node_p1->node_buff); + free(temp_spp_recv_data_node_p1); + temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p2; + } - SppRecvDataBuff.node_num = 0; - SppRecvDataBuff.buff_size = 0; - SppRecvDataBuff.first_node = NULL; + SppRecvDataBuff.node_num = 0; + SppRecvDataBuff.buff_size = 0; + SppRecvDataBuff.first_node = NULL; } -static void print_write_buffer(void) -{ - temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node; +static void print_write_buffer(void) { + temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node; - while(temp_spp_recv_data_node_p1 != NULL){ - uart_write_bytes(UART_NUM_0, (char *)(temp_spp_recv_data_node_p1->node_buff), temp_spp_recv_data_node_p1->len); - temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p1->next_node; - } + while (temp_spp_recv_data_node_p1 != NULL) { + uart_write_bytes(UART_NUM_0, (char *)(temp_spp_recv_data_node_p1->node_buff), temp_spp_recv_data_node_p1->len); + temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p1->next_node; + } } -void uart_task(void *pvParameters) -{ - uart_event_t event; - uint8_t total_num = 0; - uint8_t current_num = 0; - - for (;;) { - //Waiting for UART event. - if (xQueueReceive(spp_uart_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - switch (event.type) { - //Event of UART receving data - case UART_DATA: - if ((event.size)&&(is_connected)) { - uint8_t * temp = NULL; - uint8_t * ntf_value_p = NULL; +void uart_task(void *pvParameters) { + uart_event_t event; + uint8_t total_num = 0; + uint8_t current_num = 0; + + for (;;) { + // Waiting for UART event. + if (xQueueReceive(spp_uart_queue, (void *)&event, (portTickType)portMAX_DELAY)) { + switch (event.type) { + // Event of UART receving data + case UART_DATA: + if ((event.size) && (is_connected)) { + uint8_t *temp = NULL; + uint8_t *ntf_value_p = NULL; #ifdef SUPPORT_HEARTBEAT - if(!enable_heart_ntf){ - ESP_LOGE(GATTS_TABLE_TAG, "%s do not enable heartbeat Notify\n", __func__); - break; - } + if (!enable_heart_ntf) { + ESP_LOGE(GATTS_TABLE_TAG, "%s do not enable heartbeat Notify\n", __func__); + break; + } #endif - if(!enable_data_ntf){ - ESP_LOGE(GATTS_TABLE_TAG, "%s do not enable data Notify\n", __func__); - break; - } - temp = (uint8_t *)malloc(sizeof(uint8_t)*event.size); - if(temp == NULL){ - ESP_LOGE(GATTS_TABLE_TAG, "%s malloc.1 failed\n", __func__); - break; - } - memset(temp,0x0,event.size); - uart_read_bytes(UART_NUM_0,temp,event.size,portMAX_DELAY); - if(event.size <= (spp_mtu_size - 3)){ - esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL],event.size, temp, false); - }else if(event.size > (spp_mtu_size - 3)){ - if((event.size%(spp_mtu_size - 7)) == 0){ - total_num = event.size/(spp_mtu_size - 7); - }else{ - total_num = event.size/(spp_mtu_size - 7) + 1; - } - current_num = 1; - ntf_value_p = (uint8_t *)malloc((spp_mtu_size-3)*sizeof(uint8_t)); - if(ntf_value_p == NULL){ - ESP_LOGE(GATTS_TABLE_TAG, "%s malloc.2 failed\n", __func__); - free(temp); - break; - } - while(current_num <= total_num){ - if(current_num < total_num){ - ntf_value_p[0] = '#'; - ntf_value_p[1] = '#'; - ntf_value_p[2] = total_num; - ntf_value_p[3] = current_num; - memcpy(ntf_value_p + 4,temp + (current_num - 1)*(spp_mtu_size-7),(spp_mtu_size-7)); - esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL],(spp_mtu_size-3), ntf_value_p, false); - }else if(current_num == total_num){ - ntf_value_p[0] = '#'; - ntf_value_p[1] = '#'; - ntf_value_p[2] = total_num; - ntf_value_p[3] = current_num; - memcpy(ntf_value_p + 4,temp + (current_num - 1)*(spp_mtu_size-7),(event.size - (current_num - 1)*(spp_mtu_size - 7))); - esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL],(event.size - (current_num - 1)*(spp_mtu_size - 7) + 4), ntf_value_p, false); - } - vTaskDelay(20 / portTICK_PERIOD_MS); - current_num++; - } - free(ntf_value_p); - } - free(temp); - } - break; - default: + if (!enable_data_ntf) { + ESP_LOGE(GATTS_TABLE_TAG, "%s do not enable data Notify\n", __func__); + break; + } + temp = (uint8_t *)malloc(sizeof(uint8_t) * event.size); + if (temp == NULL) { + ESP_LOGE(GATTS_TABLE_TAG, "%s malloc.1 failed\n", __func__); + break; + } + memset(temp, 0x0, event.size); + uart_read_bytes(UART_NUM_0, temp, event.size, portMAX_DELAY); + if (event.size <= (spp_mtu_size - 3)) { + esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL], event.size, temp, false); + } else if (event.size > (spp_mtu_size - 3)) { + if ((event.size % (spp_mtu_size - 7)) == 0) { + total_num = event.size / (spp_mtu_size - 7); + } else { + total_num = event.size / (spp_mtu_size - 7) + 1; + } + current_num = 1; + ntf_value_p = (uint8_t *)malloc((spp_mtu_size - 3) * sizeof(uint8_t)); + if (ntf_value_p == NULL) { + ESP_LOGE(GATTS_TABLE_TAG, "%s malloc.2 failed\n", __func__); + free(temp); break; + } + while (current_num <= total_num) { + if (current_num < total_num) { + ntf_value_p[0] = '#'; + ntf_value_p[1] = '#'; + ntf_value_p[2] = total_num; + ntf_value_p[3] = current_num; + memcpy(ntf_value_p + 4, temp + (current_num - 1) * (spp_mtu_size - 7), (spp_mtu_size - 7)); + esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL], (spp_mtu_size - 3), ntf_value_p, false); + } else if (current_num == total_num) { + ntf_value_p[0] = '#'; + ntf_value_p[1] = '#'; + ntf_value_p[2] = total_num; + ntf_value_p[3] = current_num; + memcpy(ntf_value_p + 4, temp + (current_num - 1) * (spp_mtu_size - 7), (event.size - (current_num - 1) * (spp_mtu_size - 7))); + esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL], (event.size - (current_num - 1) * (spp_mtu_size - 7) + 4), ntf_value_p, false); + } + vTaskDelay(20 / portTICK_PERIOD_MS); + current_num++; + } + free(ntf_value_p); } - } + free(temp); + } + break; + default: + break; + } } - vTaskDelete(NULL); + } + vTaskDelete(NULL); } -static void spp_uart_init(void) -{ - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_RTS, - .rx_flow_ctrl_thresh = 122, - .source_clk = UART_SCLK_APB, - }; - - //Install UART driver, and get the queue. - uart_driver_install(UART_NUM_0, 4096, 8192, 10,&spp_uart_queue,0); - //Set UART parameters - 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); +static void spp_uart_init(void) { + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_RTS, + .rx_flow_ctrl_thresh = 122, + .source_clk = UART_SCLK_APB, + }; + + // Install UART driver, and get the queue. + uart_driver_install(UART_NUM_0, 4096, 8192, 10, &spp_uart_queue, 0); + // Set UART parameters + 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); } #ifdef SUPPORT_HEARTBEAT -void spp_heartbeat_task(void * arg) -{ - uint16_t cmd_id; - - for(;;) { - vTaskDelay(50 / portTICK_PERIOD_MS); - if(xQueueReceive(cmd_heartbeat_queue, &cmd_id, portMAX_DELAY)) { - while(1){ - heartbeat_count_num++; - vTaskDelay(5000/ portTICK_PERIOD_MS); - if((heartbeat_count_num >3)&&(is_connected)){ - esp_ble_gap_disconnect(spp_remote_bda); - } - if(is_connected && enable_heart_ntf){ - esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_HEARTBEAT_VAL],sizeof(heartbeat_s), heartbeat_s, false); - }else if(!is_connected){ - break; - } - } +void spp_heartbeat_task(void *arg) { + uint16_t cmd_id; + + for (;;) { + vTaskDelay(50 / portTICK_PERIOD_MS); + if (xQueueReceive(cmd_heartbeat_queue, &cmd_id, portMAX_DELAY)) { + while (1) { + heartbeat_count_num++; + vTaskDelay(5000 / portTICK_PERIOD_MS); + if ((heartbeat_count_num > 3) && (is_connected)) { + esp_ble_gap_disconnect(spp_remote_bda); + } + if (is_connected && enable_heart_ntf) { + esp_ble_gatts_send_indicate(spp_gatts_if, spp_conn_id, spp_handle_table[SPP_IDX_SPP_HEARTBEAT_VAL], sizeof(heartbeat_s), heartbeat_s, false); + } else if (!is_connected) { + break; } + } } - vTaskDelete(NULL); + } + vTaskDelete(NULL); } #endif -void spp_cmd_task(void * arg) -{ - uint8_t * cmd_id; +void spp_cmd_task(void *arg) { + uint8_t *cmd_id; - for(;;){ - vTaskDelay(50 / portTICK_PERIOD_MS); - if(xQueueReceive(cmd_cmd_queue, &cmd_id, portMAX_DELAY)) { - esp_log_buffer_char(GATTS_TABLE_TAG,(char *)(cmd_id),strlen((char *)cmd_id)); - free(cmd_id); - } + for (;;) { + vTaskDelay(50 / portTICK_PERIOD_MS); + if (xQueueReceive(cmd_cmd_queue, &cmd_id, portMAX_DELAY)) { + esp_log_buffer_char(GATTS_TABLE_TAG, (char *)(cmd_id), strlen((char *)cmd_id)); + free(cmd_id); } - vTaskDelete(NULL); + } + vTaskDelete(NULL); } -static void spp_task_init(void) -{ - spp_uart_init(); +static void spp_task_init(void) { + spp_uart_init(); #ifdef SUPPORT_HEARTBEAT - cmd_heartbeat_queue = xQueueCreate(10, sizeof(uint32_t)); - xTaskCreate(spp_heartbeat_task, "spp_heartbeat_task", 2048, NULL, 10, NULL); + cmd_heartbeat_queue = xQueueCreate(10, sizeof(uint32_t)); + xTaskCreate(spp_heartbeat_task, "spp_heartbeat_task", 2048, NULL, 10, NULL); #endif - cmd_cmd_queue = xQueueCreate(10, sizeof(uint32_t)); - xTaskCreate(spp_cmd_task, "spp_cmd_task", 2048, NULL, 10, NULL); + cmd_cmd_queue = xQueueCreate(10, sizeof(uint32_t)); + xTaskCreate(spp_cmd_task, "spp_cmd_task", 2048, NULL, 10, NULL); } -static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) -{ - esp_err_t err; - ESP_LOGE(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); +static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { + esp_err_t err; + ESP_LOGE(GATTS_TABLE_TAG, "GAP_EVT, event %d\n", event); - switch (event) { + switch (event) { case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT: - esp_ble_gap_start_advertising(&spp_adv_params); - break; + esp_ble_gap_start_advertising(&spp_adv_params); + break; case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - //advertising start complete event to indicate advertising start successfully or failed - if((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTS_TABLE_TAG, "Advertising start failed: %s\n", esp_err_to_name(err)); - } - break; + // advertising start complete event to indicate advertising start successfully or failed + if ((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS) { + ESP_LOGE(GATTS_TABLE_TAG, "Advertising start failed: %s\n", esp_err_to_name(err)); + } + break; default: - break; - } + break; + } } -static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) -{ - esp_ble_gatts_cb_param_t *p_data = (esp_ble_gatts_cb_param_t *) param; - uint8_t res = 0xff; - - ESP_LOGI(GATTS_TABLE_TAG, "event = %x\n",event); - switch (event) { - case ESP_GATTS_REG_EVT: - ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); - esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME); - - ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); - esp_ble_gap_config_adv_data_raw((uint8_t *)spp_adv_data, sizeof(spp_adv_data)); - - ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); - esp_ble_gatts_create_attr_tab(spp_gatt_db, gatts_if, SPP_IDX_NB, SPP_SVC_INST_ID); - break; - case ESP_GATTS_READ_EVT: - res = find_char_and_desr_index(p_data->read.handle); - if(res == SPP_IDX_SPP_STATUS_VAL){ - //TODO:client read the status characteristic - } - break; - case ESP_GATTS_WRITE_EVT: { - res = find_char_and_desr_index(p_data->write.handle); - if(p_data->write.is_prep == false){ - ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_WRITE_EVT : handle = %d\n", res); - if(res == SPP_IDX_SPP_COMMAND_VAL){ - uint8_t * spp_cmd_buff = NULL; - spp_cmd_buff = (uint8_t *)malloc((spp_mtu_size - 3) * sizeof(uint8_t)); - if(spp_cmd_buff == NULL){ - ESP_LOGE(GATTS_TABLE_TAG, "%s malloc failed\n", __func__); - break; - } - memset(spp_cmd_buff,0x0,(spp_mtu_size - 3)); - memcpy(spp_cmd_buff,p_data->write.value,p_data->write.len); - xQueueSend(cmd_cmd_queue,&spp_cmd_buff,10/portTICK_PERIOD_MS); - }else if(res == SPP_IDX_SPP_DATA_NTF_CFG){ - if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x01)&&(p_data->write.value[1] == 0x00)){ - enable_data_ntf = true; - }else if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x00)&&(p_data->write.value[1] == 0x00)){ - enable_data_ntf = false; - } - } +static void gatts_profile_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { + esp_ble_gatts_cb_param_t *p_data = (esp_ble_gatts_cb_param_t *)param; + uint8_t res = 0xff; + + ESP_LOGI(GATTS_TABLE_TAG, "event = %x\n", event); + switch (event) { + case ESP_GATTS_REG_EVT: + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); + esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME); + + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); + esp_ble_gap_config_adv_data_raw((uint8_t *)spp_adv_data, sizeof(spp_adv_data)); + + ESP_LOGI(GATTS_TABLE_TAG, "%s %d\n", __func__, __LINE__); + esp_ble_gatts_create_attr_tab(spp_gatt_db, gatts_if, SPP_IDX_NB, SPP_SVC_INST_ID); + break; + case ESP_GATTS_READ_EVT: + res = find_char_and_desr_index(p_data->read.handle); + if (res == SPP_IDX_SPP_STATUS_VAL) { + // TODO:client read the status characteristic + } + break; + case ESP_GATTS_WRITE_EVT: { + res = find_char_and_desr_index(p_data->write.handle); + if (p_data->write.is_prep == false) { + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_WRITE_EVT : handle = %d\n", res); + if (res == SPP_IDX_SPP_COMMAND_VAL) { + uint8_t *spp_cmd_buff = NULL; + spp_cmd_buff = (uint8_t *)malloc((spp_mtu_size - 3) * sizeof(uint8_t)); + if (spp_cmd_buff == NULL) { + ESP_LOGE(GATTS_TABLE_TAG, "%s malloc failed\n", __func__); + break; + } + memset(spp_cmd_buff, 0x0, (spp_mtu_size - 3)); + memcpy(spp_cmd_buff, p_data->write.value, p_data->write.len); + xQueueSend(cmd_cmd_queue, &spp_cmd_buff, 10 / portTICK_PERIOD_MS); + } else if (res == SPP_IDX_SPP_DATA_NTF_CFG) { + if ((p_data->write.len == 2) && (p_data->write.value[0] == 0x01) && (p_data->write.value[1] == 0x00)) { + enable_data_ntf = true; + } else if ((p_data->write.len == 2) && (p_data->write.value[0] == 0x00) && (p_data->write.value[1] == 0x00)) { + enable_data_ntf = false; + } + } #ifdef SUPPORT_HEARTBEAT - else if(res == SPP_IDX_SPP_HEARTBEAT_CFG){ - if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x01)&&(p_data->write.value[1] == 0x00)){ - enable_heart_ntf = true; - }else if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x00)&&(p_data->write.value[1] == 0x00)){ - enable_heart_ntf = false; - } - }else if(res == SPP_IDX_SPP_HEARTBEAT_VAL){ - if((p_data->write.len == sizeof(heartbeat_s))&&(memcmp(heartbeat_s,p_data->write.value,sizeof(heartbeat_s)) == 0)){ - heartbeat_count_num = 0; - } - } + else if (res == SPP_IDX_SPP_HEARTBEAT_CFG) { + if ((p_data->write.len == 2) && (p_data->write.value[0] == 0x01) && (p_data->write.value[1] == 0x00)) { + enable_heart_ntf = true; + } else if ((p_data->write.len == 2) && (p_data->write.value[0] == 0x00) && (p_data->write.value[1] == 0x00)) { + enable_heart_ntf = false; + } + } else if (res == SPP_IDX_SPP_HEARTBEAT_VAL) { + if ((p_data->write.len == sizeof(heartbeat_s)) && (memcmp(heartbeat_s, p_data->write.value, sizeof(heartbeat_s)) == 0)) { + heartbeat_count_num = 0; + } + } #endif - else if(res == SPP_IDX_SPP_DATA_RECV_VAL){ + else if (res == SPP_IDX_SPP_DATA_RECV_VAL) { #ifdef SPP_DEBUG_MODE - esp_log_buffer_char(GATTS_TABLE_TAG,(char *)(p_data->write.value),p_data->write.len); + esp_log_buffer_char(GATTS_TABLE_TAG, (char *)(p_data->write.value), p_data->write.len); #else - // uart_write_bytes(UART_NUM_0, (char *)(p_data->write.value), p_data->write.len); - start_receive_data_to_buffer(param->write.len, param->write.value); + // uart_write_bytes(UART_NUM_0, (char *)(p_data->write.value), p_data->write.len); + start_receive_data_to_buffer(param->write.len, param->write.value); #endif - }else{ - //TODO: - } - }else if((p_data->write.is_prep == true)&&(res == SPP_IDX_SPP_DATA_RECV_VAL)){ - ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_PREP_WRITE_EVT : handle = %d\n", res); - store_wr_buffer(p_data); - } - break; - } - case ESP_GATTS_EXEC_WRITE_EVT:{ - ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_EXEC_WRITE_EVT\n"); - if(p_data->exec_write.exec_write_flag){ - print_write_buffer(); - free_write_buffer(); - } - break; - } - case ESP_GATTS_MTU_EVT: - spp_mtu_size = p_data->mtu.mtu; - ESP_LOGI(GATTS_TABLE_TAG, "------------spp_mtu_size %d --------------\n",spp_mtu_size); - break; - case ESP_GATTS_CONF_EVT: - break; - case ESP_GATTS_UNREG_EVT: - break; - case ESP_GATTS_DELETE_EVT: - break; - case ESP_GATTS_START_EVT: - break; - case ESP_GATTS_STOP_EVT: - break; - case ESP_GATTS_CONNECT_EVT: - *hid_conn_id = param->connect.conn_id; - *hid_handle = spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL]; - *hid_gatts_if = gatts_if; - spp_conn_id = p_data->connect.conn_id; - spp_gatts_if = gatts_if; - is_connected = true; - memcpy(&spp_remote_bda,&p_data->connect.remote_bda,sizeof(esp_bd_addr_t)); + } else { + // TODO: + } + } else if ((p_data->write.is_prep == true) && (res == SPP_IDX_SPP_DATA_RECV_VAL)) { + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_PREP_WRITE_EVT : handle = %d\n", res); + store_wr_buffer(p_data); + } + break; + } + case ESP_GATTS_EXEC_WRITE_EVT: { + ESP_LOGI(GATTS_TABLE_TAG, "ESP_GATTS_EXEC_WRITE_EVT\n"); + if (p_data->exec_write.exec_write_flag) { + print_write_buffer(); + free_write_buffer(); + } + break; + } + case ESP_GATTS_MTU_EVT: + spp_mtu_size = p_data->mtu.mtu; + ESP_LOGI(GATTS_TABLE_TAG, "------------spp_mtu_size %d --------------\n", spp_mtu_size); + break; + case ESP_GATTS_CONF_EVT: + break; + case ESP_GATTS_UNREG_EVT: + break; + case ESP_GATTS_DELETE_EVT: + break; + case ESP_GATTS_START_EVT: + break; + case ESP_GATTS_STOP_EVT: + break; + case ESP_GATTS_CONNECT_EVT: + *hid_conn_id = param->connect.conn_id; + *hid_handle = spp_handle_table[SPP_IDX_SPP_DATA_NTY_VAL]; + *hid_gatts_if = gatts_if; + spp_conn_id = p_data->connect.conn_id; + spp_gatts_if = gatts_if; + is_connected = true; + memcpy(&spp_remote_bda, &p_data->connect.remote_bda, sizeof(esp_bd_addr_t)); #ifdef SUPPORT_HEARTBEAT - uint16_t cmd = 0; - xQueueSend(cmd_heartbeat_queue,&cmd,10/portTICK_PERIOD_MS); + uint16_t cmd = 0; + xQueueSend(cmd_heartbeat_queue, &cmd, 10 / portTICK_PERIOD_MS); #endif - break; - case ESP_GATTS_DISCONNECT_EVT: - *hid_gatts_if = 0; - *hid_conn_id = 0; - *hid_handle = 0; - is_connected = false; - enable_data_ntf = false; + break; + case ESP_GATTS_DISCONNECT_EVT: + *hid_gatts_if = 0; + *hid_conn_id = 0; + *hid_handle = 0; + is_connected = false; + enable_data_ntf = false; #ifdef SUPPORT_HEARTBEAT - enable_heart_ntf = false; - heartbeat_count_num = 0; + enable_heart_ntf = false; + heartbeat_count_num = 0; #endif - esp_ble_gap_start_advertising(&spp_adv_params); - break; - case ESP_GATTS_OPEN_EVT: - break; - case ESP_GATTS_CANCEL_OPEN_EVT: - break; - case ESP_GATTS_CLOSE_EVT: - break; - case ESP_GATTS_LISTEN_EVT: - break; - case ESP_GATTS_CONGEST_EVT: - break; - case ESP_GATTS_CREAT_ATTR_TAB_EVT:{ - ESP_LOGI(GATTS_TABLE_TAG, "The number handle =%x\n",param->add_attr_tab.num_handle); - if (param->add_attr_tab.status != ESP_GATT_OK){ - ESP_LOGE(GATTS_TABLE_TAG, "Create attribute table failed, error code=0x%x", param->add_attr_tab.status); - } - else if (param->add_attr_tab.num_handle != SPP_IDX_NB){ - 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, SPP_IDX_NB); - } - else { - memcpy(spp_handle_table, param->add_attr_tab.handles, sizeof(spp_handle_table)); - esp_ble_gatts_start_service(spp_handle_table[SPP_IDX_SVC]); - } - break; - } - default: - break; + esp_ble_gap_start_advertising(&spp_adv_params); + break; + case ESP_GATTS_OPEN_EVT: + break; + case ESP_GATTS_CANCEL_OPEN_EVT: + break; + case ESP_GATTS_CLOSE_EVT: + break; + case ESP_GATTS_LISTEN_EVT: + break; + case ESP_GATTS_CONGEST_EVT: + break; + case ESP_GATTS_CREAT_ATTR_TAB_EVT: { + ESP_LOGI(GATTS_TABLE_TAG, "The number handle =%x\n", param->add_attr_tab.num_handle); + if (param->add_attr_tab.status != ESP_GATT_OK) { + ESP_LOGE(GATTS_TABLE_TAG, "Create attribute table failed, error code=0x%x", param->add_attr_tab.status); + } else if (param->add_attr_tab.num_handle != SPP_IDX_NB) { + 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, SPP_IDX_NB); + } else { + memcpy(spp_handle_table, param->add_attr_tab.handles, sizeof(spp_handle_table)); + esp_ble_gatts_start_service(spp_handle_table[SPP_IDX_SVC]); + } + break; } + default: + break; + } } +static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { + ESP_LOGI(GATTS_TABLE_TAG, "EVT %d, gatts if %d\n", event, gatts_if); -static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) -{ - ESP_LOGI(GATTS_TABLE_TAG, "EVT %d, gatts if %d\n", event, gatts_if); - - /* 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) { - spp_profile_tab[SPP_PROFILE_APP_IDX].gatts_if = gatts_if; - } else { - ESP_LOGI(GATTS_TABLE_TAG, "Reg app failed, app_id %04x, status %d\n",param->reg.app_id, param->reg.status); - return; - } + /* 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) { + spp_profile_tab[SPP_PROFILE_APP_IDX].gatts_if = gatts_if; + } else { + ESP_LOGI(GATTS_TABLE_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status); + return; } - - do { - int idx; - for (idx = 0; idx < SPP_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 == spp_profile_tab[idx].gatts_if) { - if (spp_profile_tab[idx].gatts_cb) { - spp_profile_tab[idx].gatts_cb(event, gatts_if, param); - } - } + } + + do { + int idx; + for (idx = 0; idx < SPP_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 == spp_profile_tab[idx].gatts_if) { + if (spp_profile_tab[idx].gatts_cb) { + spp_profile_tab[idx].gatts_cb(event, gatts_if, param); } - } while (0); + } + } + } while (0); } -void ble_spp_server_demo_app_main(uint16_t *conn_id_ble, esp_gatt_if_t *gatts_if_ble, uint16_t *handle_ble, bluetooth_processer_t *bluetooth_processer ) -{ - esp_err_t ret; - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +void ble_spp_server_demo_app_main(uint16_t *conn_id_ble, esp_gatt_if_t *gatts_if_ble, uint16_t *handle_ble, bluetooth_processer_t *bluetooth_processer) { + esp_err_t ret; + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - hid_conn_id = conn_id_ble; - hid_gatts_if = gatts_if_ble; - hid_handle = handle_ble; + hid_conn_id = conn_id_ble; + hid_gatts_if = gatts_if_ble; + hid_handle = handle_ble; - g_bluetooth_processer = bluetooth_processer; + g_bluetooth_processer = bluetooth_processer; - // Initialize NVS + // Initialize NVS + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK( ret ); + } + ESP_ERROR_CHECK(ret); - ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); + ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)); - ret = esp_bt_controller_init(&bt_cfg); - if (ret) { - ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); - if (ret) { - ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - ESP_LOGI(GATTS_TABLE_TAG, "%s init bluetooth\n", __func__); - ret = esp_bluedroid_init(); - if (ret) { - ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - ret = esp_bluedroid_enable(); - if (ret) { - ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); - return; - } - - esp_ble_gatts_register_callback(gatts_event_handler); - esp_ble_gap_register_callback(gap_event_handler); - esp_ble_gatts_app_register(ESP_SPP_APP_ID); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } - // spp_task_init(); + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } + ESP_LOGI(GATTS_TABLE_TAG, "%s init bluetooth\n", __func__); + ret = esp_bluedroid_init(); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); return; -} + } + ret = esp_bluedroid_enable(); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret)); + return; + } -void start_receive_data_to_buffer(uint16_t length, uint8_t *value) -{ - g_bluetooth_processer->bluetooth_rx_buffer_start_receving = true; - timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); - //判断是否buffer越界 - if ((length + bluetooth_rx_buffer_len) > profile_b_buffer_size) - { - return; - } + esp_ble_gatts_register_callback(gatts_event_handler); + esp_ble_gap_register_callback(gap_event_handler); + esp_ble_gatts_app_register(ESP_SPP_APP_ID); - if (!g_bluetooth_processer->bluetooth_rx_buffer_processing) - { - //写入到buffer - for (int i = 0; i < length; i++) - { - g_bluetooth_processer->bluetooth_processer_rx_buf[bluetooth_rx_buffer_len++] = value[i]; - } - } -} + spp_task_init(); -void buffer_all_init() -{ - bluetooth_rx_buffer_len = 0; - memset(g_bluetooth_processer->bluetooth_processer_rx_buf, 0, profile_b_buffer_size); -} \ No newline at end of file + return; +} diff --git a/main/ble_spp_server_demo.h b/main/ble_spp_server_demo.h index d2fbee3..db5e2b1 100644 --- a/main/ble_spp_server_demo.h +++ b/main/ble_spp_server_demo.h @@ -10,11 +10,19 @@ #include #include -#include "driver/timer.h" -#include "cJSON.h" -#include "cJSON_Utils.h" - -#define GATTS_TABLE_TAG "GATTS_SPP_DEMO" +#include "ble_parse_data.h" +#include "driver/uart.h" +#include "esp_bt.h" +#include "esp_bt_defs.h" +#include "esp_bt_main.h" +#include "esp_gap_ble_api.h" +#include "esp_gatts_api.h" +#include "esp_log.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "nvs_flash.h" /* * DEFINES @@ -55,36 +63,4 @@ enum { SPP_IDX_NB, }; -#define profile_b_buffer_size 128 - -typedef struct bluetooth_processer -{ - char *bluetooth_processer_rx_buf; - uint8_t bluetooth_processer_rx_buf_size; // - - int bluetooth_baundrate_one_packet_delay_ms; - void (*port_delay_ms)(uint64_t us); - - bool bluetooth_rx_buffer_start_receving; - bool bluetooth_rx_buffer_processing; - - char *order; //指令名称 - int index; // - int speedLevel; // - double position; //角度 - int direction; //旋转方向 - int code; //错误码 - char *info; //错误码信息 - char *deviceState; //设备状态 - int deviceException; //设备异常编号 - char *deviceExceptionInfo; //设备异常信息 - - bool cmd_flag; - bool actively_report_flag; - -} bluetooth_processer_t; - -void ble_spp_server_demo_app_main(uint16_t *conn_id_ble, esp_gatt_if_t *gatts_if_ble, uint16_t *handle_ble, bluetooth_processer_t *bluetooth_processer); - -void start_receive_data_to_buffer(uint16_t length, uint8_t *value); -void buffer_all_init(); \ No newline at end of file +void ble_spp_server_demo_app_main(uint16_t *conn_id_ble, esp_gatt_if_t *gatts_if_ble, uint16_t *handle_ble, bluetooth_processer_t *bluetooth_processer); \ No newline at end of file diff --git a/main/main.c b/main/main.c index fb22c6f..4e444ff 100644 --- a/main/main.c +++ b/main/main.c @@ -11,24 +11,14 @@ #include "ble_spp_server_demo.h" #include "timer_u.h" -#define set_position "setPosition" -#define get_status "getStatus" +#define GATTS_TABLE_TAG "GATTS_SPP_DEMO" uint16_t table_conn_id_m; esp_gatt_if_t table_gatts_if_m; uint16_t table_handle_m; -#define cmd_length_set_position 5 -#define cmd_length_get_status 2 - -bool test_flag; - static char bluetooth_tx_buffer[profile_b_buffer_size] = {0}; -/*********************************************************************************************************************** - * ****************************************************user_define**************************************************** * - ***********************************************************************************************************************/ - char bluetooth_rx_buffer[profile_b_buffer_size] = {0}; // ble_gatts_str_t ble_gatts_a_str = { @@ -37,13 +27,6 @@ char bluetooth_rx_buffer[profile_b_buffer_size] = {0}; // .send_gatts_if = 0, // }; -/*********************************************************************************************************************** - * **********************************************user_function_statement********************************************** * - ***********************************************************************************************************************/ -void bluetooth_gatts_try_process_data(); - -bool parse_rxbuffer_and_validation_data(cJSON **json_tmp); -bool parse_json_to_struct(cJSON *ch); void receipt_json_set_position(); void receipt_json_get_status(); void bluetooth_rx_buffer_format_receipt(); @@ -75,6 +58,7 @@ bluetooth_processer_t s_bluetooth_processer = { }; void app_main(void) { + constructor_bluetooth_processer(&s_bluetooth_processer); // ble_spp_server_demo_app_main(&table_conn_id_m, &table_gatts_if_m, &table_handle_m); // table_conn_id_m = // char temp_buffer[5] = {'1', '2', '3', '4', '5'}; @@ -90,14 +74,6 @@ void app_main(void) { ble_spp_server_demo_app_main(&table_conn_id_m, &table_gatts_if_m, &table_handle_m, &s_bluetooth_processer); timer_group_init(TIMER_GROUP_0, TIMER_0, false, timer_group0_interval_num, timer_interval_ms); while (true) { - // ESP_LOGI("test", "%d,%d,%d", strlen(bluetooth_tx_buffer), 89 / 15, 99 / 15); - // ESP_LOGI("test", "%d,%d,%d", table_conn_id_m, table_gatts_if_m, table_handle_m); - // if (table_handle_m != 0 && test_flag == true) { - // ets_delay_us(6000000); - // bluetooth_rx_buffer_send_indicate(); - // test_flag = false; - // } - bluetooth_gatts_try_process_data(); if (s_bluetooth_processer.actively_report_flag) { receipt_json_get_status(); @@ -108,9 +84,6 @@ void app_main(void) { return; } -/*********************************************************************************************************************** - * *************************************************user_funtion_def************************************************** * - ***********************************************************************************************************************/ bool validation_param(cJSON *object, char *param) { cJSON *current_element = object->child; @@ -123,110 +96,6 @@ bool validation_param(cJSON *object, char *param) { return false; } -void bluetooth_gatts_try_process_data() { - cJSON *json_tmp; - // cJSON *ch; - //开始接收 - if (s_bluetooth_processer.bluetooth_rx_buffer_start_receving) { - //开启定时器 - s_bluetooth_processer.port_delay_ms(s_bluetooth_processer.bluetooth_baundrate_one_packet_delay_ms); - // port_timer_delay_ms(kbluetooth_baundrate_one_packet_delay_ms); - s_bluetooth_processer.bluetooth_rx_buffer_processing = true; - - //打印输出 - // ESP_LOGI(GATTS_TABLE_TAG, "%s", s_bluetooth_processer.bluetooth_processer_rx_buf); - - //验证解析数据是否正确 - if (parse_rxbuffer_and_validation_data(&json_tmp)) { - // JSON解析到结构体,如果order更改表示有指令传输进来,并且更改指令标志位(cmd_flag)为true - if (parse_json_to_struct(json_tmp->child)) { - ESP_LOGI(GATTS_TABLE_TAG, "order:%s ,index:%d speedLevel:%d position:%f direction:%d", s_bluetooth_processer.order, s_bluetooth_processer.index, s_bluetooth_processer.speedLevel, - s_bluetooth_processer.position, s_bluetooth_processer.direction); - if (strcmp(s_bluetooth_processer.order, set_position) == 0) { - ESP_LOGI(GATTS_TABLE_TAG, set_position); - // motor_cmd_set_position(s_bluetooth_processer.speedLevel, s_bluetooth_processer.position, s_bluetooth_processer.direction); - // receipt_json_set_position(); - } - if (strcmp(s_bluetooth_processer.order, get_status) == 0) { - ESP_LOGI(GATTS_TABLE_TAG, get_status); - test_flag = true; - // receipt_json_get_status(); - } - // if (strcmp(s_bluetooth_processer.order, "deviceStatusReport") == 0) - // { - // ESP_LOGI(GATTS_TABLE_TAG, "deviceStatusReport"); - // } - s_bluetooth_processer.actively_report_flag = true; - } - } - - //释放空间 - cJSON_Delete(json_tmp); - // buffer置0 - buffer_all_init(); - //未在处理数据 - s_bluetooth_processer.cmd_flag = false; - s_bluetooth_processer.bluetooth_rx_buffer_start_receving = false; - s_bluetooth_processer.bluetooth_rx_buffer_processing = false; - } -} - -bool parse_rxbuffer_and_validation_data(cJSON **json_tmp) { - *json_tmp = cJSON_Parse(&bluetooth_rx_buffer[0]); - if (*json_tmp == NULL) { - ESP_LOGE(GATTS_TABLE_TAG, "parse rxbuffer nil or redundant symbol ',' "); - return false; - } - return true; -} - -bool parse_json_to_struct(cJSON *ch) { - uint8_t cmd_length = 0; - while (ch != NULL) { - // ESP_LOGI(GATTS_TABLE_TAG, "%s", ch->string); - if (strcmp(ch->string, "order") == 0) { - s_bluetooth_processer.order = ch->valuestring; - - if (strcmp(ch->valuestring, set_position) == 0) { - cmd_length = cmd_length_set_position; - } - if (strcmp(ch->valuestring, get_status) == 0) { - cmd_length = cmd_length_get_status; - } - // if (strcmp(ch->valuestring, "deviceStatusReport") == 0) - // { - // cmd_length = cmd_length_device_status_report; - // } - cmd_length--; - } - if (strcmp(ch->string, "index") == 0) { - s_bluetooth_processer.index = ch->valueint; - cmd_length--; - } - if (strcmp(ch->string, "speedLevel") == 0) { - s_bluetooth_processer.speedLevel = ch->valueint; - cmd_length--; - } - if (strcmp(ch->string, "position") == 0) { - s_bluetooth_processer.position = ch->valuedouble; - cmd_length--; - } - if (strcmp(ch->string, "direction") == 0) { - s_bluetooth_processer.direction = ch->valueint; - cmd_length--; - } - ch = ch->next; - } - - if (cmd_length == 0) { - s_bluetooth_processer.cmd_flag = true; - } else { - ESP_LOGE(GATTS_TABLE_TAG, "JSON directive missing or exceeded"); - } - - return s_bluetooth_processer.cmd_flag; -} - void receipt_json_set_position() { cJSON *pRoot = cJSON_CreateObject(); //创建一个对象 if (!pRoot) {