34 bytes payload
22 bytes of params
ADV_IND or ADV_DIRECT
1 per device pair
Where We Are — Section 8.11
This file closes the SCAN_RSP payload fields left open from the Scanning state, then covers the last two link layer states: the Initiating state (how a device requests a connection) and the Connection state (what happens once that request is accepted). It ends with a deep dive into every field of the CONNECT_REQ PDU — the most data-rich single packet in BLE.
Active Scanning — SCAN_RSP Payload Wrap-up
In active scanning the Advertiser sends a SCAN_RSP after receiving a SCAN_REQ. Its payload carries two fields:
AdvA (6 octets)
The Advertiser’s Bluetooth address. Public or random, flagged by TxAdd in the header. The Scanner uses this to confirm which device replied.
AdvData (0–31 octets)
The extra advertising data the host wanted to share but could not fit in the original ADV_IND — full device name, additional service UUIDs, manufacturer data, etc.
8.11.1.4 — Initiating State
In the Initiating state the link layer listens on advertising channels 37, 38, and 39 — exactly like the Scanning state. The critical difference is intent: the Initiator is not just collecting information. It has a specific target device in mind and is waiting for that device’s advertising packet so it can send a CONNECT_REQ.
The Initiator cannot connect to just any Advertiser. There is a strict permission rule: a CONNECT_REQ may only be sent in response to two specific advertising PDU types:
ADV_IND
Connectable Undirected. Any Initiator in range may send a CONNECT_REQ to the Advertiser.
ADV_DIRECT_IND
Connectable Directed. CONNECT_REQ is only allowed if the Initiator’s own address matches the InitA field embedded in the ADV_DIRECT_IND payload.
ADV_NONCONN_IND and ADV_SCAN_IND — neither accepts a CONNECT_REQ. The Initiator must keep listening.
Advertiser becomes Slave
Initiator becomes Master
Advertiser sends ADV_IND on channel 39
Advertiser sends ADV_IND on channel 37
Advertiser sends ADV_IND on channel 38
Initiator sends CONNECT_REQ — connection begins
8.11.2 — Connection State
The Connection state is entered the moment the CONNECT_REQ is sent. Who enters it and how they entered determines the role each device takes for the duration of that connection:
Entering the Connection state does not mean data can flow immediately. There are two stages:
No data yet
Data can flow
When the CONNECT_REQ is sent both devices share the same timing, access address, and channel map — so they are synchronised. But neither has yet proven that radio packets are actually reaching the other side in both directions. When the first data channel PDU successfully arrives from the peer device, that proves the link is working. At that point the connection moves from created to established.
One LE link per pair: There can only be one LE connection between any two devices at any time. The stack will reject or reuse an existing connection if a duplicate is attempted.
CONNECT_REQ Payload — Every Field Explained
The CONNECT_REQ is the most information-dense packet in BLE. Its payload sets up the entire connection before a single data packet is exchanged.
The SCA field tells the Slave how much timing drift to expect from the Master while the radio is sleeping between connection events. A higher SCA code (worse clock accuracy) means the Slave must open a wider listening window to catch the Master’s packet, which uses more power. Better hardware oscillators give lower SCA codes and narrower windows.
These are the actual parameter values decoded from a real CONNECT_REQ capture:
InitA 0x02:07:02:a1:00:04 (public)AdvA 0x55:44:33:22:11:00 (public)Access Address 0xAF9A8AAE (random, unique)CRC Initialization Random value (chosen by Master)transmitWindowSize 3.75 mstransmitWindowOffset 86.25 msconnInterval 86.25 ms (connection events every 86.25 ms)connSlaveLatency 0 — Slave must listen at every single event/* Parsing CONNECT_REQ LLData with BlueZ */
/* Maps directly to the 22 bytes of LLData in the PDU */
typedef struct {
uint32_t aa; /* Access Address — 4 bytes */
uint8_t crc_init[3]; /* CRC seed — 3 bytes */
uint8_t win_size; /* WinSize in units of 1.25ms */
uint16_t win_offset; /* WinOffset in units of 1.25ms */
uint16_t interval; /* connInterval in units of 1.25ms */
uint16_t latency; /* connSlaveLatency (event count) */
uint16_t timeout; /* supervision timeout ×10ms */
uint8_t chm[5]; /* 37-bit channel map bitmap */
uint8_t hop_sca; /* hop[4:0] | sca[7:5] */
} __attribute__((packed)) le_lldata_t;
/* Extract hop increment and SCA from the packed byte */
uint8_t hop = lldata.hop_sca & 0x1F; /* bits 4:0 */
uint8_t sca = (lldata.hop_sca >> 5) & 0x07; /* bits 7:5 */
/* Using btmon to watch connection events live: */
/* sudo btmon | grep -A 20 "LE Connection Complete" */
Next — Link Layer Control Procedures
You now understand every link layer state and the full CONNECT_REQ payload. The next file covers Section 8.12 — the control procedures that manage an active connection: update, encryption, feature exchange, version exchange, and termination.
