3.3 NimBLE主机
在顶层,NimBLE协议栈被分为两个部件:
- 主机(Host),主机是一个逻辑实体,定义为非核心配置文件下方和主机控制接口(HCI)上分的所有层。
- 控制器(Controller),控制器是一个逻辑实体,定义在HCI以下的所有层。
主机和控制器的实现可以包含HCI的各个部分。
主机位于应用程序的下方,为应用程序提供所有BLE操作的接口。
3.3.1NimBLE主机返回值
NimBLE主机将通过一组返回代码向应用程序报告状态。根据蓝牙规范,主机包含几层,每层都定义了一组状态代码。Nimb主机目标在能够精确地指示到底发生了什么异常,而不仅仅是应用程序开发者可能有用的较低层“抽象化”信息。故而,host使用了一组较大的返回值。
返回值为0时表示成功,对于失败应用而言,失败值分为5个独立的集合。
集合 | 条件 |
---|---|
Core | NimBLE主机内部检测的错误 |
ATT | ATT服务器通过一个ATT错误应答传输的错误报告。返回代码对应于ATT错误响应中Error Code字段的值。 |
HCI | 控制器通过命令完成或命令状态HCI事件向Host报告错误。返回代码对应于事件中的Status字段的值。 |
L2CAP | L2CAP信令失败,发送一个L2CAP命令拒绝。返回代码与命令中的Reason字段对应。 |
安全管理(us) | 主机在安全管理过程中检测到错误,并向节点发送Pairing Failed命令。返回代码与配对失败命令中的Reason字段对应。 |
安全管理(peer) | 安全管理过程失败,节点发送了一个Pairing Failed命令。返回代码与配对失败命令中的Reason字段对应。 |
返回代码中的Core集合由NimBLE Host定义。其他集合在蓝牙规范中定义,也称为正式状态代码。由于在蓝牙规范中定义,正式状态代码集合之间并不是互斥的(即可能有相同的状态代码)。如,在规范中定义了状态码1,它就有以下一些含义:
Layer | 含义 |
---|---|
ATT | 无效句柄 |
HCI | 未知HCI命令 |
L2CAP | 信号MTU超限 |
SM | passkey入口错误 |
MTU,Maximum Transmission Unit,最大传输单元,表示在一个PDU(Protocol Data Unit,协议数据单元)中能够传输的最大数据量。
L2CAP为逻辑链路控制和适配层协议的简称,运行在HCI之上的Host,实现Host的更高层(GAP、GATT、APP)和底层协议栈传输数据。L2CAP负责在Host和协议栈之间将交换的数据进行分割和重组,以提供协议的多路处理能力。L2CAP允许更高级别的协议和应用程序发送和接收高达64KB(受限于实际蓝牙设备的内存)的上层数据包。
3.3.2GAP
通用访问配置文件(Generic Access Profile, GAP)负责所有的连接、广播、搜索和连接更新操作。
API
typedef int ble_gap_event_fn(struct ble_gap_event *event, void *arg)
int ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc)
搜索具有指定句柄的连接,如果找到匹配的连接,输出连接描述符。
返回值:
0成功,BLE_HS_ENOTCONN则表示没有找到匹配的连接。
参数:
- handle,想要搜寻的连接句柄
- out_desc,成功时将会填充匹配连接相关的信息;若不需要此信息,可以传递NULL
int ble_gap_conn_find_by_addr(const ble_addr_t *addr, struct ble_gap_conn_desc *out_desc)
通过指定地址搜索连接节点。若找到匹配的连接,输出连接描述符。
返回值:
0成功,BLE_HS_ENOTCONN则表示没有找到匹配的连接。
参数:
- addr,想要搜寻的连接节点的ble地址
- out_desc,成功时将会填充匹配连接相关的信息;若不需要此信息,可以传递NULL
3.3.3GATT客户端
通用属性配置文件(Generic Attribute Profile,GATT),管理所有涉及服务、特征和描述符的活动。
GATT客户端供GATT服务器读写应用数据。
3.3.4GATT服务器
GATT服务器,为GATT客户端提供数据服务。一个GATT服务器可以包含一个或多个GATT服务,GATT服务是完成特定功能的一系列数据的集合。
3.3.5NimBLE主机身份
NimBLE身份相关的API提供了查询和配置设备地址的功能。BLE的寻址方案相对复杂,提供了4种地址类型。参考头文件:“host/ble_hs.h”
类型 | 描述 | Identity | 配置参数 |
---|---|---|---|
Public | 制造商指定的地址,高三个字节构成了制造商的OUI | Yes | N/A;启动时从控制器读 |
Static random | 随机生成地址 | Yes | ble_hs_id_set_rnd() |
Resolvable private(RPA),可解析私有地址 | 身份地址和身份解析密钥随机生成的地址 | No | N/A;控制器周期性生成 |
Non-resolvable private(NRPA),非可解析私有地址 | 随机生成地址 | No | ble_hs_id_set_rnd() |
为了保护BLE设备的隐私,受信任的BLE设备使用共享的身份解析密钥(Identity Resolving Key,IRK)生成和解析随机的可解析私有地址,只有一台拥有另一台广播设备的IRK时,才能跟踪该广播设备的活动。
身份地址
第三列是每个地址类型的身份属性。身份地址永远不会改变,设备可以通过其唯一的身份地址之一进行标识。
只是BLE隐私的设备使用Non-identity地址。一个设备使用隐私特性,将周期性的改变地址,使用一个新生成的Non-identity地址。通过地址循环,设备将使得窃听者无法追踪它的位置。
一个设备可以一次同时拥有两个身份地址:一个公开地址和一个静态随机地址。如上表所示,公开的身份地址不可以配置,直接从控制器读取;而静态随机地址可以通过调用ble_hs_id_set_rnd()来设置。
地址类型根据每个GAP过程选择。每次初始化一个GAP过程,都要指定在这个过程期间要使用的地址类型。
3.3.6NimBLE主机ATT客户端
属性协议(Attribute Protocol,ATT)是所有BLE设备交换数据的中间层协议。当一个ATT客户端读或写一个属于ATT服务器的属性时,数据发生交换。任何需要发送或接收数据的设备都需要支持ATT协议的客户端和服务器功能。唯一不支持ATT的设备是:广播者(broadcaster)和观察者(observer),即Beacon设备和监听设备。
对于应用程序而言,大多数的ATT功能都不用关心。应用程序不直接使用ATT,一个应用程序将使用更高层的GATT配置文件,在Host中ATT的上方。NimBLE暴露了极少的没有封装到GATT功能中的ATT功能。