How GAP work in bluetooth what is HFP in bluetooth

How GAP work in bluetooth, what is HFP in bluetooth SPP & Hands-Free Profile
Completing GAP — discovery, bonding, security modes — then Serial Port Profile and Hands-Free Profile explained with BlueZ
4
Bluetooth Security Modes
3
Establishment Steps
2
SPP Device Roles

Key Terms in This Guide

Hello students welcome to free embedded systems course by embedded pathashala, this is part of our bluetooth development course, in this course i will explain you about How GAP work in bluetooth, Name Discovery Device Discovery Bonding Link Key Link Establishment Channel Establishment ACL Link Authentication Security Mode 1 2 3 4 SSP MITM SPP Serial Port Profile RFCOMM HFP Hands-Free Profile BlueZ bluetoothctl

🔍 Section 4.10.3.2 — Name Discovery

After Inquiry tells you a device exists (giving you its BD_ADDR and Class of Device), you may want to get its human-readable name. That is what Name Discovery does.

Inquiry only returns the BD_ADDR and CoD. The friendly name — like “John’s Car Kit” or “Sony WH-1000XM5” — requires a separate step: a Remote Name Request. This is sent directly to the target device using its BD_ADDR obtained from inquiry.

The official UI label for this procedure defined by GAP is: “Bluetooth Device Name Discovery”

Inquiry vs Name Discovery — What Each Returns:

Information Returned by Inquiry? Returned by Name Discovery?
BD_ADDR ✓ Yes ✗ No
Class of Device ✓ Yes ✗ No
Clock offset ✓ Yes ✗ No
Human-readable Device Name ~ Only if EIR supported ✓ Yes — always

BlueZ — Name Discovery:

# Remote Name Request — get human-readable name from BD_ADDR
hcitool name 00:1A:7D:DA:71:13
# Output: MyHeadset

# Name discovery via bluetoothctl (modern method)
bluetoothctl info 00:1A:7D:DA:71:13 | grep "Name"
# Output:  Name: MyHeadset

# Scan and show names automatically (bluetoothctl resolves names)
bluetoothctl scan on
# [NEW] Device 00:1A:7D:DA:71:13 MyHeadset  ← name included

# If you only have the address, trigger a name lookup
hcitool -i hci0 name 00:1A:7D:DA:71:13

📡 Section 4.10.3.3 — Device Discovery

Device Discovery combines Inquiry and Name Discovery into one complete procedure. It gives you the full picture of a remote device — everything that Inquiry provides, plus the human-readable device name.

The official UI label defined by GAP is: “Bluetooth Device Discovery”

Information Provided by Device Discovery Source
BD_ADDR From Inquiry
Clock information From Inquiry
Class of Device From Inquiry
Page Scan mode From Inquiry
Extended Inquiry Response (EIR) From Inquiry (if device supports EIR)
Bluetooth Device Name ← extra step From Name Discovery (Remote Name Request) — this is what makes Device Discovery different from plain Inquiry

Device Discovery Flow:

Discovering Device Remote Device
Step 1: Send Inquiry (GIAC) Reply with FHS: BD_ADDR, CoD, clock
Step 2: Send Remote Name Request to BD_ADDR Reply with device name string
Result: Full device profile — BD_ADDR + CoD + Clock + Name

🔑 Section 4.10.3.4 — Bonding

Bonding creates a mutual trust relationship between two Bluetooth devices. The result of bonding is a link key — a shared secret that both devices store permanently. Every time the two devices reconnect in the future, this link key is used to authenticate each other automatically without any user interaction.

Think of it like this: the first time you shake hands and exchange phone numbers is bonding. After that, you recognise each other instantly — that is the link key at work.

The official UI label defined by GAP is: “Bluetooth Bonding”

Bonding Stage What Happens
1. Pairing User enters passkey or approves numeric comparison on both devices
2. Link Key Generation A link key is created using the passkey (or SSP method) and exchanged between the two devices
3. Link Key Storage Both devices store the link key in persistent memory — the bond is saved
4. Future Reconnection When the devices meet again, the stored link key is used for authentication — no passkey needed from user

BlueZ — Bonding and Pairing:

