899  BLE Protocol Stack and GATT

Generic Attribute Profile and Service Architecture

networking
wireless
bluetooth
ble
gatt
protocol
Author

IoT Textbook

Published

January 19, 2026

Keywords

ble, gatt, bluetooth, services, characteristics, profiles, att, gap

899.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Describe the BLE protocol stack layers and their functions
  • Explain the GATT client-server model for data exchange
  • Create and interact with BLE services and characteristics
  • Understand standard Bluetooth profiles for IoT applications
  • Design GATT architectures for sensor data communication

899.2 Introduction

Bluetooth Low Energy uses a well-defined protocol stack that enables efficient data exchange between devices. At the heart of BLE data communication is the Generic Attribute Profile (GATT), which defines how devices expose and consume structured data through services and characteristics.

This chapter explores the BLE protocol architecture, GATT fundamentals, and the standard profiles that enable interoperable IoT applications.

Think of GATT like a restaurant menu: - Service = Menu category (Drinks, Appetizers, Main Course) - Characteristic = Individual item (Coffee, Salad, Steak) - Properties = What you can do (Read the price, Order it, Get refills)

A heart rate monitor has a “Heart Rate Service” containing a “Heart Rate Measurement” characteristic that you can read or subscribe to for updates.

899.3 BLE Protocol Stack

The BLE protocol stack is organized into layers, each with specific responsibilities:

899.3.1 Stack Architecture

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart TB
    subgraph APP["Application Layer"]
        PROFILES[Profiles & Applications]
    end

    subgraph HOST["Host"]
        GAP[GAP<br/>Generic Access Profile]
        GATT[GATT<br/>Generic Attribute Profile]
        SMP[SMP<br/>Security Manager]
        ATT[ATT<br/>Attribute Protocol]
        L2CAP[L2CAP<br/>Logical Link Control]
    end

    HCI[HCI<br/>Host Controller Interface]

    subgraph CTRL["Controller"]
        LL[Link Layer]
        PHY[Physical Layer<br/>2.4 GHz Radio]
    end

    PROFILES --> GAP
    PROFILES --> GATT
    GAP --> ATT
    GATT --> ATT
    SMP --> L2CAP
    ATT --> L2CAP
    L2CAP --> HCI
    HCI --> LL
    LL --> PHY

    style APP fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff
    style HOST fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff
    style CTRL fill:#2C3E50,stroke:#16A085,stroke-width:2px,color:#fff
    style HCI fill:#7F8C8D,stroke:#2C3E50,stroke-width:2px,color:#fff

Figure 899.1: BLE protocol stack showing Controller (PHY, Link Layer), Host (L2CAP, ATT, GATT, GAP, SMP), and Application layers.

899.3.2 Layer Functions

Layer Function
PHY 2.4 GHz radio, modulation, 1M/2M/Coded PHY
Link Layer Advertising, scanning, connection management
L2CAP Multiplexing, segmentation, flow control
ATT Attribute Protocol - read/write attribute values
GATT Service/characteristic organization of attributes
GAP Device roles, advertising, connection procedures
SMP Pairing, bonding, encryption key management

899.4 Generic Attribute Profile (GATT)

GATT defines how BLE devices exchange data using a client-server model:

899.4.1 GATT Roles

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#E67E22','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart LR
    subgraph CLIENT["GATT Client (Central)"]
        PHONE[Smartphone<br/>Reads/Writes data]
    end

    subgraph SERVER["GATT Server (Peripheral)"]
        SENSOR[Heart Rate Monitor<br/>Exposes services]
        subgraph SERVICES["Services"]
            HRS[Heart Rate Service]
            BAS[Battery Service]
        end
    end

    PHONE -->|"Read HR"| HRS
    PHONE -->|"Subscribe to notifications"| HRS
    HRS -->|"HR: 72 bpm"| PHONE
    PHONE -->|"Read battery"| BAS

    style CLIENT fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff
    style SERVER fill:#2C3E50,stroke:#16A085,stroke-width:2px,color:#fff
    style SERVICES fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff

