How to make 128bit service using ble gatts table demo?

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

How to make 128bit service using ble gatts table demo?

Postby newsettler_AI » Fri Nov 23, 2018 7:17 pm

Hi.

I'm using this demo:

https://github.com/espressif/esp-idf/bl ... eat_demo.c

I want to make custom 128bit service with some 128bit characteristics aswell.
My peripheral must advertize UUID of my128bit_service too.
  • [my128bit_service]
  • [128bit characteristic_1]
    [char_1_value]
    [char_1_configuration]
  • [128bit characteristic_2]
    [char_2_value]
    [char_2_configuration]
I have problem while making basic characreristic as 128 bit, its just not shown after connect.

My service and characteristics:
  1. static uint8_t service_uuid[16] = {
  2.     /* LSB <--------------------------------------------------------------------------------> MSB */
  3.         0x3d, 0x23, 0x33, 0xa0, 0xde, 0xf9,   0x42, 0x88,   0x30, 0x32,   0x12, 0xd7,   0x11, 0x37, 0x34, 0xda
  4. };
  5.  
  6. static uint8_t char1_uuid[16] = {
  7.     /* LSB <--------------------------------------------------------------------------------> MSB */
  8.         0xde, 0xba, 0x0a, 0xc3, 0xa5, 0x34,   0xb5, 0xbc,   0x00, 0x22,   0xe0, 0x11,   0xe2, 0x0c, 0x42, 0x2a
  9. };
  10.  
  11. static uint8_t char2_uuid[16] = {
  12.     /* LSB <--------------------------------------------------------------------------------> MSB */
  13.         0xbe, 0x12, 0x14, 0x43, 0x22, 0x39,   0x3e, 0xb1,   0xe5, 0xd3,   0xa5, 0xd5,   0xf6, 0x08, 0x3e, 0xd4
  14. };
Due increased value data, I limited avertizing data:
  1. static esp_ble_adv_data_t adv_data = {
  2.     .set_scan_rsp        = false,
  3.     .include_name        = false,
  4.     .include_txpower     = false,
  5.     .min_interval        = 0x20,
  6.     .max_interval        = 0x40,
  7.     .appearance          = 0x00,
  8.     .manufacturer_len    = 0,  
  9.     .p_manufacturer_data = NULL,
  10.     .service_data_len    = 0,
  11.     .p_service_data      = NULL,
  12.     .service_uuid_len    = 32, // WITH value 16 it doesnt work for some reason?
  13.     .p_service_uuid      = my_service_uuid,
  14.     .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
  15. };
  16.  
  17. // scan response data
  18. static esp_ble_adv_data_t scan_rsp_data = {
  19.     .set_scan_rsp        = true,
  20.     .include_name        = true,
  21.     .include_txpower     = false,
  22.     .min_interval        = 0x20,
  23.     .max_interval        = 0x40,
  24.     .appearance          = 0x00,
  25.     .manufacturer_len    = 0,
  26.     .p_manufacturer_data = NULL,
  27.     .service_data_len    = 0,
  28.     .p_service_data      = NULL,
  29.     .service_uuid_len    = 0,
  30.     .p_service_uuid      = NULL,
  31.     .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
  32. };
Here is what I got in nRF Connect:
esp32_gatts_table.jpg
esp32_gatts_table.jpg (64.96 KiB) Viewed 11208 times

