What is the Generic Access Profile (GAP)?
Hello students welcome to embedded pathashalas free embedded systems course, this lecture is part of our bluetooth development course in c, in this lecture i will explain you about What is Generic Access Profile (GAP) in Bluetooth? The Generic Access Profile (GAP) is the one Bluetooth profile that every single Bluetooth device — headsets, phones, laptops, speakers, fitness trackers, keyboards — must implement without exception. It is the foundation layer that all other Bluetooth profiles are built on top of.
GAP defines how a Bluetooth device behaves at the most basic level: how it announces itself to nearby devices, how it accepts or refuses connections, how it pairs securely, and how it discovers other devices and their services. Without GAP, Bluetooth devices from different manufacturers would not be able to understand or trust each other.
This guide covers GAP completely: the profile dependency tree, the mandatory protocol stack, all device modes (discoverable, connectable, bondable), and the idle mode procedures including inquiry, name discovery and bonding — with real BlueZ commands for Linux throughout.
Key Terms Covered in This Guide
Before diving into GAP itself, it helps to understand where it sits in the bigger picture. Every Bluetooth profile depends on one or more other profiles beneath it. GAP sits at the very bottom — every other profile depends on it directly or indirectly.
The dependency rule is simple: if Profile A uses parts of Profile B, then Profile A is dependent on Profile B. In the diagram below, an inner box means “depends on the outer box”.
For example: Hands-Free Profile (HFP) depends on Serial Port Profile (SPP), which in turn depends on GAP. So HFP sits inside SPP, which sits inside GAP.
Bluetooth Profile Dependency Tree (Figure 4.14):
|
Generic Access Profile (GAP) — Mandatory for ALL Bluetooth devices
|
Inner boxes depend on outer boxes. All profiles ultimately depend on GAP (outermost box).
For BR/EDR (Basic Rate / Enhanced Data Rate) Bluetooth devices, GAP defines that every device must include at minimum these five components in its protocol stack:
| Layer | What It Provides |
|---|---|
| SDP — Service Discovery Protocol | Lets devices find and list services on remote devices |
| L2CAP — Logical Link Control and Adaptation Protocol | Multiplexes higher protocols over the Baseband link |
| Link Manager (LMP) | Manages link setup, authentication, encryption and power control |
| Baseband | Handles timing, frequency hopping and packet formatting |
| Bluetooth Radio | The 2.4 GHz radio transceiver — the physical wireless layer |
Beyond the mandatory stack, GAP also defines the procedures and behaviours for:
| GAP Procedure | What It Covers |
|---|---|
| Device Discovery | How devices scan for and find each other in the vicinity using Inquiry |
| Connection Establishment | The procedure to create a Baseband connection between two devices using Paging |
| Security | Security modes, encryption requirements and access control |
| Authentication | Verifying that a device is who it claims to be using pairing and link keys |
| Service Discovery | How a device finds out what services a remote device offers (via SDP) |
GAP has three main goals that it achieves across all Bluetooth implementations:
| # | Purpose | In Plain English |
|---|---|---|
| 1 | Definitions and common requirements | GAP introduces standardised definitions for modes and access procedures that all other transport and application profiles must follow. One set of rules for everyone. |
| 2 | Behaviour in each device state | GAP describes exactly how a device must behave in states like standby, scanning, connecting and connected. Special focus is on discovery, connection and security procedures. |
| 3 | User interface requirements | GAP defines the exact names that must be used on user interfaces, manuals and settings menus. This ensures the same terminology whether the device is from Sony, Apple or Samsung. |
GAP defines procedures for two different Bluetooth technologies — classic Bluetooth (BR/EDR) and Bluetooth Low Energy (BLE). It recognises three types of devices:
| Device Type | Technology | Typical Use Cases |
|---|---|---|
| BR/EDR Only | Classic Bluetooth — Basic Rate and Enhanced Data Rate | A2DP headphones, classic hands-free kits, Bluetooth speakers |
| LE Only | Bluetooth Low Energy — optimised for battery-powered sensors | Heart rate monitors, temperature sensors, fitness trackers, beacons |
| BR/EDR/LE (Dual Mode) | Both classic Bluetooth and BLE simultaneously | Smartphones, laptops, tablets — devices that connect to both classic headsets and BLE peripherals |
The BR/EDR procedures are covered in this guide. The BLE-specific procedures are covered separately in the Low Energy chapters.
GAP defines exactly how Bluetooth parameters must be represented on user interfaces, in manuals, and in advertising. This matters because if every manufacturer uses different names and formats for the same thing, users get confused. GAP standardises the terminology.
| Parameter | UI Name (as required by GAP) | Format and Details |
|---|---|---|
| BD_ADDR | “Bluetooth Device Address” | 12 hexadecimal characters, optionally separated by colons. Example: 00:AB:CD:EF:12:34. Globally unique — like a MAC address. |
| Device Name | “Bluetooth Device Name” | A human-readable name string (max 248 bytes). Remote devices can retrieve it using a Remote Name Request. Example: “John’s AirPods”. |
| Passkey / PIN | “Bluetooth Passkey” | Used during pairing to authenticate two devices. Can be entered on the UI (phone/laptop) or pre-stored in the device (e.g. fixed PIN in a headset like “0000”). |
| Class of Device (CoD) | “Bluetooth Device Class” and “Bluetooth Service Type” | Encodes both the type of device (phone, headset, laptop) and the types of services it offers. Retrieved during Inquiry so a device knows what it is looking at before connecting. |
BlueZ — Reading and Setting These Parameters:
# Show the Bluetooth Device Address (BD_ADDR) of your adapter
hciconfig hci0 | grep "BD Address"
# Output example: BD Address: 00:AB:CD:EF:12:34
# Read local device name
hciconfig hci0 name
# Or using bluetoothctl:
bluetoothctl show | grep "Name"
# Set device name (Bluetooth Device Name)
hciconfig hci0 name "MyLinuxDevice"
# Or in bluetoothctl:
bluetoothctl system-alias "MyLinuxDevice"
# Read Class of Device
hciconfig hci0 | grep "Class"
# Output example: Class: 0x3c0104 (Computer - Desktop, Service: Capturing)
# Decode Class of Device value
# Bit fields: Service Class (bits 23-13), Major Device (bits 12-8), Minor Device (bits 7-2)
# Example: 0x3c0104 = Computer (Major), Desktop (Minor), Capturing+Audio (Service)
GAP defines three categories of modes. Each category controls a different aspect of how the device behaves with respect to other Bluetooth devices. Every mode can be toggled — you choose which state your device is in at any given time.
4.10.2.1 — Discoverability Modes (Inquiry-related)
These modes control whether your device can be found by other devices scanning for Bluetooth devices nearby. The process of finding devices is called Inquiry.
| Mode | Responds to Inquiry? | When to Use It |
|---|---|---|
| Non-Discoverable | No — hidden from all scans | When the device should be invisible to other Bluetooth devices. Use for paired devices that should not appear in new scans. |
| Limited Discoverable | Yes — only to Limited Inquiries (LIAC) | When the device should be visible only for a short time or a specific event. Example: a device entering pairing mode for 60 seconds. |
| General Discoverable | Yes — responds to any inquiry (GIAC) | When the device should always be visible. Example: a Bluetooth speaker that is always available to connect to. |
4.10.2.2 — Connectability Modes (Paging-related)
These modes control whether another device can connect to your device. The process of initiating a connection is called Paging. A device in PAGE_SCAN state is listening for incoming page requests.
| Mode | Enters PAGE_SCAN? | Effect |
|---|---|---|
| Non-Connectable | No | Other devices cannot initiate a connection to this device. It can still initiate connections outward. |
| Connectable | Yes — periodically | The device listens for incoming connection requests at regular intervals. Other devices can page and connect to it. |
4.10.2.3 — Bondable Modes (Pairing-related)
Bonding is the process of pairing where a passkey is exchanged and a bond is created — a long-term link key stored on both devices. This bond means you do not need to re-enter the passkey every time you reconnect.
| Mode | Accepts Pairing? | Notes |
|---|---|---|
| Non-Bondable | No pairing requests accepted | The device can still accept connections from already-paired devices that do not require re-bonding. |
| Bondable | Yes — pairing accepted | Device accepts pairing. Can be legacy pairing (PIN-based) or Secure Simple Pairing (SSP) with Numeric Comparison, Passkey Entry, or Just Works. |
Summary — All Three Mode Categories Together:
| Mode Category | Controls | Procedure Used | Options |
|---|---|---|---|
| Discoverability | Can other devices find you? | Inquiry / Inquiry Scan | Non-Discoverable, Limited, General |
| Connectability | Can other devices connect to you? | Paging / PAGE_SCAN | Non-Connectable, Connectable |
| Bondability | Can other devices pair with you? | Pairing / Bonding | Non-Bondable, Bondable |
BlueZ — Controlling All Three Modes:
# === DISCOVERABILITY MODES ===
# Set device to General Discoverable mode (GIAC)
hciconfig hci0 piscan # enables both Page Scan and Inquiry Scan
hciconfig hci0 iscan # Inquiry Scan only (discoverable, not connectable)
# Set device to Non-Discoverable
hciconfig hci0 noscan
# In bluetoothctl (modern interface):
bluetoothctl discoverable on # General Discoverable
bluetoothctl discoverable off # Non-Discoverable
# Limited Discoverable mode (LIAC) - timeout after N seconds
bluetoothctl discoverable-timeout 60 # visible for 60 seconds then hides
# === CONNECTABILITY MODES ===
# Make device connectable (enables PAGE_SCAN)
hciconfig hci0 pscan # Page Scan only
bluetoothctl pairable on
# Make device non-connectable
hciconfig hci0 noscan
# Check current scan modes
hciconfig hci0 | grep "UP"
# === BONDABLE (PAIRING) MODES ===
# Enable pairing (Bondable mode)
bluetoothctl pairable on
# Disable pairing (Non-Bondable mode)
bluetoothctl pairable off
# Set pairing timeout
bluetoothctl pairable-timeout 120 # bondable for 120 seconds
# View current adapter settings
bluetoothctl show
# Shows: Discoverable, Pairable, Powered, etc.
Idle mode procedures are actions a Bluetooth device takes when it is not currently busy with an active connection. The name idle is slightly misleading — these procedures can also run while a device is already connected, for example to discover a second device and form a scatternet.
The main idle mode procedures are: Inquiry, Name Discovery, and Bonding.
Inquiry is the process of scanning for Bluetooth devices in the local vicinity. Devices are mobile — they move in and out of range constantly. Inquiry gives you a live snapshot of what devices are currently reachable.
When a device completes an inquiry, it gets back a list of discovered devices. For each discovered device, the inquiry provides:
| Information Returned | What It Tells You |
|---|---|
| BD_ADDR | The unique 48-bit Bluetooth address of the discovered device |
| Clock Offset | Helps speed up future connections to this device by predicting its frequency hop timing |
| Class of Device (CoD) | What type of device it is (phone, headset, laptop) and what services it offers — before you even connect |
| Page Scan Mode | Whether and how the device listens for incoming connections |
| Extended Inquiry Response (EIR) | If supported — extra information like the device name and supported UUIDs delivered in the inquiry packet itself, saving extra round-trips |
Two Types of Inquiry
| Inquiry Type | Access Code Used | Discovers Which Devices? | Use Case |
|---|---|---|---|
| General Inquiry | GIAC (General Inquiry Access Code) | Devices in General Discoverable mode or Limited Discoverable mode | Standard scan — what you see when you tap “Scan for Bluetooth devices” on any phone |
| Limited Inquiry | LIAC (Limited Inquiry Access Code) | Only devices in Limited Discoverable mode | Finding devices that just entered a temporary pairing window — e.g. a device that became visible for 60 seconds |
Inquiry Flow — What Happens Step by Step:
| Inquiring Device (Scanner) | ↕ | Responding Device (Discoverable) |
|---|---|---|
| 1. Sends Inquiry message using GIAC or LIAC | → | Device receives inquiry — is it in Discoverable mode? |
| Waits for responses (inquiry window) | ← | 2. Responds with FHS (Frequency Hop Sync) packet containing BD_ADDR, CoD, clock offset |
| 3. Collects all responses. Builds device list. | Waits to see if connection follows | |
| Result: Inquiring device now has a list of nearby devices with BD_ADDR, device type, and clock info | ||
BlueZ — Running Inquiry / Scanning:
# General Inquiry — discover nearby Bluetooth devices (8 second scan)
hcitool scan
# Output example:
# Scanning ...
# 00:1A:7D:DA:71:13 MyHeadset
# 68:ED:43:25:0E:99 Samsung Galaxy S22
# General Inquiry with more details (RSSI, Class of Device, clock offset)
hcitool inq
# Output:
# Inquiring ...
# 00:1A:7D:DA:71:13 clock offset: 0x0abc class: 0x240404
# Limited Inquiry (LIAC) — only devices in limited discoverable mode
hcitool inq --iac liac
# Scan with Extended Inquiry Response (EIR) data
hcitool scan --extended
# Using bluetoothctl (modern recommended method)
bluetoothctl scan on
# Then: [NEW] Device 00:1A:7D:DA:71:13 MyHeadset
bluetoothctl scan off
# Get info about a specific discovered device
bluetoothctl info 00:1A:7D:DA:71:13
# Shows: Name, Alias, Class, Icon, Paired, Trusted, Blocked, Connected, UUIDs
Here is a complete quick-reference showing how GAP relates to the most commonly implemented Bluetooth classic profiles and what each requires:
| Profile | Depends On | Key Protocol Used | Typical Device Pair |
|---|---|---|---|
| GAP | Nothing — it is the base | L2CAP, LMP, Baseband, Radio | All Bluetooth devices |
| SDAP | GAP | SDP | Any device doing service discovery |
| SPP | GAP | RFCOMM | PC to serial device, GPS receivers |
| HFP | GAP, SPP | RFCOMM | Phone to car kit / headset |
| GOEP | GAP | OBEX, RFCOMM | Any device exchanging objects |
| OPP | GAP, GOEP | OBEX, RFCOMM | Phone to phone (send contact / vCard) |
| FTP | GAP, GOEP | OBEX, RFCOMM | PC to phone (file browser) |
| GAVDP | GAP | AVDTP, L2CAP | Any A/V streaming device pair |
| A2DP | GAP, GAVDP | AVDTP, L2CAP | Phone to stereo headphones / speaker |
| AVRCP | GAP, GAVDP | AVCTP, L2CAP | Headset buttons controlling phone playback |
# =============================================
# 1. ADAPTER / DEVICE INFORMATION (BD_ADDR, Name, CoD)
# =============================================
# List all Bluetooth adapters
hciconfig -a
# Show adapter details: BD_ADDR, name, class, features
hciconfig hci0
# Get adapter info via bluetoothctl
bluetoothctl show
# Read remote device name (Name Discovery procedure)
hcitool name 00:1A:7D:DA:71:13
# Remote Name Request via bluetoothctl
bluetoothctl info 00:1A:7D:DA:71:13
# =============================================
# 2. DISCOVERABILITY AND CONNECTABILITY
# =============================================
# Enable both Inquiry Scan and Page Scan (discoverable + connectable)
hciconfig hci0 piscan
# Inquiry Scan only (discoverable but not connectable)
hciconfig hci0 iscan
# Page Scan only (connectable but not discoverable)
hciconfig hci0 pscan
# Disable all scanning (non-discoverable, non-connectable)
hciconfig hci0 noscan
# Set discoverable via bluetoothctl (simpler, recommended)
bluetoothctl discoverable on
bluetoothctl discoverable off
bluetoothctl pairable on
bluetoothctl pairable off
# =============================================
# 3. INQUIRY (DEVICE DISCOVERY)
# =============================================
# Run a General Inquiry (GIAC) - 10 second scan
hcitool scan
# Run Inquiry with RSSI values
hcitool rssi 00:1A:7D:DA:71:13
# Inquiry with all returned details
hcitool inq
# Extended inquiry (gets device name in inquiry packet if EIR supported)
hcitool scan --extended --flush
# Continuous scan in bluetoothctl
bluetoothctl scan on
# Press Ctrl+C or:
bluetoothctl scan off
# =============================================
# 4. BONDING AND PAIRING
# =============================================
# Pair with a device (initiates bonding)
bluetoothctl pair 00:1A:7D:DA:71:13
# Trust a device (so it auto-connects)
bluetoothctl trust 00:1A:7D:DA:71:13
# Remove a bond (unpair)
bluetoothctl remove 00:1A:7D:DA:71:13
# List all paired/bonded devices
bluetoothctl paired-devices
# Check if a device is bonded
bluetoothctl info 00:1A:7D:DA:71:13 | grep "Paired"
# =============================================
# 5. CONNECTION ESTABLISHMENT
# =============================================
# Connect to a paired device
bluetoothctl connect 00:1A:7D:DA:71:13
# Disconnect
bluetoothctl disconnect 00:1A:7D:DA:71:13
# Check active connections
hcitool con
# Low-level connection test (ping)
l2ping 00:1A:7D:DA:71:13
Every Bluetooth device — classic or BLE — must implement GAP. It is the foundation all other profiles sit on.
Discoverability (can others find you?), Connectability (can others connect?), Bondability (can others pair?). Each is independent.
GIAC finds all discoverable devices. LIAC finds only devices in Limited Discoverable mode — typically in a timed pairing window.
Every Bluetooth device has a globally unique 48-bit address. Represented as 00:AB:CD:EF:12:34 on user interfaces per GAP requirements.
GAP is the outermost box. SPP, GAVDP, GOEP, SDAP all sit directly inside it. A2DP, HFP, OPP, AVRCP sit inside those.
A bond creates a stored link key on both devices. Future reconnections happen automatically without re-entering the passkey.