# Start pairing / bonding with a remote device
bluetoothctl pair 00:1A:7D:DA:71:13
# If the device needs a passkey, bluetoothctl will prompt you

# Trust the device after bonding (auto-connect on future encounters)
bluetoothctl trust 00:1A:7D:DA:71:13

# List all bonded devices (stored link keys)
bluetoothctl paired-devices

# Check bond status for a specific device
bluetoothctl info 00:1A:7D:DA:71:13 | grep -E "Paired|Trusted|Bonded"

# Remove a bond (delete link key from both sides if possible)
bluetoothctl remove 00:1A:7D:DA:71:13

# View link keys stored in BlueZ (requires root)
cat /var/lib/bluetooth/<adapter-address>/<device-address>/info
# Shows: [LinkKey] Key=... Type=... PINLength=...

🔗 Section 4.10.4 — Establishment Procedures

Once you have discovered a device and decided to connect to it, there are three steps that happen in sequence to build the full connection from the radio layer up to the application layer. These are called the Establishment Procedures.

Device Discovery or Inquiry always happens first to get the BD_ADDR and other information. Then the three establishment procedures follow in order.

The Three Establishment Steps — Built Layer by Layer:

Device A (Initiator) Device B (Acceptor)
Step 1 — LMP Layer
Link Manager (LMP)
Link Establishment
ACL link created
Step 1 — LMP Layer
Link Manager (LMP)
Step 2 — L2CAP Layer
L2CAP
LMP (below)
Channel Establishment
L2CAP channel opened
Step 2 — L2CAP Layer
L2CAP
LMP (below)
Step 3 — Application Layer
Application
L2CAP (below)
LMP (below)
Connection Establishment
Apps can communicate
Step 3 — Application Layer
Application
L2CAP (below)
LMP (below)

Each step builds on the one below it. You cannot have Step 2 without Step 1, or Step 3 without Step 2.

Step Procedure Layer UI Name (per GAP) What It Creates
1 Link Establishment LMP “Bluetooth link establishment” An ACL (Asynchronous Connection-Less) baseband link between the two devices
2 Channel Establishment L2CAP “Bluetooth channel establishment” An L2CAP channel — a logical connection that higher protocols (RFCOMM, AVDTP) can use
3 Connection Establishment Application “Bluetooth connection establishment” An end-to-end connection between the applications on both devices — data can now flow

BlueZ — Connection Establishment:

# Step 1: Link Establishment — create an ACL link
# BlueZ does this automatically when you connect. To verify:
hcitool con
# Output: Connections:
#   < ACL 00:1A:7D:DA:71:13 handle 11 state 1 lm MASTER

# Step 2: Channel Establishment — open an L2CAP channel
# Test raw L2CAP connectivity (ping)
l2ping 00:1A:7D:DA:71:13

# Create a raw L2CAP connection to a PSM (Protocol/Service Multiplexer)
# Example: connect to PSM 3 (RFCOMM)
l2test -r -P 3 00:1A:7D:DA:71:13

# Step 3: Connection Establishment — full application connection
# Using bluetoothctl (handles all 3 steps transparently)
bluetoothctl connect 00:1A:7D:DA:71:13

# Check ACL link quality
hcitool lq 00:1A:7D:DA:71:13  # link quality (0-255)
hcitool rssi 00:1A:7D:DA:71:13  # signal strength (dBm)

# Disconnect
bluetoothctl disconnect 00:1A:7D:DA:71:13

🔒 Section 4.10.5 — Authentication

Authentication is the process of verifying who is at the other end of the link. It answers the question: “Is this device really who it says it is?”

Authentication happens automatically when two devices initiate connection establishment. The process checks for a stored link key:

Scenario What Happens
Link key already exists (previously bonded) Authentication uses the stored link key. No user interaction needed. Connection proceeds immediately.
Link key does not exist (first time) The pairing procedure is triggered to create a link key. User may need to enter a passkey or confirm a number.
Link key exists but does not match Authentication fails. The connection is rejected. The device must be un-paired and re-paired.

BlueZ — Checking Authentication:

