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

How does a central connect?

After calling sd_ble_gap_connect() at an arbitrary time, how does the central actually connects to the peripheral? Assuming the client probably listens only at certain times, does the central constantly transmits its requests? Or is it listening for further advertisements and adjust to that timing?

Is there a timeout when a connection attempt fails, i.e. when both are too far apart and just manage to receive advertisement?

  • No, it works exactly as explained in BT SIG specification:

    • Each connectable Broadcaster listens for few microseconds exactly 150us after it finishes transmission of ADV_xxx packet. That's why there is no conenction possible without advertising and that's also why GAP peripheral/Broadcaster role is less power demanding (because it uses Tx for 1-2ms, Rx for few microseconds - unless there is something coming which would cause longer Rx window - and the rest of the time it can sleep).
    • So once you in GAP Central role asks stack (Soft Device) to connect then it uses its Rx parameters (window and interval which you set - together they make duty cycle on each of 3 adv. channels) and waits for given ADV_xxx packet. Once it is received it issues CONNECT_REQ right 150us after ADV packet ends.
    • At that moment it assumes that connection link is established (CONNECT_REQ packet has no explicit ack!) and executes LL sequence and timers (mainly supervision timer) accordingly. If API allows it triggers upper layers so they are informed that CONNECT_REQ packet was sent and that link is now observed.

    When it comes to timeout there are actually two:

    • Normally each BLE link is guarded by Supervision timeout which says how long the Link Layer on each side accepts window when all PDUs are lost.
    • However for first Link Layer PDU exchange after CONNECT_REQ the specification suggest much shorter timeout to be able to recover faster (if CONNECT_REQ is missed on Slave side then it won't follow the link but should stay in broadcasting mode so Master can do another attempt quickly).

    Isn't this all explained in like every BLE introduction?

  • Thanks a lot for your detailed explanation. I now better understand it.

    So it would be wise to call sd_ble_gap_connect() right after rcv'ing an advertisement to get within the 150us window.

    I got a bit puzzled that nRF-Sniffer shows CONNECT_REQ coming from the slave. Probably a quirk?

  • No, you will never fit into that 150us window with Nordic stack (and probably any other unless you will merge all the functionality with lower layers). Once you get adv. report as SD event to your BLE handler in your app the advertisement event is over. If you decide this is the right device and you want to connect then calling sd_ble_gap_connect() function will cause that once ADV_xxx packet from the same device is seen next time the stack will send CONNECT_REQ with the right timing. So in the end the shortest time to connect with standard GAP Central flow on Nordic Soft Device stacks are two adv. intervals (you can do it in one if you know from the start what is the target MAC address or what is bonded peer reference).

    To your sniffer problem: note that if you are using Wireshark and Nordic sniffer it used to have this Master/Slave visualization bug in v1.xx version. Upgrade.

  • Oh yes, I forgot the SD overhead. So nothing can be gained by being that fast. Good to know that.

    Thanks again !

Related