BLE Link layer tutorial – slave latency and supervision timeout

 

Chapter 8 — BLE Link Layer
Part 4: Slave Latency, Supervision Timeout, BLE Topology & The Single Packet Format
Slave Latency
Skip up to N events
CRC
24-bit (vs 16 BR/EDR)
Preamble
1 octet alt 1/0
Access Addr
4 octets unique
Keywords:

BLE slave latency connSlaveLatency BLE supervision timeout BLE transmit window CONNECT_REQ BLE piconet topology BLE scatternet 4.1 BLE packet format preamble BLE access address correlation BLE 24-bit CRC BlueZ HCI packet structure

Continuing Connection Events

Part 3 introduced the connection event concept, the Anchor Point, and the connInterval parameter. This part covers the remaining three connection parameters — Slave Latency, Supervision Timeout, and the Transmit Window — along with how these parameters interact and the practical art gallery example from the spec. We then look at BLE topology scenarios and close with the single BLE packet format that handles everything from advertising to connected data.

Slave Latency — Letting the Peripheral Sleep Longer

connSlaveLatency — How Many Events Can the Slave Skip?

Even with a long connInterval, the Slave must wake up at every single connection event to listen for the Master — even if the Master has nothing to send. This is wasteful for a Peripheral device that only transmits data infrequently, like a button that is pressed once per minute.

The connSlaveLatency parameter solves this. It allows the Slave to skip a defined number of consecutive connection events without listening. For example, if connSlaveLatency is set to 10, the Slave only needs to wake up at every 10th connection event instead of every single one. If it is 0, the Slave must listen at every event.

connSlaveLatency — Slave Skipping Events to Save Power

connSlaveLatency = 0 (must listen every event)
Master:
Slave:
Slave wakes every event → high power

connSlaveLatency = 3 (Slave listens every 4th event)
Master:
Slave:
░ Slave asleep (skipping event) █ Slave awake (must respond)
Slave sleeps 3 out of every 4 events → ~75% power reduction

Even when the Slave is “skipping” events, the Master still transmits during those events. The Master does not know in advance whether the Slave will respond. If the Slave does skip an event, the Master simply treats the missed response as normal. The Slave is still considered connected. However, if the Slave has data to send, it must listen at the next scheduled event even if its latency counter says it could skip it — the Slave can always wake up early when it has something to transmit.

connSupervisionTimeout — Detecting a Lost Connection

What happens if the two connected devices physically move out of range or one of them runs out of battery mid-connection? Without a detection mechanism, both devices could wait indefinitely for the other to respond, wasting resources. The Supervision Timeout solves this.

The connSupervisionTimeout parameter defines the maximum time that can pass without receiving any packet before the connection is declared lost. Both the Master and the Slave run this same timer. If no packet arrives for the full duration of the timeout, both devices independently declare the connection lost, stop sending packets, and notify the host application.

Short Supervision Timeout

Detects connection loss very quickly. Good for real-time applications where the app needs to react immediately when a device goes out of range (e.g., a proximity alert). But if the radio environment is noisy and packets are occasionally missed for legitimate reasons, the connection may time out unnecessarily.

Long Supervision Timeout

More tolerant of temporary interference or brief signal loss. The connection survives short blackout periods. Good for devices that may occasionally lose signal briefly (through walls, interference bursts) but should not disconnect unnecessarily.

Important constraint: The supervision timeout must always be greater than connInterval × (connSlaveLatency + 1) × 2. This ensures the timeout is long enough to allow for the maximum possible gap between actual packet exchanges (when the Slave uses all its allowed latency), otherwise the connection would time out just from the Slave using its permitted sleep time.

Transmit Window — The First Connection Event

When the Initiator sends the CONNECT_REQ packet to an Advertiser, the connection is not immediately active. There is a brief setup window before the first connection event can begin. The Master includes two parameters in the CONNECT_REQ PDU to define when the Slave should expect the first data:

transmitWindowOffset

The time difference between when the CONNECT_REQ was sent and when the transmit window starts. This tells the Slave exactly how long to wait after receiving the CONNECT_REQ before expecting the first Master transmission.

transmitWindowSize

The width of the window during which the Master will send the first connection event. The Slave must listen throughout this entire window. Having a window (rather than an exact time) gives both devices tolerance for crystal oscillator imprecision and timing jitter.

CONNECT_REQ to First Connection Event — Timeline

CONNECT_REQ

transmitWindowOffset

← transmitWindowSize →
listen window

Anchor Point 1

