Hello,
I implemented a function to add characteristics to a service, but I'm having a problem when I add notifiable characteristics. I pass a set of flags to my function, and when I set the NOTIFY bit, sd_ble_gatts_characteristic_add
returns NRF_ERROR_INVALID_PARAM
. Without that bit, all characteristics work just fine.
I looked at all the questions regarding this error, but most of them are because of the permissions. Every piece of code that I looked at, sets the CCCD exactly the same way as I do. I attached a part of my code below.
// OUR_JOB: Step 2.F Add read/write properties to our characteristic
ble_gatts_char_md_t char_md;
memset(&char_md, 0, sizeof(char_md));
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_sccd_md = NULL;
char_md.p_cccd_md = NULL;
char_md.char_props.read = (flags & READ) ? 1 : 0;
char_md.char_props.write = (flags & WRITE) ? 1 : 0;
//WHEN THIS GETS EXECUTED, I GET AN ERROR AT RUNTIME
if (flags & NOTIFY) {
// OUR_JOB: Step 3.A, Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
ble_gatts_attr_md_t cccd_md;
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK; // CCCD should always be on the stack
char_md.p_cccd_md = &cccd_md;
char_md.char_props.notify = 1;
}
// OUR_JOB: Step 2.B, Configure the attribute metadata
ble_gatts_attr_md_t attr_md;
memset(&attr_md, 0, sizeof(attr_md));
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = ((flags & READ) && ((flags & CONST) == 0)) ? 1 : 0;
attr_md.wr_auth = ((flags & WRITE) && ((flags & CONST) == 0)) ? 1 : 0;
attr_md.vlen = (flags & VARIABLE_LEN) ? 1 : 0;
// OUR_JOB: Step 2.G, Set read/write security levels to our characteristic
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
// OUR_JOB: Step 2.C, Configure the characteristic value attribute
ble_gatts_attr_t attr_char_value;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &char_uuid;
attr_char_value.p_attr_md = &attr_md;
// OUR_JOB: Step 2.H, Set characteristic length in number of bytes
attr_char_value.max_len = max_len;
attr_char_value.init_len = init_len;
if (init_len>0 && value != (uint8_t *)0) {
attr_char_value.p_value = value;
}
// OUR_JOB: Step 2.E, Add our new characteristic to the service
err_code = sd_ble_gatts_characteristic_add(p_custom_service->service_handle,
&char_md,
&attr_char_value,
char_handle);