三 蓝牙低功耗(BLE)协议栈 之 HCI层
一 HCI介绍
HCI(主机控制器接口),是主机与控制器之间的接口,主要完成两个任务:
- 发送命令给控制器、接收来自控制器的事件
- 发送和接收来自对端设备的数据
这里所说的接口既包括两个设备之间的物理接口,也包括逻辑接口。逻辑接口定义了命令、事件和数据的封包格式。而物理接口定义了主机和控制器之前如何传输这些数据。蓝牙规范定义了4种物理接口,3线串口、4线串口、HID、SDIO。这里不做过多介绍。
二 HCI的数据格式
HCI上主要传输3种数据:
- cmd : host层发来的命令
- event : Controller回复的命令
- acl data : 发送给对端BLE的数据,双向的。
HCI层和LL层的关系
- 有些HCI Cmd只是用来设置本地Controller,不导致无线传输
- 有些HCI Cmd会导致LL层发出各类广播包,比如 LE Set Scan Enable Command 在主动扫描时会导致LL层发出SCAN_REQ广播包。比如LE Create Connection Command会导致LL层发出CONNECT_REQ广播包
- 有些HCI Cmd会导致LL层发出数据包,其中LLID==11b,表示是 LL Control PDU,比如LE Read Channel MapCommand就会导致LL层发数据包给对端,以便读取对端的信道图。
- ACL data必定会导致LL层发数据包给对端,这时的LL层数据有可能是起始包(LLID = 10b)、也可能是延迟包(LLID = 01b)、也可能是空包(LLID = 01b)
Host可以向Controller发送一系列的命令来控制Controller工作,比如广播命令,连接命令(Controller收到连接命令之后,LL层会发出一个CONNECT_REQ的广播包)
举例说明,Host向Controller发送扫描的命令。
- Host向Controller发送的命令 —— Cmd
- 设置扫描参数,主动/被动扫描
- 使能扫描
- Controller开始工作
- 被动扫描,可以获得通用的广播包
- 主动扫描,SCAN_REQ
- 对端可以返回更详细的广播包,SCAN_RSP
- Controller将扫描到的数据返回给Host —— Event
一旦控制器与其他设备建立了连接,控制器的底层HCI接口就创建了一个HCI信道,我们使用一个连接句柄来标识这个HCI信道。连接句柄即用来标示主机交给控制器并准备发送给对端设备的数据,又用来标示控制器从对端设备收到的准备发送给主机的数据。
2.1 命令
在低功耗蓝牙中一共有三种基本命令类型:
- 配置控制器的状态
- 请求执行特定的操作
- 管理连接
cmd的数据格式:
详见 《Core_v5.1》 Vol 2 -> Part E -> 5 Hci data formats
1 配置控制器状态
我们可以将控制器视为一个大状态机,有一系列的参数可以进行配置。例如,将广播看成一个状态,那么我们可以通过如下命令进行配置:LE Set Advertising Parameters、LE Set Advertising Data、LE Set Scan Response Data和LE Set Advertising Enable。
在低功耗蓝牙中,如果状态机里的某个状态正在被使用,通常是不能对其进行调整的。就好像如果启动了广播就不能再改变广播参数。这个时候,我们需要先停止广播,修改广播参数,然后重新进行广播。
2 请求指定操作
一些命令可以请求控制器执行指定操作,但不会改变设备状态或者连接状态。例如,LE Encrypt命令想控制器输入**和文本并要求其生成加密数据。
3 管理连接
设备建立连接之后,可以通过发送命令来管理连接,比如用LE Read Channel Map命令来获取当前连接的自适应跳频信道图。注意,这类命令均包含连接句柄。
2.2 事件
Event的数据格式:
地功耗蓝牙主要有下列三种基本事件类型:
- 通用命令完成事件
- 通用命令状态事件
- 特定命令完成事件
1 通用命令完成事件
当主机发送给控制器的命令执行完毕时,控制器立即返回一个通用命令完成事件。事件的参数包含了之前发送命令操作码和执行命令的返回参数。返回参数中的第一个参数是状态码,状态码用来表示命令执行成功与否。
例如,LE Rand用来命令控制器返回一个随机数。它有两个返回参数,一个是状态码,另一个是返回的随机数。
注意,每当控制器执行与无线传输无关的任务时,都将使用通用命令完成事件。例如,LE Encrypt命令不涉及链路层数据包传输,因此将返回一个通用命令完成事件。而LE Create Connection命令需要在连接建立之前至少发送一个链路层连接请求数据包(CONNECT_REQ),因此不会返回通用命令完成事件。
2 通用命令状态事件
上节提及的LE Create Connection等命令类型需要执行无线传输操作,通常返回的是通用命令状态事件;一段时间后才会返回特定命令完成事件。
3 特定命令完成事件
有些命令需要一段时间才能完成执行,他们都有对应的、并且唯一的特定命令完成事件。例如,LE Create Connection命令首先返回一个命令状态事件,随后等待连接建立完成或者失败,再返回LE Connection Complete事件。需要注意的是,命令是否执行完毕并不以收到特定命令完成事件作为标志。
2.3 数据包
acl data的数据格式:
数据包是指主机和控制器之间传输的应用数据。控制器接收来自主机的数据包,将其传给对端设备。对端设备收到数据之后,将其从控制器发往主机。
数据包总是以连接句柄(Access address )作为第一个字段(12位),如果主机没有收到LE Connection Complete事件,则不能发送任何数据给对端设备;只有收到了该事件,主机才可以启动数据发送或者接收对端设备发送过来的数据。
host层想用更少的位来表示Access Address,Controller用12位的Handle用来表示Access address,PB Flag表示这个包是起始包(00b)还是延续包(01b),BC Flag对于BLE该值永远为0,接下来是数据长度。