connInterval
AP 2
Time →
/* CONNECT_REQ PDU structure in BlueZ (from hci.h) */
/* This is sent by the Initiator to start a BLE connection */

typedef struct {
    uint8_t  initiator_addr[6]; /* Initiator's Bluetooth address  */
    uint8_t  advertiser_addr[6];/* Target Advertiser's address     */
    /* Link Layer data (LLData field): */
    uint32_t access_addr;       /* Random access addr for this conn */
    uint8_t  crc_init[3];       /* CRC initialisation value         */
    uint8_t  win_size;          /* transmitWindowSize in 1.25ms     */
    uint16_t win_offset;        /* transmitWindowOffset in 1.25ms   */
    uint16_t interval;          /* connInterval in 1.25ms units     */
    uint16_t latency;           /* connSlaveLatency                 */
    uint16_t timeout;           /* connSupervisionTimeout ×10ms     */
    uint8_t  channel_map[5];    /* 37-bit used channel bitmap       */
    uint8_t  hop_sca;           /* hop increment (bits 0-4) + SCA   */
} __attribute__((packed)) le_connection_req;

Putting It Together — The Art Gallery Example

The BLE specification uses an art gallery scenario to illustrate how advInterval and connInterval should be tuned independently for the best user experience and power efficiency. Understanding this example will help you make the right parameter choices in real designs.

Art Gallery BLE Scenario — Parameter Tuning

Phase 1: User approaching painting (ADVERTISING)
🚶
adv
adv
adv
advInterval = 2–3 seconds (long → low power, user walks slowly)
🖼️

Phase 2: User in front of painting (CONNECTED, reading)
👁️
data
data
data
data
connInterval = 10–50 ms (short → fast data, painting description arrives quickly)
📱

The key insight: advertising interval and connection interval are completely independent parameters. A slow advertising interval (saves power while the device is waiting for someone to walk by) does not affect how fast data flows once the connection is made. Tune them separately for their respective jobs.

  • Long advInterval: Users walk slowly past paintings, looking at each one for several seconds. A connection that takes 2–3 seconds to establish is perfectly acceptable — the user will not even notice. Saves battery on the painting’s BLE beacon significantly.
  • Short connInterval: Once the user stops in front of a painting and the connection is made, they expect to read the artist’s biography and painting description immediately. The data must flow fast. A 10–50 ms connection interval delivers this snappy experience.

8.8 — BLE Topology

Two Fundamental Topology Scenarios

BLE supports two fundamental network topologies, both of which can coexist and interact with each other.

BLE Topology — Scenario A and Scenario B

Scenario A — Broadcast
📡
Advertiser
Broadcasting on adv channels
🔍
Scanner 1
🔍
Scanner 2
Adv Physical Channel
Scanners receive ADV_IND, may send SCAN_REQ for more info, or send CONNECT_REQ to establish a connection.

Scenario B — Piconet + Scanner
📱
Master / Scanner
Also listening for advertisers

🌡️
Slave 1
❤️
Slave 2
⚖️
Slave 3

🔑
Advertiser
(wants to join)
↑ Adv Physical Channel
Data Physical Channels ↕ (Master ↔ Slaves)

In Scenario B, the Master can simultaneously act as a Scanner on the advertising channels while it is already connected to three Slaves on the data channels. If the Master decides to connect to the Advertiser, it sends a CONNECT_REQ on the advertising channel. The Advertiser accepts and becomes the fourth Slave. Now the Master has four Slaves — all communicating on different data channels using frequency hopping.

No upper limit on Slaves: While classic BR/EDR limited a piconet to a maximum of seven active Slaves, BLE has no such hard limit. A Master can connect to as many Slaves as its hardware resources (memory, processing power, scheduling capacity) allow. The specification intentionally omits a fixed limit to give manufacturers flexibility. In practice, the limit comes from how many concurrent connection events the controller can schedule without them colliding in time.

Slave-to-Slave communication: As with classic Bluetooth, BLE Slaves cannot communicate directly with each other. All communication must go through the Master. If two sensors need to share data, it must flow: Sensor A → Master → Sensor B.

Scatternet Support — BLE 4.0 vs 4.1

BLE 4.0 only supported a piconet — one device acts as Master, all others are Slaves. A device could only belong to one piconet at a time. This kept the Link Layer state machine simple.

BLE 4.1 relaxed this restriction and introduced optional scatternet support. A device can now participate in multiple piconets simultaneously — as a Master in one and a Slave in another, or as a Slave in two different piconets.

BLE Scatternet — Device in Two Piconets (Added in 4.1)