Figure 899.2: GATT client-server model with smartphone (client) reading data from sensor (server) services.
Role Description Typical Device
GATT Server Exposes services and characteristics Sensors, peripherals
GATT Client Reads/writes data from servers Smartphones, gateways
NoteRole Independence

GATT roles are independent of GAP roles: - A BLE Central (GAP) can be a GATT Server - A BLE Peripheral (GAP) can be a GATT Client - Most often: Peripheral = Server, Central = Client

899.4.2 GATT Hierarchy

GATT organizes data in a three-level hierarchy:

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart TD
    PROFILE[Profile<br/>e.g., Heart Rate Profile]

    subgraph SERVICE1["Service: Heart Rate (0x180D)"]
        CHAR1[Characteristic:<br/>HR Measurement (0x2A37)]
        CHAR2[Characteristic:<br/>Body Sensor Location (0x2A38)]
        CHAR3[Characteristic:<br/>HR Control Point (0x2A39)]
    end

    subgraph SERVICE2["Service: Battery (0x180F)"]
        CHAR4[Characteristic:<br/>Battery Level (0x2A19)]
    end

    subgraph CHAR_DETAIL["Characteristic Structure"]
        VALUE[Value: Actual data bytes]
        PROPS[Properties: READ, WRITE, NOTIFY]
        DESC[Descriptors: CCCD, Format, Name]
    end

    PROFILE --> SERVICE1
    PROFILE --> SERVICE2
    CHAR1 --> CHAR_DETAIL

    style PROFILE fill:#2C3E50,stroke:#16A085,stroke-width:2px,color:#fff
    style SERVICE1 fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff
    style SERVICE2 fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff
    style CHAR_DETAIL fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff

Figure 899.3: GATT hierarchy: Profile → Services → Characteristics → Value/Properties/Descriptors.

899.4.3 Services

A service is a collection of related characteristics:

Component Description Example
UUID 16-bit (standard) or 128-bit (custom) identifier 0x180D (Heart Rate)
Primary/Secondary Primary = standalone, Secondary = included by other Usually Primary
Characteristics Data values within the service HR Measurement, Body Location

Standard Service UUIDs:

UUID Service Name Use Case
0x180D Heart Rate Service Fitness devices
0x180F Battery Service Battery level reporting
0x181A Environmental Sensing Temperature, humidity
0x1800 Generic Access Device name, appearance
0x1801 Generic Attribute Service changed indication

899.4.4 Characteristics

A characteristic contains the actual data value with metadata:

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart TD
    subgraph CHAR["Characteristic (e.g., Heart Rate Measurement)"]
        HANDLE[Handle: 0x0012<br/>Internal reference]
        UUID[UUID: 0x2A37<br/>Characteristic type]
        PROPS[Properties:<br/>READ | NOTIFY]
        VALUE[Value: 0x00 0x48<br/>Flags + 72 BPM]

        subgraph DESCS["Descriptors"]
            CCCD[CCCD (0x2902)<br/>Enable notifications]
            FORMAT[Format<br/>Data type info]
            NAME[User Description<br/>Human-readable name]
        end
    end

    style CHAR fill:#2C3E50,stroke:#16A085,stroke-width:2px,color:#fff
    style DESCS fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff

Figure 899.4: Characteristic structure showing Handle, UUID, Properties, Value, and Descriptors (CCCD, Format, Name).

899.4.5 Characteristic Properties

Properties define how clients can interact with a characteristic:

Property Bit Description
Broadcast 0x01 Include in advertising data
Read 0x02 Client can read value
Write Without Response 0x04 Fast write, no confirmation
Write 0x08 Write with confirmation
Notify 0x10 Server pushes updates (no ACK)
Indicate 0x20 Server pushes updates (with ACK)
Authenticated Signed Writes 0x40 Signed writes allowed
Extended Properties 0x80 Additional properties in descriptor

899.4.6 Client Characteristic Configuration Descriptor (CCCD)

