Creating our own READ,write event in BLE ESP 32 ESP IDF

Manveen
Posts: 2
Joined: Wed Jun 13, 2018 10:11 am

Creating our own READ,write event in BLE ESP 32 ESP IDF

Postby Manveen » Wed Jun 13, 2018 12:01 pm

How do we manually create read /write event to send or receive data ?
I have been using the example code for GATT client given here

https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/gatt_client/main/gattc_demo.c

I tried to use esp_ble_gattc_write_char() in app main directly after registering all the App Profile ID but it shows that all the param meters of esp_ble_gattc_write_char() are not present

So how can we manually trigger the read and write event ??


here is my code if any one wants

Code: Select all

/*
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/



/****************************************************************************
*
* This file is for gatt client. It can scan ble device, connect one device.
* Run the gatt_server demo, the client demo will automatically connect to the gatt_server demo.
* Client demo will enable gatt_server's notify after connection. Then the two devices will exchange
* data.
*
****************************************************************************/

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"

#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gattc_api.h"
#include "esp_gatt_defs.h"
#include "esp_bt_main.h"
#include "esp_gatt_common_api.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"

#define GATTC_TAG "GATTC_DEMO" //used for logging

#define REMOTE_SERVICE_UUID        0x00FF   //The service that we want the characteristics from has an UUID of 0x00FF
#define REMOTE_NOTIFY_CHAR_UUID    0xFF01   // the characteristic we are interested in has an UUID of 0xFF01:

//custom uuid i tried but they did not work
// 6 bit uuid also doenst work
//#define REMOTE_SERVICE_UUID   8e575d17-0bc3-45f1-9839-d494ae954eea
//#define REMOTE_NOTIFY_CHAR_UUID   8bf4e50f-b3ed-47e2-b776-faca59c0ab62


#define PROFILE_NUM      1 //this is an application profile
#define PROFILE_A_APP_ID 0 // this is the id of that app profile // The Application Profile are stored in the gl_profile_tab array,
#define INVALID_HANDLE   0 //char_handle: the characteristic handle, this parameter valid when the type is ESP_GATT_DB_DESCRIPTOR.
                     //If the type isn’t ESP_GATT_DB_DESCRIPTOR, this parameter should be ignore.

static const char remote_device_name[] = "ESP_GATTS_DEMO"; // this is the device we want to connect to
//static const char remote_device_name[] = "Manveenmob"; // this is the device we want to connect to

//static bool connect    = false;
static bool connect    = false;  // this means that the client is now not connected to anything
static bool get_server = false;
static esp_gattc_char_elem_t *char_elem_result   = NULL;
static esp_gattc_descr_elem_t *descr_elem_result = NULL;
uint8_t devicenumber = 1;

/* eclare static functions */
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param); // basically isr function to a gap event  used in line 451
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param); // basically isr function to a gap event used in line 451 
static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);


static esp_bt_uuid_t remote_filter_service_uuid = {
    .len = ESP_UUID_LEN_16,
    .uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
};

static esp_bt_uuid_t remote_filter_char_uuid = {
    .len = ESP_UUID_LEN_16,
    .uuid = {.uuid16 = REMOTE_NOTIFY_CHAR_UUID,},
};

/*
static esp_bt_uuid_t remote_filter_service_uuid = {
    .len = ESP_UUID_LEN_16,
    .uuid = {.uuid16 = REMOTE_SERVICE_UUID,},
};

static esp_bt_uuid_t remote_filter_char_uuid = {
    .len = ESP_UUID_LEN_16,
    .uuid = {.uuid16 = REMOTE_NOTIFY_CHAR_UUID,},
};

*/

static esp_bt_uuid_t notify_descr_uuid = {
    .len = ESP_UUID_LEN_16,
    .uuid = {.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG,},
};

