BLE应用层

低功耗蓝牙(Bluetooth Low Energy,BLE)分为三个部分组成。应用(Application)+主机(Host)+控制器(Controller)。单模BLE设备的应用层包含:

  • 通用访问配置文件 Generic Access Profile(GAP)
  • 通用属性配置文件 Generic Attribute Profile(GATT)
  • 逻辑链路控制和适配协议 Logical Link Control and Adaption Protocol (L2CAP)
  • 属性协议 Attribute Protocol(ATT)
  • 安全管理 Security Manager(SM)
  • 主机控制器接口 Host Controller Interface(HCI)

通用属性配置文件(Generic Attribute Profile,GATT)建立在属性协议(Attribute Protocol,ATT)之上,通过在其上层引入层级化的数据组织结构和抽象模型,实现了对BLE数据的统一建模与访问控制。在BLE协议体系中,GATT可视为应用层数据交互的核心框架,其定义了数据在不同设备应用之间的组织方式及交换机制。GATT定义了一组通用的数据对象,可被各类基于GATT的应用配置文件复用。其继承了ATT所采用的客户端–服务器(Client–Server)架构,但通过引入“服务(Service)”这一逻辑容器,对数据进行了更高层次的封装。每个服务由一个或多个特征(Characteristic)组成。特征用于描述具体的用户数据单元,其不仅包含实际数据值(Value),还可关联多种元数据(Metadata),例如访问权限、用户可读名称、单位、描述符等,从而为数据的发现、访问和解释提供支持。

通用访问配置文件(Generic Access Profile,GAP)定义了设备在BLE协议栈中进行连接和控制交互的行为规范。GAP被视为BLE的顶层控制模型,描述了设备在不直接涉及具体数据内容的情况下,如何完成设备发现、连接建立、安全机制协商以及角色管理等流程,以确保不同厂商设备之间的互操作性。为实现设备间一致且可互操作的通信行为,GAP进一步规范了以下内容:

  • 设备角色及其交互关系
  • 设备可发现性与可连接性模型及其状态转换
  • 建立可靠通信所需的控制流程
  • 安全模式、安全级别及相关流程
  • 用于广播和扫描的非协议数据(如Advertising Data)的格式定义

“蓝牙连接”分为广播(broadcasting)或者连接(connections)

广播(broadcasting)

在BLE中,广播机制定义了两种相互独立的角色:广播者(Broadcaster)和观察者(Observer)。广播者负责在预定义的广播信道上周期性地发送不可连接的广播数据(Advertising Data),这些数据可被任意处于监听状态的设备接收。广播过程中,广播者不与接收设备建立连接关系。观察者则持续扫描指定的广播信道,以接收当前正在广播的、不可连接的广播数据包。观察者仅被动接收信息,不参与任何连接或数据确认过程。

广播机制在BLE体系中具有重要意义,因为它是BLE中唯一一种支持单个设备在同一时间向多个设备分发数据的通信方式。该机制充分利用了BLE的低功耗和无连接特性,适用于向周围设备周期性发布状态信息或少量数据的场景。

标准BLE广播数据包包含最多31字节的有效负载(Payload),用于承载描述广播发送者身份、能力以及服务信息的数据,同时也可包含用户自定义的广播内容。当该负载空间不足以容纳所需信息时,BLE允许使用可选的扫描响应数据(Scan Response)。在此机制下,观察设备在接收到广播数据后,可向广播者发送扫描请求,从而获取额外的31字节扫描响应负载,使单次广播相关的数据总量达到62字节。

由于广播方式具有实现简单、延迟低且支持多设备同时接收的特点,当需要按照固定周期推送少量数据,或向多个设备发布公共信息时,广播是一种高效且实用的选择。然而,与基于连接的通信方式相比,广播机制存在显著的安全与隐私局限性。广播数据在未加密的情况下发送,任何处于监听状态的观察设备均可接收并解析广播内容。因此,该方式通常不适用于传输敏感或私密数据。

连接(connections)

当需要在设备之间进行双向数据传输,或所需传输的数据量超过广播与扫描响应所能承载的容量时,应采用基于连接(Connection)的通信方式。BLE连接是一种在两个设备之间建立的持续通信关系,连接建立后,设备双方在约定的时间点周期性地交换数据。与广播相比,连接通信具有天然的隐私性,其数据仅在连接的两端设备之间传输,不会被其他设备接收,除非第三方设备通过非正常手段对无线信道进行嗅探。

