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

Incorrect custom service being updated by ble_cus_custom_value_update()

Hi in the code below I successfully register multiple custom services (m_cus and m_cus2) using NRF_SDH_BLE_OBSERVERS().  In my original code when notifications is turned on for custom characteristic of m_cus the characteristic value would increment every second. However, now I notice that the characteristic value for m_cus no longer increments every second when notifications is turned on. If I turn on the notifications for the characteristic of m_cus2, strangely it will increment. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#main.c
BLE_CUS_DEF(m_cus, 0);
BLE_CUS_DEF(m_cus2, 1);
static void notification_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
ret_code_t err_code;
// Increment the value of m_custom_value before notifying it.
m_custom_value++;
if(notif_bool == 1){
err_code = ble_cus_custom_value_update(&m_cus, m_custom_value);
APP_ERROR_CHECK(err_code);
}
}
//ble_cus.h
#define BLE_CUS_DEF(_name, _cnt) \
static ble_cus_t _name[_cnt]; \
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

I further check the definition for ble_cus_custom_value_update() and it is supposed to only modify the characteristic value for the custom service passed into parameter 'p_cus'. In the 'notification_timeout_handler' code above, the event handler code only passes in m_cus into the 'p_cus' parameter of ble_cus_custom_value_update(). 

sd_ble_gatts_value_set(p_cus->conn_handle,
p_cus->custom_value_handles.value_handle,
&gatts_value);

sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);

If m_cus has a different conn_handle and custom_value_handles.value_handle, then m_cus2 the custom characteristic value updates should not be mixed up between different custom services/characteristics.

However, right now the most confusing issue is why m_cus2 is getting its custom characteristic value incremented after notifications are turned on, when this behavior was supposed to be for m_cus only.  Any suggestions? Thank you.

Project files and code attached below. 

ble_app_template_nordic_fds.zip

  • Hi Thoric_fish, 

    Firstly which SDK version are you using?

    I see that you have defined BLE_CUS_DEF the following way

     

    Fullscreen
    1
    2
    3
    4
    5
    #define BLE_CUS_DEF(_name, _cnt) \
    static ble_cus_t _name[_cnt]; \
    NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
    BLE_HRS_BLE_OBSERVER_PRIO, \
    ble_cus_on_ble_evt, &_name, _cnt)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I would argue that there is no need to add BLE_CUS_DEF twice in main.c when you're using NRF_SDH_BLE_OBSERVERS and not NRF_SDH_BLE_OBSERVER. Now, you're infact declaring 4 ble_cus structs as well as registering 4 observers instead of two. 

    However, right now the most confusing issue is why m_cus2 is getting its custom characteristic value incremented after notifications are turned on, when this behavior was supposed to be for m_cus only.  Any suggestions?

    I agree that  since ble_cus_custom_value_update(ble_cus_t * p_cusuint8_t custom_value) takes a pointer to a ble_cus_t structure, then the sd_ble_gatts_value_set() and sd_ble_gatts_hvx() calls should refer to the handle passed with the p_cus pointer. 

    Which handle is used when you're calling ble_cus_custom_value_update()? Just add a NRF_LOG_INFO() line that prints the p_cus->custom_value_handles.value_handle.

    Best regards

    Bjørn

  • Hi Bjørn,

    I am using SDK v15. I will try to find the handle for ble_cus_custom_value_update(). 

    I would argue that there is no need to add BLE_CUS_DEF twice in main.c when you're using NRF_SDH_BLE_OBSERVERS and not NRF_SDH_BLE_OBSERVER. Now, you're infact declaring 4 ble_cus structs as well as registering 4 observers instead of two. 



    So what is the proper way to declare and register 'mcus2' (the second instance of the custom service ble_cus_s struct), if there is no need to call BLE_CUS_DEF twice in main.c? 

  • Call BLE_CUS_DEF once with cnt set to 2 ( which ever number of custom services youre populating the gatt table with) so that it defines an array of ble_cus_s structures. Then refer to the first instance as &mcus[0] and the second as &mcus[2] etc.  

  • Hi Bjørn,

    So when I call BLE_CUS_DEF in main.c, I should now pass mcus into the first parameter of the BLE_CUS_DEF(mcus, 2) call? Then I can use mcus[0] and mcus[1] as the two instances

  • No, just call BLE_CUS_DEF once  with _name set to mcus and the _cnt to 2. 
    Then refer to mcus[0] and mcus[1] as the two instances