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

Is it possible to support notify and indicate via same characteristic simultaneously?

I can easily generate a custom service that has characteristic with both notify and indication enabled. If I test with mobile app (using nRF Connect or other mobile apps for Android) it seems that I can only enable notifications or indications, but not both at the same time.

If I enable notifications first and then try to enable indications, then notify is automatically disabled. And same thing the other way around.

In other words, I can only write value 0x1 or 0x2 to the CCCD, but not 0x3. (I did not try to write directly to the CCCD yet).

Is this a limitation in the Bluetooth specification or just a limitation in the mobile app (or perhaps Android BLE stack?)

Parents
  • Hello,

    I was convinced it wasn't possible to support both notifications and indications on the same characteristic, so frankly, I am a bit surprised it worked with 0x0003 on the CCCD. 

    The nRF52 server/peripheral. Did you write the application for this yourself? Is it using the Nordic SDK and the softdevice? If so, is it possible to share the (or a simplified) version of the application that supports both so I can test?

    I am not sure whether or not it is a spec violation or not, I would have to check. 

    I tested the UART example, just by adding


    add_char_params.char_props.indicate = 1;

    after

    add_char_params.char_props.notify = 1;

    I can set both using the value 0x03 (using nRF Connect), but sending notifications and indications are using the same softdevice API (sd_ble_gatts_hvx()), so if you are using this, it will send an indication (I assume) if you have enabled both.

    What is the behavior you are looking for here? When both are enabled, and you send an indication/notification. What do you want the softdevice to do?  Notification or Indication?

    I believe the correct thing to do would be to have one characteristic that supports only indications and one that supports only notifications.

    Best regards,

    Edvin

  • Hi,

    I wrote the nRF52 application myself. I uses the Softdevice (s132) and SDK is 16.0.0.

    Both notifications and indications use the same API call sd_ble_gatts_hvx, but there is a parameter to select which method you want to use. See for example this code snippet:

    hvx_params.handle = p_cus->data_char_handles.value_handle;
    hvx_params.type = BLE_GATT_HVX_NOTIFICATION;  // can change to BLE_GATT_HVX_INDICATION and it works
    hvx_params.offset = 0;
    hvx_params.p_len = &hvx_len;
    hvx_params.p_data = pu8Data;

    err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);

    What is the behavior you are looking for here? When both are enabled, and you send an indication/notification. What do you want the softdevice to do?  Notification or Indication?

    The purpose is to send data using notification or indication, depending on the type of data. The data is a stream of packets that are basically "control" and "data" packets. For data packets I want to get high throughput and for control packets there is need for some prioritization / syncrhonization. 

    Based on the BT core spec, the indication/notification are not mutually exclusive. Reference:
    BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part G page 1556

    I believe the correct thing to do would be to have one characteristic that supports only indications and one that supports only notifications.

    Yeah, I probably need to go with this option to avoid any interoperability issues. Having both notify and indicate in same characteristic seems to be legal (not violating the spec) and it also works in practice, at least between the two devices that I tested with (Bluegiga dongle as client, nRF52 as server). However, I would not be surprised if there are some limitations in the Android or iOS BLE API that make it impossible to enable both notify&indicate at the same time.

  • TylerD said:
    hvx_params.type = BLE_GATT_HVX_NOTIFICATION;  // can change to BLE_GATT_HVX_INDICATION and it works

     I didn't notice this line when I did my testing. But that makes sense.

    But yes, I would recommend using two different characteristics if you see any issues with enabling both with some phones. If not, it looks like it is possible to write 0x03 to the CCCD. Just make sure that your nRF application logic can follow the notifications/indications. For example the UART service used in the ble_app_uart example will check whether notifications are enabled before allowing you to call ble_nus_data_send. It is just a matter of checking whether indications are sent before sending indications in a similar fashion

    Best regards,

    Edvin

Reply
  • TylerD said:
    hvx_params.type = BLE_GATT_HVX_NOTIFICATION;  // can change to BLE_GATT_HVX_INDICATION and it works

     I didn't notice this line when I did my testing. But that makes sense.

    But yes, I would recommend using two different characteristics if you see any issues with enabling both with some phones. If not, it looks like it is possible to write 0x03 to the CCCD. Just make sure that your nRF application logic can follow the notifications/indications. For example the UART service used in the ble_app_uart example will check whether notifications are enabled before allowing you to call ble_nus_data_send. It is just a matter of checking whether indications are sent before sending indications in a similar fashion

    Best regards,

    Edvin

Children
  • There is a new BT SIG profile coming down the pipe called the Generic Health Sensor and it requires that the server support either notifications or indications or both on a single characteristic and the client decides. Is this possible with the Nordic SoftDevice?

    I do this:

        if (hasCCCD)
        {
            if (indicate & BLE_GATT_HVX_INDICATION)
            {
                char_md.char_props.indicate = 1;
            }
            else if (indicate & BLE_GATT_HVX_NOTIFICATION)
            {
                char_md.char_props.notify = 1;
            }
        }

    but I do not know if that will work.

  • I tried the following instead

        if (hasCCCD)
        {
            if (indicate & BLE_GATT_HVX_INDICATION)
            {
                char_md.char_props.indicate = 1;
            }
            if (indicate & BLE_GATT_HVX_NOTIFICATION)
            {
                char_md.char_props.notify = 1;
            }
        }

    so a characteristic could be set from the client as either indication, notification, or both. I have tried from an Android client with notification only and indication only and that selection does work. I have not tried setting both from the client. In my use case that would be ridiculous to receive both at the same time.

    However, if the rules for a given profile were such that by setting both the server could select to EITHER notify or indicate that would be useful. The server could choose to indicate, for example, episodic measurements like SPOT pulse ox values and notify streamed pulse ox values using one characteristic.

  • I am not sure whether this is an observation or a question, but I guess you can choose from your application whether to send a notification or an indication. Look at how it sets the notification (as opposed to indication) in the ble_app_uart example, inside ble_nus_data_send(). 

    I am not sure where you have placed the snippet that you have attached, and what it is supposed to do. 

    BR,

    Edvin

  • Well, in my proprietary protocol that is exactly what I do. I never indicate and notify. If the client enables both, I pick either as convenient. This decision would need to be up to the profile at this time.

Related