static esp_ble_scan_params_t ble_scan_params = {
    .scan_type              = BLE_SCAN_TYPE_ACTIVE,
    .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,
//   .own_addr_type          = BLE_ADDR_TYPE_RANDOM,
/*   doesnt work  shows error  BT_HCI: btu_
   hcif_hdl_command_complete opcode 0x200c status 0xc
   maybe i have to generate a random address then it will resolve this issue
   
   esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
This function set the random address for the application.
   
   */

    .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
    .scan_interval          = 0x50,
    .scan_window            = 0x30,
   // .scan_duplicate         = BLE_SCAN_DUPLICATE_DISABLE
   .scan_duplicate         = BLE_SCAN_DUPLICATE_ENABLE // filters out duplicates
};

struct gattc_profile_inst {
    esp_gattc_cb_t gattc_cb; //GATT client callback function
    uint16_t gattc_if; //GATT client interface number for this profile
    uint16_t app_id; // Application Profile ID number
    uint16_t conn_id; // Connection ID
    uint16_t service_start_handle; //Service start handle
    uint16_t service_end_handle; //Service end handle
    uint16_t char_handle; //Char handle
    esp_bd_addr_t remote_bda; //Remote device address connected to this client.
};

/* One gatt-based profile one app_id and one gattc_if, this array will store the gattc_if returned by ESP_GATTS_REG_EVT */
static struct gattc_profile_inst gl_profile_tab[PROFILE_NUM] = {
    [PROFILE_A_APP_ID] = {
        .gattc_cb = gattc_profile_event_handler,
        .gattc_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE. If callback report gattc_if/gatts_if as this macro,
                                                means this event is not correspond to any app  */
    },
};

