BLE GATTS not gating notify
Posted: Mon Dec 04, 2023 12:29 pm
base on ble_spp_server example
I'm taring to use this code to send data (notify type) to client
but in the client side i'm not gating any notification but if i check the data r there.
any help will be will be welcomed.
I'm taring to use this code to send data (notify type) to client
- int set_status(const char* status, uint8_t size)
- {
- ESP_LOGI(GATTS_TAG, "%s.", status);
- return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_STATUS_VAL, size, (const uint8_t*)status);
- }
but in the client side i'm not gating any notification but if i check the data r there.
any help will be will be welcomed.
- /*
- * bala_geet_server.c
- *
- * Created on: 21 Sep 2023
- * Author: ddial
- */
- #include <stdio.h>
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/event_groups.h"
- #include "freertos/semphr.h"
- #include "esp_system.h"
- #include "esp_random.h"
- #include "esp_log.h"
- #include "nvs_drv.h"
- #include "esp_bt.h"
- #include "string.h"
- #include "esp_gap_ble_api.h"
- #include "esp_gatts_api.h"
- #include "esp_gatt_defs.h"
- #include "esp_bt_main.h"
- #include "esp_gatt_common_api.h"
- #include "interface.h"
- #include "bala_geet_server.h"
- #define GATTS_TAG "[GATTS]"
- #define SPP_PROFILE_NUM 1
- #define SPP_PROFILE_APP_IDX 0
- #define ESP_SPP_APP_ID 0x56
- #define SAMPLE_DEVICE_NAME "ESP_SPP_SERV_1" //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
- 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);
- /// Local variables ////////////////////////////////////////////////////////////
- static SemaphoreHandle_t ble_geets_init_mutex_h = NULL;
- static uint16_t spp_handle_table[SPP_IDX_NB];
- static uint16_t spp_mtu_size = 23;
- static uint16_t spp_conn_id = 0xffff;
- static esp_gatt_if_t spp_gatts_if = 0xff;
- static bool is_connected = false;
- static esp_bd_addr_t spp_remote_bda = {0x0,};
- static bool enable_data_ntf = false;
- static QueueHandle_t cmd_cmd_queue = 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 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,
- };
- 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;
- };
- /* 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 */
- },
- };
- static const uint8_t spp_adv_data[23] = {
- /* Flags */
- 0x02,0x01,0x06,
- /* Complete List of 16-bit Service Class UUIDs */
- 0x03,0x03,0xF0,0xAB,
- /* Complete Local Name in advertising */
- 0x0F,0x09, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R','V', '_', '1'
- };
- /*
- * SPP PROFILE ATTRIBUTES
- ****************************************************************************************
- */
- #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_write = ESP_GATT_CHAR_PROP_BIT_WRITE_NR|ESP_GATT_CHAR_PROP_BIT_READ;
- #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;
- #endif
- ///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[SPP_DATA_MAX_LEN] = { 0 };
- ///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] = { 0 };
- static const uint8_t spp_data_notify_ccc[2] = { 0 };
- ///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[SPP_CMD_MAX_LEN] = { 0 };
- ///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[SPP_STATUS_MAX_LEN] = { 0 };
- static const uint8_t spp_status_ccc[2] = { 0 };
- #ifdef SUPPORT_HEARTBEAT
- ///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};
- #endif
- ///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_gatts_attr_db_t
- { /// {
- { /// esp_attr_control_t {
- ESP_GATT_AUTO_RSP /// uint8_t auto_rsp;
- }, /// }
- { /// esp_attr_desc_t {
- ESP_UUID_LEN_16, /// uint16_t uuid_length; /*!< UUID length */
- (uint8_t *)&primary_service_uuid, /// uint8_t *uuid_p; /*!< UUID value */
- ESP_GATT_PERM_READ, /// uint16_t perm; /*!< Attribute permission */
- sizeof(spp_service_uuid), /// uint16_t max_length; /*!< Maximum length of the element*/
- sizeof(spp_service_uuid), /// uint16_t length; /*!< Current length of the element*/
- (uint8_t *)&spp_service_uuid /// uint8_t *value; /*!< Element value array*/
- } /// }
- }, /// }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //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_READ,
- 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_16, (uint8_t *)&spp_data_receive_uuid, (ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
- SPP_DATA_MAX_LEN, sizeof(spp_data_receive_val), (uint8_t *)spp_data_receive_val}},
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //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_16, (uint8_t *)&spp_data_notify_uuid,
- ESP_GATT_PERM_READ, sizeof(spp_data_notify_val), 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 - 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, SPP_CMD_MAX_LEN, (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, SPP_STATUS_MAX_LEN, (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}},
- #endif
- };
- /// Local functions ////////////////////////////////////////////////////////////
- static uint8_t find_char_and_desr_index(uint16_t handle)
- {
- int i = 0;
- uint8_t error = 0xff;
- for(i = 0; i < SPP_IDX_NB ; i++)
- {
- if(handle == spp_handle_table[i])
- {
- return i;
- }
- }
- 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_TAG, "malloc error %s %d", __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;
- 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;
- }
- static void print_write_buffer(void)
- {
- temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node;
- while(temp_spp_recv_data_node_p1 != NULL)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- esp_log_buffer_char(GATTS_TAG, (char *)(temp_spp_recv_data_node_p1->node_buff),temp_spp_recv_data_node_p1->len);
- #endif
- //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;
- }
- }
- //DAVID
- /*
- void get_cmd_handler_task(void * arg)
- {
- uint8_t * cmd_id;
- for(;;)
- {
- vTaskDelay(50 / portTICK_PERIOD_MS);
- if(xQueueReceive(cmd_cmd_queue, &cmd_id, portMAX_DELAY))
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- esp_log_buffer_hex(GATTS_TAG,(char *)(cmd_id), strlen((char *)cmd_id));
- #endif
- free(cmd_id);
- }
- }
- vTaskDelete(NULL);
- }
- static void spp_task_init(void)
- {
- #ifdef SUPPORT_HEARTBEAT
- 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(get_cmd_handler_task, "get_cmd_handler_task", 2048, NULL, 10, NULL);
- }
- */
- static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
- {
- int idx = 0;
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "EVT %d, gatts if %d", event, gatts_if);
- #endif
- /* 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_TAG, "Reg app failed, app_id %04x, status %d", param->reg.app_id, param->reg.status);
- return;
- }
- }
- /* If the gatts_if equal to profile A, call profile A cb handler, so here call each profile's callback */
- 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);
- }
- }
- }
- }
- static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
- {
- esp_err_t err = ESP_FAIL;
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGE(GATTS_TAG, "GAP_EVT, event %d", event);
- #endif
- switch (event)
- {
- case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT");
- #endif
- esp_ble_gap_start_advertising(&spp_adv_params); // Trigger ESP_GAP_BLE_ADV_START_COMPLETE_EVT
- break;
- case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GAP_BLE_ADV_START_COMPLETE_EVT");
- #endif
- //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_TAG, "Advertising start failed: %s", esp_err_to_name(err));
- }
- break;
- default:
- 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)
- {
- uint8_t res = 0xff;
- //xMessage* pxMessage = NULL;
- esp_ble_gatts_cb_param_t *p_data = (esp_ble_gatts_cb_param_t *) param;
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "event = %x, handle %d.", event, p_data->write.handle);
- #endif
- switch (event)
- {
- case ESP_GATTS_REG_EVT: /*!< When register application id, the event comes */
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_REG_EVT");
- ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
- #endif
- esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
- #endif
- esp_ble_gap_config_adv_data_raw((uint8_t *)spp_adv_data, sizeof(spp_adv_data)); // Trigger ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
- #endif
- esp_ble_gatts_create_attr_tab(spp_gatt_db, gatts_if, SPP_IDX_NB, SPP_SVC_INST_ID); // Trigger ESP_GATTS_CREAT_ATTR_TAB_EVT
- break;
- case ESP_GATTS_READ_EVT: /*!< When GATT client request read operation, the event comes */
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_READ_EVT");
- #endif
- res = find_char_and_desr_index(p_data->read.handle);
- if(res == SPP_IDX_SPP_DATA_RECV_VAL)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_RECV_VAL");
- #endif
- }
- else if(res == SPP_IDX_SPP_DATA_NTY_VAL)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_NTY_VAL");
- #endif
- }
- else if(res == SPP_IDX_SPP_COMMAND_VAL) // add command to Q.
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_COMMAND_VAL");
- #endif
- }
- else if(res == SPP_IDX_SPP_STATUS_VAL)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_STATUS_VAL handle %d.", p_data->write.handle);
- #endif
- //TODO:client read the status characteristic
- //ESP_LOGI(GATTS_TAG, "send OK, write handle %d.", p_data->write.handle);
- //esp_ble_gatts_set_attr_value(p_data->write.handle, 2, (const uint8_t*)"OK");
- }
- break;
- case ESP_GATTS_WRITE_EVT: /*!< When GATT client request write operation, the event comes */
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_WRITE_EVT");
- #endif
- res = find_char_and_desr_index(p_data->write.handle);
- if(p_data->write.is_prep == false)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, " handle = %d", res);
- #endif
- if(res == SPP_IDX_SPP_COMMAND_VAL) // add command to Q.
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_COMMAND_VAL\n");
- #endif
- 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_TAG, "%s malloc failed\n", __func__);
- set_status("ERR M 7", 7);
- break;
- }
- memset(spp_cmd_buff, 0x0,(spp_mtu_size - 3));
- memcpy(spp_cmd_buff, p_data->write.value, p_data->write.len);
- if (xQueueSend(interface_queue, &spp_cmd_buff, 10 / portTICK_PERIOD_MS) != pdPASS)
- set_status("ERR Q 7", 7);
- else
- set_status("OK 7 UID", 8);
- /*
- pxMessage = (xMessage*)malloc(sizeof(xMessage));
- if(pxMessage == NULL)
- {
- ESP_LOGE(GATTS_TAG, "%s malloc failed\n", __func__);
- set_status("ERR M 7", 7);
- break;
- }
- pxMessage->ucDataBuff = (uint8_t*)malloc((spp_mtu_size - 3) * sizeof(uint8_t));
- if(pxMessage->ucDataBuff == NULL)
- {
- ESP_LOGE(GATTS_TAG, "%s malloc failed\n", __func__);
- set_status("ERR M 7", 7);
- break;
- }
- memset(pxMessage->ucDataBuff, 0x0,(spp_mtu_size - 3));
- memcpy(pxMessage->ucDataBuff, (p_data->write.value)+1, (p_data->write.len)-1);
- pxMessage->usMessageUID = esp_random();
- pxMessage->usDataLen = p_data->write.len;
- pxMessage->ucMessageID = p_data->write.value[0];
- ESP_LOGI(GATTS_TAG, "message[0x%d]: ID%d, UID%d, DATA[%s].", (int)pxMessage, pxMessage->ucMessageID, pxMessage->usMessageUID, pxMessage->ucDataBuff);
- if (interface_queue != NULL)
- {
- if (xQueueSend(interface_queue, (void*)pxMessage, 10 / portTICK_PERIOD_MS) != pdPASS)
- set_status("ERR Q 7", 7);
- else
- set_status("OK 7 UID", 8);
- }
- else
- set_status("OK 7 UID", 8);
- */
- }
- else if(res == SPP_IDX_SPP_DATA_NTF_CFG)
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_NTF_CFG");
- esp_log_buffer_char(GATTS_TAG,(char *)(p_data->write.value),p_data->write.len);
- #endif
- 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;
- }
- }
- #endif
- else if(res == SPP_IDX_SPP_DATA_RECV_VAL) // print row data.
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_RECV_VAL handle %d.", p_data->write.handle);
- esp_log_buffer_char(GATTS_TAG,(char *)(p_data->write.value),p_data->write.len);
- #endif
- // TODO process row data.
- set_status("OK 2 UID", 8);
- }
- else
- {
- //TODO:
- }
- }
- else if((p_data->write.is_prep == true)&&(res == SPP_IDX_SPP_DATA_RECV_VAL))
- {
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_PREP_WRITE_EVT : handle = %d.", res);
- #endif
- store_wr_buffer(p_data);
- }
- break;
- case ESP_GATTS_EXEC_WRITE_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
- #endif
- if(p_data->exec_write.exec_write_flag)
- {
- print_write_buffer();
- free_write_buffer();
- }
- break;
- case ESP_GATTS_MTU_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT");
- #endif
- spp_mtu_size = p_data->mtu.mtu;
- break;
- case ESP_GATTS_CONF_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT");
- #endif
- break;
- case ESP_GATTS_UNREG_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_UNREG_EVT");
- #endif
- break;
- case ESP_GATTS_DELETE_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_DELETE_EVT");
- #endif
- break;
- case ESP_GATTS_START_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_START_EVT");
- #endif
- break;
- case ESP_GATTS_STOP_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_STOP_EVT");
- #endif
- break;
- case ESP_GATTS_CONNECT_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT");
- #endif
- 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);
- #endif
- break;
- case ESP_GATTS_DISCONNECT_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT");
- #endif
- is_connected = false;
- enable_data_ntf = false;
- #ifdef SUPPORT_HEARTBEAT
- enable_heart_ntf = false;
- heartbeat_count_num = 0;
- #endif
- esp_ble_gap_start_advertising(&spp_adv_params);
- break;
- case ESP_GATTS_OPEN_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_OPEN_EVT");
- #endif
- break;
- case ESP_GATTS_CANCEL_OPEN_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CANCEL_OPEN_EVT");
- #endif
- break;
- case ESP_GATTS_CLOSE_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CLOSE_EVT");
- #endif
- break;
- case ESP_GATTS_LISTEN_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_LISTEN_EVT");
- #endif
- break;
- case ESP_GATTS_CONGEST_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONGEST_EVT");
- #endif
- break;
- case ESP_GATTS_CREAT_ATTR_TAB_EVT:
- #ifdef BLE_SPP_GEET_SERVER_DEBUG
- ESP_LOGI(GATTS_TAG, "ESP_GATTS_CREAT_ATTR_TAB_EVT");
- ESP_LOGI(GATTS_TAG, "The number handle =%x",param->add_attr_tab.num_handle);
- #endif
- if (param->add_attr_tab.status != ESP_GATT_OK)
- {
- ESP_LOGE(GATTS_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_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]); // Trigger ESP_GATTS_START_EVT
- }
- break;
- default:
- break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- int set_cmd(const char* cmd, uint8_t size)
- {
- ESP_LOGI(GATTS_TAG, "%s.", cmd);
- return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_COMMAND_VAL, size, (const uint8_t*)cmd);
- }
- int set_data(const char* data, uint8_t size)
- {
- ESP_LOGI(GATTS_TAG, "%s.", data);
- return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_DATA_RECV_VAL, size, (const uint8_t*)data);
- }
- int set_data_nty(const char* data, uint8_t size)
- {
- ESP_LOGI(GATTS_TAG, "%s.", data);
- return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_DATA_NTY_VAL, size, (const uint8_t*)data);
- }
- int set_status(const char* status, uint8_t size)
- {
- ESP_LOGI(GATTS_TAG, "%s.", status);
- return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_STATUS_VAL, size, (const uint8_t*)status);
- }
- /// Global variables ///////////////////////////////////////////////////////////
- /// Global functions ///////////////////////////////////////////////////////////
- void getts_init_variable(void)
- {
- is_connected = false;
- ble_geets_init_mutex_h = xSemaphoreCreateMutex(); // Create MUTEX.
- }
- esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); // crash when in gett_server_init()
- void gett_server_init(uint32_t timeout_ms)
- {
- esp_err_t ret = ESP_FAIL;
- ESP_LOGI(GATTS_TAG, "Init.");
- if(ble_geets_init_mutex_h != NULL)
- {
- xSemaphoreTake(ble_geets_init_mutex_h, 0); // Take the MUTEX to lock all API..
- // init in main. TODO nvs init.
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- 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_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret));
- return;
- }
- ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- ESP_LOGI(GATTS_TAG, "%s Init bluetooth.", __func__);
- ret = esp_bluedroid_init();
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
- return;
- }
- ret = esp_bluedroid_enable();
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
- return;
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- ret = esp_ble_gatts_register_callback(gatts_event_handler);
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret);
- return;
- }
- ret = esp_ble_gap_register_callback(gap_event_handler);
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret);
- return;
- }
- ret = esp_ble_gatts_app_register(ESP_SPP_APP_ID);
- if (ret)
- {
- ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
- return;
- }
- //DAVID spp_task_init();
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- xSemaphoreGive(ble_geets_init_mutex_h); // Release the MUTEX if success.
- }
- else
- {
- /// TODO error CreateMutex.
- }
- }
- void gett_server_deinit(void)
- {
- // esp_ble_gatts_app_unregister(?)
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- esp_bluedroid_disable();
- esp_bluedroid_deinit();
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- esp_bt_controller_deinit();
- esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
- }
- bool is_ble_device_connected(void)
- {
- return is_connected;
- }