Piconet 1
📱
Master (Phone 1)
🌡️
Temperature Sensor
(Slave in both piconets)

Piconet 2
📱
Master (Phone 2)
🌡️
Temperature Sensor
(Same physical device!)
One temperature sensor sends alerts to two separate mobile phones simultaneously

The scatternet example from the spec: a temperature sensor that is connected to two phones belonging to different family members. When the temperature exceeds a threshold, both phones receive an alert simultaneously. Either family member can act on it — whoever is closest to the device. This is only possible because the sensor participates in two piconets at once.

8.9 — BLE Packet Format

One Format for Everything — A Major Simplification Over BR/EDR

Classic Bluetooth BR/EDR has many different packet formats, each optimised for a specific use case: DM1, DH1, DM3, DH3, DM5, DH5 for data; HV1, HV2, HV3 for voice; plus ID, NULL, POLL, FHS for control. Every packet parser in a BR/EDR implementation must handle all of these different formats and know when to expect each one.

BLE uses exactly one packet format for all transmissions — whether it is an advertising packet on channel 37 or a GATT data packet on data channel 18. The same four fields are always present in the same order. This simplifies the firmware significantly: one encoding path and one decoding path, both reused for all packet types.

BLE Link Layer Packet Format — All Four Fields

Preamble
1 octet
(8 bits)
Access Address
4 octets
(32 bits)
PDU
2–39 bytes (BT 4.0)
2–257 bytes (BT 4.2)
CRC
3 octets
(24 bits)

LSB (transmitted first)MSB (transmitted last)
8.9.1 — Preamble: Synchronising the Receiver

The preamble is the first field in every BLE packet. It is one byte long and contains an alternating sequence of 1s and 0s — either 10101010b or 01010101b. The receiver uses this sequence for three important hardware-level tasks before it can correctly interpret the rest of the packet:

1. Frequency Synchronisation

The alternating 1/0 pattern has a known frequency spectrum. The receiver can use this to fine-tune its local oscillator to exactly match the transmitter’s frequency. Even a tiny frequency offset (parts per million) would cause bits to be decoded incorrectly, so this synchronisation happens in the first few microseconds of the preamble.

2. Symbol Timing Estimation

The receiver needs to know exactly when each bit starts and ends — the bit boundaries. The alternating pattern has very regular transitions that allow the receiver to lock onto the exact bit rate (1 MHz for BLE 1M PHY) and align its sampling clock to the middle of each bit period.

3. AGC Training (Automatic Gain Control)

The signal arriving at the receiver antenna may be very strong (nearby device) or very weak (far away). The AGC circuit adjusts the receiver’s amplification so the signal is at the right level for the demodulator. Too much gain and the signal saturates and distorts; too little and it disappears into the noise floor. The preamble gives the AGC circuit time to settle on the right gain level.

8.9.2 — Access Address: Connection Identification

The Access Address is a 32-bit value that acts as a connection identifier. When a BLE device receives a packet, it checks the Access Address first. If the address does not match the expected value for the current connection (or the fixed advertising access address), the packet is discarded immediately without further processing.

Why is this necessary? BLE uses only 40 channels. In a busy environment with multiple BLE devices, two completely unrelated connections might be using the same RF channel at the same time. Without the Access Address check, a Slave might try to interpret packets meant for a completely different Master on the same channel as its own.

Advertising Access Address

Fixed value: 0x8E89BED6
All advertising packets use this same access address. Any BLE scanner can receive any advertising packet just by listening for this value.

Connection Access Address

Randomly generated by the Initiator and included in the CONNECT_REQ packet. Every connection between any two devices gets a unique random value. Only the two devices in that connection will accept packets with this access address.

The Access Address also defines what it means to be “connected” to a BLE channel at the Link Layer level. A device is considered connected if it is synchronised to three parameters: timing (when to expect the next packet), frequency (which data channel to use next), and Access Address (the 32-bit identifier of this connection). As long as these three are synchronised, the connection is alive — even if no data has been exchanged recently.

/* BLE packet structure in BlueZ — from hci.h */
/* Shows how the link layer packet maps to C structs */

/* Advertising PDU header (first 2 bytes of the PDU field) */
typedef struct {
    uint8_t pdu_type:4;   /* ADV_IND=0, ADV_DIRECT=1, etc. */
    uint8_t rfu:2;        /* reserved for future use        */
    uint8_t tx_add:1;     /* 0=public address, 1=random     */
    uint8_t rx_add:1;     /* 0=public address, 1=random     */
    uint8_t length:6;     /* payload length in bytes        */
    uint8_t rfu2:2;
} __attribute__((packed)) le_adv_pdu_hdr;