# Check if a device is authenticated (paired with link key)
bluetoothctl info 00:1A:7D:DA:71:13 | grep "Paired"
# Paired: yes  means link key is stored

# View the stored link key (requires root access)
sudo cat /var/lib/bluetooth/<local-addr>/<remote-addr>/info
# [LinkKey]
# Key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# Type=4
# PINLength=0

# Require authentication for connections to this adapter
hciconfig hci0 auth       # enable authentication requirement
hciconfig hci0 noauth     # disable authentication requirement

# Enable encryption after authentication
hciconfig hci0 encrypt    # require encryption
hciconfig hci0 noencrypt  # disable encryption requirement

🛡 Section 4.10.6 — Bluetooth Security Modes

GAP defines four security modes. They fall into two families: Legacy (for older devices) and Secure Simple Pairing / SSP (for Bluetooth 2.1+ devices). The mode determines when security is enforced and what kind of link key is required.

Legacy Security Modes (Bluetooth 2.0 and earlier):

Mode Name When Security is Enforced Use Case
Mode 1 Non-secured Never — no security at all Open connections where no authentication or encryption is needed. Not recommended for sensitive data.
Mode 2 Service-level enforced After connection is established — only if the specific service/channel requires it Some services on the device need security, others do not. Security is per-service, not per-link.
Mode 3 Link-level enforced During connection setup — before anything else happens All connections to this device require authentication. Strongest legacy option.

SSP Security Mode (Bluetooth 2.1 + EDR and later):

Mode Name Sub-type MITM Protection? How Link Key is Generated
Mode 4 Service-level enforced (SSP) Authenticated link key required ✓ Yes Numeric Comparison, Out-of-Band (OOB), or Passkey Entry
Unauthenticated link key required ✗ No Just Works method — no user confirmation
Security optional N/A Used only for SDP transactions — lowest security requirement

Can a device support two modes at once? Yes. A device connecting to a legacy Bluetooth 2.0 device uses Security Mode 2, while the same device connecting to a modern SSP-capable device uses Security Mode 4. BlueZ handles this automatically based on the remote device’s capabilities.

Security Mode Timeline:

Bluetooth Version Security Modes Available Pairing Type
Bluetooth 1.x / 2.0 Mode 1, 2, 3 Legacy Pairing (PIN entry)
Bluetooth 2.1 + EDR and later Mode 1, 2, 3, 4 Secure Simple Pairing (SSP) — Numeric Comparison, Just Works, Passkey Entry, OOB

BlueZ — Security Configuration:

# Check SSP (Secure Simple Pairing) status on adapter
hciconfig hci0 | grep "Simple pairing"

# Enable SSP on adapter (Security Mode 4)
hciconfig hci0 sspmode 1

# Disable SSP (fall back to legacy modes 1-3)
hciconfig hci0 sspmode 0

# Set I/O capability for SSP pairing method:
# 0 = DisplayOnly         (Just Works or Passkey display)
# 1 = DisplayYesNo        (Numeric Comparison — MITM protection)
# 2 = KeyboardOnly        (Passkey Entry — MITM protection)
# 3 = NoInputNoOutput     (Just Works — no MITM protection)
hcitool cmd 0x08 0x0024 1    # set DisplayYesNo (numeric comparison)

# Using bluetoothctl to handle SSP pairing interactively
bluetoothctl agent on          # enable pairing agent
bluetoothctl default-agent     # set as default
bluetoothctl pair 00:1A:7D:DA:71:13
# For Numeric Comparison: confirm the 6-digit code matches on both devices
# For Just Works: confirms automatically, no user input

# Check security level of an active connection
hcitool con   # shows handle
hcitool auth <handle>   # request authentication on the link

Section 4.11 — Serial Port Profile (SPP)
Bluetooth’s original cable-replacement profile — making legacy serial apps work wirelessly
🔌 What is SPP?

The Serial Port Profile (SPP) defines how to create a wireless RS-232 serial connection between two Bluetooth devices. It was one of the very first Bluetooth profiles ever defined — because the original goal of Bluetooth was to replace cables, and serial cables were everywhere.

