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

  1. typedef int ble_gap_event_fn(struct ble_gap_event *event, void *arg)
  1. int ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc)

搜索具有指定句柄的连接,如果找到匹配的连接,输出连接描述符。

返回值:

0成功,BLE_HS_ENOTCONN则表示没有找到匹配的连接。

参数:

  • handle,想要搜寻的连接句柄
  • out_desc,成功时将会填充匹配连接相关的信息;若不需要此信息,可以传递NULL
  1. 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功能。