BLE GATTS not gating notify

DavidPilant
Posts: 4
Joined: Thu Jul 21, 2022 11:52 am

BLE GATTS not gating notify

Postby DavidPilant » 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
  1. int set_status(const char* status, uint8_t size)
  2. {
  3.     ESP_LOGI(GATTS_TAG, "%s.", status);
  4.     return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_STATUS_VAL, size, (const uint8_t*)status);
  5. }


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.

  1. /*
  2.   * bala_geet_server.c
  3.  *
  4.  *  Created on: 21 Sep 2023
  5.  *      Author: ddial
  6.  */
  7.  
  8. #include <stdio.h>
  9.  
  10. #include "freertos/FreeRTOS.h"
  11. #include "freertos/task.h"
  12. #include "freertos/event_groups.h"
  13. #include "freertos/semphr.h"
  14.  
  15. #include "esp_system.h"
  16. #include "esp_random.h"
  17. #include "esp_log.h"
  18. #include "nvs_drv.h"
  19. #include "esp_bt.h"
  20.  
  21. #include "string.h"
  22.  
  23. #include "esp_gap_ble_api.h"
  24. #include "esp_gatts_api.h"
  25. #include "esp_gatt_defs.h"
  26. #include "esp_bt_main.h"
  27. #include "esp_gatt_common_api.h"
  28. #include "interface.h"
  29.  
  30. #include "bala_geet_server.h"
  31.  
  32. #define GATTS_TAG "[GATTS]"
  33.  
  34. #define SPP_PROFILE_NUM             1
  35. #define SPP_PROFILE_APP_IDX         0
  36. #define ESP_SPP_APP_ID              0x56
  37.  
  38. #define SAMPLE_DEVICE_NAME          "ESP_SPP_SERV_1"    //The Device Name Characteristics in GAP
  39. #define SPP_SVC_INST_ID             0
  40.  
  41. /// SPP Service
  42. static const uint16_t spp_service_uuid = 0xABF0;
  43. /// Characteristic UUID
  44. #define ESP_GATT_UUID_SPP_DATA_RECEIVE      0xABF1
  45. #define ESP_GATT_UUID_SPP_DATA_NOTIFY       0xABF2
  46. #define ESP_GATT_UUID_SPP_COMMAND_RECEIVE   0xABF3
  47. #define ESP_GATT_UUID_SPP_COMMAND_NOTIFY    0xABF4
  48.  
  49. 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);
  50.  
  51. /// Local variables ////////////////////////////////////////////////////////////
  52. static SemaphoreHandle_t ble_geets_init_mutex_h = NULL;
  53. static uint16_t spp_handle_table[SPP_IDX_NB];
  54. static uint16_t spp_mtu_size = 23;
  55. static uint16_t spp_conn_id = 0xffff;
  56. static esp_gatt_if_t spp_gatts_if = 0xff;
  57. static bool is_connected = false;
  58. static esp_bd_addr_t spp_remote_bda = {0x0,};
  59. static bool enable_data_ntf = false;
  60. static QueueHandle_t cmd_cmd_queue = NULL;
  61.  
  62. typedef struct spp_receive_data_node{
  63.     int32_t len;
  64.     uint8_t * node_buff;
  65.     struct spp_receive_data_node * next_node;
  66. }spp_receive_data_node_t;
  67.  
  68. static spp_receive_data_node_t * temp_spp_recv_data_node_p1 = NULL;
  69. static spp_receive_data_node_t * temp_spp_recv_data_node_p2 = NULL;
  70.  
  71. typedef struct spp_receive_data_buff{
  72.     int32_t node_num;
  73.     int32_t buff_size;
  74.     spp_receive_data_node_t * first_node;
  75. }spp_receive_data_buff_t;
  76.  
  77. static spp_receive_data_buff_t SppRecvDataBuff = {
  78.     .node_num   = 0,
  79.     .buff_size  = 0,
  80.     .first_node = NULL
  81. };
  82.  
  83. static esp_ble_adv_params_t spp_adv_params = {
  84.     .adv_int_min        = 0x20,
  85.     .adv_int_max        = 0x40,
  86.     .adv_type           = ADV_TYPE_IND,
  87.     .own_addr_type      = BLE_ADDR_TYPE_PUBLIC,
  88.     .channel_map        = ADV_CHNL_ALL,
  89.     .adv_filter_policy  = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
  90. };
  91.  
  92. struct gatts_profile_inst {
  93.     esp_gatts_cb_t gatts_cb;
  94.     uint16_t gatts_if;
  95.     uint16_t app_id;
  96.     uint16_t conn_id;
  97.     uint16_t service_handle;
  98.     esp_gatt_srvc_id_t service_id;
  99.     uint16_t char_handle;
  100.     esp_bt_uuid_t char_uuid;
  101.     esp_gatt_perm_t perm;
  102.     esp_gatt_char_prop_t property;
  103.     uint16_t descr_handle;
  104.     esp_bt_uuid_t descr_uuid;
  105. };
  106.  
  107. /* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
  108. static struct gatts_profile_inst spp_profile_tab[SPP_PROFILE_NUM] = {
  109.     [SPP_PROFILE_APP_IDX] = {
  110.         .gatts_cb = gatts_profile_event_handler,
  111.         .gatts_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
  112.     },
  113. };
  114.  
  115. static const uint8_t spp_adv_data[23] = {
  116.     /* Flags */
  117.     0x02,0x01,0x06,
  118.     /* Complete List of 16-bit Service Class UUIDs */
  119.     0x03,0x03,0xF0,0xAB,
  120.     /* Complete Local Name in advertising */
  121.     0x0F,0x09, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R','V', '_', '1'
  122. };
  123.  
  124. /*
  125.  *  SPP PROFILE ATTRIBUTES
  126.  ****************************************************************************************
  127.  */
  128.  
  129. #define CHAR_DECLARATION_SIZE   (sizeof(uint8_t))
  130. static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE;
  131. static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE;
  132. static const uint16_t character_client_config_uuid = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
  133. static const uint8_t char_prop_read_notify = ESP_GATT_CHAR_PROP_BIT_READ|ESP_GATT_CHAR_PROP_BIT_NOTIFY;
  134. static const uint8_t char_prop_read_write = ESP_GATT_CHAR_PROP_BIT_WRITE_NR|ESP_GATT_CHAR_PROP_BIT_READ;
  135.  
  136. #ifdef SUPPORT_HEARTBEAT
  137. 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;
  138. #endif
  139.  
  140. ///SPP Service - data receive characteristic, read&write without response
  141. static const uint16_t spp_data_receive_uuid = ESP_GATT_UUID_SPP_DATA_RECEIVE;
  142. static const uint8_t  spp_data_receive_val[SPP_DATA_MAX_LEN] = { 0 };
  143.  
  144. ///SPP Service - data notify characteristic, notify&read
  145. static const uint16_t spp_data_notify_uuid = ESP_GATT_UUID_SPP_DATA_NOTIFY;
  146. static const uint8_t  spp_data_notify_val[20] = { 0 };
  147. static const uint8_t  spp_data_notify_ccc[2] = { 0 };
  148.  
  149. ///SPP Service - command characteristic, read&write without response
  150. static const uint16_t spp_command_uuid = ESP_GATT_UUID_SPP_COMMAND_RECEIVE;
  151. static const uint8_t  spp_command_val[SPP_CMD_MAX_LEN] = { 0 };
  152.  
  153. ///SPP Service - status characteristic, notify&read
  154. static const uint16_t spp_status_uuid = ESP_GATT_UUID_SPP_COMMAND_NOTIFY;
  155. static const uint8_t  spp_status_val[SPP_STATUS_MAX_LEN] = { 0 };
  156. static const uint8_t  spp_status_ccc[2] = { 0 };
  157.  
  158. #ifdef SUPPORT_HEARTBEAT
  159. ///SPP Server - Heart beat characteristic, notify&write&read
  160. static const uint16_t spp_heart_beat_uuid = ESP_GATT_UUID_SPP_HEARTBEAT;
  161. static const uint8_t  spp_heart_beat_val[2] = {0x00, 0x00};
  162. static const uint8_t  spp_heart_beat_ccc[2] = {0x00, 0x00};
  163. #endif
  164.  
  165.  
  166. ///Full HRS Database Description - Used to add attributes into the database
  167. static const esp_gatts_attr_db_t spp_gatt_db[SPP_IDX_NB] =
  168. {
  169.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  170.     //SPP -  Service Declaration
  171.     [SPP_IDX_SVC] =                                         /// esp_gatts_attr_db_t
  172.     {                                                       /// {
  173.         {                                                   ///     esp_attr_control_t {
  174.                 ESP_GATT_AUTO_RSP                           ///         uint8_t auto_rsp;
  175.         },                                                  ///     }
  176.         {                                                   ///     esp_attr_desc_t {
  177.             ESP_UUID_LEN_16,                                ///         uint16_t uuid_length;              /*!< UUID length */
  178.             (uint8_t *)&primary_service_uuid,               ///         uint8_t  *uuid_p;                  /*!< UUID value */
  179.             ESP_GATT_PERM_READ,                             ///         uint16_t perm;                     /*!< Attribute permission */
  180.             sizeof(spp_service_uuid),                       ///         uint16_t max_length;               /*!< Maximum length of the element*/
  181.             sizeof(spp_service_uuid),                       ///         uint16_t length;                   /*!< Current length of the element*/
  182.             (uint8_t *)&spp_service_uuid                    ///         uint8_t  *value;                   /*!< Element value array*/
  183.         }                                                   ///     }
  184.     },                                                      /// }
  185.  
  186.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  187.     //SPP -  data receive characteristic Declaration
  188.     [SPP_IDX_SPP_DATA_RECV_CHAR] = {
  189.     {ESP_GATT_AUTO_RSP }, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  190.     CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write}},
  191.     //SPP -  data receive characteristic Value
  192.     [SPP_IDX_SPP_DATA_RECV_VAL] = {
  193.     {ESP_GATT_AUTO_RSP }, { ESP_UUID_LEN_16, (uint8_t *)&spp_data_receive_uuid, (ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
  194.     SPP_DATA_MAX_LEN, sizeof(spp_data_receive_val), (uint8_t *)spp_data_receive_val}},
  195.  
  196.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  197.     //SPP -  data notify characteristic Declaration
  198.     [SPP_IDX_SPP_DATA_NOTIFY_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
  199.     ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}},
  200.     //SPP -  data notify characteristic Value
  201.     [SPP_IDX_SPP_DATA_NTY_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_data_notify_uuid,
  202.     ESP_GATT_PERM_READ, sizeof(spp_data_notify_val), sizeof(spp_data_notify_val), (uint8_t *)spp_data_notify_val}},
  203.     //SPP -  data notify characteristic - Client Characteristic Configuration Descriptor
  204.     [SPP_IDX_SPP_DATA_NTF_CFG] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
  205.     (ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE), sizeof(uint16_t), sizeof(spp_data_notify_ccc), (uint8_t *)spp_data_notify_ccc}},
  206.  
  207.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  208.     //SPP -  command characteristic Declaration
  209.     [SPP_IDX_SPP_COMMAND_CHAR] = {{ESP_GATT_AUTO_RSP},{ESP_UUID_LEN_16,(uint8_t *)&character_declaration_uuid,
  210.     ESP_GATT_PERM_READ,CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE,(uint8_t *)&char_prop_read_write}},
  211.     //SPP -  command characteristic Value
  212.     [SPP_IDX_SPP_COMMAND_VAL] = {{ESP_GATT_AUTO_RSP},{
  213.     ESP_UUID_LEN_16, (uint8_t *)&spp_command_uuid, (ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE),
  214.     SPP_CMD_MAX_LEN, SPP_CMD_MAX_LEN, (uint8_t *)spp_command_val}},
  215.  
  216.  
  217.     /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  218.     //SPP -  status characteristic Declaration
  219.     [SPP_IDX_SPP_STATUS_CHAR] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid,
  220.     ESP_GATT_PERM_READ, CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_notify}},
  221.     //SPP -  status characteristic Value
  222.     [SPP_IDX_SPP_STATUS_VAL] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_status_uuid,
  223.     ESP_GATT_PERM_READ, SPP_STATUS_MAX_LEN, SPP_STATUS_MAX_LEN, (uint8_t *)spp_status_val}},
  224.     //SPP -  status characteristic - Client Characteristic Configuration Descriptor
  225.     [SPP_IDX_SPP_STATUS_CFG] = {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid,
  226.     (ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE), sizeof(uint16_t), sizeof(spp_status_ccc), (uint8_t *)spp_status_ccc}},
  227.  
  228. #ifdef SUPPORT_HEARTBEAT
  229.     //SPP -  Heart beat characteristic Declaration
  230.     [SPP_IDX_SPP_HEARTBEAT_CHAR]  =
  231.     {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  232.     CHAR_DECLARATION_SIZE,CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  233.  
  234.     //SPP -  Heart beat characteristic Value
  235.     [SPP_IDX_SPP_HEARTBEAT_VAL]   =
  236.     {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&spp_heart_beat_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
  237.     sizeof(spp_heart_beat_val), sizeof(spp_heart_beat_val), (uint8_t *)spp_heart_beat_val}},
  238.  
  239.     //SPP -  Heart beat characteristic - Client Characteristic Configuration Descriptor
  240.     [SPP_IDX_SPP_HEARTBEAT_CFG]         =
  241.     {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ|ESP_GATT_PERM_WRITE,
  242.     sizeof(uint16_t),sizeof(spp_data_notify_ccc), (uint8_t *)spp_heart_beat_ccc}},
  243. #endif
  244. };
  245.  
  246. /// Local functions ////////////////////////////////////////////////////////////
  247. static uint8_t find_char_and_desr_index(uint16_t handle)
  248. {
  249.     int i = 0;
  250.     uint8_t error = 0xff;
  251.  
  252.     for(i = 0; i < SPP_IDX_NB ; i++)
  253.     {
  254.         if(handle == spp_handle_table[i])
  255.         {
  256.             return i;
  257.         }
  258.     }
  259.  
  260.     return error;
  261. }
  262.  
  263. static bool store_wr_buffer(esp_ble_gatts_cb_param_t *p_data)
  264. {
  265.     temp_spp_recv_data_node_p1 = (spp_receive_data_node_t *)malloc(sizeof(spp_receive_data_node_t));
  266.  
  267.     if(temp_spp_recv_data_node_p1 == NULL)
  268.     {
  269.         ESP_LOGI(GATTS_TAG, "malloc error %s %d", __func__, __LINE__);
  270.         return false;
  271.     }
  272.  
  273.     if(temp_spp_recv_data_node_p2 != NULL)
  274.     {
  275.         temp_spp_recv_data_node_p2->next_node = temp_spp_recv_data_node_p1;
  276.     }
  277.  
  278.     temp_spp_recv_data_node_p1->len = p_data->write.len;
  279.     SppRecvDataBuff.buff_size += p_data->write.len;
  280.     temp_spp_recv_data_node_p1->next_node = NULL;
  281.     temp_spp_recv_data_node_p1->node_buff = (uint8_t *)malloc(p_data->write.len);
  282.     temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1;
  283.     memcpy(temp_spp_recv_data_node_p1->node_buff,p_data->write.value,p_data->write.len);
  284.     if(SppRecvDataBuff.node_num == 0)
  285.     {
  286.         SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1;
  287.         SppRecvDataBuff.node_num++;
  288.     }
  289.     else
  290.     {
  291.         SppRecvDataBuff.node_num++;
  292.     }
  293.  
  294.     return true;
  295. }
  296.  
  297. static void free_write_buffer(void)
  298. {
  299.     temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node;
  300.  
  301.     while(temp_spp_recv_data_node_p1 != NULL)
  302.     {
  303.         temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1->next_node;
  304.         free(temp_spp_recv_data_node_p1->node_buff);
  305.         free(temp_spp_recv_data_node_p1);
  306.         temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p2;
  307.     }
  308.  
  309.     SppRecvDataBuff.node_num = 0;
  310.     SppRecvDataBuff.buff_size = 0;
  311.     SppRecvDataBuff.first_node = NULL;
  312. }
  313.  
  314. static void print_write_buffer(void)
  315. {
  316.     temp_spp_recv_data_node_p1 = SppRecvDataBuff.first_node;
  317.  
  318.     while(temp_spp_recv_data_node_p1 != NULL)
  319.     {
  320. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  321.         esp_log_buffer_char(GATTS_TAG, (char *)(temp_spp_recv_data_node_p1->node_buff),temp_spp_recv_data_node_p1->len);
  322. #endif
  323.         //uart_write_bytes(UART_NUM_0, (char *)(temp_spp_recv_data_node_p1->node_buff), temp_spp_recv_data_node_p1->len);
  324.         temp_spp_recv_data_node_p1 = temp_spp_recv_data_node_p1->next_node;
  325.     }
  326. }
  327.  
  328.  
  329. //DAVID
  330. /*
  331. void get_cmd_handler_task(void * arg)
  332. {
  333.     uint8_t * cmd_id;
  334.  
  335.     for(;;)
  336.     {
  337.         vTaskDelay(50 / portTICK_PERIOD_MS);
  338.         if(xQueueReceive(cmd_cmd_queue, &cmd_id, portMAX_DELAY))
  339.         {
  340. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  341.             esp_log_buffer_hex(GATTS_TAG,(char *)(cmd_id), strlen((char *)cmd_id));
  342. #endif
  343.             free(cmd_id);
  344.         }
  345.     }
  346.  
  347.     vTaskDelete(NULL);
  348. }
  349.  
  350.  
  351. static void spp_task_init(void)
  352. {
  353. #ifdef SUPPORT_HEARTBEAT
  354.     cmd_heartbeat_queue = xQueueCreate(10, sizeof(uint32_t));
  355.     xTaskCreate(spp_heartbeat_task, "spp_heartbeat_task", 2048, NULL, 10, NULL);
  356. #endif
  357.  
  358.     cmd_cmd_queue = xQueueCreate(10, sizeof(uint32_t));
  359.     xTaskCreate(get_cmd_handler_task, "get_cmd_handler_task", 2048, NULL, 10, NULL);
  360. }
  361. */
  362.  
  363. static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
  364. {
  365.     int idx = 0;
  366.  
  367. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  368.     ESP_LOGI(GATTS_TAG, "EVT %d, gatts if %d", event, gatts_if);
  369. #endif
  370.  
  371.     /* If event is register event, store the gatts_if for each profile */
  372.     if (event == ESP_GATTS_REG_EVT)
  373.     {
  374.         if (param->reg.status == ESP_GATT_OK)
  375.         {
  376.             spp_profile_tab[SPP_PROFILE_APP_IDX].gatts_if = gatts_if;
  377.         }
  378.         else
  379.         {
  380.             ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d", param->reg.app_id, param->reg.status);
  381.             return;
  382.         }
  383.     }
  384.  
  385.     /* If the gatts_if equal to profile A, call profile A cb handler, so here call each profile's callback */
  386.     for (idx = 0; idx < SPP_PROFILE_NUM; idx++)
  387.     {
  388.         if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
  389.                 gatts_if == spp_profile_tab[idx].gatts_if)
  390.         {
  391.             if (spp_profile_tab[idx].gatts_cb)
  392.             {
  393.                 spp_profile_tab[idx].gatts_cb(event, gatts_if, param);
  394.             }
  395.         }
  396.     }
  397. }
  398.  
  399. static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
  400. {
  401.     esp_err_t err = ESP_FAIL;
  402.  
  403. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  404.     ESP_LOGE(GATTS_TAG, "GAP_EVT, event %d", event);
  405. #endif
  406.  
  407.     switch (event)
  408.     {
  409.     case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
  410.  
  411. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  412.         ESP_LOGI(GATTS_TAG, "ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT");
  413. #endif
  414.  
  415.         esp_ble_gap_start_advertising(&spp_adv_params);         // Trigger ESP_GAP_BLE_ADV_START_COMPLETE_EVT
  416.  
  417.         break;
  418.  
  419.     case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
  420. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  421.         ESP_LOGI(GATTS_TAG, "ESP_GAP_BLE_ADV_START_COMPLETE_EVT");
  422. #endif
  423.  
  424.         //advertising start complete event to indicate advertising start successfully or failed
  425.         if((err = param->adv_start_cmpl.status) != ESP_BT_STATUS_SUCCESS)
  426.         {
  427.             ESP_LOGE(GATTS_TAG, "Advertising start failed: %s", esp_err_to_name(err));
  428.         }
  429.  
  430.         break;
  431.  
  432.     default:
  433.         break;
  434.     }
  435. }
  436.  
  437. 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)
  438. {
  439.     uint8_t res = 0xff;
  440.     //xMessage* pxMessage = NULL;
  441.     esp_ble_gatts_cb_param_t *p_data = (esp_ble_gatts_cb_param_t *) param;
  442.  
  443. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  444.     ESP_LOGI(GATTS_TAG, "event = %x, handle %d.", event, p_data->write.handle);
  445. #endif
  446.  
  447.     switch (event)
  448.     {
  449.     case ESP_GATTS_REG_EVT:                     /*!< When register application id, the event comes */
  450. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  451.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_REG_EVT");
  452.  
  453.         ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
  454. #endif
  455.         esp_ble_gap_set_device_name(SAMPLE_DEVICE_NAME);
  456. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  457.         ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
  458. #endif
  459.         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
  460. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  461.         ESP_LOGI(GATTS_TAG, "%s %d", __func__, __LINE__);
  462. #endif
  463.         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
  464.         break;
  465.  
  466.     case ESP_GATTS_READ_EVT:                    /*!< When GATT client request read operation, the event comes */
  467. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  468.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_READ_EVT");
  469. #endif
  470.         res = find_char_and_desr_index(p_data->read.handle);
  471.         if(res == SPP_IDX_SPP_DATA_RECV_VAL)
  472.         {
  473. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  474.             ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_RECV_VAL");
  475. #endif
  476.         }
  477.         else if(res == SPP_IDX_SPP_DATA_NTY_VAL)
  478.         {
  479. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  480.             ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_NTY_VAL");
  481. #endif
  482.         }
  483.         else if(res == SPP_IDX_SPP_COMMAND_VAL)     // add command to Q.
  484.         {
  485. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  486.             ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_COMMAND_VAL");
  487. #endif
  488.         }
  489.         else if(res == SPP_IDX_SPP_STATUS_VAL)
  490.         {
  491. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  492.             ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_STATUS_VAL handle %d.", p_data->write.handle);
  493. #endif
  494.             //TODO:client read the status characteristic
  495.             //ESP_LOGI(GATTS_TAG, "send OK, write handle %d.", p_data->write.handle);
  496.             //esp_ble_gatts_set_attr_value(p_data->write.handle, 2, (const uint8_t*)"OK");
  497.  
  498.         }
  499.  
  500.         break;
  501.  
  502.     case ESP_GATTS_WRITE_EVT:                   /*!< When GATT client request write operation, the event comes */
  503. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  504.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_WRITE_EVT");
  505. #endif
  506.  
  507.         res = find_char_and_desr_index(p_data->write.handle);
  508.         if(p_data->write.is_prep == false)
  509.         {
  510. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  511.             ESP_LOGI(GATTS_TAG, " handle = %d", res);
  512. #endif
  513.             if(res == SPP_IDX_SPP_COMMAND_VAL)      // add command to Q.
  514.             {
  515. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  516.                 ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_COMMAND_VAL\n");
  517. #endif
  518.  
  519.                 uint8_t * spp_cmd_buff = NULL;
  520.                 spp_cmd_buff = (uint8_t *)malloc((spp_mtu_size - 3) * sizeof(uint8_t));
  521.                 if(spp_cmd_buff == NULL)
  522.                 {
  523.                     ESP_LOGE(GATTS_TAG, "%s malloc failed\n", __func__);
  524.                     set_status("ERR M 7", 7);
  525.                     break;
  526.                 }
  527.  
  528.                 memset(spp_cmd_buff, 0x0,(spp_mtu_size - 3));
  529.                 memcpy(spp_cmd_buff, p_data->write.value, p_data->write.len);
  530.  
  531.  
  532.                 if (xQueueSend(interface_queue, &spp_cmd_buff, 10 / portTICK_PERIOD_MS) != pdPASS)
  533.                     set_status("ERR Q 7", 7);
  534.                 else
  535.                     set_status("OK 7 UID", 8);
  536. /*
  537.                 pxMessage = (xMessage*)malloc(sizeof(xMessage));
  538.                 if(pxMessage == NULL)
  539.                 {
  540.                     ESP_LOGE(GATTS_TAG, "%s malloc failed\n", __func__);
  541.                     set_status("ERR M 7", 7);
  542.                     break;
  543.                 }
  544.  
  545.                 pxMessage->ucDataBuff = (uint8_t*)malloc((spp_mtu_size - 3) * sizeof(uint8_t));
  546.                 if(pxMessage->ucDataBuff == NULL)
  547.                 {
  548.                     ESP_LOGE(GATTS_TAG, "%s malloc failed\n", __func__);
  549.                     set_status("ERR M 7", 7);
  550.                     break;
  551.                 }
  552.  
  553.                 memset(pxMessage->ucDataBuff, 0x0,(spp_mtu_size - 3));
  554.                 memcpy(pxMessage->ucDataBuff, (p_data->write.value)+1, (p_data->write.len)-1);
  555.                 pxMessage->usMessageUID = esp_random();
  556.                 pxMessage->usDataLen = p_data->write.len;
  557.                 pxMessage->ucMessageID = p_data->write.value[0];
  558.  
  559.                 ESP_LOGI(GATTS_TAG, "message[0x%d]: ID%d, UID%d, DATA[%s].", (int)pxMessage, pxMessage->ucMessageID, pxMessage->usMessageUID, pxMessage->ucDataBuff);
  560.  
  561.                 if (interface_queue != NULL)
  562.                 {
  563.                     if (xQueueSend(interface_queue, (void*)pxMessage, 10 / portTICK_PERIOD_MS) != pdPASS)
  564.                         set_status("ERR Q 7", 7);
  565.                     else
  566.                         set_status("OK 7 UID", 8);
  567.                 }
  568.                 else
  569.                     set_status("OK 7 UID", 8);
  570. */
  571.             }
  572.             else if(res == SPP_IDX_SPP_DATA_NTF_CFG)
  573.             {
  574. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  575.                 ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_NTF_CFG");
  576.                 esp_log_buffer_char(GATTS_TAG,(char *)(p_data->write.value),p_data->write.len);
  577. #endif
  578.                 if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x01)&&(p_data->write.value[1] == 0x00))
  579.                 {
  580.                     enable_data_ntf = true;
  581.                 }
  582.                 else if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x00)&&(p_data->write.value[1] == 0x00))
  583.                 {
  584.                     enable_data_ntf = false;
  585.                 }
  586.             }
  587. #ifdef SUPPORT_HEARTBEAT
  588.             else if(res == SPP_IDX_SPP_HEARTBEAT_CFG)
  589.             {
  590.                 if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x01)&&(p_data->write.value[1] == 0x00))
  591.                 {
  592.                     enable_heart_ntf = true;
  593.                 }
  594.                 else if((p_data->write.len == 2)&&(p_data->write.value[0] == 0x00)&&(p_data->write.value[1] == 0x00))
  595.                 {
  596.                     enable_heart_ntf = false;
  597.                 }
  598.             }
  599.             else if(res == SPP_IDX_SPP_HEARTBEAT_VAL)
  600.             {
  601.                 if((p_data->write.len == sizeof(heartbeat_s))&&(memcmp(heartbeat_s,p_data->write.value,sizeof(heartbeat_s)) == 0))
  602.                 {
  603.                     heartbeat_count_num = 0;
  604.                 }
  605.             }
  606. #endif
  607.             else if(res == SPP_IDX_SPP_DATA_RECV_VAL)   // print row data.
  608.             {
  609. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  610.                 ESP_LOGI(GATTS_TAG, "SPP_IDX_SPP_DATA_RECV_VAL handle %d.", p_data->write.handle);
  611.                 esp_log_buffer_char(GATTS_TAG,(char *)(p_data->write.value),p_data->write.len);
  612. #endif
  613.                 // TODO process row data.
  614.                 set_status("OK 2 UID", 8);
  615.             }
  616.             else
  617.             {
  618.                 //TODO:
  619.             }
  620.         }
  621.         else if((p_data->write.is_prep == true)&&(res == SPP_IDX_SPP_DATA_RECV_VAL))
  622.         {
  623. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  624.             ESP_LOGI(GATTS_TAG, "ESP_GATTS_PREP_WRITE_EVT : handle = %d.", res);
  625. #endif
  626.             store_wr_buffer(p_data);
  627.         }
  628.  
  629.         break;
  630.  
  631.     case ESP_GATTS_EXEC_WRITE_EVT:
  632. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  633.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
  634. #endif
  635.         if(p_data->exec_write.exec_write_flag)
  636.         {
  637.             print_write_buffer();
  638.             free_write_buffer();
  639.         }
  640.  
  641.         break;
  642.  
  643.     case ESP_GATTS_MTU_EVT:
  644. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  645.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT");
  646. #endif
  647.         spp_mtu_size = p_data->mtu.mtu;
  648.         break;
  649.  
  650.     case ESP_GATTS_CONF_EVT:
  651. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  652.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT");
  653. #endif
  654.         break;
  655.  
  656.     case ESP_GATTS_UNREG_EVT:
  657. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  658.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_UNREG_EVT");
  659. #endif
  660.         break;
  661.  
  662.     case ESP_GATTS_DELETE_EVT:
  663. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  664.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_DELETE_EVT");
  665. #endif
  666.         break;
  667.  
  668.     case ESP_GATTS_START_EVT:
  669. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  670.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_START_EVT");
  671. #endif
  672.         break;
  673.  
  674.     case ESP_GATTS_STOP_EVT:
  675. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  676.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_STOP_EVT");
  677. #endif
  678.         break;
  679.  
  680.     case ESP_GATTS_CONNECT_EVT:
  681. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  682.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT");
  683. #endif
  684.         spp_conn_id = p_data->connect.conn_id;
  685.         spp_gatts_if = gatts_if;
  686.         is_connected = true;
  687.         memcpy(&spp_remote_bda,&p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
  688. #ifdef SUPPORT_HEARTBEAT
  689.         uint16_t cmd = 0;
  690.         xQueueSend(cmd_heartbeat_queue, &cmd, 10/portTICK_PERIOD_MS);
  691. #endif
  692.  
  693.         break;
  694.  
  695.     case ESP_GATTS_DISCONNECT_EVT:
  696. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  697.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT");
  698. #endif
  699.         is_connected = false;
  700.         enable_data_ntf = false;
  701. #ifdef SUPPORT_HEARTBEAT
  702.         enable_heart_ntf = false;
  703.         heartbeat_count_num = 0;
  704. #endif
  705.         esp_ble_gap_start_advertising(&spp_adv_params);
  706.  
  707.         break;
  708.  
  709.     case ESP_GATTS_OPEN_EVT:
  710. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  711.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_OPEN_EVT");
  712. #endif
  713.         break;
  714.  
  715.     case ESP_GATTS_CANCEL_OPEN_EVT:
  716. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  717.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CANCEL_OPEN_EVT");
  718. #endif
  719.         break;
  720.  
  721.     case ESP_GATTS_CLOSE_EVT:
  722. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  723.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CLOSE_EVT");
  724. #endif
  725.         break;
  726.  
  727.     case ESP_GATTS_LISTEN_EVT:
  728. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  729.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_LISTEN_EVT");
  730. #endif
  731.         break;
  732.  
  733.     case ESP_GATTS_CONGEST_EVT:
  734. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  735.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONGEST_EVT");
  736. #endif
  737.         break;
  738.  
  739.     case ESP_GATTS_CREAT_ATTR_TAB_EVT:
  740. #ifdef BLE_SPP_GEET_SERVER_DEBUG
  741.         ESP_LOGI(GATTS_TAG, "ESP_GATTS_CREAT_ATTR_TAB_EVT");
  742.  
  743.         ESP_LOGI(GATTS_TAG, "The number handle =%x",param->add_attr_tab.num_handle);
  744. #endif
  745.         if (param->add_attr_tab.status != ESP_GATT_OK)
  746.         {
  747.             ESP_LOGE(GATTS_TAG, "Create attribute table failed, error code=0x%x", param->add_attr_tab.status);
  748.         }
  749.         else if (param->add_attr_tab.num_handle != SPP_IDX_NB)
  750.         {
  751.             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);
  752.         }
  753.         else
  754.         {
  755.             memcpy(spp_handle_table, param->add_attr_tab.handles, sizeof(spp_handle_table));
  756.             esp_ble_gatts_start_service(spp_handle_table[SPP_IDX_SVC]);     // Trigger ESP_GATTS_START_EVT
  757.         }
  758.         break;
  759.  
  760.     default:
  761.         break;
  762.     }
  763. }
  764.  
  765. ///////////////////////////////////////////////////////////////////////////////
  766. int set_cmd(const char* cmd, uint8_t size)
  767. {
  768.     ESP_LOGI(GATTS_TAG, "%s.", cmd);
  769.     return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_COMMAND_VAL, size, (const uint8_t*)cmd);
  770. }
  771.  
  772. int set_data(const char* data, uint8_t size)
  773. {
  774.     ESP_LOGI(GATTS_TAG, "%s.", data);
  775.     return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_DATA_RECV_VAL, size, (const uint8_t*)data);
  776. }
  777.  
  778. int set_data_nty(const char* data, uint8_t size)
  779. {
  780.     ESP_LOGI(GATTS_TAG, "%s.", data);
  781.     return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_DATA_NTY_VAL, size, (const uint8_t*)data);
  782. }
  783.  
  784. int set_status(const char* status, uint8_t size)
  785. {
  786.     ESP_LOGI(GATTS_TAG, "%s.", status);
  787.     return esp_ble_gatts_set_attr_value(40 + SPP_IDX_SPP_STATUS_VAL, size, (const uint8_t*)status);
  788. }
  789.  
  790.  
  791. /// Global variables ///////////////////////////////////////////////////////////
  792.  
  793. /// Global functions ///////////////////////////////////////////////////////////
  794. void getts_init_variable(void)
  795. {
  796.     is_connected = false;
  797.     ble_geets_init_mutex_h = xSemaphoreCreateMutex();                           // Create MUTEX.
  798. }
  799.  
  800. esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();        // crash when in gett_server_init()
  801.  
  802. void gett_server_init(uint32_t timeout_ms)
  803. {
  804.     esp_err_t ret = ESP_FAIL;
  805.  
  806.     ESP_LOGI(GATTS_TAG, "Init.");
  807.  
  808.     if(ble_geets_init_mutex_h != NULL)
  809.     {
  810.         xSemaphoreTake(ble_geets_init_mutex_h, 0);                              // Take the MUTEX to lock all API..
  811.  
  812.         // init in main. TODO nvs init.
  813.  
  814.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  815.         ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  816.  
  817.         ret = esp_bt_controller_init(&bt_cfg);
  818.         if (ret)
  819.         {
  820.             ESP_LOGE(GATTS_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret));
  821.             return;
  822.         }
  823.  
  824.         ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  825.         if (ret)
  826.         {
  827.             ESP_LOGE(GATTS_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret));
  828.             return;
  829.         }
  830.  
  831.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  832.         ESP_LOGI(GATTS_TAG, "%s Init bluetooth.", __func__);
  833.  
  834.         ret = esp_bluedroid_init();
  835.         if (ret)
  836.         {
  837.             ESP_LOGE(GATTS_TAG, "%s init bluetooth failed: %s", __func__, esp_err_to_name(ret));
  838.             return;
  839.         }
  840.  
  841.         ret = esp_bluedroid_enable();
  842.         if (ret)
  843.         {
  844.             ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed: %s", __func__, esp_err_to_name(ret));
  845.             return;
  846.         }
  847.  
  848.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  849.         ret = esp_ble_gatts_register_callback(gatts_event_handler);
  850.         if (ret)
  851.         {
  852.             ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret);
  853.             return;
  854.         }
  855.  
  856.         ret = esp_ble_gap_register_callback(gap_event_handler);
  857.         if (ret)
  858.         {
  859.             ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret);
  860.             return;
  861.         }
  862.  
  863.         ret = esp_ble_gatts_app_register(ESP_SPP_APP_ID);
  864.         if (ret)
  865.         {
  866.             ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
  867.             return;
  868.         }
  869.  
  870.         //DAVID spp_task_init();
  871.         ////////////////////////////////////////////////////////////////////////////////////////////////////////
  872.         xSemaphoreGive(ble_geets_init_mutex_h);                                 // Release the MUTEX if success.
  873.     }
  874.     else
  875.     {
  876.         /// TODO error CreateMutex.
  877.     }
  878.  
  879.  
  880. }
  881.  
  882. void gett_server_deinit(void)
  883. {
  884.     // esp_ble_gatts_app_unregister(?)
  885.     ////////////////////////////////////////////////////////////////////////////////////////////////////////
  886.     esp_bluedroid_disable();
  887.     esp_bluedroid_deinit();
  888.     ////////////////////////////////////////////////////////////////////////////////////////////////////////
  889.     esp_bt_controller_deinit();
  890.     esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
  891. }
  892.  
  893. bool is_ble_device_connected(void)
  894. {
  895.     return is_connected;
  896. }

Who is online

Users browsing this forum: No registered users and 95 guests