This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

add characteristics with distinct uuids (128-bit)

Hi,

I have created a custom service, and now I want to add different characteristics to it but with completely different uuids, not only the 12-13 octets.

This service will have 23 characteristics with completely different UUIDS. I tried to implement this by calling sd_ble_uuid_vs_add() and then sd_ble_gatts_characteristic_add() to every characteristic.

The problem is that when I try to se it on my phone on some characteristics it seems that the base uuid is not changed. It is like the first thrre characteristics have the correct UUIDs but the following one have the base UUID from the third one and only change the 12-13 octets to the correct one.

I am not sure if this is a visual bug on the phone, since I had a previous error that I changed the UUID but only after some complete resets of the phone I got the correct UUID displayed.

I already tried to reboot the phone 4 times and it is displayed everytime the same way.

If anyone with the same error or with some help would be apreciated.

I am using SDK11 with SD 130 on a nRF51-DK

Thank you for the help, Jorge

EDIT 1:

ble_uuid128_t base1 = CHAR1_BASE;
sd_ble_uuid_vs_add(&base1, &p_service->uuid_type); //I change the base uuid for the first characteristic
Char1_value_char_add(p_service, p_service_init); //were I define all the characteristic's properties for the first one and also add the 16-bit UUIDs to the new base

ble_uuid128_t base2 = CHAR2_BASE;
sd_ble_uuid_vs_add(&base2, &p_service->uuid_type); //I change the base uuid for the second characteristic
Char2_value_char_add(p_service, p_service_init); //were I define all the characteristic's properties for the second one and also add the 16-bit UUIDs to the new base

I do this 23 times, all with different base values.

EDIT 2:

#define CHAR1_BASE {{0x11, 0x22, 0x33, 0x44...}};
#define CHAR2_BASE {{0x22, 0x33, 0x44, 0x55...}};
#define CHAR3_BASE {{0x33, 0x44, 0x55, 0x66...}};
test
#define CHAR1 0xFFFF
#define CHAR2 0xEEEE
#define CHAR3 0xDDDD
test
//Create the primary service and after that I need to change the base uuids and add the characteristics.
ble_uuid128_t base1 = CHAR1_BASE;
ble_uuid128_t base2 = CHAR2_BASE;
ble_uuid128_t base3 = CHAR3_BASE;
sd_ble_uuid_vs_add(&base1, &p_service->uuid_type); //changing the base for the first characteristic
Char1_value_char_add(p_service, p_service_init);
//add the relevant properties of the characteristic in a function, the following is what is inside this function
Char1_value_char_add(ble_service_t *p_cus, const ble_service_init_t *p_cus_init)
{
uint32_t            err_code;
ble_gatts_char_md_t char_md;
ble_gatts_attr_t    attr_char_value;
ble_uuid_t          ble_uuid;
ble_gatts_attr_md_t attr_md;
memset(&char_md, 0, sizeof(char_md));

char_md.char_props.read   				= 1;
char_md.char_props.write  				= 1;
char_md.char_props.notify 				= 1; 
char_md.char_props.write_wo_resp 	= 0;
char_md.p_char_user_desc  				= NULL;
char_md.p_char_pf         				= NULL;
char_md.p_user_desc_md    				= NULL;
char_md.p_cccd_md         				= NULL;
char_md.p_sccd_md         				= NULL;

memset(&attr_md, 0, sizeof(attr_md));

attr_md.read_perm  = p_cus_init->custom_value_char_attr_md.read_perm;
attr_md.write_perm = p_cus_init->custom_value_char_attr_md.write_perm;
attr_md.vloc       = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth    = 1;
attr_md.wr_auth    = 1;
attr_md.vlen       = 0;

ble_uuid.type = p_cus->uuid_type;
ble_uuid.uuid = CHAR1; //will add the 16-bit UUID

memset(&attr_char_value, 0, sizeof(attr_char_value));

attr_char_value.p_uuid    = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len  = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len   = sizeof(uint8_t);

err_code = sd_ble_gatts_characteristic_add(p_cus->service_handle, &char_md,
                                         &attr_char_value,
                                         &p_cus->custom_value_handles);
if (err_code != NRF_SUCCESS)
{
  return err_code;
}

return NRF_SUCCESS;
}
  • If you are sure that you store "indexes" of each UUID base provisioned to the stack by sd_ble_uuid_vs_add() function and that you use it properly in sd_ble_gatts_characteristic_add() function call then just use BLE sniffer or similar radio analyzer to observe GATT Service discovery procedure from Client side and you can verify UUIDs yourself.

  • I am using the same way for every characteristic, so it should work for every one. I will try to get a BLE Sniffer and check the data that I see there.

  • Only now I had time to check this. I checked on the nrf Connect (mobile app) and on the Master Control Panel (Windows tool) to check if the UUIDS were correct.

    I can see that the 2 first UUIDs have the correct values but after the second one every UUID has the same base, only the 12-13 octects are correct.

    I edited on my question the code that I have to do this.

    But I don't understand why it works for the first two and not for the rest... Could it be a memory problem?

  • But that's not how UUID bae index works in Nordic Soft Device API! You should not invent and assign your values, you should always populate it through passing pointer to sd_ble_uuid_vs_add function call (after return the new UUID base is assigned). Then you should use it to assemble new UUID (by combining with some 16-bit value into structure) and use it in other calls like service or characteristic add. Maybe you are doing it but from this code snippet it's definitely not visible.

  • I assemble the new UUID on the Char#_value_char_add functions, each one as their own base and 16- bit value. This is done by adding the 16-bit UUID to the p_uuid paramater of the ble_gatts_attr_t structure.

    I need different base UUIDs for every characteristic, what I see is that the 16-bit UUIDs are changed but not the base UUID for each different characteristic.

    Let me know if I am not being clear on what I intend to achieve or if I am not explaining the error that is occurring.

    I can make a zip file that has some parts of my code with different data if you need.

Related