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

Unable to add descriptors to the characteristic

Hello,

I have created a service with three characteristics in which the 1st and 3rd characteristics have all the three Notify, read, write properties. The second characteristic has only read and write properties. So in the creation of these characteristics under a service i did not face any problems and i could see them on the nRF connect app when i run the code. The problem came when i tried to add the descriptors to these characteristics. The 1st and 3rd characteristics advertise a Client Characteristic Configuration Descriptor (CCCD) even if i dont write them. But when i try to add them in the code and also a Client User Descriptor (CUD) in the code there are no errors at compilation but when i  run the code the program breaks at a breakpoint named as NRF_BREAKPOINT_COND.

uint32_t ble_dts_init(ble_dts_t * p_dts, const ble_dts_init_t * p_dts_init)
{
    uint32_t              err_code;
    ble_uuid_t            ble_uuid;
    ble_add_char_params_t add_char1_params;
    ble_add_char_params_t add_char2_params;
    ble_add_char_params_t add_char3_params;
    ble_add_descr_params_t add_descr1_params;
    //ble_add_descr_params_t add_descr2_params;
    //ble_add_descr_params_t add_descr3_params;
    // Initialize service structure.
    p_dts->spectrum_write_handler = p_dts_init->spectrum_write_handler;

    // Add service.
    ble_uuid128_t base_uuid = {BLE_DTS_UUID_BASE};
    err_code = sd_ble_uuid_vs_add(&base_uuid, &p_dts->uuid_type);
    VERIFY_SUCCESS(err_code);

    ble_uuid.type = p_dts->uuid_type;
    ble_uuid.uuid = BLE_DTS_UUID_SERVICE;

    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_dts->service_handle);
    VERIFY_SUCCESS(err_code);

    //Add 1st Characteristic
    memset(&add_char1_params, 0, sizeof(add_char1_params));
    add_char1_params.uuid = DTS_UUID_SPECTRUM_CHAR;
    add_char1_params.uuid_type = p_dts->uuid_type;
    add_char1_params.init_len = sizeof(uint8_t);
    add_char1_params.max_len = 20;
    add_char1_params.char_props.read = 1;
    add_char1_params.char_props.notify = 1;
    add_char1_params.char_props.write = 1;
    add_char1_params.read_access = SEC_OPEN;
    add_char1_params.cccd_write_access = SEC_OPEN;
    
    err_code = characteristic_add(p_dts->service_handle,&add_char1_params,&(p_dts->spectrum_handles));
    
    if(err_code != NRF_SUCCESS)
    {
      return err_code;
    }
    
    //Add Client Characteristic Configuration Descriptor for Spectrum characteristic
    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);
    
    
    // Add Characteristic User Descriptor for Spectrum characteristic
    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;
    }
    
I have attached the service init function that i have written that has the complete 1st characteristic with its 2 descriptors. here the uuid for CCCD is 0x2092 and uuid for CUD is 0x2901.

I am new to the BLE part and i have only tried some basic examples with the nRF52832 DK. I have also uploaded the image that shows the error i get when i run the code.

static void services_init(void)
{
    ret_code_t                   err_code;
    ble_dts_init_t               dts_init  = {0};
    ble_dis_init_t               dis_init;
    nrf_ble_qwr_init_t           qwr_init  = {0};
    ble_dis_sys_id_t             sys_id;
    ble_dis_reg_cert_data_list_t reg_cert_data_list;
    ble_dis_pnp_id_t             pnp_id;  
    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

     // Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init)); 
    sys_id.manufacturer_id = 0x000000000030241D;
    sys_id.organizationally_unique_id = 0x00341513;
    dis_init.p_sys_id = &sys_id;
    uint8_t temp_list [] = {0xFE, 0x00, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6D, 0x65, 0x6E, 0x74, 0x61, 0x6C};
    reg_cert_data_list.list_len = 14;
    reg_cert_data_list.p_list = temp_list;
    dis_init.p_reg_cert_data_list = &reg_cert_data_list;
    ble_srv_ascii_to_utf8(&dis_init.model_num_str, (char *)MODEL_NUMBER);
    ble_srv_ascii_to_utf8(&dis_init.serial_num_str, (char *)SERIAL_NUMBER);
    ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, (char *)FW_REVISION);
    ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, (char *)HW_REVISION);
    ble_srv_ascii_to_utf8(&dis_init.sw_rev_str, (char *)SW_REVISION);
    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
    dis_init.dis_char_rd_sec = SEC_OPEN;
    pnp_id.vendor_id_source = BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG;
    pnp_id.vendor_id = 0x0059;
    pnp_id.product_id = 0;
    pnp_id.product_version = 272;
    dis_init.p_pnp_id = &pnp_id;
    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);
    
    // Initialize DTS.
    dts_init.spectrum_write_handler = spectrum_write_handler;

    err_code = ble_dts_init(&m_dts, &dts_init);
    APP_ERROR_CHECK(err_code);
    

}
The lase piece of code shows my services_init function.

Kindly help me with any solutions or examples so that i can continue with my work. This is the first time  I am dealing with the descriptors and hence i am a total novice to this. I will be really gratefull for any help that is received.

Thanks in advance!!   

Parents
  • The UUID for CCCD is 0x2902. Apologies for typing mistake.

  • Seems you have an assert, so you need to identify the file name, line number and error code to understand what is wrong. This should be possible to do like shown in this thread:

    https://devzone.nordicsemi.com/f/nordic-q-a/52220/ble-connection-lost-after-flash-write

  • Hey Kenneth,

    I am SRJ here with my other account and thanks for your reply. According to your reply what i understood is you want me to know where the error is in the program that is causing the program to halt at that breakpoint. I already know where it is causing the error. I debugged the code step by step and i went into the services_init(void) function then at the bottom of that function i stepped into ble_dts_init(&m_dts, &dts_init) function call.

    Then in that ble_dts_init function i stepped over all the lines and when i reached the descriptor_add() function then again i stepped into it and at the last in that function there is function call for sd_ble_gatts_descriptor_add() function which in turn is a SV Call. From there the function returns an error code of value 15.

    So this is where the things are going wrong. Shouldn't I write the code for CCCD as it is added to the descriptors list of the characteristics that have the notify property? The first picture shows the line of code that enters into descriptor_add function in the ble_srv_common.c file.

     The second image shows the line of code that returns a SV Call and that is where the error is coming from.

    Kindly help me with this i am stuck with my work.

    Thanks & Regards

    Sudeep R J

  • The return code 0x15 = NRF_ERROR_FORBIDDEN, and the description for this error code when returned from sd_ble_gatts_service_add() is "Forbidden value supplied, certain UUIDs are reserved for the stack" (you can find this text in the ble_gatts.h).

    I expect the problem here is that uuid type is not BLE_UUID_TYPE_BLE.

Reply Children
  • Hi Kenneth,

    I tried changing the uuid type of the descriptor but still the result is no different. I want to tell you something interesting. I tried writing these descriptors in the ble_app_blinky example and the same code i pasted in its service init function. When i run the program i could see the descriptors in the button characteristic but they are displayed as unknown descriptors. And since the button characteristic has a notify property the CCCD is displayed by default and the descriptors that i added are displayed below that CCCD as unknown descriptors.

    My questions are:

    1) Why is the same descriptor code not resulting in the termination of execution of the program when i write it in the blinky example?

    2) Why are the descriptors that I added in the blinky example shown as unknown where as i have used the defined UUID BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG in ble_types.h file.

    Please write to me regarding this. 

    Thanks & Regards

    Sudeep R J 

Related