And here is database:

  1.  
  2. #define GATTS_DEMO_CHAR_VAL_LEN_MAX   500
  3. const uint8_t charact_1_descr[2] = {0x00, 0x00};
  4. const uint8_t charact_2_descr[2] = {0x00, 0x00};
  5.  
  6. static const esp_gatts_attr_db_t gatt_db[HRS_IDX_NB] =
  7. {
  8. //      [HRS_IDX_SVC]: Named or designated initializer in the enum table.
  9. //      ESP_GATT_AUTO_RSP: Auto respond configuration, set to respond automatically by the stack.
  10. //      ESP_UUID_LEN_16: UUID length set to 16 bits.
  11. //      (uint8_t *)&primary_service_uuid: UUID to identify the service as a primary one (0x2800).
  12. //      ESP_GATT_PERM_READ: Read Permission for the service.
  13. //      sizeof(uint16_t): Maximum length of the service UUID (16 bits).
  14. //      sizeof(heart_rate_svc): Current service length set to the size of the variable heart_rate_svc, which is 16 bits.
  15. //      (uint8_t *)&heart_rate_svc: Service attribute value set to the variable heart_rate_svc which contains the Heart Rate Service UUID (0x180D).
  16.  
  17.         // Service Declaration
  18.  
  19.             //tried this and no success:
  20.         [IDX_SVC]        =
  21.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
  22.                  //16, sizeof(service_uuid), (uint8_t *)&service_uuid}}, //- none
  23.                 //32, 32, (uint8_t *)&service_uuid}}, //- none
  24.                         // what to insert here?
  25.  
  26.         /* Characteristic Declaration */
  27.         [IDX_CHAR_A]     =
  28.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  29.           CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  30.  
  31.         /* Characteristic Value */
  32.         [IDX_CHAR_VAL_A] =
  33.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&char1_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  34.           GATTS_DEMO_CHAR_VAL_LEN_MAX   , sizeof(char_value), (uint8_t *)char_value}},
  35.  
  36.         /* Client Characteristic Configuration Descriptor */
  37.         [IDX_CHAR_CFG_A]  =
  38.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  39.           sizeof(uint16_t), sizeof(charact_1_descr), (uint8_t *)charact_1_descr}},
  40.  
  41.         /* Characteristic Declaration */
  42.         [IDX_CHAR_B]     =
  43.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  44.           CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  45.  
  46.         /* Characteristic Value */
  47.         [IDX_CHAR_VAL_B] =
  48.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&char_2_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  49.           GATTS_DEMO_CHAR_VAL_LEN_MAX   , sizeof(char_value), (uint8_t *)char_value}},
  50.  
  51.         /* Client Characteristic Configuration Descriptor */
  52.         [IDX_CHAR_CFG_B]  =
  53.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  54.           sizeof(uint16_t), sizeof(charact_2_descr), (uint8_t *)charact_2_descr}},
  55.  
  56. };

