Page 1 of 1

Common GATTC Profile definition

Posted: Fri Jan 29, 2021 10:06 am
by Efisio
Hello!

Based on the BLE Multi connection Client example https://github.com/espressif/esp-idf/bl ... _connect.c, I'm trying to find a way to have multiple Profiles (one for each BLE Server) without repeating the same piece of code for all of them.

If I understand, the example does the following:
1) Defines Number of GATTC Profiles and their corresponding ID (Profile A is 0, Profile B is 1 and so on)
2) Declares the device name (ESP_DEMO_A, ESP_DEMO_B,...)
3) Declares and registers each GATT Profile Handler (gattc_profile_a_event_handler, gattc_profile_b_event_handler,...)

My question is related to steps 2 and 3, GATTC Profile Handlers B and C are copies of A, which makes the code way longer, repetitive and difficult to maintain. Any pointers on how to do this properly? I'm trying to reinvent the wheel maybe?

I'd like to have something like gattc_profile_common_event_handler to add multiple servers (let's say 5 for example) without repeating so many lines of code.

Thanks in advance for your answers

For instance, this is how the example looks like:

Here, they simply define the ID for each GATT Profile

Code: Select all

/* register three profiles, each profile corresponds to one connection,
   which makes it easy to handle each connection event */
#define PROFILE_NUM 3
#define PROFILE_A_APP_ID 0
#define PROFILE_B_APP_ID 1
#define PROFILE_C_APP_ID 2
Here, they use an array of structs to specify the parameters of each connection, where PROFILE_A_APP_ID is actually an index

Code: Select all

/* 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_a_event_handler,
        .gattc_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
    },
    [PROFILE_B_APP_ID] = {
        .gattc_cb = gattc_profile_b_event_handler,
        .gattc_if = ESP_GATT_IF_NONE,       /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
    },
Here is the issue, I should be able to replace gattc_profile_a_event_handler and in some way get rid of PROFILE_A_APP_ID but it is not straightforward.

Code: Select all

static void gattc_profile_a_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{

    ...
    
        memcpy(gl_profile_tab[PROFILE_A_APP_ID].remote_bda, p_data->open.remote_bda, 6);
        gl_profile_tab[PROFILE_A_APP_ID].conn_id = p_data->open.conn_id;
        ESP_LOGI(GATTC_TAG, "ESP_GATTC_OPEN_EVT conn_id %d, if %d, status %d, mtu %d", p_data->open.conn_id, gattc_if, p_data->open.status, p_data->open.mtu);
        ESP_LOGI(GATTC_TAG, "REMOTE BDA:");
        esp_log_buffer_hex(GATTC_TAG, p_data->open.remote_bda, sizeof(esp_bd_addr_t));
        esp_err_t mtu_ret = esp_ble_gattc_send_mtu_req (gattc_if, p_data->open.conn_id);
        if (mtu_ret){
            ESP_LOGE(GATTC_TAG, "config MTU error, error code = %x", mtu_ret);
        }

Re: Common GATTC Profile definition

Posted: Tue May 24, 2022 7:40 am
by MrHause
Hi,
You can use:
gattc_if
variable that it is passed to this function as the argument instead hardcoded indexes.