Zephyr BLE How a central device acknowledges an indication

My peripheral device used the API function bt_gatt_indicate() to send a indication to a central device and I used a callback function for func (bt_gatt_indicate_func_t).

I confirmed that the central device received the indication and I expected the peripheral would receive the confirmation in the func callback, but it never happened. 

Did I miss something here? Do I need to implement a function to send the confirmation from the central device side, or it will be handled by the BLE stack automatically?

Both peripheral and central devices use nrf52832.

Thanks for the help!

  • Hi,

    You are correct, for indications you will need to handle the acknowledge on the application layer. 

    However, based on your description, I suspect you might be interested in Notifications instead? Notifications does not require the acknowledge on application layer

    Kind regards,
    Andreas

  • Hi Andreas,

    Our application needs both notification and indication.

    As to handling the acknowledge, which API function should be used?

    And what the callback function func (bt_gatt_indicate_func_t) of the struct bt_gatt_indicate_params is used for, i.e. when this callback gets called anyway?

    Thanks! 

  • Is the API function bt_gatt_write_without_response used to send the confirmation of acknowledging the indication? If so, what is the use case of the callback function specified in the struct bt_gatt_indicate_params when the indication is generated? It seems the callback function never being called.

  • Hi,

    Apologies for the delayed response. I had to double check something. So to clarify the difference in how notifications and indications works w.r.t. acks:

    • With Notification, you have a callback from the controller when the notification packet is sent to the peer bt_gatt_notify_cb
    • With indications, you have the same + another callback that is coming as an ack from the peer. This callback is called destroy (confusing name)

    Look into the zephyr\samples\bluetooth\peripheral_ht\src\hts.c

    ind_params.attr = &hts_svc.attrs[2];
    
    ind_params.func = indicate_cb;
    
    ind_params.destroy = indicate_destroy;
    
    ind_params.data = &htm;
    
    ind_params.len = sizeof(htm);
    
    
    
    if (bt_gatt_indicate(NULL, &ind_params) == 0) {
    
    indicating = 1U;
    
    }

    As you can see, indicate_cb will be call immediate when the radio sent the indication to the peer. and indicate_destroy will be called when the peer acknowledged it

    Let me know if this makes things more clear for you! 

    Kind regards,
    Andreas

  • It works after using the destroy callback instead. Thanks!

Related