GATT协议简介
在蓝牙的世界里,GATT(通用属性配置文件)就是这套"交接规则" 。它专门负责在两个蓝牙设备连接之后 ,数据该如何组织和传输。
📊 GATT的核心概念
GATT把数据组织得像一个严格的表格,你可以把它想象成一个带目录和标签的文件柜。
为了让你看得更清楚,我们用 "一个带心率监测功能的智能手环" 举个例子:
| 概念 | 大白话解释 | 手环例子 |
|---|---|---|
| 服务 (Service) | 一个功能模块,包含一组相关的数据。 | "心率服务"(UUID: 0x180D),所有和心率相关的数据都在这里。 |
| 特征 (Characteristic) | 服务里一个具体的"数据项",它包含实际数值和访问权限(可读/可写/通知等)。 | "心率测量值"特征(UUID: 0x2A37),里面就是具体的每分钟心跳次数。 |
| 描述符 (Descriptor) | 特征的"说明书",用来描述或配置这个特征。 | 客户端特征配置描述符(CCCD),手机通过修改它来"订阅"心率通知。这样一旦心跳变化,手环就会主动推送,不用手机反复来问。 |
UUID就像每个服务和特征的唯一身份证号,有全球统一的标准(16位短ID),也可以用自定义的(128位长ID)。
🔄 客户端与服务器
在GATT里,只有两个角色:
-
GATT服务器 (GATT Server) :数据的提供方。它负责存储数据并响应请求。你的智能手环就是服务器,它存着你的心率数据。每个蓝牙设备至少得能当个基本的服务器。
-
GATT客户端 (GATT Client) :数据的使用方。它主动去服务器读写数据。你的手机App就是客户端,它去手环上读取心率。
连接后,客户端必须先"服务发现",才能知道服务器提供了哪些服务和特征,就像拿到一份文件柜的目录。
✉️ 四种数据操作方式
角色定好后,它们通过这四种方式"对话":
-
读 (Read):客户端主动向服务器"要"数据(例如:手机读取当前心率)。
-
写 (Write):客户端主动向服务器"写"数据(例如:手机设置手环的时间)。
-
通知 (Notify) :服务器主动"推送"数据给客户端,不需要客户端回复确认。这种方式最省电、最常用(例如:心跳变了,手环就自动推给手机)。
-
指示 (Indicate) :服务器主动"推送"数据,但需要客户端回复确认,更可靠但稍慢。
一个常见的误解是:GATT的客户端/服务器角色,和负责连接建立的GAP(通用访问配置文件)里的中央/外围设备角色是两套独立的体系。一个中央设备(手机)可以是GATT客户端,而一个外围设备(手环)也可以是GATT客户端。
简单来说,GAP负责"怎么连上",而GATT负责"连上后怎么聊"。
COC协议简介
目前是open Harmony6.1统一互联共建3.0版本,我看项目里面目前用的是BLE4.2,但还没有实现coc协议连接的,不过也要铺垫一下。
CoC"在蓝牙BLE里的全称是 L2CAP 面向连接的通道 (Connection-Oriented Channel),它和 GATT 是两种完全不同的数据传输思路。
如果拿寄送物品 来比喻,GATT 和 CoC 的区别就像寄包裹 和修一条管道:
-
GATT(寄包裹):你想给对方东西,得按规定的格式打包好(属性协议),贴上标签(UUID),在"快递点"(固定通道)等着对方来取件(读)或叫快递员送过去(写/通知)。每次只能送一个标准大小的包裹,比较适合传递心率这种小数据。
-
CoC(修管道) :为了高效地传送大量数据(比如音频流或大文件),你们直接在两个设备间修了一条专用的"管道"。一旦接通,数据就可以像流水一样持续、双向地传输。
COC 与 GATT 的关键区别:
| 特性 | GATT | COC (L2CAP) |
|---|---|---|
| 传输可靠性 | 基于 ATT 协议 | 基于 L2CAP 面向连接通道 |
| 数据格式 | 必须符合 GATT Profile | 更灵活的字节流 |
| 适用场景 | 设备发现、服务读写 | 高可靠性的字节流传输 |
| MTU | 较小(默认 512) | 可更大 |
| 实现复杂度 | 较复杂 | 较简单 |
🌊 "管道"内部是怎么工作的?
这条"管道"有几个很实用的设计:
-
容量更大 (MTU更大):相比于GATT,CoC的"管道"一次能承载更大的数据包,最高可支持到512字节,传输效率更高。
-
自带调节阀 (基于信用的流量控制):为了防止"管道"里的数据太多把接收方冲垮,CoC采用了一种"信用"机制。发送方只有收到接收方给的"信用"才能发送数据,从而实现了流控,确保传输的可靠性。
-
独立"阀门" (PSM) :要连接到不同的CoC"管道",需要知道一个叫 PSM (协议/服务复用器) 的"阀门编号"作为服务识别码。这就像GATT里用UUID来找到特定服务一样,但层级更底层。
🎯 什么时候用CoC?
正因为CoC高效且可靠,它在很多对实时性和数据传输量要求较高的场景里非常适用:
-
音频传输 :这是CoC最典型的应用。比如助听器通过BLE传输音频流,就是利用CoC通道来保证稳定、低延迟的声音质量。
-
批量数据同步:传输文件、日志记录等较大块的数据时,CoC的效率要远高于GATT。
总结来说,GATT适合"查字典"式的小数据查询 ,而 CoC适合"拉专线"式的流数据传输。它们是互补的关系,各司其职。
软总线 BLE GATT 连接模块设计实现分析
总述
GATT(Generic Attribute Profile) 是软总线(dsoftbus)在 BLE(蓝牙低功耗) 场景下的核心连接协议。它负责设备发现、连接建立、数据传输等完整生命周期管理。
从架构视角看,GATT 模块处于软总线连接层的最底层,承上启下:
- 对上 :为
Connection Manager、Bus Center、Transmission等上层模块提供统一的 BLE 连接和数据传输能力 - 对下 :通过
Adapter层调用华为自研的 BLE 协议栈(HDI)接口,完成实际的蓝牙操作
一、整体架构