BLE连接模型中定义了两种通信角色:中心设备(Central)与外围设备(Peripheral)。中心设备通过周期性扫描广播信道,以发现可连接的广播数据包。当检测到符合条件的广播后,中心设备发起连接请求并建立连接。连接建立后,中心设备负责控制连接时序(Timing),并调度周期性的数据交换过程。外围设备则以周期性发送可连接的广播数据包为主要行为,并在接收到连接请求后接受并进入连接状态。在连接建立后,外围设备需遵循中心设备所控制的连接时序,在预定的连接事件(Connection Event)中与中心设备进行数据交换。

需要注意的是,尽管中心设备负责连接的建立与时序控制,但在每一个连接事件中,数据的发送方向是双向对等的。中心设备与外围设备在数据吞吐量和访问优先级方面并不存在协议层面的强制限制。自蓝牙4.1版本起,BLE规范取消了对角色组合方式的限制,允许设备在同一时间承担多种角色。具体而言:

  • 单个设备可以同时作为中心设备和外围设备
  • 一个中心设备可以同时与多个外围设备建立连接
  • 一个外围设备也可以同时与多个中心设备建立连接

相较于早期规范中对外围设备只能连接单一中心设备的限制,上述改动显著增强了BLE网络拓扑的灵活性。连接通信的最大优势在于其支持通过更高层协议对数据进行精细化组织和访问控制。BLE通过在连接之上引入通用属性配置文件(Generic Attribute Profile,GATT),将数据组织为服务(Service)和特征(Characteristic)等逻辑单元。服务可包含多个特征,每个特征均具备独立的访问权限及描述性元数据,从而构建出结构清晰、可扩展的数据模型。

此外,基于连接的通信方式还具备更高的数据吞吐能力、支持安全加密链路的建立,并允许在连接建立过程中协商连接参数,以优化数据传输效率与功耗表现。在功耗方面,连接通信在某些场景下甚至可能优于广播方式。由于通信双方可预先确定连接事件的时间点,无线模块可在非通信时段进入休眠状态,从而降低整体能耗。相比之下,广播方式需要持续在固定频率下发送完整负载,且不区分是否存在接收设备,这在数据量较大或通信频率较高的情况下可能导致额外的能耗开销。


通用访问配置文件(GAP)

GAP是BLE设备实现互操作性的基础框架。GAP为所有BLE实现定义了一套统一的行为规范,要求设备能够以标准化的方式完成设备发现、广播数据、建立连接、协商安全机制以及执行其他基础控制操作。对GAP的深入理解至关重要,因为在许多BLE协议栈实现中,GAP通常被作为向上层应用暴露的最底层功能接口之一,为应用开发者提供设备控制和连接管理能力。

BLE核心规范中,GAP主要从以下几个方面定义了设备之间的交互行为:

  • 角色(Roles)每个BLE设备可以同时承担一个或多个角色。不同角色对设备行为施加特定的约束,并规定了设备在交互过程中的强制行为要求。某些角色组合允许设备之间建立通信关系,而GAP则精确定义了这些角色之间的交互方式。尽管并非绝对如此,角色通常与特定类型的设备或应用场景相关联。在大多数实际实现中,设备角色往往在其生命周期内保持稳定,并不会频繁发生变化。
  • 模式(Modes)模式是在角色之上的进一步抽象,用于描述设备在特定时间段内为实现某一目标而进入的运行状态。模式通常对应某一具体流程的执行条件,用以允许或限制设备在该阶段的行为。模式的切换既可由用户操作触发,也可由协议栈根据运行需要自动触发,其发生频率通常高于角色的切换。
  • 流程(Procedures)流程是指设备为达成特定目标而执行的一系列操作步骤,通常涉及链路层控制或必要的数据交换。一个流程往往依赖于对端设备处于特定模式之中,因此流程与模式在实际交互中通常紧密关联、协同执行。
  • 安全性(Security)GAP在底层安全管理协议之上,通过定义安全模式和安全等级,规定了设备在不同数据交换需求下应采用的安全策略,并描述了这些安全等级的建立与强制执行流程。此外,GAP还定义了一些不依赖于特定模式或流程的通用安全特性,使设备能够根据具体应用需求灵活提升数据保护级别。
  • GAP相关数据格式。为支持设备发现和控制流程,GAP定义了用于广播和扫描的附加数据格式,用以描述设备的基本属性、能力以及服务信息,从而确保设备之间能够以统一且可互操作的方式完成初始交互。