static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
    esp_ble_gattc_cb_param_t *p_data = (esp_ble_gattc_cb_param_t *)param;

    switch (event)
   {
      case ESP_GATTC_REG_EVT: // sets scan parameters
          ESP_LOGI(GATTC_TAG, "REG_EVT"); // logs
          esp_err_t scan_ret = esp_ble_gap_set_scan_params(&ble_scan_params); // checks wether the scan parameters have been set or not
          if (scan_ret)
          {// if scan parameter are not set then
              ESP_LOGE(GATTC_TAG, "set scan params error, error code = %x", scan_ret);
          }
        break;
      case ESP_GATTC_CONNECT_EVT: //this wasnt triggered connection wasnt opened
         {  //After opening the connection, an ESP_GATTC_CONNECT_EVT event is triggered:
         ESP_LOGI(GATTC_TAG, "ESP_GATTC_CONNECT_EVT conn_id %d, if %d", p_data->connect.conn_id, gattc_if);
         gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->connect.conn_id;
         memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->connect.remote_bda, sizeof(esp_bd_addr_t));
         ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
         esp_log_buffer_hex(GATTC_TAG, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, sizeof(esp_bd_addr_t));
         esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->connect.conn_id);
         if (mtu_ret)
         {
             ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
         }
        break;
    }
    case ESP_GATTC_OPEN_EVT:    //The connection opening also triggers an ESP_GATTC_OPEN_EVT,
                        //which is used to check that the opening of the connection was done successfully,
                        //otherwise print an error and exit.
         if (param->open.status != ESP_GATT_OK)
         {
             ESP_LOGE(GATTC_TAG, "open failed, status %d", p_data->open.status);
             break;
         }
        ESP_LOGI(GATTC_TAG, "open success");
        break;
    case ESP_GATTC_CFG_MTU_EVT: // when mtu is exchanged
        if (param->cfg_mtu.status != ESP_GATT_OK) // when there is a problem in exchange
      {
            ESP_LOGE(GATTC_TAG,"config mtu failed, error status = %x", param->cfg_mtu.status);
        }
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_CFG_MTU_EVT, Status %d, MTU %d, conn_id %d", param->cfg_mtu.status, param->cfg_mtu.mtu, param->cfg_mtu.conn_id);
        //The MTU configuration event is also used to start discovering the services available in the server that the client just connected to.
      esp_ble_gattc_search_service(gattc_if, param->cfg_mtu.conn_id, &remote_filter_service_uuid);
        //To discover the services, the function esp_ble_gattc_search_service() is used.
      break;
      
    case ESP_GATTC_SEARCH_RES_EVT: {
         ESP_LOGI(GATTC_TAG, "SEARCH RES: conn_id = %x is primary service %d", p_data->search_res.conn_id, p_data->search_res.is_primary);
         ESP_LOGI(GATTC_TAG, "start handle %d end handle %d current handle value %d", p_data->search_res.start_handle, p_data->search_res.start_handle, p_data->search_res.srvc_id.inst_id);
       
       // this is used to look for the service
      
       if (p_data->search_res.srvc_id.uuid.len == ESP_UUID_LEN_16 && p_data->search_res.srvc_id.uuid.uuid.uuid16 == REMOTE_SERVICE_UUID) {
             ESP_LOGI(GATTC_TAG, "service found");
             get_server = true;
             gl_profile_tab[PROFILE_A_APP_ID].service_start_handle = p_data->search_res.start_handle;
             gl_profile_tab[PROFILE_A_APP_ID].service_end_handle = p_data->search_res.end_handle;
             ESP_LOGI(GATTC_TAG, "UUID16: %x", p_data->search_res.srvc_id.uuid.uuid.uuid16);
         }
        break;
    }
    case ESP_GATTC_SEARCH_CMPL_EVT: // when search event is complete
        if (p_data->search_cmpl.status != ESP_GATT_OK)
      { // if searching for devices has failed
            ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status);
            break;
        }
       
      ESP_LOGI(GATTC_TAG, "ESP_GATTC_SEARCH_CMPL_EVT");
       
      if (get_server)
      {
            uint16_t count = 0;
            esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if,
                                                                     p_data->search_cmpl.conn_id,
                                                                     ESP_GATT_DB_CHARACTERISTIC,
                                                                     gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                                     gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                                     INVALID_HANDLE,
                                                                     &count);
            if (status != ESP_GATT_OK)
         {
                ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
            }

            if (count > 0)
         {
                char_elem_result = (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * count);
                if (!char_elem_result)
            {
                    ESP_LOGE(GATTC_TAG, "gattc no mem");
                }else
             {
                    status = esp_ble_gattc_get_char_by_uuid( gattc_if,
                                                             p_data->search_cmpl.conn_id,
                                                             gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                             gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                             remote_filter_char_uuid,
                                                             char_elem_result,
                                                             &count);
                    if (status != ESP_GATT_OK)
               {
                        ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error");
                    }

                    /*  Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */
                    if (count > 0 && (char_elem_result[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY))
               {
                        gl_profile_tab[PROFILE_A_APP_ID].char_handle = char_elem_result[0].char_handle;
                        esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, char_elem_result[0].char_handle);
                    }
                 }
                /* free char_elem_result */
                free(char_elem_result);
            }else
          {
                ESP_LOGE(GATTC_TAG, "no char found");
             }
        }
         break;
    case ESP_GATTC_REG_FOR_NOTIFY_EVT:
   {
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_REG_FOR_NOTIFY_EVT");
        if (p_data->reg_for_notify.status != ESP_GATT_OK)
      {
            ESP_LOGE(GATTC_TAG, "REG FOR NOTIFY failed: error status = %d", p_data->reg_for_notify.status);
        }else
       {
            uint16_t count = 0;
            uint16_t notify_en = 1;
            esp_gatt_status_t ret_status = esp_ble_gattc_get_attr_count( gattc_if,
                                                                         gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                                                         ESP_GATT_DB_DESCRIPTOR,
                                                                         gl_profile_tab[PROFILE_A_APP_ID].service_start_handle,
                                                                         gl_profile_tab[PROFILE_A_APP_ID].service_end_handle,
                                                                         gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                                                                         &count);
            if (ret_status != ESP_GATT_OK)
         {
                ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error");
            }
            if (count > 0)
         {
                descr_elem_result = malloc(sizeof(esp_gattc_descr_elem_t) * count);
                if (!descr_elem_result)
            {
                    ESP_LOGE(GATTC_TAG, "malloc error, gattc no mem");
                }else
             {
                    ret_status = esp_ble_gattc_get_descr_by_char_handle( gattc_if,
                                                                         gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                                                         p_data->reg_for_notify.handle,
                                                                         notify_descr_uuid,
                                                                         descr_elem_result,
                                                                         &count);
                    if (ret_status != ESP_GATT_OK)
               {
                        ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_descr_by_char_handle error");
                    }
                    /* Every char has only one descriptor in our 'ESP_GATTS_DEMO' demo, so we used first 'descr_elem_result' */
                    if (count > 0 && descr_elem_result[0].uuid.len == ESP_UUID_LEN_16 && descr_elem_result[0].uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG)
               {
                        ret_status = esp_ble_gattc_write_char_descr( gattc_if,
                                                                     gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                                                     descr_elem_result[0].handle,
                                                                     sizeof(notify_en),
                                                                     (uint8_t *)&notify_en,
                                                                     ESP_GATT_WRITE_TYPE_RSP,
                                                                     ESP_GATT_AUTH_REQ_NONE);
                    }

                    if (ret_status != ESP_GATT_OK)
               {
                        ESP_LOGE(GATTC_TAG, "esp_ble_gattc_write_char_descr error");
                    }

                    /* free descr_elem_result */
                    free(descr_elem_result);
                 }
            }
            else
          {
                ESP_LOGE(GATTC_TAG, "decsr not found");
             }

         }
        break;
    }
    case ESP_GATTC_NOTIFY_EVT:
        if (p_data->notify.is_notify)
      {
            ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive notify value:");
        }else
      {
            ESP_LOGI(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive indicate value:");
        }
        esp_log_buffer_hex(GATTC_TAG, p_data->notify.value, p_data->notify.value_len);
        break;
    case ESP_GATTC_WRITE_DESCR_EVT:
        if (p_data->write.status != ESP_GATT_OK)
      {
            ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status);
            break;
        }
        ESP_LOGI(GATTC_TAG, "write descr success ");
        uint8_t write_char_data[35];
        for (int i = 0; i < sizeof(write_char_data); ++i)
        {
            write_char_data[i] = i % 256;
        }
        esp_ble_gattc_write_char( gattc_if,
                                  gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                  gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                                  sizeof(write_char_data),
                                  write_char_data,
                                  ESP_GATT_WRITE_TYPE_RSP,
                                  ESP_GATT_AUTH_REQ_NONE);
        break;
    case ESP_GATTC_SRVC_CHG_EVT: {
        esp_bd_addr_t bda;
        memcpy(bda, p_data->srvc_chg.remote_bda, sizeof(esp_bd_addr_t));
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_SRVC_CHG_EVT, bd_addr:");
        esp_log_buffer_hex(GATTC_TAG, bda, sizeof(esp_bd_addr_t));
        break;
    }
    case ESP_GATTC_WRITE_CHAR_EVT:
        if (p_data->write.status != ESP_GATT_OK){
            ESP_LOGE(GATTC_TAG, "write char failed, error status = %x", p_data->write.status);
            break;
        }
        ESP_LOGI(GATTC_TAG, "write char success ");
        break;
    case ESP_GATTC_DISCONNECT_EVT:
        connect = false;
        get_server = false;
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_DISCONNECT_EVT, reason = %d", p_data->disconnect.reason);
        break;
    default:
        break;
    }
}

