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

Triggering event handler upon CCCD for notifications change

In the ble_nus service (SDK11.0.0 S132 nRF52), what is the simplest way to modify on_write() to send inform the main application the CCCD for notifications has changed:

static void on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt){
ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

if (
    (p_evt_write->handle == p_nus->rx_handles.cccd_handle)
    &&
    (p_evt_write->len == 2)
   )
{
    if (ble_srv_is_notification_enabled(p_evt_write->data))
    {
        p_nus->is_notification_enabled = true;
    }
    else
    {
        p_nus->is_notification_enabled = false;
    }
}
else if (
         (p_evt_write->handle == p_nus->tx_handles.value_handle)
         &&
         (p_nus->data_handler != NULL)
        )
{
    p_nus->data_handler(p_nus, p_evt_write->data, p_evt_write->len);
}
else
{
    // Do Nothing. This event is not relevant for this service.
}}

Currently just the is_notification_enabled field is set, but the event handler is not triggered in the application level, so the application will not be informed or know that some data in p_nus has been modified.

  • I think I confused you by saying "main application". What I mean is that I want the event handler p_nus->data_handler() to be called with some information stating that the CCCD has changed. What is the simplest way to do this?

  • in that case just add one more variable in ble_nus_t

    bool cccd_changed;
    

    and on write

    static void on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt){
    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    if (
        (p_evt_write->handle == p_nus->rx_handles.cccd_handle)
        &&
        (p_evt_write->len == 2)
       )
    {
        if (ble_srv_is_notification_enabled(p_evt_write->data))
        {
            p_nus->is_notification_enabled = true;
        }
        else
        {
            p_nus->is_notification_enabled = false;
        }
        p_nus->cccd_changed = true;
        p_nus->data_handler(p_nus, p_evt_write->data, p_evt_write->len);
    }
    else if (
             (p_evt_write->handle == p_nus->tx_handles.value_handle)
             &&
             (p_nus->data_handler != NULL)
            )
    {
        p_nus->data_handler(p_nus, p_evt_write->data, p_evt_write->len);
    }
    else
    {
        // Do Nothing. This event is not relevant for this service.
    }}
    
    
    static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
    {
      if(p_nus->cccd_changed)
       {
         p_nus->cccd_changed = false;
         // do your processing here
       }
       
       ....
       ....
    }
    
Related