Active scanning
Connection setup
White list 3 uses
Lower layers complete
Section 9.3 — Practical Sequence Diagrams
Section 9.3 provides complete end-to-end sequence diagrams showing both sides of each BLE operation — the HCI commands at the host, what the link layer does, and the HCI events that come back. These are the reference diagrams that show exactly what a real BLE implementation produces and receives for the most common operations. Command Complete and Command Status events are omitted from the diagrams for clarity but do fire in practice after every command.
9.3.1 — Passive Scanning
The passive scanning sequence (Figure 9.7) was fully covered at the end of PDF 1012. The scanner sets scan parameters with LE_Scan_Type=0x00, enables scanning, and receives LE_Advertising_Report_Event for each ADV_IND heard. No SCAN_REQ is ever sent — the radio only listens.
9.3.2 — Active Scanning
Active scanning is identical to passive scanning in setup, with one key difference: LE_Scan_Type is set to 0x01 instead of 0x00. When the scanner receives an ADV_IND or ADV_SCAN_IND, the controller automatically sends a SCAN_REQ back to the Advertiser on the same channel. The Advertiser replies with SCAN_RSP containing extra data. Both the ADV_IND data and the SCAN_RSP data are combined into one LE_Advertising_Report_Event delivered to the host.
(LE_Scan_Type = 0x01 ACTIVE)
(ADV + SCAN_RSP data merged) to A-Host
(ADV_IND or ADV_SCAN_IND)
/* Active vs passive scan: only scan_type differs */
sudo hcitool lescan /* active by default */
sudo hcitool lescan --passive /* passive — no SCAN_REQ */
/* Programmatic active scan: */
le_set_scan_parameters_cp p;
memset(&p, 0, sizeof(p));
p.type = 0x01; /* 0x01 = ACTIVE (sends SCAN_REQ) */
p.filter = 0x00; /* accept all */
p.interval = htobs(0x0010);
p.window = htobs(0x0010);
hci_send_cmd(sock, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS,
LE_SET_SCAN_PARAMETERS_CP_SIZE, &p);
9.3.3 — Connection Establishment
This is the most important sequence diagram in Chapter 9. It shows the complete flow from advertising on one side and initiating on the other, all the way through to active data exchange. The critical insight: LE_Connection_Complete_Event fires on both hosts — both the connecting side and the accepting side receive this event and learn the connection handle and their role.
(peer addr, conn params)
(Connectable Undirected)
→ A-Host (Role = Master)
→ B-Host (Role = Slave)
The key observations from Figure 9.9:
- Both Device A and Device B receive
LE_Connection_Complete_Event— A gets Role=Master, B gets Role=Slave - The connection handle in the event is the local identifier used in all subsequent HCI commands for this link
- The Master always transmits first at each connection event Anchor Point
- Data Channel PDUs use frequency hopping — different channel for each connection event
/* Watching a BLE connection with btmon: */
/* sudo btmon */
/* Central side output: */
/* < HCI Command: LE Create Connection (0x08|0x000d) */
/* > HCI Event: LE Meta Event (0x3e) */
/* LE Connection Complete (0x01) */
/* Status: Success (0x00) */
/* Handle: 0x0040 */
/* Role: Master (0x00) */
/* Address: AA:BB:CC:DD:EE:FF */
/* Connection interval: 86.25 ms */
/* Supervision timeout: 720 ms */
/* hcitool con — list active connections: */
/* Connections: */
/* LE AA:BB:CC:DD:EE:FF handle 64 state 1 lm MASTER */
9.3.4 — Setting Up a White List
The white list always starts empty after HCI_Reset. The host adds devices, and then activates the filter by setting one or more of three filter policy parameters in existing commands. The three usages are completely independent — each controls a different aspect of how the controller filters traffic.
/* White list setup and activation with BlueZ */
/* Populate the white list: */
hcitool cmd 0x08 0x0010 /* Clear first */
hcitool cmd 0x08 0x0011 00 FF EE DD CC BB AA /* Add device */
/* Usage 1: only WL devices can connect (filter_policy=0x01) */
/* Set inside advertising parameters — see PDF 79 for code */
/* Usage 2: only see WL devices while scanning */
le_set_scan_parameters_cp sp;
sp.filter = 0x01; /* White List filter ON */
hci_send_cmd(sock, OGF_LE_CTL, OCF_LE_SET_SCAN_PARAMETERS,
LE_SET_SCAN_PARAMETERS_CP_SIZE, &sp);
/* Usage 3: connect to first available WL device */
/* HCI_LE_Create_Connection with filter_policy=0x01 */
/* The peer_address and peer_address_type fields are ignored */
9.4 — Chapter 9 Summary
The Host Controller Interface provides the standardised communication bridge between the host software and the controller hardware. Chapter 9 explained how BLE reused the BR/EDR HCI and extended it with LE-specific commands and events. The key takeaways:
- Code reuse — same host HCI layer
- Backward compatible controllers
- Zero software change for dual-mode
- Device Setup, Flow Control
- White List + Resolving List (4.2)
- Controller + Remote Information
- Configuration, Discovery, Connection
- Encryption, Testing
- Fig 9.7: Passive scanning
- Fig 9.8: Active scanning + SCAN_REQ
- Fig 9.9: Connection establishment
- Fig 9.10: White list 3 usage modes
Subsequent chapters cover the LE upper layers and profiles: L2CAP for BLE, the Attribute Protocol (ATT), the Generic Attribute Profile (GATT), the Security Manager (SM), the Generic Access Profile (GAP), and GATT-based application profiles.
Chapter 9 Complete — LE Lower Layers Done
All HCI commands, events, flow control, security, and practical sequences are fully documented. Next: L2CAP, ATT, GATT and upper layer profiles.