static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) // this is a function created to
{
    uint8_t *adv_name = NULL;
    uint8_t adv_name_len = 0;
    switch (event)
   {
      case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
      {
         //the unit of the duration is second
         
            ESP_LOGI(GATTC_TAG, "Started scaning");
            //uint32_t duration = 15;
            uint32_t duration = 5;
            
            esp_ble_gap_start_scanning(duration); // couldnt start the scan
         
        break;
      }
    case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
         //scan start complete event to indicate scan start successfully or failed
         if (param->scan_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
       {
            ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status);
            break;
         }
         ESP_LOGI(GATTC_TAG, "scan start success");

    break;
    case ESP_GAP_BLE_SCAN_RESULT_EVT: 
        {  // after scaning this event is called
         esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; // it copies all the parameters to a new param meter called scan result
         ESP_LOGI(GATTC_TAG, "ESP_GAP_BLE_SCAN_RESULT_EVT is trigerd ");
         // switch inside a switch
         
         switch (scan_result->scan_rst.search_evt) //checks what search event has given output
                                       /*
                                    ESP_GAP_SEARCH_INQ_RES_EVT             = 0,      !< Inquiry result for a peer device.
                                    ESP_GAP_SEARCH_INQ_CMPL_EVT            = 1,      !< Inquiry complete.
                                    ESP_GAP_SEARCH_DISC_RES_EVT            = 2,      !< Discovery result for a peer device.
                                    ESP_GAP_SEARCH_DISC_BLE_RES_EVT        = 3,      !< Discovery result for BLE GATT based service on a peer device.
                                    ESP_GAP_SEARCH_DISC_CMPL_EVT           = 4,      !< Discovery complete.
                                    ESP_GAP_SEARCH_DI_DISC_CMPL_EVT        = 5,     !< Discovery complete.
                                    ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT  = 6,      < Search cancelled
         */
         {
            case ESP_GAP_SEARCH_INQ_RES_EVT:  //ESP_GAP_SEARCH_INQ_RES_EVT event, which is called every time a new device is found.
               //Every time we receive a result from the ESP_GAP_SEARCH_INQ_RES_EVT event, the code first prints the address of the remote device:
               
                esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); // prints the device address
                //The client then prints the advertised data length and the scan response length
               
                ESP_LOGI(GATTC_TAG, "scanned device number = %d",devicenumber);
                ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);
                devicenumber++;
               
               /*In order to get the device name, we use the esp_ble_resolve_adv_data() function,
               which takes the advertised data stored in scan_result->scan_rst.ble_adv, the type of advertising data
               and the length, in order to extract the value from the advertising packet frame.
               Then the device name is printed.
               */
               
               // this is used to print the device name
               adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv,
                                                ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
               ESP_LOGI(GATTC_TAG, "searched Device Name Len %d", adv_name_len);
               esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len);
               ESP_LOGI(GATTC_TAG, "\n");
               
               
               if (adv_name != NULL)
               { // this line is used to check create a connection
                  if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0)
                  {
                     ESP_LOGI(GATTC_TAG, "searched device %s\n", remote_device_name);
                     if (connect == false)
                     {
                      connect = true;
                      ESP_LOGI(GATTC_TAG, "connect to the remote device.");
                      esp_ble_gap_stop_scanning();
                      esp_ble_gattc_open(gl_profile_tab[PROFILE_A_APP_ID].gattc_if, scan_result->scan_rst.bda, scan_result->scan_rst.ble_addr_type, true);
                     }
                  }   
               }
            break;
         
            case ESP_GAP_SEARCH_INQ_CMPL_EVT: // this is the last event trigered this event is trigered when there is no connection formed
                ESP_LOGI(GATTC_TAG, "esp gap search inq cmpl evnt all the devices have been searched .. what happens after this ? where and how to connect");
                uint32_t duration = 15;
            //uint32_t duration = 5;
            
            esp_ble_gap_start_scanning(duration); // couldnt start the scan
            break;
            default:
            break;
         }
    break;
    }

    case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:   // stopped scanning
      
      //this event was not trigerd
      
       ESP_LOGI(GATTC_TAG, "Stop scan event");
        if (param->scan_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
      {
            ESP_LOGE(GATTC_TAG, "scan stop failed, error status = %x", param->scan_stop_cmpl.status);
            break;
        }
        ESP_LOGI(GATTC_TAG, "stop scan successfully");
        break;

    case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:    // advertising has completed
        if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
      {
            ESP_LOGE(GATTC_TAG, "adv stop failed, error status = %x", param->adv_stop_cmpl.status);
            break;
        }
        ESP_LOGI(GATTC_TAG, "stop adv successfully");
        break;
    case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:   // updates the parameter
         ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
                  param->update_conn_params.status,
                  param->update_conn_params.min_int,
                  param->update_conn_params.max_int,
                  param->update_conn_params.conn_int,
                  param->update_conn_params.latency,
                  param->update_conn_params.timeout);
        break;
    default:
        break;
    }
}
                  // this is event             this is interface      these are parameters
