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

BLE Central - getting HVX notification before service discovery completes and handles are saved

Hi Nordic team,

My dev environment is as follows:

nrf52840 + s140 +SD6.0.0 + SDK15.0.0 + SES + nrf52840-DK

nrf52840 is configured as BLE central with bonding enabled

Following is the RTT log when I reboot nrf52840 and connect to peripheral:

<info> app: Enter pairing mode in Lock and enter key as 123456
<info> app: Found Onity device with MAC as DC:A6:32:A9:77:D5
<info> app: Enter pairing mode in Lock and enter key as 123456
<info> app: Connecting to target DC:A6:32:A9:77:D5
<debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
<debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
<info> app: Connected to a previously bonded device.
<info> app: Connected to target
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<info> app: Connection secured: role: 2, conn_handle: 0x0, procedure: 0.
<debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
<info> app: GATT ATT MTU on connection 0x0 changed to 247.
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
<debug> nrf_ble_gatt: max_rx_octets: 251
<debug> nrf_ble_gatt: max_tx_octets: 251
<debug> nrf_ble_gatt: max_rx_time: 2120
<debug> nrf_ble_gatt: max_tx_time: 2120
<info> app: Data length for connection 0x0 updated to 251.
<debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 517 bytes.
<debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
<info> app: GATT ATT MTU on connection 0x0 changed to 247.
<debug> ble_db_disc: Found service UUID 0x9B5F.
<debug> app: BLE_GATTC_EVT_HVX
<debug> app: on_hvx
<debug> ble_db_disc: Discovery of service with UUID 0x9B5F completed with success on connection handle 0x0.
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<debug> ble_db_disc: Found service UUID 0x9B5F.
<debug> ble_db_disc: Discovery of service with UUID 0x9B5F completed with success on connection handle 0x0.
<info> app: Discovery complete.
<info> app: Connected to device with Onity Event Service.
<debug> app: Notification enabled
<info> app: Discovery complete.
<info> app: Connected to device with Onity Message Service.
<debug> app: BLE_GATTC_EVT_WRITE_RSP
<info> app: Disconnected.
<info> app: Disconnected.
<info> app: Disconnected, reason 0x13.

If you see on line #24 and #25, we see that I'm getting the notification even before the discovery is complete, handles assigned and notification is set. I'm aware that in case of bonded devices, the notification set/clear is saved and need not be enabled everytime. But, here we are getting the notification even before handles are assigned and thus, the checks under "on_hvx()" fails and I cannot see data.

Below is the RTT log for 2nd time connection without any reboot:

<info> app: Found Onity device with MAC as DC:A6:32:A9:77:D5
<info> app: Enter pairing mode in Lock and enter key as 123456
<info> app: Connecting to target DC:A6:32:A9:77:D5
<debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
<debug> nrf_ble_gatt: Updating data length to 251 on connection 0x0.
<info> app: Connected to a previously bonded device.
<info> app: Connected to target
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<info> app: Connection secured: role: 2, conn_handle: 0x0, procedure: 0.
<debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
<info> app: GATT ATT MTU on connection 0x0 changed to 247.
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
<debug> nrf_ble_gatt: max_rx_octets: 251
<debug> nrf_ble_gatt: max_tx_octets: 251
<debug> nrf_ble_gatt: max_rx_time: 2120
<debug> nrf_ble_gatt: max_tx_time: 2120
<info> app: Data length for connection 0x0 updated to 251.
<debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 517 bytes.
<debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
<info> app: GATT ATT MTU on connection 0x0 changed to 247.
<debug> ble_db_disc: Found service UUID 0x9B5F.
<debug> app: BLE_GATTC_EVT_HVX
<debug> app: on_hvx
<debug> app:  01 06 00 00 00 00 00 00|........
<debug> app:  00 00 00 2B 11 5A 83 80|...+.Z..
<debug> app: Client sending data.
<debug> ble_db_disc: Discovery of service with UUID 0x9B5F completed with success on connection handle 0x0.
<debug> ble_db_disc: Starting discovery of service with UUID 0x9B5F on connection handle 0x0.
<debug> ble_db_disc: Found service UUID 0x9B5F.
<debug> ble_db_disc: Discovery of service with UUID 0x9B5F completed with success on connection handle 0x0.
<info> app: Discovery complete.
<info> app: Connected to device with Onity Event Service.
<debug> app: Notification enabled
<info> app: Discovery complete.
<info> app: Connected to device with Onity Message Service.
<debug> app: BLE_GATTC_EVT_WRITE_RSP
<info> app: Disconnected.
<info> app: Disconnected.
<info> app: Disconnected, reason 0x13.

on line #25 and #26, we see the data getting logged this time. looks like the handles existed before hand from the 1st connection.

can someone please explain this behavior? Is it the intended way? How can I get it correct from the 1st connection instance.

Thanks

Parents
  • This is kind of the way it is intended to work, since in a bonded relationship it is (as you already write) CCCD that are enabled once the link is secured/encrypted. The peer can then send notification before service discovery is complete. My suggested workarounds:

    1. Executing service discovery before bonding/securing the link may help.

    2. The application can buffer any notifications received and analyze them when service discovery is complete.

    3. The application can cache the handles, e.g. in RAM between connections.

    Best regards,
    Kenneth

Reply
  • This is kind of the way it is intended to work, since in a bonded relationship it is (as you already write) CCCD that are enabled once the link is secured/encrypted. The peer can then send notification before service discovery is complete. My suggested workarounds:

    1. Executing service discovery before bonding/securing the link may help.

    2. The application can buffer any notifications received and analyze them when service discovery is complete.

    3. The application can cache the handles, e.g. in RAM between connections.

    Best regards,
    Kenneth

Children
Related