属性配置文件(GATT)

通用属性配置文件(Generic Attribute Profile,GATT)定义了如何在蓝牙低功耗(BLE)连接之上交换应用数据和用户数据。与负责设备发现、连接建立及控制行为的通用访问配置文件(GAP)不同,GATT专注于实际数据的组织方式、访问规则以及数据交换流程。

GATT同时为基于GATT的各类标准配置文件提供了统一的参考框架。这些配置文件由蓝牙SIG定义,用于覆盖特定的应用场景,并确保来自不同厂商的设备能够实现互操作性。所有标准的BLE应用配置文件均建立在GATT之上,并必须遵循其定义的数据模型和操作规则。因此,GATT构成了BLE规范中至关重要的组成部分,所有面向应用和用户的数据项都必须依据GATT的规则进行格式化、封装并传输。

GATT通过属性协议(Attribute Protocol,ATT)作为底层传输机制,实现设备之间的数据交换。数据在逻辑上按照层级结构进行组织,其中一组相关属性被封装为服务(Service),而服务中与具体用户数据语义相关的最小功能单元被定义为特征(Characteristic)。这一数据组织方式构成了GATT的基本结构模型。

GATT角色(Roles)

与蓝牙规范中其他协议和配置文件一致,GATT通过定义参与通信的角色来描述设备间的交互方式。

  • 客户端(Client)GATT客户端与属性协议(ATT)中的客户端角色相对应。客户端负责向服务器发送请求并接收响应,包括读取、写入属性值以及接收由服务器发起的属性更新。初始状态下,GATT客户端并不了解服务器端所包含的属性结构,因此必须首先执行服务发现(Service Discovery)流程,以获取服务器上可用服务及其特征的相关信息。完成服务发现后,客户端即可对已发现服务中的属性进行访问,并接收来自服务器的通知或指示。
  • 服务器(Server)GATT服务器对应于ATT中的服务器角色,负责接收来自客户端的请求并返回相应的响应。在特定配置下,服务器还可以主动向客户端发送属性更新。作为服务器角色,设备需要负责存储和组织用户数据,并以属性的形式向客户端提供访问接口。所有已投入使用的BLE设备至少必须包含一个基本的GATT服务器,以便能够响应客户端请求,即便该响应仅为错误返回。

需要强调的是,GATT角色与GAP角色之间不存在依赖关系。GATT客户端或服务器角色可以与任意GAP角色组合使用。因此,GAP中的中心设备或外围设备既可以作为GATT客户端,也可以作为GATT服务器,甚至在同一设备中同时承担两种GATT角色。

UUID(Universally Unique Identifier)

通用唯一标识符(Universally Unique Identifier,UUID)是一种128位(16字节)的标识符,用于在全球范围内唯一标识对象。UUID并非蓝牙专有,其格式、生成方式和使用规则由ITU-T Rec. X.667(亦即 ISO/IEC 9834-8:2005)进行规范。

由于完整的128位UUID在BLE链路层中会占用较大的数据负载空间,BLE规范引入了两种压缩形式的UUID:16位UUID和32位UUID。这些缩短形式仅适用于由蓝牙SIG定义和分配的标准UUID,用于标识标准服务、特征及相关类型。缩短形式的UUID可通过嵌入至蓝牙基础UUID(Bluetooth Base UUID)中恢复为完整的128位UUID,其格式如下:

xxxxxxxx-0000-1000-8000-00805F9B34FB

其中,xxxxxxxx表示16位或32位的SIG分配值(高位补零)。

蓝牙SIG为所有标准服务、特征及其定义的配置文件分配了对应的UUID。当应用需求无法由现有标准UUID满足,或需要实现规范之外的自定义功能时,可生成厂商自定义(Vendor-Specific)的UUID。此类UUID必须使用完整的128位形式,并通常通过ITU所规定的UUID生成机制生成。对于不基于蓝牙基础UUID的厂商自定义UUID,不允许使用16位或32位的缩短形式,必须在整个协议交互过程中始终使用完整的128位UUID。


启动一个广播服务

// golang

import (
    "github.com/muka/go-bluetooth/api"
    "github.com/muka/go-bluetooth/bluez/profile/adapter"
)

func main() {
    a, err := adapter.GetDefaultAdapter()
    if err != nil {
        panic(err)
    }

    a.SetPowered(true)
    a.SetDiscoverable(true)
    a.SetAlias("My-BLE-Device")

    select {}
}