Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Connecting to third party peripheral always results in a BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED disconnect event

Hello!

We have hit a wall trying to add support for a particular BLE peripheral to one of our products (which is acting as a BLE central).  We support other peripherals, but there is something unique about this particular device that is causing problems.

We can see that the device is advertising, when we send it a scan request, we get the expected scan response. When we call sd_ble_gap_connect(), we soon receive a  BLE_GAP_EVT_CONNECTED event, but a few milliseconds later we recieve a BLE_GAP_EVT_DISCONNECTED event with the reason code 0x3E (BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED).

This happens every time that we try to connect - it is not a rare event related to signal strength or something like that.

When I watch the process in a BLE sniffer, I can see the advertising packets, I can see the scan request, the scan response, and the connection request. After the connection request, I can see our device continue to try to interact with the peripheral (sending discovery request, or just empty packets to keep the connection open), but the peripheral doesn't send any responses. eventually it starts advertising again. I believe that the problem is with the connection request and not with the discovery related requests that come after it because I tried disabling discovery and I still did not see any response from the peripheral in sniffer and I still got the 0x3E disconnect code.

We are able to successfully connect to the peripheral using NRF connect. When I look at the sniffer data there are a few differences in the connection request sent by the app and the connection request sent by our central device

Connection request packet sent by our Central device Connection request packet sent by NRF Connect App
Frame 236: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface wireshark_extcap2028, id 0
Nordic BLE Sniffer
Bluetooth Low Energy Link Layer
Access Address: 0x8e89bed6
Packet Header: 0x2265 (PDU Type: CONNECT_REQ, ChSel: #2, TxAdd: Random, RxAdd: Public)
.... 0101 = PDU Type: CONNECT_REQ (0x5)
...0 .... = RFU: 0
..1. .... = Channel Selection Algorithm: #2
.1.. .... = Tx Address: Random
0... .... = Rx Address: Public
Length: 34
Initator Address: d5:d6:38:ac:56:b4 (d5:d6:38:ac:56:b4)
Advertising Address: TelinkSe_e5:80:15 (a4:c1:38:e5:80:15)
Link Layer Data
Access Address: 0x98a46d95
CRC Init: 0x3595fa
Window Size: 5 (6.25 msec)
Window Offset: 0 (0 msec)
Interval: 48 (60 msec)
Latency: 0
Timeout: 1000 (10000 msec)
Channel Map: ffffffff1f
...0 1110 = Hop: 14
111. .... = Sleep Clock Accuracy: 0 ppm to 20 ppm (7)
CRC: 0xfb7392
Frame 1473: 60 bytes on wire (480 bits), 60 bytes captured (480 bits) on interface wireshark_extcap1772, id 0
Nordic BLE Sniffer
Bluetooth Low Energy Link Layer
Access Address: 0x8e89bed6
Packet Header: 0x2245 (PDU Type: CONNECT_REQ, ChSel: #1, TxAdd: Random, RxAdd: Public)
.... 0101 = PDU Type: CONNECT_REQ (0x5)
...0 .... = RFU: 0
..0. .... = Channel Selection Algorithm: #1
.1.. .... = Tx Address: Random
0... .... = Rx Address: Public
Length: 34
Initator Address: 48:5b:57:2e:eb:e7 (48:5b:57:2e:eb:e7)
Advertising Address: TelinkSe_e5:80:15 (a4:c1:38:e5:80:15)
Link Layer Data
Access Address: 0x65f7669f
CRC Init: 0x322b50
Window Size: 1 (1.25 msec)
Window Offset: 32 (40 msec)
Interval: 36 (45 msec)
Latency: 0
Timeout: 500 (5000 msec)
Channel Map: ffffffff1f
...0 0110 = Hop: 6
000. .... = Sleep Clock Accuracy: 251 ppm to 500 ppm (0)
CRC: 0x936eea

The window size, interval, and timeout are all MORE conservative for our central device than the app, so they are lower on our suspect list.

We saw these two seemingly relevant posts

 RE: Channel Selection Algorithm S132 SoftDevice 

 ChSel Algorithm 

which suggests that the channel selection algorithm cannot be changed and that it is probably not the problem.

apparently the hop increment is a random value, so that should not be the problem.

That leaves us without any leads into why the peripheral will not connect.

Does anyone have any idea what the problem might be?

I have attached sniffer logs for both our central device and for nrf connect.

We are using sdk version 15.2.0 for this project, soft device s132_nrf52_6.1.0.

sniffer_log_nrf52_central_device.pcapngsniffer_log_nrf52_nrf_connect.pcapng

  • Hi,

    The disconnect reason BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED means that no packets were received from the peripheral after the CONNECT_IND. This matches the sniffer trace. There is no more information than that, though. Is it possible for you to get any logs or other information from the peripheral, or is it a black box? If not, all we can do is think of potential reasons and try to see if changing those parameters has effect.

    Some factors/ideas that could be relevant (in no particular order):

    • Whitelisting. If the device use a whitelist, and the central that attempts to connect is not whitelisted, the peripheral would ignore the connection resulting in a disconnect with reason BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED seen from the central.
    • The peripheral ignores the central for some other reason (perhaps some custom blacklist, perhaps something else entirely - if the peripheral is a black box, we can only speculate).
    • Low frequency clock mismatch between central and peripheral, so that they do not communicate at the right time. You could try to configure a lower sleep clock accuracy in this case, to say 500 ppm to give more slack.
    • The connection parameters are for some reason unacceptable for the peripheral. Perhaps try to use the same as is used by the phone just to see if that has an effect?
  • Thanks Einar, It's helpful to have some more insight into the meaning of the disconnect message and the possible causes.

    • The device does not seem to use a whitelist, and we didn't have to whitelist our phones to get the nrf connect app to connect. I suppose this doesn't completely rule out the possibility of a whitelist though.
    • Unfortunately, changing the sleep clock accuracy did not help in this case. Thanks for the idea though.
    • Same story with the connection parameters. I changed them to match the nrf connect app as you suggested, but the peripheral still acted as though it was not receiving packets after receiving the connection request. I was only able to change the actual connection parameters - the connection interval, the latency, and the timeout. I was not able to change the transmit window size or the transmit window offset. Based off of this post, I believe that those values are determined by the softdevice. How to configure/query the Transmit Window Size

    At this point, I think all we can do is assume that the peripheral is failing to connect, as you suggest, for some other unknown reason. I appreciate the confirmation that there probably isn't something obvious that we were missing.

Related