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

ISSUE ADDING DESCRIPTOR TO CHARACTERISTIC ON nRF52810 FOR CUSTOM SERVICE

Hi,

I've been trying to develop a custom service for a Bluetooth application. This custom service (called ble_dts - Data Transfer Service) has two characteristics - Spectrum Characteristic and Control Characteristic. The Spectrum Characteristic is permitted for READ, NOTIFY and WRITE, while the Control Characteristic is permitted for READ and WRITE.

The Spectrum Characteristic is supposed to have two descriptors - Client Characteristic Configuration Descriptor (CCCD) and Characteristic User Descriptor (USER_DESC).

The Control Characteristic is supposed to have ten descriptors - 9 Custom Descriptors and 1 Characteristic User Descriptor.

I added the code for adding characteristics and descriptors in the ble_dts_init() function. I have defined the UUIDs for the custom descriptors in the header file ble_dts.h and the UUIDs for the pre-defined descriptors are present in the ble_types.h file.

When I compile this code, or download it to the device (BL651), there is no problem. However, when I run the program, there seems to be an NRF_ERROR_FORBIDDEN that occurs. This takes the program to the NRF breakpoint, after which, I am forced to reset. This happens almost immediately after I run the program. It looks something like this:

Another issue I am facing is that, even when there is no code written to add the Client Characteristic Configuration Descriptor, the CCCD descriptor is still advertised and I am able to access the descriptor details from the nRF Connect App.

As I experimented more with this, I saw that this error pops up in the descriptor_add() function call that is issued for either the Client Characteristic Configuration Descriptor or the Characteristic User Descriptor. I commented the code that initialised these descriptors, while keeping the code for the custom descriptors intact, and I was able to check the descriptors out on the nRF connect App. Here's a screenshot of that:

But, if I try to add either one of these pre-defined descriptors, the control jumps from within the descriptor_add() function to the nRF Breakpoint.  

Here's the code for adding the Client Characteristic Configuration Descriptor:

ble_add_descr_params_t add_descr1_params;

memset(&add_descr1_params, 0, sizeof(add_descr1_params));
add_descr1_params.uuid = BLE_UUID_CCC_DESCR;
add_descr1_params.uuid_type = add_char1_params.uuid_type;
add_descr1_params.init_len = sizeof(uint8_t);
add_descr1_params.max_len = sizeof(uint8_t);
add_descr1_params.read_access = SEC_OPEN;
add_descr1_params.write_access = SEC_NO_ACCESS;
err_code = descriptor_add(p_dts->spectrum_handles.value_handle, &add_descr1_params, &p_dts->spectrum_handles.cccd_handle);
VERIFY_SUCCESS(err_code);

Here's the code for adding the Characteristic User Descriptor:

memset(&add_descr1_params, 0, sizeof(add_descr1_params));
add_descr1_params.uuid = BLE_UUID_DESCRIPTOR_CHAR_USER_DESC;
add_descr1_params.uuid_type = add_char1_params.uuid_type;
add_descr1_params.init_len = sizeof(uint8_t);
add_descr1_params.max_len = sizeof(uint8_t);
add_descr1_params.read_access = SEC_OPEN;
add_descr1_params.write_access = SEC_OPEN;
err_code = descriptor_add(p_dts->spectrum_handles.value_handle, &add_descr1_params, &(p_dts)->spectrum_handles.user_desc_handle);
if(err_code != NRF_SUCCESS)
{
return err_code;
}

Here's the code for adding one of the Custom Descriptors:

    memset(&add_descr1_params, 0, sizeof(add_descr1_params));
    add_descr1_params.uuid             = DTS_UUID_CONTROL_CUSTOM1_DESCR;
    add_descr1_params.uuid_type        = add_char2_params.uuid_type;
    add_descr1_params.init_len         = sizeof(uint8_t);
    add_descr1_params.max_len          = sizeof(uint8_t);
    add_descr1_params.read_access      = SEC_OPEN;
    add_descr1_params.write_access     = SEC_OPEN;
    err_code = descriptor_add(p_dts->control_handles.value_handle, &add_descr1_params, &p_dts->control_custom1_handle);
    VERIFY_SUCCESS(err_code);

Please help me out as soon as possible. In a bit of a hurry.

Regards,

Karthik K R

Parents Reply
  • It is not easy to step through the code when you are using the softdevice. If the softdevice is enabled, then you can only set a breakpoint, see if it hits, and you may be able to step a few times, but if the softdevice misses some time critical operations, it will go directly to NRF_BREAKPOINT_COND. Just reset the debug session, and move your breakpoint. 

    So NRF_ERROR_FORBIDDEN probably comes from sd_ble_gatts_descriptor_add(). You can see in ble_gatts.h on line 520 that sd_ble_gatts_descriptor_add returns NRF_ERROR_FORBIDDEN if the value supplied contains a UUID that is reserved for the stack. 

    If you want to figure out what UUID that is not working, I suggest you change the last line in descriptor_add from:

    return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);

    to:

    uint32_t err_code =  sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
    if(err_code != NRF_SUCCESS)
    {
        NRF_LOG_INFO("err_code %d on uuid: %d, type %d", err_code, desc_uuid.uuid, desc_uuid.type);
        
    }
    return err_code;

    Does that ever print in the log? If you don't have logging enabled, you can set a breakpoint inside the if() check and see what combination of uuid and type that is not accepted.

Children
Related