二、核心数据结构
2.1 BLE 连接对象(ConnBleConnection)
这是 GATT 连接的核心实体,贯穿整个连接生命周期:
typedef struct {
ListNode node; // 链表节点(用于全局管理)
BleProtocolType protocol; // 协议类型:BLE_GATT = 0
uint32_t connectionId; // 连接ID(全局唯一)
ConnSideType side; // 角色:CLIENT 或 SERVER
bool fastestConnectEnable; // 是否启用快速连接
char addr[BT_MAC_LEN]; // 蓝牙地址
uint32_t sequence; // 数据包序列号
// 接收缓冲(支持分包组包)
ConnBleReadBuffer buffer;
// 线程安全锁
SoftBusMutex lock;
// 连接状态机
enum ConnBleConnectionState state;
// 底层句柄(对应对端设备)
int32_t underlayerHandle;
// MTU 大小(默认 512)
uint32_t mtu;
// 设备标识
char udid[UDID_BUF_LEN]; // 唯一设备ID
char networkId[NETWORK_ID_BUF_LEN]; // 网络ID
// 特性集
ConnBleFeatureBitSet featureBitSet;
// 引用计数(业务计数 + 内存计数)
int32_t connectionRc;
int32_t objectRc;
} ConnBleConnection;
2.2 连接状态机(ConnBleConnectionState)
enum ConnBleConnectionState {
// 客户端专用状态
BLE_CONNECTION_STATE_CONNECTING = 0, // 初始连接中
BLE_CONNECTION_STATE_CONNECTED, // 底层已连接
BLE_CONNECTION_STATE_SERVICE_SEARCHING, // GATT 服务发现中
BLE_CONNECTION_STATE_SERVICE_SEARCHED, // 服务发现完成
BLE_CONNECTION_STATE_CONN_NOTIFICATING, // 通知特征订阅中
BLE_CONNECTION_STATE_CONN_NOTIFICATED, // 通知订阅完成
// 服务端/共用状态
BLE_CONNECTION_STATE_NET_NOTIFICATING, // 网络特征通知中
BLE_CONNECTION_STATE_NET_NOTIFICATED, // 网络特征通知完成
BLE_CONNECTION_STATE_MTU_SETTING, // MTU 协商中
BLE_CONNECTION_STATE_MTU_SETTED, // MTU 协商完成
BLE_CONNECTION_STATE_EXCHANGING_BASIC_INFO, // 交换基本信息
BLE_CONNECTION_STATE_EXCHANGED_BASIC_INFO, // 基本信息交换完成
// 结束状态
BLE_CONNECTION_STATE_NEGOTIATION_CLOSING, // 协商关闭
BLE_CONNECTION_STATE_CLOSING, // 关闭中
BLE_CONNECTION_STATE_CLOSED, // 已关闭
BLE_CONNECTION_STATE_INVALID,
};
三、核心模块设计与实现
3.1 BLE Manager(连接管理器)
职责:统一管理所有 BLE 连接,负责连接的创建、查找、释放和消息路由。
typedef struct {
SoftBusList *connections; // 所有活跃连接
ConnBleState *state; // BLE 模块状态
ListNode waitings; // 等待连接的设备队列
ConnBleDevice *connecting; // 正在连接的设备
SoftBusList *prevents; // 阻止连接的设备(防冲突)
} BleManager;
关键能力:
- 防冲突机制:防止多个模块同时对同一设备发起连接
- 连接复用:已存在的连接被新请求复用,而非重复建立
- 延迟清理:空闲超时(60秒)后才真正释放连接
3.2 GATT Client(客户端)
职责:作为 GATT Client,发起连接请求并与 GATT Server 通信。
核心 UUID 定义:
#define SOFTBUS_SERVICE_UUID "11C8B310-80E4-4276-AFC0-F81590B2177F"
#define SOFTBUS_CHARA_BLENET_UUID "00002B00-0000-1000-8000-00805F9B34FB"
#define SOFTBUS_CHARA_BLECONN_UUID "00002B01-0000-1000-8000-00805F9B34FB"
#define SOFTBUS_DESCRIPTOR_CONFIGURE_UUID "00002902-0000-1000-8000-00805F9B34FB"
客户端连接流程:

