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

BLE disconnect

I'm observing frequent Bluetooth disconnection on my custom board which has nRF51822 SoC. So far, I haven't been able to figure out the root cause. In order to narrow down the issue, I'm using the ble_app_template example from the SDK, with very litle modifications (since the example template is for NRF51422, therefore, I had to make few changes in the KEIL Toolchain and some chanegs for clock source and button support package).

Steps to reproduce:

  • Erase entire chip.
  • Program Softdevice.
  • Observe that the device is advertising.
  • Connect using MCP app running on Smartphone.
  • Connection established, read services.
  • Perform Bond (In my opinion, it does not matter here)
  • Leave the peripheral and the central in IDLE (Observe that Empty PDUs are being exchanged)

Result:

  • Disconnect after sometime (Control opcode: LL_TERMINATE_IND from my peripheral - > Smartphone)
  • Disconnect reason: BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION (0x16)

Refer the attached Sniffer capture screenshot.

Environment:

  • SoC: NRF51822QFAA, IC revision 3
  • Softdevice: S110, v8.0
  • SDK: v10.0.0
  • Clock source: NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION (No external clock)
  • Central: Nordic MCP (v4.1.3) Android (v4.3) application running on Samsung S3 Smartphone

GAP connection parameters

MIN_CONN_INTERVAL   MSEC_TO_UNITS(100, UNIT_1_25_MS)
MAX_CONN_INTERVAL   MSEC_TO_UNITS(200, UNIT_1_25_MS)
SLAVE_LATENCY       8
CONN_SUP_TIMEOUT    MSEC_TO_UNITS(6000, UNIT_10_MS)

Please correct me if I'm wrong; my understanding with the above values is that:

minimum connection interval = 100 ms

maximum connection interval = 200 ms

slave latency (number of connection events that the slave can safely skip) = 8

connection supervisor timeout (max time period, before a link is finally considered lost) = 6000 ms

The reason, I picked these values to satisfy:

  1. Connection interval (MIN_CONN_INTERVAL and MAX_CONN_INTERVAL respectively) must be between 7.5 ms to 4 seconds
  2. conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval, i.e. (6000 ms * 4) > (1 + 8) * 200 ms => 24000 ms > 1800 ms

As, I'd like to be able to connect to my peripheral (custom board) with iOS based devices as well, I referred the Apple's recommended BLE Connection parameters and those connection settings also satisfy Apple's guidelines. Snip from section 3.6 of this document:

  1. Interval Max * (Slave Latency + 1) ≤ 2 seconds
  2. Interval Min ≥ 20 ms
  3. Interval Min + 20 ms ≤ Interval Max Slave Latency ≤ 4 (What is 4 here ???)
  4. connSupervisionTimeout ≤ 6 seconds
  5. Interval Max * (Slave Latency + 1) * 3 < connSupervisionTimeout

Please let me know, how to debug and fix this issue further.

  • FormerMember
    0 FormerMember

    I would recommend you to do the following:

    Set a breakpoint on all sd_ble_gap_disconnect() calls in your application. When your peripheral device wants to disconnect, it will then stop there. From there, you can start "going backwards" and try to track down the root cause for the disconnect.

  • @Kristin: Thank you. I followed your suggestion and found that there were multiple problems. 1: I was not properly handling BLE_GAP_EVT_CONN_PARAM_UPDATE event coming from the central (on_ble_event) and 2: there were some explicit call to sd_ble_gap_disconnect(), which I've commented out at the moment. A call to ble_conn_param_init(&cp_init) creates a connection parameter update timer and associates a handler update_timeout_handler with it. It is called MAX_CONN_PARAMS_UPDATE_COUNT number of times if the parameters are not okay with the central and if the central rejects all of those requests from peripheral, the event handler on_conn_params_evt associated with the connection parameter gets invoked, where I was calling sd_ble_gap_disconnect. Now instead of calling sd_ble_gap_disconnect, I accept central's connection parameter by callingsd_ble_gap_ppcp_set in the connection parameter event handler. I know, I should also do some parameter validation, before accepting the values, but is this an okay approach ?

  • FormerMember
    0 FormerMember in reply to FormerMember

    What you describe should work fine as long as it is fine for your device to accept any connection interval set by the central. However, I would recommend to have some parameter validation.

  • @Kristin: Thank you. The above method worked on Android, however later, while testing with an iOS based device, found that newer version of iOS (v9.3.2) exhibit Bluetooth spec. violation and had to resort to method described here.

  • Hi @sidekick, I had a similar kind of doubt regarding the connection interval time for BLE Nordic UART Service on nrf52840 microcontroller with softdevice s140. I want to know after connecting with a nordic mobile app, can the connection remain idle for longer time. If I keep the connection idle it disconnects after certain time The solution you mentioned of replacing "sd_ble_gap_disconnect" with "sd_ble_gap_ppcp_set" in connection parameter event handler, so "sd_ble_gap_ppcp_set" accepts connection parameters as input do I need to initialize the gap connection parameters in event handler again?

Related