The key power of SPP: legacy applications that were written for wired RS-232 serial ports can use SPP with zero code changes. From the application’s point of view, it is just talking to a COM port. The fact that the COM port is actually a virtual port running over Bluetooth RFCOMM is completely transparent.

SPP depends on GAP (reusing all its discovery and connection procedures) and is in turn used as a foundation by other profiles — specifically Hands-Free Profile (HFP) and the Generic Object Exchange Profile (GOEP).

The Two SPP Device Roles:

Role What It Does Analogy
Dev A Initiates the Bluetooth connection — the active side that starts the session Like the person who picks up the phone and dials
Dev B Waits for an incoming connection and accepts it when Dev A connects Like the person who waits for the phone to ring and answers it

📊 SPP Protocol Stack and How Applications Use It

The SPP stack has two types of applications running side by side. A Bluetooth management application handles discovery and connection setup. Once connected, a legacy serial application uses the emulated port as if it were a normal RS-232 cable — it never knows Bluetooth is involved.

SPP Stack Diagram — Dev A and Dev B (Figure 4.16):

Dev A (Initiator) Dev B (Acceptor)
Legacy Serial App
BT Connection App
Serial Port Emulation (/dev/rfcomm0)
SDP  |  RFCOMM
L2CAP
Lower Layers (Baseband + Radio)
RFCOMM
virtual link
Legacy Serial App
BT Connection App
Serial Port Emulation (/dev/rfcomm1)
SDP  |  RFCOMM
L2CAP
Lower Layers (Baseband + Radio)

The legacy serial app uses the emulated port exactly like a physical RS-232 cable. It has no knowledge of Bluetooth underneath.

How SPP Works — Step by Step:

Step Action Who Does It
1 Bluetooth management app on Dev A scans and discovers Dev B (GAP inquiry) BT Connection App
2 Dev A uses SDP to find the RFCOMM channel number of Dev B’s SPP service BT Connection App + SDP
3 Dev A establishes an RFCOMM connection to Dev B on that channel BT Connection App + RFCOMM
4 A virtual serial port device appears on Dev A (e.g. /dev/rfcomm0 on Linux) Serial Port Emulation layer (OS driver)
5 Legacy serial application opens /dev/rfcomm0 and sends/receives data — no code change needed Legacy Serial App

BlueZ — SPP on Linux:

# === DEV B SIDE: Register an SPP service (server) ===

# Add an SPP service record to SDP (makes device discoverable as SPP server)
sdptool add SP

# Open an RFCOMM listener on channel 1 (Dev B waiting for connection)
rfcomm listen /dev/rfcomm0 1
# Now Dev B waits. Dev A can connect to this channel.


# === DEV A SIDE: Connect to Dev B's SPP service ===

# Step 1: Find Dev B's SPP RFCOMM channel via SDP
sdptool browse 00:1A:7D:DA:71:13 | grep -A2 "Serial Port"
# Output: Channel: 1

# Step 2: Bind the RFCOMM device
rfcomm bind /dev/rfcomm0 00:1A:7D:DA:71:13 1

# Step 3: Connect
rfcomm connect /dev/rfcomm0 00:1A:7D:DA:71:13 1
# Output: Connected /dev/rfcomm0 to 00:1A:7D:DA:71:13 on channel 1


# === LEGACY APP USAGE (after connection) ===

# Use the virtual serial port just like RS-232:
screen /dev/rfcomm0 115200       # terminal emulator
minicom -D /dev/rfcomm0          # minicom serial monitor
cat /dev/rfcomm0                 # read data
echo "Hello" > /dev/rfcomm0     # send data

# Using pyserial in Python (legacy app example):
# import serial
# ser = serial.Serial('/dev/rfcomm0', 115200)
# ser.write(b'Hello\n')
# data = ser.readline()

# Check RFCOMM status
rfcomm show /dev/rfcomm0

# Release the binding
rfcomm release /dev/rfcomm0

Section 4.12 — Headset Profile & Hands-Free Profile (HFP)
How Bluetooth handles phone calls — from mono headsets to full car kits
🎧 What are the Headset and Hands-Free Profiles?