3.3 GATT Server(服务端)
职责:作为 GATT Server,发布服务并响应 Client 的读写请求。
服务状态机:
enum GattServerState {
BLE_SERVER_STATE_INITIAL = 0,
BLE_SERVER_STATE_SERVICE_ADDING, // 添加服务中
BLE_SERVER_STATE_SERVICE_ADDED, // 服务已添加
BLE_SERVER_STATE_NET_CHARACTERISTIC_ADDING, // 添加网络特征
BLE_SERVER_STATE_NET_CHARACTERISTIC_ADDED,
BLE_SERVER_STATE_NET_DISCRIPTOR_ADDING, // 添加描述符
BLE_SERVER_STATE_NET_DISCRIPTOR_ADDED,
BLE_SERVER_STATE_CONN_CHARACTERISTIC_ADDING, // 添加连接特征
BLE_SERVER_STATE_CONN_CHARACTERISTIC_ADDED,
BLE_SERVER_STATE_CONN_DISCRIPTOR_ADDING,
BLE_SERVER_STATE_CONN_DISCRIPTOR_ADDED,
BLE_SERVER_STATE_SERVICE_STARTING, // 服务启动中
BLE_SERVER_STATE_SERVICE_STARTED, // 服务已启动
// ... 停止/删除状态
};
GATT 服务结构:

两个特征值的作用:
| 特征值 | UUID | 用途 |
|---|---|---|
| NET | 0x2B00 | 网络数据传输通道 |
| CONN | 0x2B01 | 连接控制/引用计数消息 |
3.4 BLE Trans(传输层)
职责:处理分包/组包、流量控制、数据收发。
传输帧格式:
typedef struct {
uint32_t seq; // 序列号
uint32_t size; // 当前包大小
uint32_t offset; // 数据偏移
uint32_t total; // 总数据大小
} BleTransHeader;
分包组包机制:

流量控制:采用滑动窗口控制器,防止发送过快导致接收端缓冲区溢出。
四、关键流程解析
4.1 设备发现与连接建立

4.2 引用计数机制(Reference Counting)
连接采用引用计数来管理生命周期,支持连接复用和延迟释放:
// 连接建立后,初始 connectionRc = 0
// 每次业务模块使用连接时 +1,使用完毕后 -1
// 当 connectionRc = 0 且空闲超时时,连接才真正释放
int32_t ConnBleUpdateConnectionRc(
ConnBleConnection *connection,
uint16_t challengeCode, // 挑战码(用于配对)
int32_t delta // 增量:+1 或 -1
)
4.3 防冲突机制
当多个业务模块同时请求连接同一设备时:

五、模块间协作关系

六、总结
设计亮点
| 特性 | 实现方式 | 优势 |
|---|---|---|
| 状态机驱动 | 详细的状态定义和状态转换检查 | 确保连接流程正确性,避免意外状态 |
| 引用计数 | connectionRc + objectRc 双计数 |
支持连接复用,防止提前释放 |
| 防冲突队列 | waitings + prevents 双队列 |
避免多模块同时连接同一设备 |
| 分包组包 | BleTransHeader + 滑动窗口 |
支持大数据传输,保证可靠性 |
| 超时机制 | 各阶段独立超时定时器 | 快速失败,避免无限等待 |
| 快速连接 | fastestConnectEnable |
减少连接延迟 |
核心价值
GATT 连接模块是 dsoftbus 实现 BLE 近场设备间高速通信 的基石,它:
- 屏蔽了 BLE 协议的复杂性,为上层提供简洁的连接和数据传输接口
- 实现了企业级的可靠性,包括状态机校验、引用计数、超时机制
- 适配了华为自研 BLE 协议栈,通过 Adapter 层抽象了平台差异