/* Fixed advertising access address — all scanners listen for this */
#define LE_ADV_ACCESS_ADDR  0x8E89BED6

/* Connection access address — unique per connection */
/* Generated by Initiator and passed in CONNECT_REQ  */
uint32_t generate_access_addr(void)
{
    /* Must satisfy specific bit pattern requirements per spec  */
    /* (not all random bit patterns are valid access addresses) */
    /* BlueZ handles this automatically in the controller       */
    uint32_t addr;
    do {
        /* generate random 32-bit value */
        getrandom(&addr, sizeof(addr), 0);
        /* validate against spec requirements... */
    } while (!is_valid_access_addr(addr));
    return addr;
}
8.9.3 — CRC: Error Detection Made Stronger

The final field in every BLE packet is a 24-bit CRC (Cyclic Redundancy Check) calculated over the PDU field. The receiver recomputes the CRC from the received PDU bytes and compares it to the transmitted CRC value. If they do not match, the packet was corrupted during transmission and is discarded. A retransmission is requested if the protocol requires it.

Classic Bluetooth uses a 16-bit CRC. BLE uses 24 bits. The improvement matters:

CRC Strength Comparison — 16-bit vs 24-bit
BR/EDR CRC
16-bit
1 in 65,536 chance
a corrupted packet
passes CRC check

Probability of false
positive: ~0.0015%

BLE CRC
24-bit
1 in 16,777,216
chance a corrupted
packet passes

Probability of false
positive: ~0.000006%

256× stronger error detection in BLE compared to BR/EDR

This improvement is especially important in noisy environments — like a crowded office with many Bluetooth and Wi-Fi devices — where multiple-bit errors in a single packet are more likely. A 16-bit CRC can only detect up to a certain pattern of bit errors; a 24-bit CRC catches many more patterns that would slip through a 16-bit check undetected.

/* BLE uses a 24-bit CRC with a specific polynomial */
/* Polynomial: x^24 + x^10 + x^9 + x^6 + x^4 + x^3 + x + 1 */
/* CRC is initialised with a value from the CONNECT_REQ PDU   */

/* Checking received packet validity in BlueZ kernel driver   */
/* (simplified from net/bluetooth/hci_event.c concept)        */

static int ble_check_crc(const uint8_t *pdu, int pdu_len,
                          uint32_t crc_init,
                          const uint8_t *received_crc)
{
    uint32_t crc = crc_init;

    /* Run the CRC polynomial over each byte of the PDU */
    for (int i = 0; i < pdu_len; i++) {
        uint8_t byte = pdu[i];
        for (int bit = 0; bit < 8; bit++) {
            int data_bit = (byte >> bit) & 1;
            int crc_bit  = crc & 1;
            crc >>= 1;
            if (data_bit ^ crc_bit)
                crc ^= 0xDA6000; /* polynomial mask, 24-bit */
        }
    }

    /* Compare computed 24-bit CRC against received 3-byte CRC */
    return (crc & 0xFFFFFF) ==
           (received_crc[0] | (received_crc[1]<<8) | (received_crc[2]<<16));
}

Chapter 8 Complete — Link Layer Summary
States & Roles

  • 5 states: Standby→Adv→Scan→Init→Connect
  • Initiator becomes Master
  • Advertiser becomes Slave
  • Scatternet added in 4.1
Events & Timing

  • Adv events: ADV_IND, SCAN_REQ, SCAN_RSP
  • T_advEvent = advInterval + advDelay
  • Connection events at Anchor Points
  • connInterval: 7.5ms–4s
Connection Params

  • Slave Latency: skip N events
  • Supervision Timeout: detect loss
  • Transmit Window: first event setup
  • advInterval ≠ connInterval
Packet Format

  • One universal format (vs many in BR/EDR)
  • Preamble: AGC + clock sync
  • Access Address: 32-bit filter
  • CRC: 24-bit (256× stronger)

Complete Chapter 8 Series — Link Layer
🔗

Part 1

5 States & Device Address
📡

Part 2

Channels, Map & Hopping
📢

Part 3

Events & Timing Params

Part 4 (Here)

Topology, Slave Latency & Packet

🎉 Chapter 8 Complete!

You now have a complete understanding of the BLE Link Layer — from the five-state machine through device addressing, channel management, events, topology, and the packet format. The next chapter moves to L2CAP.

Next Chapter: L2CAP Layer → ← Part 3: Events

Leave a Reply

Your email address will not be published. Required fields are marked *