2 (4.0) + 2 (4.2)
2 total
676 to 4785
5 states, complete
Continuing Section 8.15.2 — Scanner Filter
The previous file (PDF 46) introduced the Scanner Filter Policy and its BLE 4.0 modes. This file picks up with the BLE 4.2 extended scanner filter policies that handle Resolvable Private Addresses, then covers the Initiator Filter Policy, a real sniffer capture showing all the LLCP procedures working together, and closes with the full Chapter 8 summary.
8.15.2 — Scanner Filter Policy — BLE 4.2 Extended Modes
In BLE 4.0, when a scanner received an ADV_DIRECT_IND (Connectable Directed advertising), it checked whether the InitA field — the address the Advertiser was trying to reach — matched its own address. If not, it discarded the packet. Simple and efficient.
But this breaks when both devices use Resolvable Private Addresses (RPAs). Here is why: the Advertiser puts the scanner’s last known RPA in the InitA field. But RPAs rotate every 15 minutes. If the Advertiser is using a stale RPA that was valid 20 minutes ago, the scanner’s own current address no longer matches, so the scanner discards the packet — even though the packet was genuinely meant for it.
BLE 4.2 fixed this by adding two extended scanner filter modes. In these modes, the scanner does not immediately discard an ADV_DIRECT_IND whose InitA does not match. Instead it first tries to resolve the InitA using its IRK. If the resolution succeeds — meaning the InitA was indeed a private address generated for this scanner — the packet is accepted.
InitA = old RPA (e.g. 7D:A3:F1…)
(even though packet was for this device)
InitA = old RPA (e.g. 7D:A3:F1…)
(correctly identifies intended recipient)
The two new BLE 4.2 scanner filter modes are:
Same as the BLE 4.0 Mode 1 (white list in use), but additionally: if a connectable directed advertising packet arrives with an InitA that is a resolvable private address, do not automatically discard it — resolve it first. The white list still applies for all other packet types.
Same as the BLE 4.0 Mode 0 (all packets accepted), but additionally: if a connectable directed packet arrives with a resolvable private address in InitA, try to resolve it before deciding. The default after controller reset remains all packets accepted (same as 4.0).
The overall effect of these two extended modes is that both the Advertiser and the Scanner can now freely use Resolvable Private Addresses without their directed advertising breaking. The filter policy resolves the InitA before making the accept/discard decision — strengthening Link Layer Privacy for directed advertising as well as undirected.
/* Setting BLE 4.2 extended scanner filter policy in BlueZ */
/* Own address type must be RPA (0x02) for this to work */
le_set_scan_parameters_cp sp;
memset(&sp, 0, sizeof(sp));
sp.type = 0x01; /* active scan */
sp.interval = htobs(0x0010);
sp.window = htobs(0x0010);
sp.own_bdaddr_type = 0x02; /* 0x02 = RPA */
/* filter values:
* 0x00 = all packets, no WL (BLE 4.0 default)
* 0x01 = white list only (BLE 4.0)
* 0x02 = white list + resolve directed RPA (BLE 4.2)
* 0x03 = all packets + resolve directed RPA (BLE 4.2) */
sp.filter = 0x03; /* all packets + RPA resolution */
hci_send_cmd(sock, OGF_LE_CTL,
OCF_LE_SET_SCAN_PARAMETERS,
LE_SET_SCAN_PARAMETERS_CP_SIZE, &sp);
8.15.3 — Initiator Filter Policy
The Initiator Filter Policy controls which advertising packets the Initiator’s link layer acts upon when deciding to send a CONNECT_REQ. Unlike the Advertising and Scanner filter policies which use HCI parameter commands, the Initiator filter policy is specified at the moment a connection is created — inside the HCI_LE_Create_Connection command itself.
There are exactly two modes:
Specific Single Device (White List not in use)
The host specifies the exact address of the one device it wants to connect to inside the HCI_LE_Create_Connection command. The Initiator ignores all other advertising packets and only sends a CONNECT_REQ when it hears from that specific device.
Connect to Any Device in the White List
The Initiator will accept a connectable advertising packet from any device whose address is in the White List. The controller sends a CONNECT_REQ to whichever white-listed device becomes available first and reports back which address was connected to via the Peer_Address field of LE_Connection_Complete.
/* Creating a BLE connection using BlueZ HCI */
/* HCI_LE_Create_Connection: OGF=0x08, OCF=0x000D */
typedef struct {
uint16_t scan_interval; /* 0x0004–0x4000, units 0.625ms */
uint16_t scan_window; /* must be ≤ scan_interval */
uint8_t filter_policy; /* 0=specific device, 1=WL */
uint8_t peer_bdaddr_type; /* 0=public, 1=random */
uint8_t peer_bdaddr[6]; /* target address (mode 0 only) */
uint8_t own_bdaddr_type; /* 0=public, 2=RPA */
uint16_t conn_interval_min; /* 0x0006–0x0C80 × 1.25ms */
uint16_t conn_interval_max;
uint16_t conn_latency; /* 0x0000–0x01F3 */
uint16_t supervision_timeout; /* 0x000A–0x0C80 × 10ms */
uint16_t min_ce_length; /* connection event length */
uint16_t max_ce_length;
} __attribute__((packed)) le_create_connection_cp;
/* Using bluetoothctl (easier for scripting): */
/* [bluetooth]# scan on */
/* [NEW] Device AA:BB:CC:11:22:33 MySensor */
/* [bluetooth]# connect AA:BB:CC:11:22:33 */
8.16 — Practical Examples — Reading a Real Air Log
The textbook shows a real BLE air log capture (Figure 8.33) of two devices running the Proximity profile. The Proximity profile is used for applications like “alert when the paired device moves out of range” — think a key finder or a child tracking bracelet. What makes this capture interesting is that it shows every LLCP procedure we have studied happening in sequence on a real connection.
The capture starts after the connection is already established. These are all link layer control operations, not application data. Here is what each group of frames does:
M↔S
Start PDUs
#2985
#3578
_REQ
Master→Slave
Slave→Master
This single capture demonstrates the typical life of a real BLE connection in sequence: identify each other (Version Exchange) → secure the link (Encryption) → adapt to the radio environment (Channel Map Updates) → close cleanly (Termination). Most real BLE connections follow a very similar pattern.
/* Capturing this kind of air log with btmon in BlueZ */
/* btmon logs all HCI traffic between host and controller */
/* Run: sudo btmon -w proximity_capture.snoop */
/* Then connect to the device and capture the session */
/* Press Ctrl+C when done */
/* To read the capture back: */
/* sudo btmon -r proximity_capture.snoop */
/* You will see lines like: */
/* @ OPEN: proximity_capture.snoop */
/* < HCI Command: LE Create Connection (...) */
/* > HCI Event: LE Meta Event → Connection Complete */
/* < HCI Command: Read Remote Version Information (...) */
/* > HCI Event: Read Remote Version Complete */
/* Version: 6 (BT 4.0), Manufacturer: 0x000A (CSR) */
/* < HCI Command: LE Start Encryption (...) */
/* > HCI Event: Encryption Change (encrypt=1) */
/* < HCI Command: LE Connection Update (new params) */
/* > HCI Event: LE Connection Update Complete */
/* < HCI Command: Disconnect (reason=0x13) */
/* > HCI Event: Disconnection Complete */
BLE supports several types of Bluetooth device addresses. Each has a different structure and purpose. Figure 8.34 from the textbook shows the format of each type. Understanding these is important for reading sniffer captures and for correctly setting address type parameters in HCI commands.
8.17 — Chapter 8 Summary
The link layer is the heart of BLE. Everything above it — L2CAP, ATT, GATT, GAP, profiles — depends on the link layer to create, maintain, and close the fundamental radio link. Chapter 8 covered every aspect of how it does this.
- Standby → default idle state
- Advertising → broadcasts PDUs
- Scanning → listens for PDUs
- Initiating → sends CONNECT_REQ
- Connection → data exchange
- 3 advertising channels (37/38/39)
- 37 data channels for connections
- AFH hop: f(n+1)=(fn+hop) mod 37
- Channel map bitmap (37 bits)
- Master updates map via LLCP
- ADV_IND — connectable undirected
- ADV_DIRECT_IND — reconnect
- ADV_NONCONN_IND — beacon
- ADV_SCAN_IND — scannable only
- SCAN_REQ/RSP, CONNECT_REQ
- Data PDU with SN/NESN ACK
- Connection & Channel Update
- Encryption Start/Pause
- Feature Exchange (bitmask)
- Version Exchange
- Termination (anytime)
- LE Ping, Data Length (4.2)
- RPA rotates every 15 minutes
- IRK allows bonded device to resolve
- Controller resolves (4.2, not Host)
- White List filters by address
- 3 filter policies (Adv/Scan/Init)
- 4.2 extended scanner policies
The next chapter focuses on the HCI (Host Controller Interface) — the standardised command and event channel between the host software and the Bluetooth controller chip. Everything the host needs to control the link layer (start advertising, initiate connections, update parameters) is done through HCI commands, and everything the controller reports back (connection events, data arrival, disconnection) comes via HCI events.
Chapter 8 Complete — On to Chapter 9: HCI
The Link Layer is fully covered. Chapter 9 covers the Host Controller Interface — how the host software talks to the Bluetooth controller chip using commands and events.
Next: Chapter 9 — HCI Interface → ← PDF 46: Privacy & White List
