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

notification_timeout_handler no longer working when NRF_SDH_BLE_OBSERVERS() is used (SDK v15)

Hi in my original code when notifications is turned on for custom characteristic the characteristic value would increment every second. However after I add  NRF_SDH_BLE_OBSERVERS() so I can add multiple custom services, I notice the characteristic value no longer increments every second when notifications is turned on. 

If I switch back to NRF_SDH_BLE_OBSERVER() and turn on notifications the characteristic value increments every second again. 

/*
#define BLE_CUS_DEF(_name)                                                                          \
static ble_cus_t _name;                                                                             \
NRF_SDH_BLE_OBSERVER(_name ## _obs,                                                                 \
                     BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                     ble_cus_on_ble_evt, &_name)
                     */

#define BLE_CUS_DEF(_name)                                                                          \
static ble_cus_t _name;                                                                               
#define BLE_CUS_DEF2(_name2)                                                                          \
static ble_cus_t _name2;                                                                               //\
#define ble_cus_t* cus_array[] = {&_name, &_name2};                                                            \
NRF_SDH_BLE_OBSERVERS(_name ## _obs,                                                                 \
                     BLE_HRS_BLE_OBSERVER_PRIO,                                                     \
                     ble_cus_on_ble_evt, cus_array, 2)

In the code, 'notification_timeout_handler' is called when the repeated app timer 'm_notification_timer_id' expires. The 'notification_timeout_handler' increments the value of integer variable 'm_custom_value' each time the app_timer event handler is called. 

APP_TIMER_DEF(m_notification_timer_id);

static uint8_t m_custom_value = 0;
static uint8_t notif_bool = 0;


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 nortifing 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);
    }
}

static void timers_init(void)
{
    // Initialize timer module.
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    // Create timers.
    err_code = app_timer_create(&m_notification_timer_id, APP_TIMER_MODE_REPEATED, notification_timeout_handler);
    APP_ERROR_CHECK(err_code);

}

tatic void on_cus_evt(ble_cus_t     * p_cus_service,
                       ble_cus_evt_t * p_evt)
{
    ret_code_t err_code;
    
    switch(p_evt->evt_type)
    {
        case BLE_CUS_EVT_NOTIFICATION_ENABLED:
             
             notif_bool = 1;
             break;

        case BLE_CUS_EVT_NOTIFICATION_DISABLED:

            break;
}

I also attached the project files below.

multiple_cus_app_timer.zip

Why does calling NRF_SDH_BLE_OBSERVERS() to register multiple custom services cause the event handler call from the repeated app timer to not work? Is there a way to fix this if I want to have multiple custom services and the app_timer event handler?

  • I suggest you copy the approach from the other SDK service implementations if you want a macro to make multiple instances (you can look at line 98-102 in <SDK15.3>\components\ble\ble_services\ble_dis_c\ble_dis_c.h, or any of the other services in the SDK).

    I also checked this and the macro #define BLE_DIS_C_ARRAY_DEF(_name,_cnt) is identical to the Nordic documentation for NRF_SDH_BLE_OBSERVERS(). I know you are supposed to pass in the number of custom services you want to register to the _cnt argument of the macro.

    But (like the Nordic documentation) it doesn't show or explain how to register the array of event handlers for the multiple custom services or create the array of multiple nrf_sdh_ble_evt_observer_t that can be passed in to  NRF_SDH_BLE_OBSERVERS().

    #define BLE_DIS_C_ARRAY_DEF(_name, _cnt)                 \
        static ble_dis_c_t  _name[_cnt];                     \
        NRF_SDH_BLE_OBSERVERS(_name ## _obs,                 \
                            BLE_DIS_C_BLE_OBSERVER_PRIO,     \
                            ble_dis_c_on_ble_evt, &_name, _cnt)

  • thoric_fish said:
    Also note that when I do not uncomment out the backslash I get errors after I call BLE_CUS_DEF2(_name2);

    That may be, but C preprocessor macros are by definition always on one line. I can explain by showing an intermediate step in addition to the one from my previous post. Let's put everything on one line like the preprocessor does (when you escape the newline with \), but also let's keep the comments as the intermediate step.

    When it comes to BLE_CUS_DEF() that is straightforward. "#define BLE_CUS_DEF(_name)" expands to:

    static ble_cus_t _name;

    For "#define BLE_CUS_DEF2(_name2)" we first get (just removing the newlines and additional whitespaces):

    static ble_cus_t _name2; // #define ble_cus_t* cus_array[] = {&_name, &_name2}; NRF_SDH_BLE_OBSERVERS(_name ## _obs, BLE_HRS_BLE_OBSERVER_PRIO, ble_cus_on_ble_evt, cus_array, 2)

    As you can see everything after // is commented out, so it really ends up with:

    static ble_cus_t _name2;

    ...and this is clearly not what you want.

  • Hi Einar,

    Is there also an available example of how to set up the array of custom service instances to pass into the '_name' parameter of the macro BLE_DIS_C_ARRAY_DEF() or NRF_SDH_BLE_OBSERVERS()?  

  • Update: I think I managed to figure out how to do NRF_SDH_BLE_OBSERVERS() properly. The app_timer now increments the characteristic value for one of the custom characteristics. I will further investigate to confirm there are no other issues. Thank you! 

  • A new issue now that NRF_SDH_BLE_OBSERVERS is properly working is that the characteristic value of m_cus2 not m_cus1 is being incremented when notifications are turned on. I will post a new case for this issue. 

Related