连接模块中的BLE方式GATT协议分析

连接模块中的BLE方式GATT协议分析
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 的关键区别特性GATTCOC (L2CAP)传输可靠性基于 ATT 协议基于 L2CAP 面向连接通道数据格式必须符合 GATT Profile更灵活的字节流适用场景设备发现、服务读写高可靠性的字节流传输MTU较小默认 512可更大实现复杂度较复杂较简单 “管道”内部是怎么工作的这条“管道”有几个很实用的设计容量更大 (MTU更大)相比于GATTCoC的“管道”一次能承载更大的数据包最高可支持到512字节传输效率更高。自带调节阀 (基于信用的流量控制)为了防止“管道”里的数据太多把接收方冲垮CoC采用了一种“信用”机制。发送方只有收到接收方给的“信用”才能发送数据从而实现了流控确保传输的可靠性。独立“阀门” (PSM)要连接到不同的CoC“管道”需要知道一个叫PSM (协议/服务复用器)的“阀门编号”作为服务识别码。这就像GATT里用UUID来找到特定服务一样但层级更底层。 什么时候用CoC正因为CoC高效且可靠它在很多对实时性和数据传输量要求较高的场景里非常适用音频传输这是CoC最典型的应用。比如助听器通过BLE传输音频流就是利用CoC通道来保证稳定、低延迟的声音质量。批量数据同步传输文件、日志记录等较大块的数据时CoC的效率要远高于GATT。总结来说GATT适合“查字典”式的小数据查询而CoC适合“拉专线”式的流数据传输。它们是互补的关系各司其职。软总线 BLE GATT 连接模块设计实现分析总述GATTGeneric 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 连接状态机ConnBleConnectionStateenum 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用途NET0x2B00网络数据传输通道CONN0x2B01连接控制/引用计数消息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 防冲突机制当多个业务模块同时请求连接同一设备时五、模块间协作关系六、总结设计亮点特性实现方式优势状态机驱动详细的状态定义和状态转换检查确保连接流程正确性避免意外状态引用计数connectionRcobjectRc双计数支持连接复用防止提前释放防冲突队列waitingsprevents双队列避免多模块同时连接同一设备分包组包BleTransHeader 滑动窗口支持大数据传输保证可靠性超时机制各阶段独立超时定时器快速失败避免无限等待快速连接fastestConnectEnable减少连接延迟核心价值GATT 连接模块是 dsoftbus 实现BLE 近场设备间高速通信的基石它屏蔽了 BLE 协议的复杂性为上层提供简洁的连接和数据传输接口实现了企业级的可靠性包括状态机校验、引用计数、超时机制适配了华为自研 BLE 协议栈通过 Adapter 层抽象了平台差异