The Headset Profile (HSP) and Hands-Free Profile (HFP) define how a Bluetooth connection handles phone calls between a mobile phone and a hands-free device — such as a mono Bluetooth headset or a car kit.

HSP was one of the very first Bluetooth profiles ever created. Over time, HFP replaced it because HFP is a superset of HSP — everything HSP can do, HFP can also do, plus much more. Modern devices implement HFP.

Profile Status Key Point
HSP — Headset Profile Superseded / Legacy Original profile for mono headsets. Basic call control only — answer, reject, volume.
HFP — Hands-Free Profile Current standard Full superset of HSP. Adds call waiting, voice dialing, battery indicator, signal strength display, and more.

Functions Defined by Headset / HFP Profiles:

Function Category Specific Functions
Connection Route audio from mobile phone to the hands-free device when a call is active or incoming
Call Control Accept an incoming call from the headset button
Reject an incoming call
Terminate (hang up) an active call

HFP Roles — AG and HF:

Role Short Name Device Responsibility
Audio Gateway AG Mobile phone or device connected to cellular network Handles the actual call, manages audio routing to the HF device
Hands-Free HF Bluetooth headset, car kit, speakerphone Provides microphone and speaker, sends call control commands to the AG

HFP Protocol Stack:

Audio Gateway (AG) — Phone Hands-Free (HF) — Headset / Car Kit
Phone App (call handling)
HFP / AT Commands over RFCOMM
SDP  |  RFCOMM
L2CAP
Baseband + Radio
AT Commands →
← Responses + Audio
HF App (mic + speaker)
HFP / AT Commands over RFCOMM
SDP  |  RFCOMM
L2CAP
Baseband + Radio

HFP uses AT commands (the same commands modems use) sent over an RFCOMM channel to control calls

BlueZ — HFP on Linux:

# Check if a device supports HFP via SDP
sdptool browse 00:1A:7D:DA:71:13 | grep -A5 "Handsfree"
# Shows: Handsfree Audio Gateway or Handsfree

# Connect to a paired HFP headset
bluetoothctl connect 00:1A:7D:DA:71:13

# HFP in BlueZ uses oFono (telephony) or PulseAudio/PipeWire for audio
# Check HFP profile in bluetoothctl
bluetoothctl info 00:1A:7D:DA:71:13 | grep "UUID"
# Look for: Handsfree Audio Gateway (HFP AG) UUID

# PulseAudio: list Bluetooth HFP cards
pactl list cards | grep -A10 "bluez_card"

# Switch between A2DP (music) and HFP (call) profiles
pactl set-card-profile bluez_card.00_1A_7D_DA_71_13 headset_head_unit
pactl set-card-profile bluez_card.00_1A_7D_DA_71_13 a2dp_sink

# With PipeWire (modern replacement for PulseAudio)
wpctl status   # show Bluetooth audio devices
# Switch profile:
pactl set-card-profile bluez_card.00_1A_7D_DA_71_13 handsfree_head_unit

# AT Commands used by HFP (sent over RFCOMM channel under the hood):
# ATA       - Answer call
# AT+CHUP   - Terminate call
# AT+CHLD=1 - Hold call / accept waiting call
# AT+CLCC   - List current calls
# AT+VGS=N  - Set speaker volume (0-15)
# AT+VGM=N  - Set microphone gain (0-15)

✅ Key Takeaways — GAP Procedures, SPP and HFP
Discovery is 3 steps

Inquiry → Name Discovery → Device Discovery. Each adds more information. Device Discovery is the complete procedure.

Connection is also 3 steps

Link (LMP/ACL) → Channel (L2CAP) → Connection (Application). Each layer builds on the one below it.

Bonding creates a link key

The link key is stored permanently on both devices. Future reconnections use it for authentication automatically.

Four security modes

Mode 1 = none. Mode 2 = after connection (per service). Mode 3 = during connection. Mode 4 = SSP (BT 2.1+).

SPP = wireless RS-232

Legacy apps see /dev/rfcomm0 as a normal serial port. RFCOMM + L2CAP carry the data wirelessly underneath.

HFP superseded HSP

HFP is a superset of HSP. It handles everything from answering calls to volume control using AT commands over RFCOMM.

Leave a Reply

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