蓝牙是一种短距离通信系统,蓝牙系统分为两种不同的技术:经典蓝牙(Classic Bluetooth)和蓝牙低功耗(Bluetooth Low Energy)。
从整体结构上,蓝牙可分为控制器(Controller)和主机(Host)两大部分;
ESP32应用的三种场景:
场景一(ESP-IDF默认):在 ESP32 的系统上,选择 BLUEDROID 为蓝⽛牙主机,并通过 VHCI(软件实现的虚拟 HCI 接⼝口)接⼝口,访问控制器器。
场景⼆:在 ESP32 上运⾏控制器器(此时设备将单纯作为蓝⽛控制器使⽤),外接⼀个运⾏蓝⽛主机的设备(如运⾏ BlueZ 的 Linux PC、运⾏BLUEDROID 的 Android等)。
场景三:此场景与场景二类似,特别之处在于,在 BQB(或其它认证)的控制器测试下,可以将 ESP32 作为 DUT,用 UART 作为 IO 接口,接上认证测试的 PC 机,即可完成认证。
HCI接口选择
ESP32 上,HCI 只能同时使⽤用⼀个 IO 接口,即如使用 UART,则放弃 VHCI、 SDIO 等其他 IO 接口。在 ESP-IDF(V2.1 以后)中,可以在 menuconfig 中将蓝牙的 HCI IO 接口方式配置为 VHCI 或 UART。
蓝牙运行环境
ESP-IDF的默认运行环境为双核FreeRTOS,ESP32的蓝牙可按照功能分为多个任务(task)运行,不同任务的优先级也有不同,其中优先级最高的为运行控制器的任务。控制器任务对实时性的要求较高,在FreeRTOS系统中的优先级仅次于IPC任务(IPC任务用于双核CPU的进程通信)。BLUEDROID(ESP-IDF默认蓝牙主机)共包含4个任务,分别运行BTC、BTU、HCI UPWARD以及HCI DOWNWARD。
控制器
ESP32 的控制器同时⽀支持 Classic BT 和 BLE,支持的蓝牙版本为 4.2。控制器器中主要集成了 H4 协议、 HCI、 Link Manager、 Link Controller、 Device Manager、 HW Interface 等功能。这些功能都以库的形式提供给开发者,并做了一些 API 用来访问控制器。
主机架构
在 ESP-IDF 中,使用经过大量修改后的 BLUEDROID 作为蓝牙主机 (Classic BT + BLE)。
BLUEDROID内部大致分为2层:BTU层和BTC层(除去HCI);BTU层主要负责蓝牙主机底层协议栈的处理,包括L2CAP、GATT/ATT、SMP、GAP以及部分规范等,并向上提供以“bta”为前缀的接口;BTC层主要负责向应用层提供接口支持、处理给予GATT的规范、处理杂项等,并向应用层提供以“esp”为前缀的接口。所有的API都在ESP_API层,开发者应当使用“esp”为前缀的蓝牙API(特殊的除外)。
OS相关适配
蓝牙目录
经典蓝牙
主机协议栈支持的经典蓝牙协议规范和协议如下:
协议和规范
L2CAP信道共支持6种模式:基本L2CAP模式、流量控制模式、重传模式、加强重传模式、流模式、基于LE Credit的流量控制模式
允许应用程序发现其他对等蓝牙设备提供的服务,并确定可用服务的特征。
可提供有关设备可发现性、可连接性和安全性的模式和过程描述。
蓝牙低功耗(BLE)
GAP协议层定义了 BLE 设备的发现流程,设备管理理和设备连接的建立。
BLE设备角色转换状态图
BLE广播流程
使用public地址进行广播时,需要将esp_ble_adv_params_t成员own_addr_type设置为BLE_ADDR_TYPE_PUBLIC。
使用可解析地址进行广播时,底层协议栈会15分钟更新一次广播地址,需要将esp_ble_adv_params_t成员own_addr_type设置为BLE_ADDR_TYPE_RANDOM。
与可解析地址进行广播一样,使用静态随机地址进行广播也需要将esp_ble_adv_params_t成员own_addr_type设置为BLE_ADDR_TYPE_RANDOM。
BLE广播类型介绍
BLE广播过滤策略介绍
BLE扫描流程
BLE GAP实现机制
ESP32 的 BLE 通用访问规范 (GAP) 采用调用 BLE gap API 相关的 API 和注册 BLE gap callback 并通过事件 (event) 返回来获取当前设备状态。
GATT
BLE 里面的数据以属性 (Attribute) 方式存在,每条属性由四个元素组成:
属性句柄 (Attribute Handle)、属性类型 (Attribute UUID)、属性值 (Attribute Value)、属性许可 (Attribute Permissions)
我们把存有数据(即属性)的设备叫做服务器 (Server),而将获取别人设备数据的设备叫做客户端 (Client)。
服务器和客户端之间的交互操作都是通过上述的消息 ATT PDU 实现的。每个设备可以指定自己设备支持的最大 ATT 消息长度,我们称之为 MTU。 ESP32 IDF 里面规定 MTU 可以设置的范围是 23~517 字节,对属性值的总⻓长度没有做限制。
基于ESP32 IDF建立GATT服务(GATT服务器)
esp_gatts_attr_db_t定义如下:
基于ESP32 IDF发现对方设备的服务信息(GATT客户端)
SMP(安全管理协议)