creating multiple services in a profile

User4356
Posts: 35
Joined: Wed Feb 17, 2021 7:52 am

creating multiple services in a profile

Postby User4356 » Mon Mar 01, 2021 3:31 am

Hello.
In this tutorial: https://github.com/espressif/esp-idf/bl ... g-services
shows how to add services to a profile, characteristics to services, descriptors to characteristics.

First we define profile table:

Code: Select all

static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
    [PROFILE_A_APP_ID] = {
        .gatts_cb = gatts_profile_a_event_handler,
        .gatts_if = ESP_GATT_IF_NONE,
    [PROFILE_B_APP_ID] = {
        .gatts_cb = gatts_profile_b_event_handler,
        .gatts_if = ESP_GATT_IF_NONE,
    },
};
And register that:

Code: Select all

ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
That call ESP_GATTS_REG_EVT event. In handler of that event we define service:

Code: Select all

         gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true;
         gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00;
         gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
         gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_A;
And create it:

Code: Select all

esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A);
That call ESP_GATTS_CREATE_EVT event. Using this event we define characteristic:

Code: Select all

        gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle;	
        gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16;				
        gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A;
and create characteristic:

Code: Select all

esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
        	ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,	
			a_property,									
			&gatts_demo_char1_val,							
			NULL);	
That call ESP_GATTS_ADD_CHAR_EVT event. We use it for adding descriptor:

Code: Select all

        gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
        gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
        gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
And create descriptor:

Code: Select all

     esp_err_t ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
                                                                ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
What is the behavior of the program after calling the esp_ble_gatts_create_service () function? Will the execution be interrupted at this line of code and processing of the ESP_GATTS_CREATE_EVT event will start? Or does the ESP_GATTS_CREATE_EVT event start after the end of the ESP_GATTS_REG_EVT event?
So, in this code, we are creating one service, one characteristic and one descriptor. But if I need to add two services, how can I do it?

User avatar
WardMas
Posts: 75
Joined: Fri Jun 19, 2020 9:09 am

Re: creating multiple services in a profile

Postby WardMas » Mon Mar 01, 2021 4:32 am

Hi,
ESP-IDF BLE GATT service example: https://github.com/espressif/esp-idf/t ... att_server Creates services A and B. The extra thing you need to do is to add the new service to your profile, register it using esp_ble_gatts_app_register() right after registering your first service and characteristic/descriptor creation is done as you mentioned. Not sure exactly about the whole service registration flow but since GATT register call back is done before before profile registration, most probably the creation interrupts start to execute right after profile registration. If you want to see the order of the whole process, I recommend you a J-Link to ESP32 JTAG pins and start debugging.
You can always visit my YouTube channel for embedded systems related tutorials
https://youtube.com/user/wardzx1

User4356
Posts: 35
Joined: Wed Feb 17, 2021 7:52 am

Re: creating multiple services in a profile

Postby User4356 » Mon Mar 01, 2021 10:09 am

Ok, lets try that. To create services, I need place to his handle and id into profile structure. So, firstly, need to change this structure:

Code: Select all

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;					// GATT ID, include uuid and instance 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;
};
To something like that:

Code: Select all

struct gatts_profile_inst {
    esp_gatts_cb_t gatts_cb;
    uint16_t gatts_if;
    uint16_t app_id;
    uint16_t conn_id;
    uint16_t service1_handle;
    uint16_t service2_handle;
    esp_gatt_srvc_id_t service1_id;					// GATT ID, include uuid and instance id.
    esp_gatt_srvc_id_t service2_id;					// GATT ID, include uuid and instance id.
    uint16_t char_service1_handle;
    uint16_t char_servise2_handle;
    esp_bt_uuid_t char_service1_uuid;
    esp_bt_uuid_t char_service2_uuid;
    esp_gatt_perm_t perm;
    esp_gatt_char_prop_t property;
    uint16_t descr_handle;
    esp_bt_uuid_t descr_uuid;
};
Than I create both of them:

Code: Select all

esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service1_id, GATTS_NUM_HANDLE_TEST_A);
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service2_id, GATTS_NUM_HANDLE_TEST_A);
And that call ESP_GATTS_CREATE_EVT event:

Code: Select all

        gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle;	
        gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16;				
        gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A;
Here, what I have to do? I have only one param->create.service_handle and I dont know what service registring now. How I register characteristic of both of services? How I can give to different dharacteristics different UUID?

User avatar
WardMas
Posts: 75
Joined: Fri Jun 19, 2020 9:09 am

Re: creating multiple services in a profile

Postby WardMas » Tue Mar 02, 2021 4:23 am

Hi,
The characteristic and description creation is done inside the GATTS profile callback handler, which I think you are missing. Remember each service will be having different callback handler and inside ESP_GATTS_CREATE_EVT event you should be starting the service that is responsible oof the callback using

Code: Select all

esp_ble_gatts_start_service() 
can pass the UUID taht you want and specify the characteristic attribute and add the characteristic using

Code: Select all

esp_ble_gatts_add_char()
You can always visit my YouTube channel for embedded systems related tutorials
https://youtube.com/user/wardzx1

User4356
Posts: 35
Joined: Wed Feb 17, 2021 7:52 am

Re: creating multiple services in a profile

Postby User4356 » Sat Mar 06, 2021 2:27 pm

Hello WardMas.

Tell me please, what exacly I miss in the GATTS profile callback handler? Where is characteristic and description creation?

Code: Select all

static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param){
    if (event == ESP_GATTS_REG_EVT) {						
        if (param->reg.status == ESP_GATT_OK) {
            gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
        } else {
            ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n", param->reg.app_id, param->reg.status);
            return;
    }}
    do {	
        for (int idx = 0; idx < PROFILE_NUM; idx++) {
            if (gatts_if == ESP_GATT_IF_NONE || gatts_if == gl_profile_tab[idx].gatts_if) {
                if (gl_profile_tab[idx].gatts_cb) {
                    gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
	}}}} while (0);
}

sap1359
Posts: 3
Joined: Sun Apr 22, 2018 8:26 am

Re: creating multiple services in a profile

Postby sap1359 » Sun Apr 03, 2022 9:21 am

Hi
Refer to this page. I believe that this can solve your problem.
https://github.com/espressif/esp-idf/bl ... through.md

Who is online

Users browsing this forum: Bing [Bot], ESP_Roland and 102 guests