GAP Connection Modes, Procedures & Bonding
Chapter 14 · Part 3 of 3 · Sections 14.6.3–14.6.4 · 3 Connection Modes · 6 Connection Procedures · Bonding Modes
14.6.3 — Connection Modes and Procedures
Three Connection Modes — Peripheral Controls Acceptability
Connection modes determine what kinds of incoming connection requests the Peripheral will respond to. Once a connection is established, the Peripheral always exits its connectable mode and enters Nonconnectable mode until the next advertising session starts.
No connection requests accepted. The Peripheral only sends non-connectable or scannable undirected events. Mandatory for Peripheral, Broadcaster, and Observer. Excluded for Central.
Accepts connections from one specific peer only. The Peripheral includes the target peer’s address in ADV_DIRECT_IND. Any other device trying to connect is ignored. Optional for Peripheral, excluded for all other roles.
Accepts connections from any peer. The Peripheral advertises using ADV_IND with no target address restriction. Mandatory for Peripheral, excluded for all other roles. The most common connection mode.
14.6.3.2/3/4 — Directed, Undirected & Auto Connection Establishment
These three procedures all result in the same outcome — a connected link — but differ in how the Central decides which device to connect to. The diagram below shows the full host-to-controller signalling for both the Peripheral (advertising side) and the Central (initiating side).
Set Adv Data
Enable Adv
ADV_DIRECT_IND
(for Auto mode)
Use White List (Auto)
or specific device (Direct)
HCI_LE_Create_Connection with the target address. No White List involved. The controller ignores all other advertisers and connects only to the specified device. Used when the user explicitly taps a specific device to connect to.14.6.3.5 — Direct Connection Establishment Detail
/* Direct Connection in BlueZ btmgmt: */
sudo btmgmt connect AA:BB:CC:DD:EE:FF
/* With hcitool: */
sudo hcitool lecc AA:BB:CC:DD:EE:FF
/* With bluetoothctl: */
bluetoothctl
[bluetooth]# connect AA:BB:CC:DD:EE:FF
/* Raw HCI: HCI_LE_Create_Connection = OGF 0x08, OCF 0x000D */
sudo hcitool cmd 0x08 0x000D \
60 00 # scan interval (96 * 0.625ms = 60ms) \
30 00 # scan window (48 * 0.625ms = 30ms) \
00 # filter policy = 0 (ignore white list) \
00 # peer address type = public \
AA BB CC DD EE FF # peer address (reversed) \
00 # own address type = public \
18 00 28 00 # min/max connection interval \
00 00 # slave latency = 0 \
48 00 # supervision timeout = 720ms \
00 00 00 00 # min/max CE length
14.6.3.6 — General Connection Establishment
The General procedure is the typical user-facing flow: “scan for devices, display a list, let the user pick one, then connect to the chosen device.” White Lists are not used because the user makes the choice, not a predefined filter. The Central first runs a General Discovery scan to collect visible devices, presents them to the user, then fires a Direct Connection Establishment to the selected address.
Enable Advertising
14.6.3.7 — Selective Connection Establishment
Selective Connection uses a White List to pre-filter which advertising packets the controller even reports to the host. The controller discards ads from devices not in the White List before they reach the host. When an allowed device is spotted, the host stops scanning and connects directly to it. This reduces host load compared to the General procedure where the host has to process every advertising report.
(controller filters: only White List passes)
/* Managing White List in BlueZ: */
/* White List is called "Trusted Devices" in bluetoothctl */
/* Add device to White List / mark as trusted: */
bluetoothctl
[bluetooth]# trust AA:BB:CC:DD:EE:FF
/* hcitool: Add to LE White List (OGF 0x08, OCF 0x0011): */
sudo hcitool cmd 0x08 0x0011 \
00 # address type = public \
AA BB CC DD EE FF # device address (reversed)
/* Clear White List (OGF 0x08, OCF 0x0010): */
sudo hcitool cmd 0x08 0x0010
/* Auto-connect to trusted devices in BlueZ: */
/* Set AutoConnect=true in /etc/bluetooth/main.conf */
/* or via D-Bus org.bluez.Device1.Connect() which BlueZ */
/* uses the White List mechanism internally */
14.6.3.8 — Connection Parameter Update Procedure
After a connection is established, either the Peripheral or Central can request that the connection interval, slave latency, and supervision timeout be changed. The procedure used differs depending on who initiates the update — a design that keeps the Link Layer change authority with the Central (Master) while still allowing the Peripheral to request adjustments via a higher-layer L2CAP channel.
The Central is always authoritative for Link Layer parameters. Even when the Peripheral requests an update via L2CAP, the Central decides whether to accept and then applies the change through the Link Layer. A Central can also reject the Peripheral’s request, in which case the connection continues with the old parameters.
/* Check current connection parameters with btmgmt: */
sudo btmgmt info
/* Update connection parameters for a connected device: */
/* BlueZ exposes this via D-Bus org.bluez.Device1 */
/* Connection parameters are set automatically by BlueZ */
/* based on the device's PPCP characteristic */
/* Force specific interval with hcitool: */
/* HCI_LE_Connection_Update OGF=0x08 OCF=0x0013 */
sudo hcitool cmd 0x08 0x0013 \
01 00 # connection handle = 0x0001 \
18 00 # min interval = 24 * 1.25ms = 30ms \
28 00 # max interval = 40 * 1.25ms = 50ms \
00 00 # slave latency = 0 \
C8 00 # supervision timeout = 200 * 10ms = 2s \
00 00 00 00 # min/max CE length
/* btmon shows result: */
/* LE Connection Update Complete (0x03) */
/* Status: Success (0x00) */
/* Connection Handle: 1 */
/* Connection Interval: 40.00 msec */
14.6.3.9 — Terminate Connection Procedure
Either the Central or the Peripheral can end the connection at any time. The termination is initiated at the Link Layer using the LL_TERMINATE_IND PDU. Both sides are notified via a Disconnection Complete event. The procedure is always clean — there is no ambiguity about who closed the connection or why.
/* Disconnect from a device in bluetoothctl: */
bluetoothctl
[AA:BB:CC:DD:EE:FF]# disconnect
/* With hcitool (using connection handle): */
sudo hcitool cmd 0x01 0x0006 \
01 00 # handle = 0x0001 \
13 # reason = 0x13 = Remote User Terminated
/* btmon shows: */
/* < HCI Command: Disconnect (0x01|0x0006) plen 3 */
/* Handle: 1 */
/* Reason: Remote User Terminated Connection (0x13) */
/* > HCI Event: Command Status (0x0f) plen 4 */
/* > HCI Event: Disconn Complete (0x05) plen 4 */
/* Status: Success (0x00) */
/* Handle: 1 */
/* Reason: Connection Terminated By Local Host (0x16) */
14.6.4 — Bonding Modes and Procedures
Creating Persistent Trusted Relationships
Bonding is the process of storing security keys between two devices so they can reconnect securely without repeating the full pairing procedure. Both the Central and Peripheral participate — GAP defines two bondable modes and one bonding procedure.
The device participates in pairing for the duration of the connection but does not store the resulting keys. When the connection ends, all security context is discarded. The next connection will require full pairing from scratch. Used for temporary or one-off connections where persistent trust is not desired.
The device stores the keys distributed during SM Phase 3 (LTK, IRK, CSRK). On subsequent connections, both sides can use these keys to re-establish encryption quickly without pairing again. This is the normal operating mode for most BLE devices — earphones, fitness bands, and medical devices all use bonding.
/var/lib/bluetooth/<adapter>/<device>/info with their stored keys./* Check bonded devices in BlueZ: */
ls /var/lib/bluetooth/AA:BB:CC:DD:EE:FF/
/* Each subdirectory is a bonded device address */
cat /var/lib/bluetooth/AA:BB:CC:DD:EE:FF/11:22:33:44:55:66/info
/* [General] */
/* Name=Battery V1.0 */
/* [LinkKey] */
/* Key=... */
/* [LongTermKey] */
/* Key=aabbccdd... */
/* EncSize=16 */
/* [IdentityResolvingKey] */
/* Key=112233... */
/* Remove a bond (unpair): */
bluetoothctl
[bluetooth]# remove AA:BB:CC:DD:EE:FF
/* Set bondable mode via btmgmt: */
sudo btmgmt bondable on /* allow bonding */
sudo btmgmt bondable off /* reject bonding requests */
Chapter 14 Summary — GAP Brings it All Together
GAP is the governance layer of BLE. It defines what every device must implement, how devices identify themselves to users and to each other, how they find each other through advertising, how connections are established and terminated, and how trust is built through bonding. Every application-layer BLE feature — from pairing a phone to a sensor to performing a firmware update — relies on the foundation GAP provides.
- Broadcaster (TX only)
- Observer (RX only)
- Peripheral (Slave, 1 conn)
- Central (Master, multi-conn)
- Nondiscoverable
- Limited (temp window)
- General (indefinite)
- Name via GATT
- Auto (White List)
- Direct (specific address)
- General (scan + select)
- Selective (filtered scan)
- Nonbondable (session only)
- Bondable (store keys)
- Authentication via Passkey
- Bonding via SM Phase 3