The CCCD (UUID 0x2902) controls notifications and indications:

CCCD Value:
0x0000 = Notifications/Indications disabled
0x0001 = Notifications enabled
0x0002 = Indications enabled
ImportantEnabling Notifications

To receive real-time updates from a characteristic:

  1. Connect to the GATT server
  2. Discover services and characteristics
  3. Write 0x0001 to the CCCD to enable notifications
  4. Handle incoming notification callbacks

Without writing to the CCCD, you will NOT receive updates even if the characteristic has the Notify property!

899.5 Standard Bluetooth Profiles

Bluetooth SIG defines standard profiles for interoperability:

899.5.1 Common IoT Profiles

Profile Services Use Case
Heart Rate Profile Heart Rate (0x180D) Fitness trackers, monitors
Health Thermometer Health Thermometer (0x1809) Medical thermometers
Blood Pressure Blood Pressure (0x1810) BP monitors
Environmental Sensing Environmental (0x181A) Temperature, humidity sensors
Proximity Link Loss, TX Power Proximity beacons
HID over GATT (HOGP) HID Service BLE keyboards, mice

899.5.2 Classic Bluetooth Profiles

Profile Abbreviation Use Case
Advanced Audio Distribution A2DP Stereo audio streaming
Audio/Video Remote Control AVRCP Media controls
Hands-Free Profile HFP Car kits, headsets
Human Interface Device HID Keyboards, mice
Serial Port Profile SPP UART replacement
Object Push Profile OPP File transfer

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart TB
    subgraph CLASSIC["Classic Bluetooth Profiles"]
        A2DP[A2DP<br/>Audio Streaming]
        HFP[HFP<br/>Phone Calls]
        SPP[SPP<br/>Serial Port]
        HID_C[HID<br/>Input Devices]
    end

    subgraph BLE["BLE GATT Services"]
        HRS[Heart Rate<br/>0x180D]
        BAS[Battery<br/>0x180F]
        ESS[Environmental<br/>0x181A]
        HID_B[HID over GATT<br/>HOGP]
    end

    CLASSIC -->|"Connection-oriented<br/>Continuous data"| USES1[Headphones<br/>Speakers<br/>Car Kits]
    BLE -->|"Attribute-based<br/>Intermittent data"| USES2[Sensors<br/>Wearables<br/>Beacons]

    style CLASSIC fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff
    style BLE fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff

Figure 899.5: Comparison of Classic Bluetooth profiles for streaming vs BLE GATT services for sensor data.

899.6 BLE Advertising

BLE advertising enables device discovery and connectionless data broadcast:

899.6.1 Advertising Packet Structure

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart LR
    subgraph PACKET["BLE Advertising Packet"]
        PRE[Preamble<br/>1 byte]
        AA[Access Address<br/>4 bytes<br/>0x8E89BED6]
        PDU[PDU Header<br/>2 bytes]
        ADDR[Advertiser<br/>Address<br/>6 bytes]
        DATA[Advertising<br/>Data<br/>0-31 bytes]
        CRC[CRC<br/>3 bytes]
    end

    PRE --> AA --> PDU --> ADDR --> DATA --> CRC

    style PRE fill:#7F8C8D,stroke:#2C3E50,color:#fff
    style AA fill:#2C3E50,stroke:#16A085,color:#fff
    style PDU fill:#2C3E50,stroke:#16A085,color:#fff
    style ADDR fill:#16A085,stroke:#2C3E50,color:#fff
    style DATA fill:#E67E22,stroke:#2C3E50,color:#fff
    style CRC fill:#7F8C8D,stroke:#2C3E50,color:#fff

Figure 899.6: BLE advertising packet structure with fixed header and variable advertising data payload.

899.6.2 Advertising Types

Type Code Description Connectable
ADV_IND 0x00 Connectable undirected Yes
ADV_DIRECT_IND 0x01 Connectable directed Yes
ADV_SCAN_IND 0x02 Scannable undirected No
ADV_NONCONN_IND 0x03 Non-connectable No