static void esp_gattc_cb(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
    /* If event is register event, store the gattc_if for each profile */
    if (event == ESP_GATTC_REG_EVT) {
        if (param->reg.status == ESP_GATT_OK)
      { // checks the status
            gl_profile_tab[param->reg.app_id].gattc_if = gattc_if;  // if status is ok then create a gl profile tab
        } else {
            ESP_LOGI(GATTC_TAG, "reg app failed, app_id %04x, status %d",
                    param->reg.app_id,
                    param->reg.status);    //logs that registration failed
            return;
        }
    }

    /* If the gattc_if equal to profile A, call profile A cb handler,
     * so here call each profile's callback */
    //Finally, the callback function invokes the corresponding event handler for each profile in the gl_profile_tab table.
    do {
        int idx;
        for (idx = 0; idx < PROFILE_NUM; idx++)
         {
            if (gattc_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
                    gattc_if == gl_profile_tab[idx].gattc_if)
            {
                if (gl_profile_tab[idx].gattc_cb)
             {
                    gl_profile_tab[idx].gattc_cb(event, gattc_if, param);
                }
            }
        }
    } while (0);// runs one time  this is done to remove  int idx from memory
}

void app_main()
{
    // Initialize NVS.
    esp_err_t ret = nvs_flash_init();
   //esp_bd_addr_t rand_addr;
   //esp_err_t  randaddrret =   esp_ble_gap_set_rand_addr(rand_addr);
/*   if (ret) {   
        ESP_LOGE(GATTC_TAG, "didnt work");
        return; 
    }*/
   
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {  // if there is no free space then
        ESP_ERROR_CHECK(nvs_flash_erase());  // perform an error check by erasing the whole memory
        ret = nvs_flash_init();  // again put ret as nvs flash initialization
    }
    ESP_ERROR_CHECK( ret );  //performs a function

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();// bt_cfg is a configurations data type which has default settings
    ret = esp_bt_controller_init(&bt_cfg);   //Initialize BT controller to allocate task and other resource. and it returns esp ok if succesfull
    if (ret) {   // here ret is not esp_ok  // esp ok has 0 value so if ret has any value this means an error has occoured
        ESP_LOGE(GATTC_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;  // this function creates a log for this
    }

    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);  // now we have started bt controller   in ble mode
    if (ret) {
        ESP_LOGE(GATTC_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return; // this creates a log that enable controller failed
    }

    ret = esp_bluedroid_init(); // now we have to initialize the bt controller
    if (ret) {
        ESP_LOGE(GATTC_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    ret = esp_bluedroid_enable(); // enable the bt
    if (ret) {
        ESP_LOGE(GATTC_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    //register the  callback function to the gap module
    ret = esp_ble_gap_register_callback(esp_gap_cb); // This function is called to occur gap event, such as scan result.
    if (ret){
        ESP_LOGE(GATTC_TAG, "%s gap register failed, error code = %x\n", __func__, ret);
        return;
    }

    //register the callback function to the gattc module
    ret = esp_ble_gattc_register_callback(esp_gattc_cb);
    if(ret){
        ESP_LOGE(GATTC_TAG, "%s gattc register failed, error code = %x\n", __func__, ret);
        return;
    }
   /*
   The GAP and GATT event handlers are the functions used to catch
   the events generated by the BLE stack and execute functions
   to configure parameters of the application.
   */   
//The functions esp_gap_cb() and esp_gattc_cb() handle all the events generated by the BLE stack.
    ret = esp_ble_gattc_app_register(PROFILE_A_APP_ID);
    if (ret){
        ESP_LOGE(GATTC_TAG, "%s gattc app register failed, error code = %x\n", __func__, ret);
    }
    esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
    if (local_mtu_ret){
        ESP_LOGE(GATTC_TAG, "set local  MTU failed, error code = %x", local_mtu_ret);
    }
   
   //vTaskDelay(10000 / portTICK_PERIOD_MS);
   
   gattc_profile_event_handler(ESP_GATTC_WRITE_DESCR_EVT,gattc_if,*param);
   
   
}



 // tutorial
 //https://github.com/espressif/esp-idf/blob/64b56be/examples/bluetooth/gatt_client/tutorial/Gatt_Client_Example_Walkthrough.md

 /*
 /// Ble scan parameters
typedef struct {
    esp_ble_scan_type_t     scan_type;               !< Scan type 
    esp_ble_addr_type_t     own_addr_type;           !< Owner address type 
    esp_ble_scan_filter_t   scan_filter_policy;      !< Scan filter policy 
    uint16_t                scan_interval;           !< Scan interval. This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. 
    //Range: 0x0004 to 0x4000
    //Default: 0x0010 (10 ms)
    //Time = N * 0.625 msec
    //Time Range: 2.5 msec to 10.24   seconds
    uint16_t                scan_window;             !< Scan window. The duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval
    //Range: 0x0004 to 0x4000                                                       //Default: 0x0010 (10 ms)
    //Time = N * 0.625 msec
    //Time Range: 2.5 msec to 10240 msec
} esp_ble_scan_params_t;
 
 An it is initialized as:

static esp_ble_scan_params_t ble_scan_params = {
    .scan_type              = BLE_SCAN_TYPE_ACTIVE,
    .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,
    .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
    .scan_interval          = 0x50,
    .scan_window            = 0x30
};




A service is defined using the esp_gatt_srvc_id_t structure as:

@brief Gatt id, include uuid and instance id
 
typedef struct {
    esp_bt_uuid_t   uuid;                  < UUID
    uint8_t         inst_id;                < Instance id
} __attribute__((packed)) esp_gatt_id_t;
 
 ESP_GAP_SEARCH_INQ_CMPL_EVT, which is triggered when the duration of the scanning is
 completed and can be used to restart the scanning procedure:
 
 */

chegewara
Posts: 346
Joined: Wed Jun 14, 2017 9:00 pm

Re: Creating our own READ,write event in BLE ESP 32 ESP IDF

Postby chegewara » Tue Jun 19, 2018 1:41 am

Why you are trying to write to characteristic on write to descriptor event ESP_GATTC_WRITE_DESCR_EVT:

Code: Select all

case ESP_GATTC_WRITE_DESCR_EVT:
        if (p_data->write.status != ESP_GATT_OK)
      {
            ESP_LOGE(GATTC_TAG, "write descr failed, error status = %x", p_data->write.status);
            break;
        }
        ESP_LOGI(GATTC_TAG, "write descr success ");
        uint8_t write_char_data[35];
        for (int i = 0; i < sizeof(write_char_data); ++i)
        {
            write_char_data[i] = i % 256;
        }
        esp_ble_gattc_write_char( gattc_if,
                                  gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                  gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                                  sizeof(write_char_data),
                                  write_char_data,
                                  ESP_GATT_WRITE_TYPE_RSP,
                                  ESP_GATT_AUTH_REQ_NONE);
        break;

Manveen
Posts: 2
Joined: Wed Jun 13, 2018 10:11 am

Re: Creating our own READ,write event in BLE ESP 32 ESP IDF

Postby Manveen » Tue Jun 19, 2018 4:19 am

This is the example code provided by expressif themselves. I am just trying to modify it so that I can perform the required operation. thats why I have not changed any other line of code. I will just add my code on top of it.

Who is online

Users browsing this forum: Bing [Bot], loboris, WiFive and 5 guests