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

Supervision timeout issue

I'm having a strange problem where the Supervision timeout does not seem to work right at the point the connection is initiated (sd_ble_gap_connect() was called but BLE_GAP_EVT_CONNECTED is not yet received). At any other point during the connection, it works properly.

Our setup is as follows:

  • Client (sensor) running s132_nrf52_3.0.0_softdevice.hex and an app using SDK 12.1 on a BMD300 (nRF52832 module).
  • Host side with the same BMD300 running the HCI UART code from the Nordic SDK12.1 ble_connectivity example (+ s132_nrf52_3.1.0_softdevice.hex) to a linux-box using (115200 Baud).

The client sends out continuous advertisements and the Host side will connect as soon as it sees one. Subsequently the Host bonds with the client and some data is exchanged after which the Host disconnects (~ 1 - 3 seconds total).

The issue is rather easy to reproduce by removing power from the client side right when the connection is formed. At this point no more data is received on the Linux host side (the device is essentially hung up) until power is re-applied to the client at which point everything proceeds as if nothing happened. The BMD on the Host side was hung up at the connection. Note that it never resets, it really is still operating, just waiting for something. The serial link is very reliable and the only reason we discovered the issue is because we flooded the Host with many client device advertisements (30+). The host would connect to up to 3 clients at a time. When we started testing reliability by killing power to the Clients during this process, connections would be dropped and in some cases we would hit the issue described here.

I could not find any mention in release notes of subsequent SoftDevice versions or the support forum. I attached some quite verbose logs from the BMD on the Host and from the Linux app which includes all packets exchanged over the serialization interface. Interesting places are tagged with !@!

Update 04/28: As a work around I put in a manual supervision timer at the application level:

  1. sd_ble_gap_connect()
  2. Start a timer. 1 second timeout, gets re-started for every BLE event received to make sure activity takes place.
  3. When the BLE_GAP_EVT_CONNECTED is received, stop the Timer.

In case the issue occurs, the nRF52 on the host will hang right before item #3. In that case the timer expires and calls:

  • sd_ble_gap_connect_cancel

  • sd_ble_gap_scan_start

The nRF52 on the Host generates the following events:

  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0xE/33
  • SPHY_HCI:DEBUG:EVT_ACK_SENT
  • SER_CONN:DEBUG:[SD_CALL]:SD_BLE_GAP_CONNECT
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4

!@! Hangs here

  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0xE/8
  • SPHY_HCI:DEBUG:EVT_ACK_SENT
  • SER_CONN:DEBUG:[SD_CALL]:SD_BLE_GAP_CONNECT_CANCEL
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0xE/16
  • SPHY_HCI:DEBUG:EVT_ACK_SENT
  • SER_CONN:DEBUG:[SD_CALL]:SD_BLE_GAP_SCAN_START
  • SPHY_HCI:DEBUG:EVT_PKT_SENT
  • SPHY_HCI:DEBUG:EVT_PKT_RECEIVED 0x0/4
  • SPHY_HCI:DEBUG:EVT_PKT_SENT

This workaround seems to be quite reliable. I do hope someone at Nordic can root-cause this. I'll be happy to provide more logs and assist in reproducing this.

Cheers, Dirk

Linux_HCI_Host.log

nRF52832_Host.log

  • Are you sure the connection was actually established? If it's not you will scan for the device until the scan_params timeout is reached.

  • It's been a while, but I wanted to close this out. In short, mea culpa: 

    ble_gap_scan_params_t is passed to sd_ble_gap_scan_start() to scan for advertisements:

    ble_gap_scan_params_t scan_params = {
            0,                      // Active scanning not set (we don't care about scan responses at this point).
            0,                      // Selective scanning not set.
            0,                      // White-list not set.
            BLE_SCAN_INTERVAL,      // Scan interval.
            BLE_SCAN_WINDOW,        // Scan window.
            0                       // Never stop scanning unless explicitly asked to.
    };

    When we want to connect to a device, we call sd_ble_gap_connect() and we passed the same scan_params[] structure which still has "timeout" set to 0 (= timeout disabled). 

Related