I dont know why nothing appears when I connected to device. Log looks clean (no errors):
  1. 2018-11-23_19:29:22][0;32mI (0) cpu_start: Starting scheduler on APP CPU.[0m
  2. [2018-11-23_19:29:22][0;32mI (84) BTDM_INIT: BT controller compile version [8353b1b]
  3. [2018-11-23_19:29:22][0m
  4. [2018-11-23_19:29:22][0;32mI (85) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE[0m
  5. [2018-11-23_19:29:22][0;32mI (150) phy: phy_version: 3960, 5211945, Jul 18 2018, 10:40:07, 0, 0[0m
  6. [2018-11-23_19:29:22][0;32mI (335) BLE: create attribute table successfully, the number handle = 10
  7. [2018-11-23_19:29:22][0m
  8. [2018-11-23_19:29:22][0;32mI (339) BLE: SERVICE_START_EVT, status 0, service_handle 40[0m
  9. [2018-11-23_19:29:22][0;32mI (339) BLE: advertising start successfully[0m

I got only working only when service comes with 16bit.
I set 0xDDDD, rest of UID values (0000-1000-8000-00805F9B34FB) are reserved by SIG as I understand.
esp32_gatts_table2.jpg
esp32_gatts_table2.jpg (94.33 KiB) Viewed 11202 times
  1. static const uint16_t GATTS_SERVICE_UUID_TEST      = 0xDDDD;
  2.  
  3.         [IDX_SVC]        =
  4.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
  5.                  2, sizeof(GATTS_SERVICE_UUID_TEST), (uint8_t *)&GATTS_SERVICE_UUID_TEST}},
  6.  
  7.         /* Characteristic Declaration */
  8.         [IDX_CHAR_A]     =
  9.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  10.           CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  11.  
  12.         /* Characteristic Value */
  13.         [IDX_CHAR_VAL_A] =
  14.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&char1_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  15.           GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
  16.  
  17.         /* Client Characteristic Configuration Descriptor */
  18.         [IDX_CHAR_CFG_A]  =
  19.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  20.           sizeof(uint16_t), sizeof(charact_1_descr), (uint8_t *)charact_1_descr}},
  21.  
  22.         /* Characteristic Declaration */
  23.         [IDX_CHAR_B]     =
  24.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_declaration_uuid, ESP_GATT_PERM_READ,
  25.           CHAR_DECLARATION_SIZE, CHAR_DECLARATION_SIZE, (uint8_t *)&char_prop_read_write_notify}},
  26.  
  27.         /* Characteristic Value */
  28.         [IDX_CHAR_VAL_B] =
  29.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_128, (uint8_t *)&char2_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  30.           GATTS_DEMO_CHAR_VAL_LEN_MAX, sizeof(char_value), (uint8_t *)char_value}},
  31.  
  32.         /* Client Characteristic Configuration Descriptor */
  33.         [IDX_CHAR_CFG_B]  =
  34.         {{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
  35.           sizeof(uint16_t), sizeof(charact_2_descr), (uint8_t *)charact_2_descr}},

So is it possible to completely change service with custom 128 bit values?

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

Re: How to make 128bit service using ble gatts table demo?

Postby chegewara » Fri Nov 23, 2018 9:52 pm

First of all there is nice tutorial for gatt service table demo:
https://github.com/espressif/esp-idf/bl ... through.md

Next you have to know that some values in GATT attribute table cant be changed:
https://github.com/espressif/esp-idf/bl ... #L167-L169

Each of this value tells bt stack what kind of GATT attribute you want to create, either service, characteristic or descriptor (or to be more accurate in this case its CCC descriptor).

So, for example, in this declaration:

Code: Select all

{{ESP_GATT_AUTO_RSP}, {ESP_UUID_LEN_16, (uint8_t *)&primary_service_uuid, ESP_GATT_PERM_READ,
      sizeof(uint16_t), sizeof(GATTS_SERVICE_UUID_TEST), (uint8_t *)&GATTS_SERVICE_UUID_TEST}},
you want to change nothing except declaration of this variable GATTS_SERVICE_UUID_TEST with this:

Code: Select all

static uint8_t service_uuid[16] = {
    /* LSB <--------------------------------------------------------------------------------> MSB */
        0x3d, 0x23, 0x33, 0xa0, 0xde, 0xf9,   0x42, 0x88,   0x30, 0x32,   0x12, 0xd7,   0x11, 0x37, 0x34, 0xda
};
In other words, when you read tutorial from above link you find this:
  • ESP_GATT_AUTO_RSP: Auto respond configuration, set to respond automatically by the stack. // <-- you can change this value
  • ESP_UUID_LEN_16: UUID length set to 16 bits. // <-- dont change this value
  • (uint8_t *)&primary_service_uuid: UUID to identify the service as a primary one (0x2800). // <-- dont change this value, unless you want to create secondary service (less likely)
  • ESP_GATT_PERM_READ: Read Permission for the service. // <-- dont change this value
  • sizeof(uint16_t): Maximum length of the service UUID (16 bits). // <-- dont change this value
  • sizeof(heart_rate_svc): Current service length set to the size of the variable heart_rate_svc, which is 16 bits. // <-- you must change it
  • (uint8_t *)&heart_rate_svc: Service attribute value set to the variable heart_rate_svc which contains the Heart Rate Service UUID (0x180D). // <-- you must change it
Now characteristic. To create characteristic with attribute table you have 2 parts of puzzle. Characteristic declaration which is similar to service declaration described above and characteristic value. To adjust characteristic you have to do most changes in characteristic value.


I am trying to provide information as best accurate as i can, but you have to remember that i didnt work with gatt service table and my knowledge is only theoretical.

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: How to make 128bit service using ble gatts table demo?

Postby newsettler_AI » Sat Nov 24, 2018 11:40 am

Thanks for the reply.
chegewara wrote:
Fri Nov 23, 2018 9:52 pm

Next you have to know that some values in GATT attribute table cant be changed:
https://github.com/espressif/esp-idf/bl ... #L167-L169
I want to change not this, but this:

https://github.com/espressif/esp-idf/bl ... emo.c#L162

by default it comes as 16 bit values:

https://github.com/espressif/esp-idf/bl ... #L182-L183

Can I change it to 128 bit?

Am I mising something?
By my knowledge I see route as next:
1) Server (peripheral) advertizing with custom 128bit service (actually adv data can set as any value, I just need it as identifier)
2) Client (central) see this adv packet and know that there should exist special 128bit service
3) Client connects to server and discovering services and their characteristics

At this stage does client should expecting full 128bit service (at 2nd screen its marked red)? Or cant be set and I need use 13 and 14 byte as provided in example?

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

Re: How to make 128bit service using ble gatts table demo?

Postby chegewara » Sat Nov 24, 2018 12:10 pm

This is what i think (not what i know for sure):

Code: Select all

[IDX_SVC]        = {
{ESP_GATT_AUTO_RSP}, 
{ESP_UUID_LEN_128, 
(uint8_t *)&primary_service_uuid, 
ESP_GATT_PERM_READ,
50,  // max service length (try some bigger value, you only waste few bytes or ram)
sizeof(service_uuid),
(uint8_t *)service_uuid}  // service_uuid is already array, so variable is address to the first element of array (without reference &)
},

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: How to make 128bit service using ble gatts table demo?

Postby newsettler_AI » Sat Nov 24, 2018 4:46 pm

chegewara wrote:
Sat Nov 24, 2018 12:10 pm
This is what i think (not what i know for sure):

Code: Select all

[IDX_SVC]        = {
{ESP_GATT_AUTO_RSP}, 
{ESP_UUID_LEN_128, 
(uint8_t *)&primary_service_uuid, 
ESP_GATT_PERM_READ,
50,  // max service length (try some bigger value, you only waste few bytes or ram)
sizeof(service_uuid),
(uint8_t *)service_uuid}  // service_uuid is already array, so variable is address to the first element of array (without reference &)
},

I have tried set max service lenght 16, 50, 500 - same result. I got next output in log:
  1. [2018-11-24_18:42:00][0;32mI (334) BLE: create attribute table successfully, the number handle = 11
  2. [2018-11-24_18:42:00][0m
  3. [2018-11-24_18:42:00][0;31mE (335) BT_APPL: service not created
  4. [2018-11-24_18:42:00][0m
  5. [2018-11-24_18:42:00][0;32mI (337) BLE: advertising start successfully[0m
My params ():
  1. {
  2. {ESP_GATT_AUTO_RSP},
  3. {ESP_UUID_LEN_128,
  4. (uint8_t *)&primary_service_uuid,
  5. ESP_GATT_PERM_READ,
  6. 500, // 16, 50 no success aswell
  7.  sizeof(service_uuid),
  8. (uint8_t *)service_uuid}
  9. },

I see advertizing, but after connect there is no my service at all:
esp32_gatts_table3.jpg
esp32_gatts_table3.jpg (54.55 KiB) Viewed 11140 times

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: How to make 128bit service using ble gatts table demo?

Postby newsettler_AI » Sun Nov 25, 2018 1:52 pm

Ok, I got working as I want with next settings:
  1. [IDX_SVC]        ={
  2. {ESP_GATT_AUTO_RSP},
  3. {ESP_UUID_LEN_16, // why 16bits lenght?
  4. (uint8_t *)&primary_service_uuid,
  5.  ESP_GATT_PERM_READ,
  6. 500, sizeof(service_uuid),
  7. (uint8_t *)service_uuid}
  8. },
And here is what nrfConnect shows:
esp32_gatts_table4.jpg.JPEG.jpg
esp32_gatts_table4.jpg.JPEG.jpg (69.8 KiB) Viewed 11103 times
Can anyone explain me why there should be ESP_UUID_LEN_16? :|

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

Re: How to make 128bit service using ble gatts table demo?

Postby chegewara » Sun Nov 25, 2018 2:59 pm

In other words, when you read tutorial from above link you find this:
ESP_GATT_AUTO_RSP: Auto respond configuration, set to respond automatically by the stack. // <-- you can change this value
ESP_UUID_LEN_16: UUID length set to 16 bits. // <-- dont change this value
(uint8_t *)&primary_service_uuid: UUID to identify the service as a primary one (0x2800). // <-- dont change this value, unless you want to create secondary service (less likely)
This is my earlier info. It is 16 in len because its the length of primary service uuid, which is 0x2800, which is 16 bit.

I see in next my post i just copied part of your code and missed that you had 128 bit value in it. Sorry.

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

Re: How to make 128bit service using ble gatts table demo?

Postby chegewara » Sat Dec 01, 2018 12:32 pm

Just a word of explanation. With this code snippet you can declare service, characteristic or descriptor.

Code: Select all

[IDX_SVC]        ={
{ESP_GATT_AUTO_RSP},
{ESP_UUID_LEN_16, // why 16bits lenght?
(uint8_t *)&attr_type_uuid,
 ESP_GATT_PERM_READ,  // <-- can be read, write, read_encrypted, write_encrypted bitwise OR-ed (for service declaration only read)
500, sizeof(attr_uuid),
(uint8_t *)attr_uuid}
}
- attr_type_uuid can have one of four values from this link -> https://www.bluetooth.com/specification ... clarations
- why 16 bits length; because its size of attr_type_uuid.

Who is online

Users browsing this forum: Apostal2008 and 92 guests