899.6.3 Advertising Channels

BLE uses 3 dedicated advertising channels:

Channel Frequency Wi-Fi Overlap
37 2402 MHz Avoids Ch 1
38 2426 MHz Avoids Ch 6
39 2480 MHz Avoids Ch 11

899.7 iBeacon and Eddystone

BLE beacons broadcast location/proximity information:

899.7.1 iBeacon (Apple)

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor':'#2C3E50','primaryTextColor':'#fff','primaryBorderColor':'#16A085','lineColor':'#16A085','secondaryColor':'#E67E22','tertiaryColor':'#7F8C8D'}}}%%
flowchart LR
    subgraph IBEACON["iBeacon Manufacturer Data"]
        CID[Company ID<br/>0x004C<br/>Apple]
        TYPE[Type<br/>0x02]
        LEN[Length<br/>0x15<br/>21 bytes]
        UUID[Proximity UUID<br/>16 bytes]
        MAJOR[Major<br/>2 bytes]
        MINOR[Minor<br/>2 bytes]
        TXPWR[TX Power<br/>1 byte]
    end

    CID --> TYPE --> LEN --> UUID --> MAJOR --> MINOR --> TXPWR

    style CID fill:#7F8C8D,stroke:#2C3E50,color:#fff
    style UUID fill:#16A085,stroke:#2C3E50,color:#fff
    style MAJOR fill:#E67E22,stroke:#2C3E50,color:#fff
    style MINOR fill:#E67E22,stroke:#2C3E50,color:#fff
    style TXPWR fill:#2C3E50,stroke:#16A085,color:#fff

Figure 899.7: iBeacon packet format with UUID for application identification, Major/Minor for location hierarchy.
Field Size Description Example
UUID 16 bytes Application/company identifier Store chain ID
Major 2 bytes Coarse location Store number
Minor 2 bytes Fine location Aisle/department
TX Power 1 byte Calibrated RSSI at 1m Distance estimation

899.7.2 Eddystone (Google)

Eddystone supports multiple frame types:

Frame Description Use Case
Eddystone-UID Unique ID (similar to iBeacon) Asset tracking
Eddystone-URL Broadcasts URL Physical web
Eddystone-TLM Telemetry (battery, temp) Beacon health
Eddystone-EID Ephemeral ID (rotating) Secure beacons

899.8 Inline Knowledge Check

Question 1: What is a BLE GATT characteristic?

A GATT characteristic is a data value exposed by a BLE peripheral, containing: Value (actual data bytes), Properties (READ, WRITE, NOTIFY, INDICATE), and Descriptors (metadata about the value). The hierarchy is: Profile → Service → Characteristic → Value/Properties/Descriptors.

Question 2: What is an iBeacon?

iBeacon is Apple’s BLE beacon protocol for proximity detection and location-based services. It uses Proximity UUID (16 bytes) for application identification, Major (2 bytes) for coarse location, Minor (2 bytes) for fine location, and TX Power (1 byte) for distance estimation.

Question 3: Which Bluetooth profile is used for wireless keyboards?

HID (Human Interface Device) Profile is used for keyboards, mice, game controllers, and joysticks. It’s based on the USB HID specification with low latency for responsive input. BLE keyboards use HID-over-GATT (HOGP).

899.9 Summary

This chapter covered the BLE protocol stack and GATT:

  • Protocol Stack: Layered architecture from PHY through GATT to Application
  • GATT Model: Client-server architecture for data exchange
  • Hierarchy: Profile → Services → Characteristics → Values/Descriptors
  • Properties: READ, WRITE, NOTIFY, INDICATE control data access
  • CCCD: Must write 0x0001 to enable notifications
  • Standard Profiles: Heart Rate, Environmental Sensing, HID, and more
  • Beacons: iBeacon (Apple) and Eddystone (Google) for location services

899.10 What’s Next

Continue to Bluetooth Implementation and Labs for practical code examples, ESP32 Wokwi labs, and hands-on exercises for building BLE applications.