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;
}
  • Ok, I think I have abetter idea on the problem. I tried to mess around with the common_enable_params.vs_uuid_count value and the maximum i can set with the default memory settings is 17, after that I get the error NO_MEM.

    I tried to add more RAM memory by increasing the size on the "options for Target" and then "Target" Tab, but it didn't seem to help since I still have the same error. Do you know if 17 is the maximum number for the vs_uuid_count? Since I don't find that information. Or to add memory space I need to do it another way.

    And the worst thing is at the moment I only need 18 different 128-bit uuids so I am only missing one.

  • Hi Jorge, I'm afraid there is still some small misunderstanding:

    • As you can see in the documentation the default ATT VS UUID table size is 10. If you are able to fit 17 it means that Soft Device uses some RAM allocated for other structures/layers or that some of these UUIDs are equal.
    • Also from the documentation it's evident that maximum number is 254 so there is no confusion about it.
    • Once you change max ATT VS UUID count you need to adjust RAM limits for SD (like if you change any other parameter, e.g. count of concurrent links/GAP roles, their bandwidth etc.!!!) There are many guides how to make this properly depending on what toolchain you use (it must be present at the time of linking and because each ANSI C compiler/linked does it differently - Keil in project settings, GCC in LD script etc. - you need to find guidelines specific for your choice).
  • The maximum is defined only on the nRF52, for my chip and softdevice this is not defined, that is why I didn't knew if it was the same value. I will check the guides on how to do this then.

  • You are right, it's not said what is maximum for S130 V2.0.1 (please stick to the Soft Device versions and forget the HW for the moment;) My understanding is that a) it's restricted just by global amount of RAm available on nRF51 chip (there are 16kB and 32kB variants) or b) it's the same as S132 (where documentation was updated to explicitly mention it). In every case it's pretty strange that it would be limited to exactly 17 or that it would have 17 as default (not 10 as said in the document).

Related