设备文件服务器硬件配置

文件服务器硬件配置  时间:2021-01-13  阅读:()

前言本文档的主要目的是为开发人员提供有关如何使用BlueNRG-1、BlueNRG-2BLE栈v2.
x系列API和相关事件回调开发低功耗蓝牙(BLE)应用的一些参考编程指南.
本文档介绍了允许访问BlueNRG-1、BlueNRG-2片上系统所提供的低功耗蓝牙功能的BlueNRG-1、BlueNRG-2低功耗蓝牙栈库框架、API接口和事件回调.
本编程手册还提供一些与低功耗蓝牙(BLE)技术有关的基本概念,以便将BlueNRG-1、BlueNRG-2BLE栈API、参数及相关事件回调与BLE协议栈特性联系起来.
用户必须具备有关BLE技术及其主要功能的基本知识.
有关BlueNRG-1、BlueNRG-2设备和低功耗蓝牙规范的更多信息,请参考本文档末尾的第5节参考.
BlueNRG-1和BlueNRG-2是超低功耗蓝牙(BLE)单模片上系统,这些系统符合低功耗蓝牙规范并支持主从角色,BlueNRG-2还支持扩展数据包长度功能.
手册结构如下:低功耗蓝牙(BLE)技术的基本原理BlueNRG-1、BlueNRG-2BLE栈v2.
x库API和事件回调概述如何使用BlueNRG-1、BlueNRG-2栈v2.
x库API和事件回调设计应用提示本文内容适用于BlueNRG-1和BlueNRG-2设备.
任何对BlueNRG-1设备的参考文档也同时适用于BlueNRG-2设备.
必要时,会着重标明具体的区别.
BlueNRG-1、BlueNRG-2BLE栈v2.
x编程指南根据保密协议–不可复制PM0257PM0257-Rev3-May2019更多垂询,请联系您本地的意法半导体销售处www.
st.
com1低功耗蓝牙技术低功耗蓝牙(BLE)无线技术由蓝牙技术联盟(SIG)开发,目的是使设备能够以极低功耗标准使用纽扣电池工作数年.
传统蓝牙作为一种无线技术标准,可以取代连接便携式和/或固定式电子设备的线缆,但是由于采取了快速跳频、以连接为导向的行为方式和相对复杂的连接流程,无法采用电池供电的方式.

低功耗蓝牙设备的功耗仅为标准蓝牙产品的一小部分,让使用纽扣电池的设备能够无线连接到启用了标准蓝牙的设备.
图1.
支持低功耗蓝牙技术的以钮扣电池供电的设备低功耗蓝牙技术广泛应用于传输少量数据的传感器应用中.
汽车电子运动与健身医疗娱乐家庭自动化安全和接近感测1.
1BLE堆栈架构低功耗蓝牙技术已被蓝牙核心规范4.
0正式采纳(参见第5节参考).
该版本的蓝牙标准支持两种无线技术系统:基础速率(BR)低功耗蓝牙(BLE)低功耗蓝牙技术工作在工业、科学和医疗(ISM)频段2.
4~2.
485GHz,可以在全球许多国家使用而无需官方授权.
它使用扩频、跳频、全双工信号.
低功耗蓝牙技术的关键特性:稳健性性能可靠性互操作性低数据速率低功耗另外,低功耗蓝牙技术的目的是为了实现在传输极小数据包的同时,其功耗显著低于基础速率(BR)、增强数据率(EBR)以及高速设备(HS).
蓝牙低能耗技术旨在解决两种替代方案:根据保密协议–不可复制PM0257低功耗蓝牙技术PM0257-Rev3page2/76智能设备(Smartdevice)智能就绪设备(Smartreadydevice)智能设备仅支持BLE标准.
它适用于低功耗并使用纽扣电池供电的应用(例如传感器).
智能就绪设备支持BR/EDR/HS和BLE标准(通常为移动设备或笔记本电脑).
低功耗蓝牙协议栈有两个组成部分:控制器(Controller)主机(Host)控制器包含物理层和链路层.
主机包括逻辑链路控制和适配协议(L2CAP)、安全管理器(SM)、属性协议(ATT)、通用属性配置文件(GATT)和通用访问配置文件(GAP).
两个组成部分之间的接口被称为主机控制器接口(HCI).

此外,已发布的蓝牙规范v4.
1、v4.
2和5.
0具备以下新特性:关于这些新特性的更多信息,请参考相关规范文档.
根据保密协议–不可复制PM0257BLE堆栈架构PM0257-Rev3page3/76图2.
低功耗蓝牙栈架构GAMSEC201411251124主机控制器接口链路层物理层根据保密协议–不可复制PM0257BLE堆栈架构PM0257-Rev3page4/761.
2物理层物理层用来接收和发射1Mbps自适应跳频射频信号,采用高斯频移键控(GFSK)技术.
它在无需执照的2.
4GHzISM波段中以2400-2483.
5MHz的频率工作.
许多其他标准也使用该波段,例如:IEEE802.
11,IEEE802.
15.
BLE系统使用40射频通道(0-39),2MHz间隔.
这些射频通道的频率中心为:240+k*2MHz,werek=0.
39(1)有两种类型的通道:1.
广告通道,使用三个固定的射频通道(37、38和39)用于:a.
广告通道数据包b.
用于发现/连接的数据包c.
广播/扫描2.
数据物理通道使用其他37个射频通道进行已连接设备的双向通信.
表1.
BLERF通道类型和频率通道索引射频中心频率通道类型372402MHz广告通道02404MHz数据通道12406MHz数据通道……数据通道102424MHz数据通道382426MHz广告通道112428MHz数据通道122430MHz数据通道……数据通道362478MHz数据通道392480MHz广告通道BLE是一种自适应跳频(AFH)技术,只能使用所有可用频率的一个子集,以避开其他非自适应技术使用的所有频率.
通过使用特定的跳频算法确定下一个要使用的良好通道,可以从不良通道转移到已知良好通道.

根据保密协议–不可复制PM0257物理层PM0257-Rev3page5/761.
3链路层(LL)链路层(LL)定义了两个设备使用射频信号在彼此之间传递信息的方式.
链路层定义了具有五种状态的状态机:图3.
链路层状态机GAMSEC201411251131连接启动待机广告扫描待机:设备不发送或接收数据包广告:设备在广告通道中广播广告(称为广告设备).
扫描:设备寻找广告设备(称为扫描设备)发起:设备发起与广告设备的连接连接:发起设备为主设备,与从设备进行通讯并定义通讯的方式和时序.
广告设备是从设备,只能和单个主设备进行通讯.
根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page6/761.
3.
1BLE数据包数据包是带标签的数据,由一个设备发送并由一个或多个其他设备接收.

BLE数据包的结构如下.
根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page7/76图4.
数据包结构8328824访问地址包头长度0-296(37字节)位根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page8/76蓝牙低功耗BLE规范v4.
2定义了LE数据包长度扩展功能,它将LE链路层PDU的数据有效负载从27字节扩展到251字节.
根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page9/76图5.
LE数据包长度扩展功能的数据包结构832880(8*255)24前导码访问地址包头长度-位根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page10/76长度字段的范围为0到255字节.
使用加密时,数据包末尾的消息完整性代码(MIC)为4字节,从而导致实际最大可用有效数据长度为251字节.
前导码:射频同步序列访问地址:32位,广告或数据访问地址(用于识别物理层通道上的通信数据包)包头:其内容取决于数据包类型(广告或数据包)广告数据包包头:表2.
广告数据头内容广告数据包类型保留发送地址类型接收地址类型(4位)(2位)(1位)(1位)广告数据包类型定义如下:表3.
广告数据包类型数据包类型说明注释ADV_IND可连接非定向广告由广告方在需要另一台设备与之连接时使用.
设备可被扫描设备扫描到,或者在收到连接请求时作为从设备建立连接.
ADV_DIRECT_IND可连接定向广告由广告方在需要特定设备与之连接时使用.
ADV_DIRECT_IND数据包仅包含广告方地址和发起方地址.
ADV_NONCONN_IND不可连接非定向广告由广告方在需要向所有设备提供某些信息,但是不希望其他设备向其请求更多信息或与之连接时使用.
设备只在相关通道上发送广告数据包,但不希望任何其他设备与之连接或扫描到它.

ADV_SCAN_IND可扫描非定向广告由希望允许扫描设备请求更多信息的广告方使用.
设备不能连接,但是对于广告数据和扫描响应数据而言可发现.
SCAN_REQ扫描请求由处于扫描状态的设备用于向广告方请求更多信息.
SCAN_RSP扫描响应由广告设备用于向扫描设备提供更多信息.
CONNECT_REQ连接请求由发起设备发送给处于可连接/可发现模式的设备.
广告事件类型决定了允许的响应:表4.
广告事件类型和允许的响应广告事件类型是否允许响应SCAN_REQCONNECT_REQADV_IND是是ADV_DIRECT_IND否是ADV_NONCONN_IND否否ADV_SCAN_IND是否数据包包头:根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page11/76表5.
数据包包头内容链路层标识符下一个序号序号更多数据保留(2位)(1位)(1位)(1位)(3位)下一个序号(NESN)位用于执行数据包确认.
它将发送设备预期将发送的下一个序号通知接收设备.
将重新发送数据包,直至NESN不同于所发送数据包中的序号(SN)值.
更多数据位用于向设备发送信号,表明在当前连接事件期间发送设备有更多数据准备发送.

关于广告和数据头内容及类型的详细描述,请参考第5节参考中的蓝牙规范[第2卷].
长度:数据字段中的字节数表6.
数据包长度字段和有效值长度字段位数广告数据包6位,有效值为0至37字节数据包5位,有效值为0至31字节8位,有效值为0到255字节,支持LE数据包长度扩展数据或载荷:实际发送的数据(广告数据、扫描响应数据、连接建立数据或连接期间发送的应用数据)CRC(24位):用于保护数据,避免发生位错误.
它通过包头、长度和数据字段计算得出1.
3.
2广告状态广告状态允许链路层发送广告数据包,并对正在执行扫描的设备发出的扫描请求作出扫描响应.

可通过停止广告使广告设备进入待机状态.
设备每次进行广告时,通过三个广告通道发送相同数据包.
此三个数据包序列称为一个广告事件.
两个广告事件之间的时间被称为广告间隔,长度从20毫秒到10.
24秒不等.
广告数据包的示例列出了设备实现的服务UUID(一般可发现标记,发送功率=4dbm,服务数据=温度服务和16位服务UUID).
图6.
具有AD类型标记的广告数据包PreambleAdvertisingAccessAddressAdvertisingHeaderPayloadLengthAdvertisingAddressFlags-LEGeneralDiscoverableFlagTXPowerLevel=4dBmServiceData"Temperature"o=20.
.
5C16bitserviceUUIDs="Temperatureservice"CRCGAMSEC201411251139AD类型标记字节(Flags)包含以下标记位:有限可发现模式(第0位)一般可发现模式(第1位)不支持BR/EDR(第2位,在BLE上为1)可同时以LE和BR/EDR连接到同一设备(控制器)(第3位)可同时以LE和BR/EDR连接到同一设备(主机)(第4位)如果任意位为非零,则在广告数据中包含AD类型标记(不包括在扫描响应中).
在启用广告之前,可设置下列广告参数:根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page12/76广告间隔广告地址类型广告设备地址广告通道映射:应使用三个广告通道中的哪一个广告过滤策略:–处理来自白名单中的设备的扫描/连接请求–处理所有扫描/连接请求(默认的广告方过滤策略)–处理来自所有设备的连接请求,但仅处理来自白名单中的设备的扫描请求–处理来自所有设备的扫描请求,但仅处理来自白名单中的设备的连接请求白名单是设备控制器用于过滤设备的已保存设备地址列表.
当白名单正在使用时,不能修改其内容.
如果设备处于广告状态且正在使用白名单过滤设备(扫描请求或连接请求),必须禁用广告模式才能修改其白名单.

1.
3.
3扫描状态有两种类型的扫描:被动扫描:允许接收来自广告设备的广告数据主动扫描:在接收到广告数据包时,设备可以发回扫描请求数据包,以便得到广告方的扫描响应.
这使扫描设备能够获取来自广告设备的额外信息.
可以设置下列扫描参数:扫描类型(被动或主动)扫描间隔:控制器的扫描频率扫描窗口:对于每个扫描间隔而言,它定义了设备扫描的持续时间扫描过滤策略:它可以接受所有广告数据包(默认策略)或仅接受来自白名单设备的广告数据包.

在设置扫描参数后,可以启用设备扫描.
扫描设备的控制器向上层发送任何在广告报告事件中接收的广告数据包.

该事件包含该广告数据包的广告方地址、广告方数据和接收信号强度指示(RSSI).
可将RSSI与广告数据包中包含的发送功率水平信息一起使用,以确定信号的路径损耗和设备距离:路径损耗=发送功率–RSSI1.
3.
4连接状态当待发送数据的复杂度超过广告数据允许的水平,或者需要在两个设备之间建立双向可靠通信时,建立连接.

当发起设备接收到它要连接的广告设备发出的广告数据包时,它可以向广告设备发送连接请求数据包.
该数据包包含建立和处理两个设备之间的连接所需的所有必要信息:用于识别已建立连接的物理链路层通讯的访问地址.
CRC初始值发送窗口大小(第一个数据包的时序窗口)发送窗口偏移(发送窗口起点)连接间隔(两个连接事件之间的时间)从设备延迟(从设备在被强制监听前可以忽略的连接事件次数)监控超时(在链路被视为丢失之前两次正确接收到数据包之间的最长时间)通道映射:37位(1=良好;0=不良)跳频值(5至16之间的随机数)睡眠时钟精度范围(用于确定连接事件中从设备的不确定性窗口)关于连接请求数据包的详细描述,请参考蓝牙规范[第6卷].
表7.
连接请求时序间隔中总结了允许的时序范围:根据保密协议–不可复制PM0257链路层(LL)PM0257-Rev3page13/76表7.
连接请求时序间隔参数最小值最大值注释发送窗口长度1.
25毫秒10毫秒发送窗口偏移0连接间隔1.
25毫秒的倍数连接间隔7.
5毫秒4秒1.
25毫秒的倍数监控超时100毫秒32秒10毫秒的倍数在连接请求数据包结束+发送窗口偏移+1.
25ms强制延时后,发送窗口开始.
当发送窗口开始时,从设备进入接收器模式,并等待来自主设备的数据包.
如果这段时间内没有接收到数据包,从设备将退出接收器模式,并且在下一个连接间隔重新尝试接收来自主设备的数据.
在连接建立后,主设备必须就每个连接事件向从设备发送数据包,以允许从设备向主设备发送数据包.
或者,从设备可以跳过给定数量的连接事件(从设备延迟).

连接事件是上一个连接事件的起点与下一个连接事件的起点之间的时间.

一个BLE从设备只能连接一个BLE主设备,但是一个BLE主设备可以连接多个BLE从设备.
蓝牙SIG对一个主设备可以连接的从设备数量并无限制(只受限于使用的特定BLE技术或栈).
1.
4主机控制器接口(HCI)主机控制器接口(HCI)层通过软件API或硬件接口(例如,SPI、UART或USB)在主机和控制器之间提供了一种通信方式.
它来自标准蓝牙规范,提供额外的新指令用于低功耗特定的功能.

1.
5逻辑链路控制和适配层协议(L2CAP)逻辑链路控制和适配层协议(L2CAP)支持更高层协议复用、数据包分割和重组操作以及服务信息质量的通知.

1.
6属性配置文件(ATT)属性配置文件(ATT)允许设备向另一设备公开某些数据,即属性.
公开属性的设备被称为服务器,而使用它们的对端设备被称为客户端.
属性是一种包含下列组成部分的数据:属性句柄:16位值,用于标识服务器端相应属性数据.
客户端在读写请求中引用该句柄;属性类型:通过通用唯一标识符(UUID)定义,决定了值的含义.
蓝牙SIG定义了标准16位属性UUID属性值:长度为一个(0~512)字节属性权限:由使用该属性的更高层协议定义.
它们指定读和/或写访问以及通知和/或指示需要的安全级别.
使用属性协议不能发现权限.
几种不同的许可类型如下:–访问权限:决定了可以对属性执行的请求类型(可读、可写、可读且可写)–验证权限:决定了属性是否需要验证.
如果发生了验证错误,客户端可以尝试使用安全管理器进行验证并发回请求.
–授权权限(无授权、授权):这是服务器的属性,决定了是否授权客户端访问一组属性(客户端不能解决授权错误)表8.
属性示例句柄属性属性类型属性值属性权限0x0008"温度UUID""温度值""只读,无授权,无验证""温度UUID"由"温度特征"规范定义,为有符号16位整数.
属性的集合被称为数据库,始终包含在属性服务器中.
属性协议定义了一组方法协议,用于在对端设备上发现、读取和写入属性.
它在如下属性服务器和属性客户端之间实现端到端的客户端-服务器协议:根据保密协议–不可复制PM0257主机控制器接口(HCI)PM0257-Rev3page14/76服务器角色–包含所有属性(属性数据库)–接收请求、执行、响应指令–在数据变化时可以指示、通知属性值客户端角色–与服务器通信–发送请求,等待响应(可以访问(读取)和更新(写入)数据)–确认指示服务器公开的属性可以被客户端发现、读取和写入,并且可通过服务器指示和通知,如表9.
属性协议消息所示:表9.
属性协议消息协议数据单元(PDU消息)发送者说明请求客户端客户询问服务器(总会导致响应)响应服务器服务器发送对客户端请求的响应指令客户端客户端命令服务器做某事(无响应)通知服务器服务器将新值通知客户端(无确认)指示服务器服务器向客户端指示新值(总是导致确认)确认客户端对指示的确认1.
7安全管理器(SM)低功耗蓝牙链路层支持使用采用CBC-MAC(加密块链-消息验证码)算法的计数器模式和128位AES分组密码(AES-CCM)进行加密和验证.
当在连接中使用加密和认证时,为数据通道PDU的载荷添加4字节的消息完整性检查(MIC).
加密应用于PDU载荷和MIC字段.
当两个设备要在连接期间进行通信加密时,安全管理器使用配对流程.
此流程允许通过交换身份信息来验证两个设备,交换信息是为了创建可作为受信任关系或(单个)安全连接基础的安全密钥.
有一些方法用于执行配对过程.

其中一些方法提供了中间人(MITM)攻击防护:设备能够监控和修改两个设备之间的通信通道或向其添加新消息.
典型场景为设备能够连接每个设备,并通过与每个设备通信来充当其他设备被动窃听攻击:通过嗅探设备监听其他设备的通信低功耗蓝牙规范v4.
0或v4.
1的配对也被称为LE传统配对,该配对支持基于设备IO功能的以下方法:直接工作法、输入密钥法和带外法(OOB).
在低功耗蓝牙规范v4.
2中,已定义LE安全连接配对模型.
新安全模型的主要特性为:1.
密钥交换过程使用了椭圆曲线(ECDH)算法:该算法允许通过不安全的通道交换密钥,并可以防止被动窃听攻击(通过嗅探设备秘密监听其他设备的通信)2.
在3种可用的LE传统配对方法的基础上,增加了一种名为"数字比较"的新方法.
根据设备IO功能选择配对程序.
有三种输入功能:无输入能够选择是/否能够使用键盘输入数字有两种输出功能:无输出数字输出:能够显示六位数字下表显示了可能的IO功能组合根据保密协议–不可复制PM0257安全管理器(SM)PM0257-Rev3page15/76表10.
BLE设备上输入/输出功能的组合无输出显示无输入无输入,无输出仅显示是/否无输入,无输出显示是/否键盘仅键盘键盘,显示LE传统配对LE传统配对算法使用并生成2个密钥:临时密钥(TK):用于生成短期密钥(STK)的128位临时密钥短期密钥(STK):用于在配对后加密链接的128位临时密钥配对流程分为三个阶段:第1阶段:配对特征交换两个已建立连接的设备通过配对请求消息交换其输入/输出能力.
该消息还包括用于说明带外数据是否可以用的指示位以及身份验证需求等信息.
在第1阶段交换的信息将用于选择第2阶段使用的STK生成配对方法.
第2阶段:短期密钥(STK)生成配对设备首先使用下列密钥生成方法之一定义临时密钥(TK).
1.
带外(OOB)法将带外通信(如NFC)用于TK协议.
它提供了身份认证(MITM保护).
仅在两个设备上都设置了带外位时才选择此方法,否则必须使用设备的IO功能来确定可以使用其他方法(输入密钥法或直接工作法).
2.
输入密钥法:用户输入六位数字作为设备之间的TK.
它提供了身份认证(MITM保护)3.
直接工作法:该方法不提供认证,也不提供中间人(MITM)攻击防护根据下表所定义的IO功能在输入密钥法和直接工作法之间进行选择.
表11.
计算临时密钥(TK)的方法仅显示显示是/否仅键盘无输入,无输出键盘,显示仅显示直接工作直接工作输入密钥直接工作输入密钥显示是/否直接工作直接工作输入密钥直接工作输入密钥仅键盘输入密钥输入密钥输入密钥直接工作输入密钥无输入,无输出直接工作直接工作直接工作直接工作直接工作键盘,显示输入密钥输入密钥输入密钥直接工作输入密钥第3阶段:用于计算临时密钥(TK)的传输特定密钥分配方法一旦第2阶段完成,可通过使用STK密钥加密的消息分配最多三个128位密钥:1.
长期密钥(LTK):用于生成链路层加密和验证使用的128位密钥2.
连接签名解析密钥(CSRK):用于在ATT层上执行数据签名和验证的128位密钥3.
身份解析密钥(IRK):用于生成和解析随机地址的128位密钥LE安全连接LE安全连接配对方法使用并生成一个密钥:长期密钥(LTK):用于在配对和后续连接后加密连接的128位密钥配对流程分为三个阶段:第1阶段:配对特征交换两个已建立连接的设备通过配对请求消息交换其输入/输出能力.
该消息还包括用于说明带外数据是否可以用的指示位以及身份验证需求等信息.
在第1阶段交换的信息将用于选择第2阶段使用的配对方法.
第2阶段:长期密钥(LTK)生成根据保密协议–不可复制PM0257安全管理器(SM)PM0257-Rev3page16/76配对流程由发起设备启动,该设备将公钥发送至接收设备.
接收设备将回复其公钥.
对于所有配对方法(除了OOB以外),公钥交换阶段已完成.
每个设备均产生自己的椭圆Diffie-Hellman(ECDH)公钥-私钥对.
每个密钥对均包含一个私钥(密钥)和一个公钥.
密钥对应仅在每个设备上生成一次,并可以在执行配对之前计算.

支持以下配对密钥生成方法:1.
使用带外通信来建立公钥的带外(OOB)法.
如果带外位在配对请求/响应中至少由一个设备设置,则选择该方法,否则必须使用设备的IO功能来确定可以使用其他方法(输入密钥法、直接工作法或数字比较法).

2.
JustWorks:该方法无需验证,并且不提供针对中间人(MITM)攻击的任何保护3.
输入密钥法:该方法需要认证.
用户输入六位数字.
该六位数字是设备认证的基础4.
数字比较:该方法需要认证.
两种设备都将IO能力设为是/否或键盘显示.
两个设备都计算在两个设备上向用户显示的六位数字确定值:用户需要输入是或否来确认是否匹配.
如果在两个设备上都选择是,则配对执行成功.
当多个设备具有相同名字的情况下,此方法可以确保用户设备与正确的设备连接.

根据下表在可能的方法中选择.
表12.
将IO功能映射到可能的密钥生成方法发起者/响应方仅显示显示是/否仅键盘无输入,无输出键盘,显示仅显示直接工作直接工作输入密钥直接工作输入密钥显示是/否直接工作直接工作(LE传统)数字比较(LE安全连接)输入密钥直接工作输入密钥(LE传统)数字比较(LE安全连接)仅键盘输入密钥输入密钥输入密钥直接工作输入密钥无输入,无输出直接工作直接工作直接工作直接工作直接工作键盘,显示输入密钥输入密钥(LE传统)数字比较(LE安全连接)输入密钥直接工作输入密钥(LE传统)数字比较(LE安全连接)提示如果可能的密钥生成方法未提供与安全属性匹配的密钥(经过身份验证-MITM保护或未经过身份验证-无MITM保护),则设备将发送配对失败指令,并显示"验证要求"的错误代码.
第3阶段:传输特定密钥分配主设备和从设备之间交换以下密钥:用于验证未加密数据的连接签名解析密钥(CSRK)用于设备身份和隐私的身份解析密钥(IRK)当设备保存确定的加密密钥以用于未来验证时,设备被绑定.
数据签名还可以使用CSRK密钥,通过未加密的链路层连接传输已验证数据:12位签名位于数据载荷之后.
签名算法还使用可防止重放攻击的计数器(一种外部设备,可以只获取某些数据包然后发送,无需对数据包内容有任何理解:接收设备只检查数据包计数器并丢弃,因为它的帧计数器少于最近接收的良好数据包).

1.
8私有总是用相同地址信息(公共地址或静态随机地址)的广告设备,很容易被其他扫描设备追踪.
为了防止这种情况发生,可以在广告设备上启用私有功能.
在启用了私有的设备上,将使用私有地址.
有两种私有地址:不可解析私有地址可解析私有地址不可解析私有地址是完全随机的(两个最高有效位除外),不能进行解析.
因此,使用不可解析私有地址的设备不能被没有预先配对的设备识别.
可解析私有地址由24位随机部分和哈希部分组成.
哈希部分来源于随机数和IRK(身份解析密钥).
因此,只有知晓该IRK的设备能够解析地址并识别该设备.
在配对过程中分发IRK.
两种类型的地址都经常改变,从而增强了设备身份机密性.
在GAP发现模式和过程期间不使用私有功能,仅在GAP连接模式和过程期间使用私有功能.
根据保密协议–不可复制PM0257私有PM0257-Rev3page17/76在v4.
1及以下的低功耗蓝牙栈中,通过主机解析和产生私有地址.
在蓝牙4.
2中,私有功能已从版本1.
1更新到版本1.
2.
在低功耗蓝牙栈v4.
2中,控制器可以使用主机提供的设备身份信息来解析和生成私有地址.
外设设备启用了私有功能的处于不可连接模式的外设将使用不可解析或可解析私有地址.

如需连接中央设备,外设设备中如启用主机私有,则必须且只能使用非定向可连接模式;如启用控制器私有,则外设设备还可使用定向可连接模式.
在可连接模式中,外设设备使用可解析私有地址.

无论使用的是不可解析还是可解析私有地址,均以15分钟的间隔时间自动重新生成.
设备不向广告数据发送设备名称.
中央设备启用了私有功能的执行主动扫描的中央设备只使用不可解析或可解析私有地址.
为了连接外设,如果启用了主机私有,应使用通用连接建立流程.
对于基于控制器的私有,可使用任何连接流程.
中央设备将使用可解析私有地址作为发起方的设备地址.
每间隔15分钟后生成可解析或不可解析私有地址.
广播设备启用了私有的广播设备使用不可解析或可解析私有地址.
每间隔15分钟后将自动生成新地址.
广播设备不应将设备名称或唯一数据发送到广告数据.
监听设备启用了私有的监听设备使用不可解析或可解析私有地址.
每间隔15分钟后将自动生成新地址.
1.
8.
1设备过滤蓝牙LE可通过减少设备的响应数量来降低功耗,因为这样可以减少控制器与上层之间的传输和交互.
设备过滤通过白名单来实现.
启用白名单后,链路层将忽略不在白名单中的设备.
在蓝牙4.
2之前,当远程设备使用私有功能后,无法实现设备过滤.
由于引入了链路层私有,可以在检查远程设备身份地址是否在白名单中之前解析远程设备身份地址.
1.
9通用属性配置文件(GATT)通用属性配置文件(GATT)定义了使用ATT协议的框架,它被用于服务、特征、描述符发现、特征读取、写入、指示和通知.
就GATT而言,当两个设备已经连接时,有两种设备角色:GATT客户端:通过读取、写入、通知或指示操作访问远程GATT服务器上的数据的设备GATT服务器:在本地保存数据并向远程GATT客户端提供数据访问方法的设备一个设备可以既是GATT服务器又是GATT客户端.
设备的GATT角色在逻辑上独立于主、从角色.
主、从角色定义了BLE无线连接的管理方式,而GATT客户端/服务器角色由数据存储和数据流动来决定.
因此,不要求从(外围)设备必须是GATT服务器以及主(中央)设备必须是GATT客户端.
ATT传输的属性封装在下列基础类型中:1.
特征(具有相关描述符)2.
服务(主要、次要和包含)1.
9.
1特征属性类型特征是一种包含单个值和任意数量描述符的属性类型,描述符描述的特征值使用户能够理解该特征.

特征揭示了值代表的数据类型、值是否能够读取或写入以及如何配置要指示或通知的值,它还描述了值的含义.

特征具有以下组成部分:1.
特征声明2.
特征值3.
特征描述符根据保密协议–不可复制PM0257通用属性配置文件(GATT)PM0257-Rev3page18/76图7.
特征定义示例特征声明是一种属性,其定义如下:表13.
特征声明句柄属性属性类型属性值属性权限0xNNNN0x2803(特征属性类型的UUID)特征值属性(读取、广播、写入、写入但不响应、通知、指示等).
确定如何能够使用特征值或如何能够访问特征描述符只读,无验证,无授权特征值属性句柄特征值UUID(16或128位)特征声明包含特征值.
该值是特征声明后的第一个属性:表14.
特征值句柄属性属性类型属性值属性权限0xNNNN0xuuuu–16位或128位(特征UUID)特征值取决于更高层配置文件或应用1.
9.
2特征描述符类型特征描述符用于描述特征值,以便为特征添加特定"含义",使客户能够理解特征.
有以下特征描述符可供使用:1.
特征扩展属性:允许为特征添加扩展属性2.
特征用户描述:使设备能够将文本字符串关联到特征3.
客户端特征配置:如果特征可以通知或指示,为强制要求.
客户端应用必须写入该特征描述符以使特征通知或指示成为可能(前提是特征属性允许通知或指示)4.
服务器特征配置:可选描述符根据保密协议–不可复制PM0257通用属性配置文件(GATT)PM0257-Rev3page19/765.
特征表达格式:它允许通过一些字段(例如,格式、指数、单位命名空间、描述)定义特征值表达格式,以便正确显示相关值(例如,oC格式的温度测量值);6.
特征聚合格式:它可以聚合多种特征表达格式.
关于特征描述符的详细描述,请参考蓝牙规范.
1.
9.
3服务属性类型服务是特征的集合,共同为一个可实现的应用配置文件提供通用服务类型.
例如,健康体温计服务包含温度测量值特征和每次测量的间隔时间特征.
服务或主要服务可以引用被称为次要服务的其他服务.

服务的定义如下:表15.
服务声明句柄属性属性类型属性值属性权限0xNNNN0x2800–"主要服务"的UUID,或x2801–"次要服务"的UUID0xuuuu–16位或128位(服务UUID)只读,无验证,无授权服务包含服务声明,其他服务包含定义(可选)和特征定义.
服务包含声明位于服务声明之后.

表16.
包含声明句柄属性属性类型属性值属性权限0xNNNN0x2802(包含属性类型的UUID)包含服务属性句柄结束组句柄服务UUID只读,无验证,无授权"包含服务属性句柄"是所包含次要服务的属性句柄,"结束组句柄"是所包含次要服务中最后一个属性的句柄.

1.
9.
4GATT流程通用属性配置文件(GATT)定义了一组发现服务、特征和相关描述符的标准流程以及它们的使用方法.

有以下流程可供使用:发现流程(表17.
发现流程和相关响应事件)客户端发起的流程(表18.
客户端发起的流程和相关响应事件)服务器发起的流程(表19.
服务器发起的流程和相关响应事件)表17.
发现流程和相关响应事件步骤响应事件发现所有主要服务按组读取响应通过服务UUID发现主要服务按类型值响应查找查找包含的服务按类型响应事件读取发现服务的所有特征按类型响应读取通过UUID发现特征按类型响应读取发现所有特征描述符查找信息响应根据保密协议–不可复制PM0257通用属性配置文件(GATT)PM0257-Rev3page20/76表18.
客户端发起的流程和相关响应事件步骤响应事件读取特征值读取响应事件通过UUID读取特征值读取响应事件读取长特征值读取BLOB响应事件读取多个特征值读取响应事件写入特征值,无响应不生成事件签名写入,无响应不生成事件写入特征值写入响应事件.
写入长特征值准备写入响应执行写入响应可靠写入准备写入响应执行写入响应表19.
服务器发起的流程和相关响应事件步骤响应事件通知不生成事件指示确认事件关于GATT流程和相关响应事件的详细描述,请参考第5节参考中的蓝牙规范.
1.
10通用访问配置文件(GAP)蓝牙系统为所有的蓝牙设备定义了一个基础配置文件,叫做通用访问配置文件(GAP).
此配置文件定义了一个蓝牙设备所需具备的基本要求.
下表中描述了四种GAP配置文件的角色:表20.
GAP角色角色(1)说明发送器接收器典型示例广播设备发送广告事件MO发送温度值的温度传感器监听设备接收广告事件OM只接收和显示温度值的温度显示装置外设设备始终为从设备.
处于可连接广告模式.
支持所有LL控制流程;可选择加密或不加密MM手表中央设备始终为主设备.
从不广告.
支持主动或被动扫描.
支持所有LL控制流程;可选择加密或不加密MM移动电话1.
1.
M=强制;O=可选在GAP中,定义了两个基本概念:GAP模式:配置设备,使之以特定方式长时间工作.
GAP模式有四种类型:广播、可发现、可连接和可绑定类型根据保密协议–不可复制PM0257通用访问配置文件(GAP)PM0257-Rev3page21/76GAP流程:配置设备,使之在特定的时间段或有限时间内执行某一动作.
有四种类型的GAP流程:监听、发现、连接和绑定流程不同类型的可发现和可连接模式可以同时使用.
定义的GAP模式如下:表21.
GAP广播器模式模式说明注释GAP角色广播模式设备仅使用链路层广告通道和数据包广播数据(不在AD类型标记上设置任何位)设备可使用监听流程检测广播数据广播设备表22.
GAP可发现模式模式说明注释GAP角色非可发现模式不能在AD类型标记上设置有限和一般可发现位不能通过执行通用和有限发现流程的设备发现它外设设备有限可发现模式在AD类型标记上设置有限可发现位可持续约30秒.
它由用户最近交互的设备使用,例如用户按下设备上的按钮外设设备一般可发现模式在AD类型标记上设置一般可发现位在设备希望成为可发现设备时使用.
对可发现时间无限制外设设备表23.
GAP可连接模式模式说明注释GAP角色不可连接模式只能使用ADV_NONCONN_IND或ADV_SCAN_IND广告数据包在广告时不能使用可连接广告数据包外设设备直接可连接模式使用ADV_DIRECT广告数据包由要快速连接中央设备的外设使用.
只能使用1.
28秒,并且需要外设和中央设备地址外设设备非定向可连接模式使用ADV_IND广告数据包在设备希望成为可连接设备时使用.
由于ADV_IND广告数据包可以包含AD类型标记,因此设备可同时处于可发现和非定向可连接模式.
当设备进入连接模式或不可连接模式时,可连接模式终止外设设备表24.
GAP可绑定模式模式说明注释GAP角色不可绑定模式不允许与对端设备建立绑定设备不保存密钥外设设备可绑定模式设备接受来自中央设备的绑定请求.
外设设备表25.
GAP监听流程中定义了以下GAP流程:表25.
GAP监听流程步骤说明注释Role监听流程它允许设备搜索广播设备设备数据监听设备根据保密协议–不可复制PM0257通用访问配置文件(GAP)PM0257-Rev3page22/76表26.
GAP发现流程步骤说明注释Role有限可发现流程用于在有限发现模式下发现外设根据AD类型标记信息应用设备过滤中央设备通用可发现流程用于在通用和有限发现模式下发现外设根据AD类型标记信息应用设备过滤中央设备名称发现流程用于从可连接设备检索"蓝牙设备名称"的流程中央设备表27.
GAP连接流程步骤说明注释Role自动连接建立流程允许连接一个或多个处于定向可连接模式或非定向可连接模式的设备使用白名单中央设备通用连接建立流程允许连接一组处于定向可连接模式或非定向可连接模式的已知对端设备当在被动扫描期间检测到具有私有地址的设备时,它使用直接连接建立流程支持私有地址中央设备选择性连接建立流程使用主机的选定连接配置参数与白名单中的一组设备建立连接使用白名单,并按照该白名单进行扫描中央设备直接连接建立流程使用一组连接间隔参数与特定设备建立连接由通用和选择性流程使用中央设备连接参数更新流程在连接期间更新使用的连接参数中央设备终止流程终止GAP流程中央设备表28.
GAP绑定流程步骤说明注释Role绑定流程在配对请求上设置了绑定位的情况下,启动配对过程中央设备关于GAP流程的详细描述,请参考蓝牙规范.
1.
11BLE配置文件和应用服务集合一组特征并公开这些特征的行为(设备的操作内容,而不是设备如何使用它们).
服务不定义特征用例.

用例决定了需要的服务(如何在设备上使用服务).
这是通过配置文件实现的,它定义了特定用例需要的服务:配置文件客户端实现用例配置文件服务器实现服务可以使用标准配置文件或专有配置文件.
在使用非标准配置文件时,需要128位UUID,并且必须是随机生成的.
目前,任何标准蓝牙SIG配置文件(服务和特征)均使用16位UUID.
可从以下SIG网页下载服务和特征规范及UUID分配:https://developer.
bluetooth.
org/gatt/services/Pages/ServicesHome.
aspxhttps://developer.
bluetooth.
org/gatt/characteristics/Pages/CharacteristicsHome.
aspx根据保密协议–不可复制PM0257BLE配置文件和应用PM0257-Rev3page23/76图8.
客户端和服务器配置文件1.
11.
1接近感测示例本节将简单介绍接近感测的目标、工作原理和需要的服务:目标当一个设备由近及远,到一定距离时:–导致报警工作原理如果设备断开,则会导致报警链路丢失报警:链路丢失服务–如果设备距离太远–导致路径丢失报警:即时报警和发送功率服务链路丢失服务–报警级别特征–行为:链路丢失时,因被枚举导致报警即时报警服务–报警级别特征–行为:写入时,因被枚举导致报警发送功率服务–发送功率特征–行为:读取时,报告连接的当前发送功率根据保密协议–不可复制PM0257BLE配置文件和应用PM0257-Rev3page24/762BlueNRG-1、BlueNRG-2低功耗蓝牙栈BlueNRG-1、BlueNRG-2设备是支持低功耗蓝牙(BLE)无线电的片上系统.
低功耗蓝牙(BLE)栈标准C库采用二进制格式,并提供用于控制BlueNRG-1、BlueNRG-2低功耗蓝牙功能的高级接口.
BLE二进制库提供以下功能:栈API:–BLE栈初始化–BLE栈应用命令接口(以hci_为前缀的HCI指令和以aci_为前缀的厂商特定指令)–睡眠定时器访问–BLE栈状态机处理栈事件回调–向用户应用通知BLE栈事件–睡眠定时器事件为无线电IP提供中断处理程序为能够访问BLE栈功能,只需用户应用程序:调用相关API通过提供的栈回调处理预期事件将BLE栈二进制库链接到用户应用程序,如图9.
BLE栈参考应用中所述.
图9.
BLE栈参考应用提示1.
API是由BLE栈库定义并由用户应用调用的C函数.
2.
回调是由BLE栈库调用并由用户应用定义的C函数.
3.
驱动源是一组驱动程序(头文件和源文件),用于处理所有BlueNRG-1、BlueNRG-2外设(ADC、I2C、SPI、定时器、看门狗、UART).
根据保密协议–不可复制PM0257BlueNRG-1、BlueNRG-2低功耗蓝牙栈PM0257-Rev3page25/762.
1BLE栈库框架BLE栈库框架允许将指令发送至BlueNRG-1、BlueNRG-2SoCBLE栈,并且还提供了BLE事件回调定义.
BLE栈API利用并扩展了在蓝牙规范中定义的标准HCI数据格式.
提供的一组API支持以下命令:蓝牙规范定义的控制器标准HCI指令供应商特定的(VS)控制器HCI指令供应商特定的(VS)主机HCI指令(L2CAP、ATT、SM、GATT和GAP)在面向BlueNRG-1、BlueNRG-2DK平台的BlueNRG-1_2DK软件包中提供了BLEAPI接口框架的参考第5节参考).
通过以下头文件定义BlueNRG-1、BlueNRG-2设备的BLE栈库框架接口表29.
BLE栈库框架接口文件说明位置注释ble_status.
hBLE栈错误代码的头文件Library\Bluetooth_LE\incbluenrg1_api.
hBlueNRG-1BLE栈API的头文件"它包含在bluenrg1_stack.
h头文件中bluenrg1_events.
h用于BlueNRG-1BLE栈事件回调的头文件"它包含在bluenrg1_stack.
h头文件中stack_user_cfg.
hBLE栈配置头文件"它为BLE栈v2.
1提供了可用的配置选项stack_user_cfg.
cBLE栈配置文件Library\Bluetooth_LE\src要包含在用户应用IDE项目中的源文件,用于支持BLE栈v2.
1提供的BLE模块化方法提示BLE栈v2.
1或更高版本提供了在编译时根据用户特定应用场景启用/禁用以下BLE栈特性的功能:1.
启用/禁用控制器私有2.
启用/禁用LE安全连接3.
启用/禁用主设备4.
启用/禁用数据长度扩展(仅对BlueNRG-2设备有效)这使得用户有可能从BLE协议栈的二进制库文件中去除某些功能,以达到减少片内闪存使用空间的目的.

请参阅在Library\Bluetooth_LE\inc\stack_user_cfg.
h文件中定义的BLE栈预处理器配置选项,以确定哪些是可用和支持的组合.
从BLE栈v2.
1开始,所有其他BLE应用层头文件均已移至Library\BLE_Application\layers_inc文件夹.
表30.
BLE应用栈库框架接口文件说明位置注释ble_const.
h它包括所需的BLE栈头文件Library\BLE_Application\layers_inc将包含在用户主应用中bluenrg1_gap.
hBlueNRG-1GAP协议层常量的头文件""它包含在ble_const.
h头文件中bluenrg1_gatt_server.
hGATT服务器常量的头文件""它包含在ble_const.
h头文件中bluenrg1_hal.
h包含用于BlueNRG-1的HAL的头文件""它包含在ble_const.
h头文件中根据保密协议–不可复制PM0257BLE栈库框架PM0257-Rev3page26/76文件说明位置注释bluenrg1_stack.
hBlueNRG-1BLE栈初始化、时间片和睡眠定时器API的头文件""将包含在用户主应用中hci_const.
h包含HCI层的常量.
它包含在ble_const.
h头文件中link_layer.
hBlueNRG-1链路层常量的头文件""它包含在ble_const.
h头文件中sm.
hBlueNRG-1安全管理器常量的头文件""它包含在ble_const.
h头文件中提示从BLE协议栈v2.
1开始,BLE协议栈所需的AESCMAC加密功能由新的独立的二进制库文件:Library\\cryptolib\\cryptolib.
a.
来提供.
该库也必须包含在用户应用的IDE项目中.
2.
2BLE栈事件回调BLE栈库框架提供一组事件与相关回调,用于向用户应用程序通知要处理的特定事件.

BLE事件回调原型在头文件bluenrg1_events.
h中定义.
默认情况下,通过弱定义定义所有回调(不对用户定义的事件回调名称进行检查,所以用户应仔细检查每个定义的回调是否与预期的函数名称一致).

用户应用必须使用与特定应用场景一致的应用代码定义所使用的事件回调.

2.
3BLE栈初始化和时间片API必须对BlueNRG-1BLE栈进行初始化,以便适当地配置与特定应用场景一致的某些参数.
在使用任何其他BLE栈v2.
x功能以前,必须先调用以下API:BlueNRG_Stack_Initialization(&BlueNRG_Stack_Init_params);BlueNRG_Stack_Init_params是包含设备内存和底层硬件配置数据的变量,并使用以下结构定义:typedefstruct{uint8_t*bleStartFlashAddress;uint32_tsecDbSize;uint32_tserverDbSize;uint8_t*stored_device_id_data_p;uint8_t*bleStartRamAddress;uint32_ttotal_buffer_size;uint16_tnumAttrRecord;uint16_tnumAttrServ;uint16_tattrValueArrSize;uint8_tnumOfLinks;uint8_textended_packet_length_enable;uint8_tprWriteListSize;uint8_tmblockCount;uint16_tattMtu;hardware_config_table_thardware_config;}BlueNRG_Stack_Initialization_t;hardware_config_table_t结构定义如下:typedefstruct{uint32_t*hot_ana_config_table;uint32_tmax_conn_event_length;uint16_tslave_sca;uint8_tmaster_sca;uint8_tls_source;uint16_ths_startup_time;}hardware_config_table_t;根据保密协议–不可复制PM0257BLE栈事件回调PM0257-Rev3page27/76表31.
BlueNRG-1BLE栈初始化参数名称说明值bleStartFlashAddressSDB基址:这是分配给堆栈的非易失性存储区的起始地址,用于存储绑定设备的信息对齐2048字节的Flash扇区边界(1)secDbSize安全数据库大小:这是由于存储绑定设备的安全信息的安全数据库大小.
1kB(1)serverDbSize服务器数据库大小:这是用于存储绑定设备的服务变更通知的服务数据库大小1kB(1)stored_device_id_data_p栈内部参数存储区(安全根密钥、静态随机地址、公共地址)56字节,32位对齐FLASH区域,所有元素均必须初始化为0xFFbleStartRamAddress栈GATT数据库的RAM缓存的起始地址32位对齐RAM区域total_buffer_size为堆栈分配的总缓存大小TOTAL_BUFFER_SIZE(NUM_LINKS,NUM_GATT_ATTRIBUTES,NUM_GATT_SERVICES,ATT_VALUE_ARRAY_SIZEMBLOCKS_COUNT,CONTROLLER_DATA_LENGTH_EXTENSION_ENABLED)numAttrRecord与特定用户BLE应用中可存储在GATT数据库中的所有所需特征(不包括服务)相关的属性记录的最大数量对于每个特征,属性的数量为2到5,具体取决于特征属性:最少为2个(一个用于声明,一个用于值)为每个附加属性再添加一条记录:通知或指示、广播、扩展属性.
由于在初始化GATT和GAP层时,与标准属性配置文件和GAP服务特性相关的记录会自动增加,所以总计算值必须增加9.
numAttrServ对于特定用户BLE应用程序,可存储在GATT数据库中的最大服务数量由于在初始化GATT和GAP层时,标准属性配置文件和GAP服务会自动增加,总计算值必须增加2attrValueArrSize属性值的存储区大小attrValueArrSize值的每个特征属性如下:特征值长度特征UUID为16位:添加5个字节特征UUID为128位:添加19个字节特征具有服务器配置描述符:添加2个字节特征具有客户端配置描述符:为每个同时连接添加2个字节特性具有扩展属性:添加2个字节numOfLinks设备可以支持的最大同时连接数量有效值为1到8extended_packet_length_enable不支持的功能(保留供将来使用)0prWriteListSize(2)长度大于20字节的特征的长写程序所需的准备写入请求数量使用bluenrg1_stack.
hfile:PREP_WRITE_X_ATT()上提供的特定宏计算最小需求值mblockCount(2)BLE栈分配的存储器块数量使用bluenrg1_stack.
hfile:MBLOCKS_COUNT上提供的特定宏计算最小需求值attMtu(2)支持的最大ATT_MTU大小支持的值范围为23到247字节hot_ana_config_table射频子系统的低级配置参数表.
使用所需的Hot表配置值进行配置(参见system_bluenrg1.
c文件)根据保密协议–不可复制PM0257BLE栈初始化和时间片APIPM0257-Rev3page28/76名称说明值max_conn_event_length设备处于从模式时的连接事件最长持续时间,以625/256μs(~2.
44μs)为单位RADIO_CONFIG=0x10000U|(uint16_t)((uint32_t)cold_start_config&0x0000FFFFU);while((BLUE_CTRL->RADIO_CONFIG&0x10000)!
=0);2.
5BLE栈时间片函数BlueNRG-1、BlueNRG-2BLE栈提供了一个特殊APIBTLE_StackTick(),当BLE栈活动正在进行时(通常在主应用程序的while循环中),必须调用它才能处理内部BLE栈状态机.
BTLE_StackTick()函数执行所有主机栈层的处理,必须定期执行,以处理传入链路层数据包和主机层程序.
通过此函数来调用所有栈回调.
如果使用低速环形振荡器来替代LS晶振,则此函数也执行LSRO校准,因此必须在每次系统唤醒时至少调用一次,以保持500ppm的精度(如果作为主设备,则必须至少保持500ppm的精度).
提示当BTLE_StackTick()正在运行时,不能调用其他任何BLE协议栈接口函数.
例如,如果在中断程序中可能调用BLE栈函数,则必须在执行BTLE_StackTick()期间禁用该中断.
示例:如果可能在UARTISR中调用栈函数,则应使用以下代码:NVIC_DisableIRQ(UART_IRQn);BTLE_StackTick();NVIC_EnableIRQ(UART_IRQn);提示如果无线电活动正在进行,则应将全局中断限制为几微秒(s).
根据保密协议–不可复制PM0257BLE栈时间片函数PM0257-Rev3page31/763使用BlueNRG-1、BlueNRG-2BLE栈设计应用本节提供关于如何使用BLE栈v2.
x二进制库在BlueNRG-1、BlueNRG-2设备上设计和实现低功耗蓝牙应用的信息和代码示例.
在BlueNRG-1、BlueNRG-2设备上实现BLE应用的用户必须完成一些基本的常见步骤:1.
初始化阶段和应用程序主循环2.
BLE栈事件回调设置3.
服务和特征配置(在GATT服务器上)4.
创建连接:可发现、可连接模式与流程5.
安全(配对和绑定)6.
服务和特征发现7.
特征通知/指示、写入、读取8.
基本/典型错误条件描述提示在后面的章节中,将使用一些用户应用"定义",以便轻松识别设备低功耗蓝牙的角色(中央设备、外设、客户端和服务器).
表35.
BLE设备角色的用户应用定义定义说明GATT_CLIENTGATT客户端角色GATT_SERVERGATT服务器角色3.
1初始化阶段和应用程序主循环正确配置BlueNRG-1、BlueNRG-2设备需执行以下主要步骤.
1.
初始化BLE设备向量表、中断优先级、时钟:SystemInit()API2.
配置选定BLE平台:SdkEvalIdentification()API3.
初始化串口,可作为软件调试口或其他信息获取的通讯渠道:SdkEvalComUartInit(UART_BAUDRATE)API4.
初始化BLE栈:BlueNRG_Stack_Initialization(&BlueNRG_Stack_Init_params)API5.
配置BLE设备公共地址(如果使用公共地址):aci_hal_write_config_data()API6.
初始化BLEGATT层:aci_gatt_init()API7.
根据所选设备角色初始化BLEGAP层:aci_gap_init("role")API8.
设置合适的安全I/O能力和验证要求(如果使用了BLENRG安全):aci_gap_set_io_capability()和aci_gap_set_authentication_requirement()API9.
如果设备是GATT服务器,定义需要的服务和特征以及特征描述符:aci_gatt_add_service(),aci_gatt_add_char(),aci_gatt_add_char_desc()API10.
在主环while(1)中添加BLE协议栈时间片APIBTLE_StackTick()和处理用户操作/时间的特定用时间片处理函数.
此外还需调用APIBlueNRG_Sleep(),以启用BLE设备睡眠模式并保留BLE无线电操作模式.
以下伪代码示例描述了需要的初始化步骤:intmain(void){uint8_tret;/*SystemInit*/SystemInit();/*IdentifyBlueNRG1platform*/SdkEvalIdentification();根据保密协议–不可复制PM0257使用BlueNRG-1、BlueNRG-2BLE栈设计应用PM0257-Rev3page32/76/*ConfigureI/Ocommunicationchannel*/SdkEvalComUartInit(UART_BAUDRATE);/*BLEstackinit*/ret=BlueNRG_Stack_Initialization(&BlueNRG_Stack_Init_params);if(ret!
=BLE_STATUS_SUCCESS){printf("ErrorinBlueNRG_Stack_Initialization()0x%02x\r\n",ret);while(1);}/*DeviceInitialization:BLEstackGATTandGAPInitAPIs.
ItcouldaddBLEservicesandcharacteristics(ifitisaGATTserver)andinitializeitsstatemachineandotherspecificdrivers(i.
e.
leds,buttons,sensors,…)*/ret=DeviceInit();if(ret!
=BLE_STATUS_SUCCESS){while(1);}while(1){/*BLEStackTick*/BTLE_StackTick();/*ApplicationTick:userapplicationwhereapplicationstatemachineishandled*/ishandled*/APP_Tick();/*PowerSavemanagement:enablesleepmodewithwakeuponradiooperatingtimings(adverting,connectionsintervals)*/operatingtimings(adverting,connectionsintervals)*/BlueNRG_Sleep(SLEEPMODE_WAKETIMER,0,0,0);}/*while(1)*/}}/*endmain()*/提示1.
BlueNRG_Stack_Init_params变量定义了第2.
2节BLE栈事件回调中所述的BLE栈初始化参数第2.
2节BLE栈事件回调2.
要处理BLE栈事件,必须调用BTLE_StackTick().
3.
APP_Tick()只是一个依赖于应用的函数,该函数根据应用工作场景来处理用户应用程序状态机.

4.
BlueNRG_Sleep(SLEEPMODE_WAKETIMER,0,0,0)启用BLE设备硬件睡眠低功耗模式:CPU停止运行并且所有外设均被禁用(仅低速振荡器和外部唤醒源模块运行).
值得注意的是,必须在应用程序的mainwhile循环中调用具有指定参数(SLEEPMODE_WAKETIMER,0,0,0)的此API,以便BlueNRG-1、BlueNRG-2设备能够进入在BLE栈广告或连接间隔上具有唤醒源的睡眠模式.
如果不调用,则BLE设备始终处于节能运行模式(除非调用这一指定API,否则BLE栈不会自动进入睡眠模式).
用户应用可使用BlueNRG_Sleep()API选择其中一种受支持的BLE设备硬件低功耗模式(CPU停止、睡眠、待机),并设置相关的唤醒源和睡眠超时(如果适用).
BlueNRG_Sleep()API将来自应用的低功耗请求与无线操作模式相结合,选择适用于当前情况的最佳低功耗模式.
在无线模块与应用请求之间进行这种协商的目的是避免丢失无线通信数据.
5.
有关BlueNRG_Sleep()API和BLE设备低功耗模式的更多信息,请参考本文档末尾的第5节参考中的相关应用笔记.
6.
在执行aci_gatt_init()与aci_gap_init()API时,BLE栈总是添加两个标准服务:具有服务更改特征的属性配置文件服务(0x1801)和具有设备名称和外观特征的GAP服务(0x1800).
7.
当未在aci_gap_init()API上启用私有或基于主机的私有时,为标准GAP服务保留的最后一个属性句柄为0x000B,若在aci_gap_init()API上启用基于控制器的私有,则为0x000D.
根据保密协议–不可复制PM0257初始化阶段和应用程序主循环PM0257-Rev3page33/76表36.
GATT、GAP默认服务默认服务开始句柄结束句柄服务UUID属性配置文件服务0x00010x00040x1801通用访问配置文件(GAP)服务0x00050x000B0x1800表37.
GATT、GAP默认特征默认服务特征句柄属性特征属性特征值句柄特征UUID特征值长度(字节)属性配置文件服务服务更改0x0002指示0x00030x2A054通用访问配置文件(GAP)服务设备名称0x0006读取|写入,无响应|写入|验证签名写入0x00070x2A008外观0x0008读取|写入,无响应|写入|验证签名写入0x00090x2A012外设首选的连接参数0x000A读|写0x000B0x2A048中央地址解析(1)0x000C无需身份验证或授权即可读取.
不可写0x000D0x2AA611.
仅在aci_gap_init()API上启用基于控制器的隐私(0x02)时添加.
aci_gap_init()角色参数值如下:表38.
aci_gap_init()角色参数值参数角色参数值注释Role0x01:外设设备0x02:广播设备0x04:中央设备0x08:监听设备角色参数可以是支持的任意值的按位或(同时支持多个角色)enable_Privacy0x00用于禁用隐私;0x01用于启用隐私;0x02用于启用基于控制器的隐私BLE栈v2.
x支持基于控制器的隐私device_name_char_len它允许指定设备名称特性的长度.
关于该API和相关参数的完整描述,请参考第5节参考中的蓝牙LE栈API和事件文档.
3.
1.
1BLE地址BlueNRG-1、BlueNRG-2设备支持以下设备地址:公共地址随机地址私有地址根据保密协议–不可复制PM0257初始化阶段和应用程序主循环PM0257-Rev3page34/76公共MAC地址(6字节-48位地址)唯一标识了BLE设备,它们由电气和电子工程师协会(IEEE)定义.
公共地址的前3个字节标识了发布标识符的公司,称为组织唯一标识符(OUI).
组织唯一标识符(OUI)是一种从IEEE购买的24位数字.
该标识符唯一标识了某个公司,并可以为公司独家使用特定OUI预留一组可能的公共地址(最多2^24个,来自公共地址的其余3个字节).
当之前分配的地址组的至少95%已被使用时,任何组织/公司均可以请求一组新的6字节地址(最多2^24个,通过特定OUI提供可能的地址).
如果用户想要在程序中使用其自定义的MAC地址,则必须将其存储在特定设备上仅用于存储MAC地址的Flash位置.
然后,在设备上电时,必须通过调用特定协议栈API将该MAC地址写入射频模块中.
用于设置MAC地址的BLEAPI指令为aci_hal_write_config_data()在开始任何BLE操作之前(在BLE栈初始化APIBlueNRG_Stack_Initialization()之后),应将aci_hal_write_config_data()指令发送到BlueNRG-1、BlueNRG-2设备.
以下伪代码示例描述了如何设置公共地址:uint8_tbdaddr[]={0x12,0x34,0x00,0xE1,0x80,0x02};ret=aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,CONFIG_DATA_PUBADDR_LEN,bdaddr);if(ret)PRINTF("Settingaddressfailed.
\n")}在BLE产品生产时,需要将设备MAC地址存储在内部flash的指定位置.
用户在写入其应用时,可以假设MAC地址位于BLE设备的已知特定MACFlash位置.
在生产期间,可通过SWD使用客户Flash映像为微控制器编程.
第二步可能包括生成唯一的MAC地址(即从数据库读取),并将MAC地址存储在已知MACFlash位置.
根据保密协议–不可复制PM0257初始化阶段和应用程序主循环PM0257-Rev3page35/76图10.
BLEMAC地址存储BlueNRG-1、BlueNRG-2设备没有有效的预分配MAC地址,但有唯一的序列号(对用户为只读).
唯一序列号是存储在地址0x100007F4中的六字节值:它作为两个字(8字节)存储在地址0x100007F4和0x100007F8中,并用0xAA55填充唯一序列号.
静态随机地址是在设备第一次启动时生成并被写入闪存的指定位置.
Flash上的值是设备使用的实际值:用户每次重置设备时,堆栈都会检查专用Flash区域是否存在有效数据并使用该数据(FLASH上的特殊有效标记用于标识是否存在有效数据).
如果用户执行了批量擦除,则会删除存储值(包括标记),下一次设备重启时又会生成新的MAC地址,并存储到闪存的指定位置上.
当启用了私有时,按照低功耗蓝牙规范使用私有地址.
关于私有地址的更多信息,请参考第1.
7节安全管理器(SM).
3.
1.
2设置发送功率在初始化阶段,用户还可以使用以下API选择发送功率:aci_hal_set_tx_power_level(高功率水平)下面是将无线发送功率设置为高功率和--2dBm输出功率的伪代码示例:ret=aci_hal_set_tx_power_level(1,4);关于该API和相关参数的完整描述,请参考第5节参考中的蓝牙LE栈API和事件文档.
根据保密协议–不可复制PM0257初始化阶段和应用程序主循环PM0257-Rev3page36/763.
2服务和特征配置为了添加服务和相关特征,用户应用必须定义要寻址的特定配置文件:1.
标准配置文件由蓝牙SIG组织定义.
用户必须遵循配置文件规范和服务、特征规范文档,以便使用定义的相关配置文件、服务和特征16位UUID实现它们(请参考蓝牙SIG网页:www.
bluetooth.
org/en-%20us/specification/adopted-specifications).
2.
专有的非标准配置文件.
用户必须定义其自己的服务和特征.
在本例中,需要128位UUID,并且由用户自己生成(请参考UUID生成器网页:www.
famkruithof.
net/uuid/uuidgen).
可使用以下指令添加服务:aci_gatt_add_service(uint8_tService_UUID_Type,Service_UUID_t*Service_UUID,uint8_tService_Type,uint8_tMax_Attribute_Records,uint16_t*Service_Handle);该指令返回服务句柄的指针(Service_Handle),用于标识用户应用中的该服务.
可使用以下指令为该服务添加特征:aci_gatt_add_char(uint16_tService_Handle,uint8_tChar_UUID_Type,Char_UUID_t*Char_UUID,uint8_tChar_Value_Length,uint8_tChar_Properties,uint8_tSecurity_Permissions,uint8_tGATT_Evt_Mask,uint8_tEnc_Key_Size,uint8_tIs_Variable,uint16_t*Char_Handle);该指令返回特征句柄的指针(Char_Handle),用于标识用户应用中的该特征.
有关aci_gatt_add_service()和aci_gatt_add_char()函数参数的详细描述,请参考Library\Bluetooth_LE\inc\bluenrg1_events.
h头文件.
以下伪代码示例描述了在专有非标准配置文件中添加服务和两个关联的特征所要执行的步骤.

/*ServiceandcharacteristicUUIDsvariables.
RefertotheheaderfileLibrary\Bluetooth_LE\inc\bluenrg1_api.
hforadetaileddescription*/Service_UUID_tservice_uuid;Char_UUID_tchar_uuid;tBleStatusAdd_Server_Services_Characteristics(void){tBleStatusret=BLE_STATUS_SUCCESS;/*Thefollowing128bitsUUIDshavebeengeneratedfromtherandomUUIDgenerator:generator:D973F2E0-B19E-11E2-9E96-0800200C9A66:Service128bitsUUIDD973F2E1-B19E-11E2-9E96-0800200C9A66:Characteristic_1128bitsUUIDD973F2E2-B19E-11E2-9E96-0800200C9A66:Characteristic_2128bitsUUID*//*Service128bitsUUID*/constuint8_tuuid[16]={0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe0,0xf2,0x73,0xd9};/*Characteristic_1128bitsUUID*/constuint8_tcharUuid_1[16]={0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe1,0xf2,0x73,0xd9};/*Characteristic_2128bitsUUID*/constuint8_tcharUuid_2[16]={0x66,0x9a,0x0c,0x20,0x00,0x08,0x96,0x9e,0xe2,0x11,0x9e,0xb1,0xe2,0xf2,0x73,0xd9};根据保密协议–不可复制PM0257服务和特征配置PM0257-Rev3page37/76Osal_MemCpy(&service_uuid.
Service_UUID_128,uuid,16);/*Addtheservicewithservice_uuid128bitsUUIDtotheGATTserverdatabase.
database.
TheservicehandleService_Handleisreturned.
*/ret=aci_gatt_add_service(UUID_TYPE_128,&service_uuid,PRIMARY_SERVICE,6,&Service_Handle);if(ret!
=BLE_STATUS_SUCCESS)return(ret);Osal_MemCpy(&char_uuid.
Char_UUID_128,charUuid_1,16);/*AddthecharacteristicwithcharUuid_1128bitsUUIDtotheserviceService_Handle.
Service_Handle.
Thischaracteristichas20asMaximumlengthofthecharacteristicvalue,Notifyproperties(CHAR_PROP_NOTIFY),nosecuritypermissions(ATTR_PERMISSION_NONE),noGATTeventmask(0),16askeyencryptionsize,andvariable-lengthcharacteristic(1).
Thecharacteristichandle(CharHandle_1)isreturned.
*/ret=aci_gatt_add_char(Service_Handle,UUID_TYPE_128,&char_uuid,20,CHAR_PROP_NOTIFY,ATTR_PERMISSION_NONE,0,16,1,&CharHandle_1);if(ret!
=BLE_STATUS_SUCCESS)return(ret);Osal_MemCpy(&char_uuid.
Char_UUID_128,charUuid_2,16);/*AddthecharacteristicwithcharUuid_2128bitsUUIDtotheserviceService_Handle.
Service_Handle.
Thischaracteristichas20asMaximumlengthofthecharacteristicvalue,Read,WriteandWriteWithoutResponseproperties,nosecuritypermissions(ATTR_PERMISSION_NONE),notifyapplicationwhenattributeiswritten(GATT_NOTIFY_ATTRIBUTE_WRITE)asGATTeventmask,16askeyencryptionsize,andvariable-lengthcharacteristic(1).
Thecharacteristichandle(CharHandle_2)isreturned.
*/ret=aci_gatt_add_char(Service_Handle,UUID_TYPE_128,&char_uuid,20,CHAR_PROP_WRITE|CHAR_PROP_WRITE_WITHOUT_RESP,ATTR_PERMISSION_NONE,GATT_NOTIFY_ATTRIBUTE_WRITE,16,1,&&CharHandle_2);if(ret!
=BLE_STATUS_SUCCESS)return(ret);}/*endAdd_Server_Services_Characteristics()*/3.
3创建连接:可发现和可连接API为在BLEGAP中央(主)设备和BLEGAP外围(从)设备之间建立连接,可根据表39.
GAP模式API、表40.
GAP发现流程API和表41.
连接流程API中的描述,并通过使用头文件Library\Bluetooth_LE\inc\bluenrg1_api.
h中所提供的相关BLE栈API,使用GAP可发现/可连接模式和流程.
GAP外设可发现和可连接模式API可按照以下API的描述使用不同类型的可发现和可连接模式:表39.
GAP模式APIAPI支持的广告事件类型说明aci_gap_set_discoverable()0x00:可连接非定向广告(默认)将设备设置为一般可发现模式.
设备处于可发现模式,直至设备发布aci_gap_set_non_discoverable()API.
0x02:可扫描非定向广告0x03:不可连接非定向广告aci_gap_set_limited_discoverable()0x00:可连接非定向广告(默认)将设备设置为有限可发现模式.
设备处于可发现模式的最长时间为TGAP(lim_adv_timeout)=180秒.
随时可通过调用aci_gap_set_non_discoverable()API禁用广告.
0x02:可扫描非定向广告0x03:不可连接非定向广告aci_gap_set_non_discoverable()NA将设备设置为不可发现模式.
该指令禁用LL广告并将设备设置为待机状态.
根据保密协议–不可复制PM0257创建连接:可发现和可连接APIPM0257-Rev3page38/76API支持的广告事件类型说明aci_gap_set_direct_connectable()NA将设备设置为定向可连接模式.
设备的定向可连接模式仅持续1.
28秒.
如果在此期间没有建立连接,设备将进入不可发现模式,并且必须明确地重新启用广告功能.
aci_gap_set_non_connectable()0x02:可扫描非定向广告使设备进入不可连接模式.
0x03:不可连接非定向广告aci_gap_set_undirect_connectable()NA使设备进入非定向可连接模式.
表40.
GAP发现流程APIAPI说明aci_gap_start_limited_discovery_proc()启动有限发现流程.
命令控制器开始主动扫描.
当该流程启动时,仅处于有限可发现模式的设备返回上层.
aci_gap_start_general_discovery_proc()启动一般发现流程.
命令控制器开始主动扫描.
表41.
连接流程APIAPI说明aci_gap_start_auto_connection_establish_proc()启动自动连接建立流程.
主机将指定设备添加到控制器的白名单,在发起方过滤策略被设置为"忽略白名单,只处理来自特定设备的可连接广播数据包"的情况下,GAP从控制器调用创建连接.
aci_gap_create_connection()启动直接连接建立流程.
在发起方过滤策略被设置为"只对特定设备忽略白名单并处理可连接广告数据包"的情况下,GAP从控制器调用创建连接.
aci_gap_start_general_connection_establish_proc()启动通用连接建立流程.
在扫描仪过滤策略设置为"接受所有广告数据包"的情况下,主机在控制器中启用扫描,并使用事件callbackhci_le_advertising_report_event()将扫描结果中的所有设备发送至上层.
aci_gap_start_selective_connection_establish_proc()启动选择性连接建立流程.
GAP将指定设备地址添加到白名单中,并在扫描仪过滤策略设置为"仅接受来自白名单中的设备的数据包"的控制器中启用扫描.
通过事件回调hci_le_advertising_report_event()将找到的所有设备发送至上层.
aci_gap_terminate_gap_proc()终止指定的GAP流程.
3.
3.
1设置可发现模式并使用直接连接建立流程下列伪代码示例仅描述了使GAP外设进入一般可发现模式,以及通过直接连接建立流程将GAP中央设备直接连接到该GAP外设要执行的特定步骤.
注意:假设在初始化阶段设置了设备公共地址,如下所示:uint8_tbdaddr[]={0x12,0x34,0x00,0xE1,0x80,0x02};ret=aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,CONFIG_DATA_PUBADDR_LEN,bdaddr);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");/*GAPPeripheral:generaldiscoverablemode(andnoscanresponseissent)*/voidGAP_Peripheral_Make_Discoverable(void){tBleStatusret;constcharlocal_name[]={AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G','1','T','e','s','t'};/*disablescanresponse:passivescan*/hci_le_set_scan_response_data(0,NULL);根据保密协议–不可复制PM0257创建连接:可发现和可连接APIPM0257-Rev3page39/76/*PuttheGAPperipheralingeneraldiscoverablemode:Advertising_Type:ADV_IND(undirectedscannableandconnectable);Advertising_Interval_Min:100;Advertising_Interval_Max:100;Own_Address_Type:PUBLIC_ADDR(publicaddress:0x00);Adv_Filter_Policy:NO_WHITE_LIST_USE(nowhitlistisused);Local_Name_Lenght:13Local_Name:BlueNRG1Test;Service_Uuid_Length:0(noservicetobeadvertised);Service_Uuid_List:NULL;Slave_Conn_Interval_Min:0(Slaveconnectioninternalminimumvalue);Slave_Conn_Interval_Max:0(Slaveconnectioninternalmaximumvalue).
*/ret=aci_gap_set_discoverable(ADV_IND,100,100,PUBLIC_ADDR,NO_WHITE_LIST_USE,sizeof(local_name),local_name,0,NULL,0,0);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");}/*endGAP_Peripheral_Make_Discoverable()*//*GAPCentral:directconnectionestablishmentproceduretoconnecttotheGAPPeripheralindiscoverablemode*/voidGAP_Central_Make_Connection(void){/*StartthedirectconnectionestablishmentproceduretotheGAPperipheraldeviceingeneraldiscoverablemodeusingthefollowingconnectionparameters:LE_Scan_Interval:0x4000;LE_Scan_Window:0x4000;Peer_Address_Type:PUBLIC_ADDR(GAPperipheraladdresstype:publicaddress);Peer_Address:{0xaa,0x00,0x00,0xE1,0x80,0x02};Own_Address_Type:PUBLIC_ADDR(deviceaddresstype);Conn_Interval_Min:40(Minimumvaluefortheconnectioneventinterval);interval);Conn_Interval_Max:40(Maximumvaluefortheconnectioneventinterval);interval);Conn_Latency:0(Slavelatencyfortheconnectioninanumberofconnectionevents);connectionevents);Supervision_Timeout:60(SupervisiontimeoutfortheLELink);Minimum_CE_Length:2000(MinimumlengthofconnectionneededfortheLEconnection);LEconnection);Maximum_CE_Length:2000(MaximumlengthofconnectionneededfortheLEconnection).
*/tBDAddrGAP_Peripheral_address={0xaa,0x00,0x00,0xE1,0x80,0x02};ret=aci_gap_create_connection(0x4000,0x4000,PUBLIC_ADDR,GAP_Peripheral_address,PUBLIC_ADDR,40,40,0,60,2000,2000);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");}/*GAP_Central_Make_Connection(void)*/提示1.
如果在GAP流程终止时返回了ret=BLE_STATUS_SUCCESS,则调用hci_le_connection_complete_event()事件回调,以指示已与GAP_Peripheral_address建立连接(在GAP外设上返回相同事件).
2.
可通过发出APIaci_gap_terminate_gap_proc()明确终止连接流程.
3.
aci_gap_create_connection()的最后两个参数Minimum_CE_Length和Maximum_CE_Length是BLE连接所需连接事件的长度.
这些参数允许用户指定主设备必须为单个从设备分配的时间量,因此必须精心选择.
具体来说,当主设备连接更多从设备时,每个从设备的连接间隔必须等于其他连接间隔或是它们的根据保密协议–不可复制PM0257创建连接:可发现和可连接APIPM0257-Rev3page40/76倍数,并且用户不得为每个从设备设置过长的连接事件长度.
有关时序分配策略的更多信息,请参考第4节BLE多连接时序策略.
3.
3.
2设置可发现模式并使用一般发现流程(主动扫描)下列伪代码示例仅描述了使GAP外设进入一般可发现模式,以及GAP中央设备启动一般发现流程(以便发现无线传输范围内的设备)要执行的特定步骤.
提示假设在初始化阶段设置了设备公共地址,如下所示:uint8_tbdaddr[]={0x12,0x34,0x00,0xE1,0x80,0x02};ret=aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,CONFIG_DATA_PUBADDR_LEN,bdaddr);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");/*GAPPeripheral:generaldiscoverablemode(scanresponsesaresent):*/voidGAP_Peripheral_Make_Discoverable(void){tBleStatusret;constcharlocal_name[]={AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};/*Asscanresponsedata,aproprietary128bitsServiceUUIDisused.
由于长度限制(31字节),此128位数据不能插入广告数据包(ADV_IND).
AD类型描述:0x11:长度0x06:128位服务UUID类型0x8a,0x97,0xf7,0xc0,0x85,0x06,0x11,0xe3,0xba,0xa7,0x08,0x00,0x20,0x0c,0x9a,0x66:128bitsServiceUUID*/uint8_tServiceUUID_Scan[18]={0x11,0x06,0x8a,0x97,0xf7,0xc0,0x85,0x06,0x11,0xe3,0xba,0xa7,0x08,0x00,0x2,0x0c,0x9a,0x66};/*EnablescanresponsetobesentwhenGAPperipheralreceivesscanrequestsfromGAPCentralperforminggeneraldiscoveryprocedure(activescan)*/hci_le_set_scan_response_data(18,ServiceUUID_Scan);/*PuttheGAPperipheralingeneraldiscoverablemode:Advertising_Type:ADV_IND(undirectedscannableandconnectable);Advertising_Interval_Min:100;Advertising_Interval_Max:100;Own_Address_Type:PUBLIC_ADDR(publicaddress:0x00);Advertising_Filter_Policy:NO_WHITE_LIST_USE(nowhitlistisused);Local_Name_Length:8Local_Name:BlueNRG;Service_Uuid_Length:0(noservicetobeadvertised);Service_Uuid_List:NULL;Slave_Conn_Interval_Min:0(Slaveconnectioninternalminimumvalue);Slave_Conn_Interval_Max:0(Slaveconnectioninternalmaximumvalue).
*/ret=aci_gap_set_discoverable(ADV_IND,100,100,PUBLIC_ADDR,NO_WHITE_LIST_USE,sizeof(local_name),local_name,0,NULL,0,0);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");}/*endGAP_Peripheral_Make_Discoverable()*//*GAPCentral:startgeneraldiscoveryproceduretodiscovertheGAPperipheraldeviceindiscoverablemode*/voidGAP_Central_General_Discovery_Procedure(void){tBleStatusret;/*Startthegeneraldiscoveryprocedure(activescan)usingthefollowingparameters:parameters:LE_Scan_Interval:0x4000;LE_Scan_Window:0x4000;Own_address_type:0x00(publicdeviceaddress);根据保密协议–不可复制PM0257创建连接:可发现和可连接APIPM0257-Rev3page41/76Filter_Duplicates:0x00(duplicatefilteringdisabled);*/ret=aci_gap_start_general_discovery_proc(0x4000,0x4000,0x00,0x00);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");}通过hci_le_advertising_report_event()事件回调提供流程响应.
通过aci_gap_proc_complete_event()事件回调(其Procedure_Code参数等于GAP_GENERAL_DISCOVERY_PROC(0x2))来指示流程结束.
/*Thiscallbackiscalledwhenanadvertisingreportisreceived*/voidhci_le_advertising_report_event(uint8_tNum_Reports,Advertising_Report_tAdvertising_Report[]){/*Advertising_Reportcontainsalltheexpectedparameters.
UserapplicationshouldaddcodefordecodingthereceivedAdvertising_Reporteventdatabasedonthespecificevt_type(ADV_IND,SCAN_RSP,.
.
)*//*Example:storethereceivedAdvertising_Reportfields*/uint8_tbdaddr[6];/*typeofthepeeraddress(PUBLIC_ADDR,RANDOM_ADDR)*/uint8_tbdaddr_type=Advertising_Report[0].
Address_Type;/*eventtype(advertisingpacketstypes)*/uint8_tevt_type=Advertising_Report[0].
Event_Type;/*RSSIvalue*/uint8_tRSSI=Advertising_Report[0].
RSSI;/*addressofthepeerdevicefoundduringdiscoveryprocedure*/Osal_MemCpy(bdaddr,Advertising_Report[0].
Address,6);/*lengthofadvertisingorscanresponsedata*/uint8_tdata_length=Advertising_Report[0].
Length_Data;/*data_lengthoctetsofadvertisingorscanresponsedataformattedareonAdvertising_Report[0].
Datafield:tobestored/filteredbasedonspecificuserapplicationscenario*/}/*hci_le_advertising_report_event()*/具体来说,在这一特定背景下,由于GAP外设处于可发现模式并启用了扫描响应,GAP中央设备上的hci_le_advertising_report_event()回调将发起下列事件:1.
具有广告数据包类型(evt_type=ADV_IND)的广告报告事件2.
具有扫描响应数据包类型(evt_type=SCAN_RSP)的广告报告事件表42.
ADV_IND事件类型事件类型地址类型地址广告数据RSSI0x00(ADV_IND)0x00(公共地址);0x0280E10034120x02,0x01,0x06,0x08,0x09,0x42,0x6C,0x75,0x65,0x4E,0x52,0x47,0x02,0x0A,0xFE0xCE广告数据可作如下解释(请参考第5节参考中的蓝牙规范版本):根据保密协议–不可复制PM0257创建连接:可发现和可连接APIPM0257-Rev3page42/76表43.
ADV_IND广告数据AD类型标记字段本地名称字段发送功率水平0x02:字段长度0x01:AD类型标记0X06:0x110(第2位:BR/EDR不支持;第1位:一般可发现模式)0x08:字段的长度0x09:完整的本地名称类型0x42,0x6C,0x75,0x65,0x4E0x52,0x47:BlueNRG0x02:字段的长度0x0A:发送功率类型0x08:功率值表44.
SCAN_RSP事件类型事件类型地址类型地址扫描响应数据RSSI0x04(SCAN_RSP)0x01(随机地址)0x0280E10034120x12,0x66,0x9A,0x0C,0x20,0x00,0x08,0xA7,0xBA,0xE3,0x11,0x06,0x85,0xC0,0xF7,0x97,0x8A,0x06,0x110xDA扫描响应数据可作如下解释(请参考蓝牙规范):表45.
扫描响应数据扫描响应数据0x12:数据长度0x11:服务UUID广告数据的长度;0x06:128位服务UUID类型;0x66,0x9A,0x0C,0x20,0x00,0x08,0xA7,0xBA,0xE3,0x11,0x06,0x85,0xC0,0xF7,0x97,0x8A:128位服务UUID3.
4BLE栈事件和事件回调每次有需要处理的BLE栈事件时,BLE栈库通过特定事件回调将该事件通知用户应用.
事件回调是由用户应用程序定义并被BLE栈调用的函数,而API则是由栈定义而被用户应用程序调用的函数.
BlueNRG-1、BlueNRG-2BLE栈事件回调原型在bluenrg1_events.
h文件中定义.
所有事件回调均可以采用弱定义,以便让每个事件回调都有一个定义.
因此,用户根据其自身应用场景确定要调用的所需设备事件回调,以及要执行的相关应用特定操作.
在实现BLE应用时,最常见且使用最广泛的BLE栈事件是与发现、连接、终止流程、服务、特征、特征描述符发现流程、GATT客户端上的属性通知/指示事件和GATT服务器上的属性修改事件相关的事件.
表46.
BLE栈:主要事件回调事件回调说明调用设备hci_disconnection_complete_event()连接终止GAP中央设备/外设hci_le_connection_complete_event()向构成连接的两个设备指示新的连接已建立GAP中央设备/外设aci_gatt_attribute_modified_event()如果事件启用,由GATT服务器在客户端修改服务器上的任何属性时生成GATT服务器根据保密协议–不可复制PM0257BLE栈事件和事件回调PM0257-Rev3page43/76事件回调说明调用设备aci_gatt_notification_event()由GATT客户端在服务器通知客户端上的任何属性时生成GATT客户端aci_gatt_indication_event()由GATT客户端在服务器指示客户端上的任何属性时生成GATT客户端aci_gap_pass_key_req_event()当需要密钥用于配对时,由安全管理器向应用生成.
在接收到该事件时,应用必须以aci_gap_pass_key_resp()API响应GAP中央设备/外设aci_gap_pairing_complete_event()在配对过程成功完成或发生配对过程超时或配对失败时生成GAP中央设备/外设aci_gap_bond_lost_event()在配对请求发出时生成的事件,响应来自主设备(之前已与从设备绑定)的从设备安全请求.
在接收到该事件时,上层必须发出指令aci_gap_allow_rebond(),以允许从设备继续完成与主设备的配对过程GAP外设设备aci_att_read_by_group_type_resp_event()发送按组读取型响应,以回复接收到的按组读取型请求,包含已读取的属性的句柄和值GATT客户端aci_att_read_by_type_resp_event()发送按类型读取的响应,以回复接收到的按类型读取的请求请求并包含已读取属性的句柄和值GATT客户端aci_gatt_proc_complete_event()GATT流程已完成GATT客户端hci_le_advertising_report_event在上层启动GAP流程之一后,在扫描期间发现设备时GAP层向上层生成的事件GAP中央设备有关BLE事件和相关格式的详细说明,请参考第5节参考中的BlueNRG-1、BlueNRG-2蓝牙LE栈API和事件文档.
以下伪代码提供了处理一些描述的BLE栈事件(断开完成事件、连接完成事件、GATT属性修改事件、GATT通知事件)的事件回调示例:/*Thiseventcallbackindicatesthedisconnectionfromapeerdevice.
ItiscalledintheBLEradiointerruptcontext.
*/voidhci_disconnection_complete_event(uint8_tStatus,uint16_tConnection_Handle,uint8_tReason){/*AddusercodeforhandlingBLEdisconnectioncompleteeventbasedonapplicationscenario.
applicationscenario.
*/}/*endhci_disconnection_complete_event()*//*Thiseventcallbackindicatestheendofaconnectionprocedure.
*/voidhci_le_connection_complete_event(uint8_tStatus,uint16_tConnection_Handle,uint8_tRole,uint8_tPeer_Address_Type,uint8_tPeer_Address[6],uint16_tConn_Interval,uint16_tConn_Latency,uint16_tSupervision_Timeout,uint8_tMaster_Clock_Accuracy)根据保密协议–不可复制PM0257BLE栈事件和事件回调PM0257-Rev3page44/76{/*AddusercodeforhandlingBLEconnectioncompleteeventbasedonapplicationscenario.
applicationscenario.
NOTE:RefertoheaderfileLibrary\Bluetooth_LE\inc\bluenrg1_events.
hforacompletedescriptionoftheeventcallbackparameters.
*//*Storeconnectionhandle*/connection_handle=Connection_Handle;.
.
.
}/*endhci_le_connection_complete_event()*/#ifGATT_SERVER/*Thiseventcallbackindicatesthatanattributehasbeenmodifiedfromapeerdevice.
peerdevice.
*/voidaci_gatt_attribute_modified_event(uint16_tConnection_Handle,uint16_tAttr_Handle,uint16_tOffset,uint8_tAttr_Data_Length,uint8_tAttr_Data[]){/*Addusercodeforhandlingattributemodificationeventbasedonapplicationscenario.
applicationscenario.
NOTE:RefertoheaderfileLibrary\Bluetooth_LE\inc\bluenrg1_events.
hforacompletedescriptionoftheeventcallbackparameters.
*/.
.
.
}/*endaci_gatt_attribute_modified_event()*/#endif/*GATT_SERVER*/#ifGATT_CLIENT/*Thiseventcallbackindicatesthatanattributenotificationhasbeenreceivedfromapeerdevice.
receivedfromapeerdevice.
*/voidaci_gatt_notification_event(uint16_tConnection_Handle,uint16_tAttribute_Handle,uint8_tAttribute_Value_Length,uint8_tAttribute_Value[]){/*Addusercodeforhandlingattributemodificationeventbasedonapplicationscenario.
applicationscenario.
NOTE:RefertoheaderfileLibrary\Bluetooth_LE\inc\bluenrg1_events.
hforacompletedescriptionoftheeventcallbackparameters.
*/.
.
.
}/*endaci_gatt_notification_event()*/#endif/*GATT_CLIENT*/3.
5安全(配对和绑定)本节介绍在两个设备之间建立配对要使用的主要功能(验证设备身份,加密链路,以及分发下一次重新连接时要使用的密钥).
为了与设备成功配对,必须根据所选设备的可用IO能力正确配置IO能力.
aci_gap_set_io_capability(io_capability)应与下列io_capability值之一一起使用:0x00:'IO_CAP_DISPLAY_ONLY'0x01:'IO_CAP_DISPLAY_YES_NO',0x02:'KEYBOARD_ONLY'根据保密协议–不可复制PM0257安全(配对和绑定)PM0257-Rev3page45/760x03:'IO_CAP_NO_INPUT_NO_OUTPUT'0x04:'IO_CAP_KEYBOARD_DISPLAY'2个BlueNRG设备(Device_1、Device_2)的输入密钥示例下列伪代码示例仅描述了使用输入密钥法将两个设备配对时要执行的特定步骤.

如表11.
计算临时密钥(TK)的方法所述,为了选择输入密钥作为安全方法,必须为Device_1、Device_2设置IO能力.
在本例中,对Device_1选择"仅显示",对Device_2选择"仅键盘",如下所示:/*Device_1:*/tBleStatusret;\ret=aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");/*Device_2:*/tBleStatusret;ret=aci_gap_set_io_capability(IO_CAP_KEYBOARD_ONLY);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");在定义了IO能力后,应使用aci_gap_set_authentication_requirement()设置设备需要的所有安全验证要求(MITM模式(链路是否经过验证),是否有OOB数据,是否使用固定引脚,以及是否启用绑定).
下列伪代码示例仅描述了为设备设置以下验证要求要执行的特定步骤:"MITM保护,无OOB数据,不使用固定引脚":这一配置用于验证链路和在使用输入密钥法的配对过程中使用非固定引脚.

ret=aci_gap_set_authentication_requirement(BONDING,/*bondingisenabled*/MITM_PROTECTION_REQUIRED,SC_IS_SUPPORTED,/*Secureconnectionsupportedbutoptional*/KEYPRESS_IS_NOT_SUPPORTED,7,/*Minencryptionkeysize*/16,/*Maxencryptionkeysize*/keysize*/0x01,/*fixedpinisnotused*/0x123456,/*fixedpin*/0x00/*PublicIdentityaddresstype*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");在定义了安全IO能力和验证要求后,应用可通过以下方式启动配对流程:1.
在GAP外围(从)设备上使用aci_gap_slave_security_req()(它向主设备发送从设备安全请求):tBleStatusret;ret=aci_gap_slave_security_req(conn_handle,if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");或在GAP中央(主)设备上使用aci_gap_send_pairing_req().
由于未设置固定配对码,一旦两个设备之一启动了配对流程,BLE设备调用aci_gap_pass_key_req_event()事件回调(具有相关连接句柄),以要求用户应用提供用于建立加密密钥的密码.
BLE应用必须通过使用aci_gap_pass_key_resp(conn_handle,passkey)API提供正确密码.
当在Device_1上调用aci_gap_pass_key_req_event()回调时,它应该生成一个随机配对码,并通过aci_gap_pass_key_resp()API对其进行设置,如下所示:voidaci_gap_pass_key_req_event(uint16_tConnection_Handle){tBleStatusret;uint32_tpin;/*Generatearandompinwithanuserspecificfunction*/pin=generate_random_pin();ret=aci_gap_pass_key_resp(Connection_Handle,pin);根据保密协议–不可复制PM0257安全(配对和绑定)PM0257-Rev3page46/76if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");}由于Device_1的I/O能力被设置为"仅显示",它应在设备显示装置上显示生成的引脚.
由于Device_2的I/O能力被设置为"仅键盘",用户可以使用键盘,并通过相同的aci_gap_pass_key_resp()API为Device_2提供Device_1上显示的配对码.
或者,如果用户想要设置具有固定配对码0x123456的验证要求(无需输入密钥事件),可以使用下列伪代码:tBleStatusret;ret=aci_gap_set_auth_requirement(BONDING,/*bondingisenabled*/MITM_PROTECTION_REQUIRED,SC_IS_SUPPORTED,/*Secure安全连接但为可选*/KEYPRESS_IS_NOT_SUPPORTED,7,/*Minencryptionkeysize*/keysize*/16,/*Maxencryptionkeysize*/keysize*/0x00,/*fixedpinisused*/0x123456,/*fixedpin*/0x00/*PublicIdentityaddresstype*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");提示1.
如果通过调用所述API(aci_gap_slave_security_req()或aci_gap_send_pairing_req())启动配对流程并返回值ret=BLE_STATUS_SUCCESS,则在流程结束时,将调用aci_gap_pairing_complete_event()事件回调,以便在回调状态参数上指示配对状态:–0x00:配对成功–0x01:配对超时–0x02:配对失败如果失败,则原因参数提供配对失败原因代码(如果状态参数返回成功或超时,则为0).
parameterreturnssuccessortimeout).
2.
如果2个设备成功配对,将在首次连接时自动加密链路.
如果还启用了绑定(存储了密钥以备后用),在重新连接2个设备时,可以直接加密链路(无需再次执行配对流程).
用户应用可以直接使用相同的API,不执行配对流程而直接加密链路:–aci_gap_slave_security_req)(对于GAP外围(从)设备)或–aci_gap_send_pairing_req()(对于GAP中央(主)设备).
3.
如果从设备已与主设备绑定,可以向主设备发送从设备安全请求以加密链路.
当收到从设备安全请求时,主设备可以加密链路、启动配对流程或拒绝请求.
通常情况下,主设备只加密链路,不执行配对流程.
相反地,如果主设备启动配对流程,这意味着主设备因某些原因丢失了绑定信息,因此必须重新启动配对流程.

因此,从设备调用aci_gap_bond_lost_event()事件回调,以通知用户应用其已不再与之前绑定的主设备绑定.
然后,从设备应用可以决定允许安全管理器完成配对流程,并通过调用指令aci_gap_allow_rebond()与主设备重新绑定,或者只是关闭连接并将安全问题通知用户.

3.
6服务和特征发现本节介绍在两个设备建立连接后,允许BlueNRG-1、BlueNRG-2GAP中央设备发现GAP外设服务和特征的主要函数.
在下面的伪代码示例中,使用了传感器感测演示服务和特征及相关句柄作为参考服务和特征.
此外,假设GAP中央设备连接了运行传感器演示配置文件应用的GAP外设.
GAP中央设备使用服务和发现流程寻找GAP外设传感器感测演示服务和特征.
根据保密协议–不可复制PM0257服务和特征发现PM0257-Rev3page47/76表47.
BLE传感器感测演示服务和特征句柄服务特征服务/特征句柄特征值句柄特征客户端描述符配置句柄特征格式句柄加速服务NA0x000CNANANA自由落体特征0x000D0x000E0x000FNA加速特征0x00100x00110x0012NA环境服务NA0x0013NANANA温度特征0x00140xx0015NA0x0016压力特性0x00170xx0018NA0x0019关于传感器感测演示的详细信息,请参考BlueNRG-1_2DK用户手册和BlueNRG-1_2DK软件包中的传感器演示源代码(参见第5节参考).
服务发现流程与相关GATT事件.
下面是包含相关描述的服务发现API列表:表48.
服务发现流程API发现服务API说明aci_gatt_disc_all_primary_services()此API启动GATT客户端流程以发现GATT服务器上的所有主要服务.
在GATT客户端连接了设备,并想要寻找设备上提供的所有主要服务以确定其功能时使用.
aci_gatt_disc_primary_service_by_uuid()此API启动GATT客户端流程,以通过使用其UUID发现GATT服务器上的主要服务.
在GATT客户端连接了设备并想要寻找特定服务而无需获取任何其他服务时使用.
aci_gatt_find_included_services()此API启动寻找所有已包含服务的流程.
在GATT客户端已发现主要服务并想要发现次要服务时使用.
以下伪代码示例描述了aci_gatt_disc_all_primary_services()API:/*GAPCentralstartsadiscoveryallservicesprocedure:conn_handleistheconnectionhandlereturnedonhci_le_advertising_report_event()eventcallbackhci_le_advertising_report_event()eventcallback*/if(aci_gatt_disc_all_primary_services(conn_handle)!
=BLE_STATUS_SUCCESS){PRINTF("Failure.
\n");}通过aci_att_read_by_group_type_resp_event()事件回调提供流程响应.
通过aci_gatt_proc_complete_event()事件回调()调用指示流程结束.
/*ThiseventisgeneratedinresponsetoaReadByGroupTypeRequest:refertoaci_gatt_disc_all_primary_services()*/voidaci_att_read_by_group_type_resp_event(uint16_tConn_Handle,uint8_tAttr_Data_Length,uint8_tData_Length,uint8_tAtt_Data_List[]);{根据保密协议–不可复制PM0257服务和特征发现PM0257-Rev3page48/76/*Conn_Handle:与响应相关的连接句柄;Attr_Data_Length:每个属性数据的长度;Data_Length:Attribute_Data_List的八位组长度;Att_Data_List:蓝牙核心规范所定义的属性数据列表.
specifications.
一系列属性句柄、结束组句柄、属性值元组:[2个八位组的属性句柄、2个八位组的结束组句柄,(Attribute_Data_Length-4个八位组)的属性值].
*//*AddusercodefordecodingtheAtt_Data_Listfieldandgettingtheservicesattributehandle,endgrouphandleandserviceuuid*/}/*aci_att_read_by_group_type_resp_event()*/就传感器感测演示而言,GAP中央设备应用应获取三个按组读取型响应事件(通过相关的aci_att_read_by_group_type_resp_event()事件回调),并具有以下回调参数值.
第一个按组类型读取的响应事件回调参数:Connection_Handle:0x0801(连接句柄);Attr_Data_Length:0x06(每个已发现服务数据(服务句柄、结束组句柄、服务UUID)的长度);Data_Length:0x0C(Attribute_Data_List的八位组长度)Att_Data_List:0x0C字节如下:表49.
第一个按组类型读取的响应事件回调参数句柄属性结束组句柄服务UUID注释0x00010x00040x1801属性配置文件服务(由GATT_Init()添加).
标准16位服务UUID0x00050x000B0x1800GAP配置文件服务(由GAP_Init()添加).
标准16位服务UUID.
第二个按组类型读取的响应事件回调参数:Conn_Handle:0x0801(连接句柄);Attr_Data_Length:0x14(每个已发现服务数据(服务句柄、结束组句柄、服务UUID)的长度);Data_Length:0x14(Attribute_Data_List的八位组长度);Att_Data_List:0x14字节如下:表50.
第二个按组类型读取的响应事件回调参数句柄属性结束组句柄服务UUID注释0x000C0x00120x02366E80CF3A11E19AB40002A5D5C51B128位服务专有UUID的加速服务第三个按组类型读取的响应事件回调参数:Connection_Handle:0x0801(连接句柄);Attr_Data_Length:0x14(每个已发现服务数据(服务句柄、结束组句柄和服务uuid);Data_Length:0x14(Attribute_Data_List的八位组长度);Att_Data_List:0x14字节如下:根据保密协议–不可复制PM0257服务和特征发现PM0257-Rev3page49/76表51.
第三个按组类型读取的响应事件回调参数句柄属性结束组句柄服务UUID注释0x00130x00190x42821A40E47711E282D00002A5D5C51B128位服务专有UUID的环境服务就传感器感测演示而言,当发现所有主要服务流程完成时,在GAP中央设备应用上调用aci_gatt_proc_complete_event()事件回调,并具有以下参数:Conn_Handle:0x0801(连接句柄);Error_Code:0x003.
6.
1特征发现流程与相关GATT事件下面是包含相关描述的特征发现API列表:表52.
特征发现流程API发现服务API说明aci_gatt_disc_all_char_of_service()此API启动GATT流程以发现给定服务的所有特征aci_gatt_disc_char_by_uuid()此API启动GATT流程以发现通过UUID指定的所有特征aci_gatt_disc_all_char_desc()此API启动GATT服务器上发现所有特征描述符的流程就BLE传感器感测演示而言,下面是描述GAP中央设备应用如何发现所有加速服务特征的简单伪代码(请参考表1第二个按组类型读取的响应事件回调参数):uint16_tservice_handle=0x000C;uint16_tend_group_handle=0x0012;/*GAPCentralstartsadiscoveryallthecharacteristicsofaserviceprocedure:conn_handleistheconnectionhandlereturnedonhci_le_advertising_report_event()eventcallback*/hci_le_advertising_report_event()eventcallback*/if(aci_gatt_disc_all_char_of_service(conn_handle,service_handle,/*Servicehandle*/end_group_handle/*Endgrouphandle*/);)!
=BLE_STATUS_SUCCESS){PRINTF("Failure.
\n");}通过aci_att_read_by_type_resp_event()事件回调提供流程响应.
通过aci_gatt_proc_complete_event()事件回调调用指示流程结束.
/*Thiseventisgeneratedinresponsetoaci_att_read_by_type_req().
Refertoaci_gatt_disc_all_char()API*/voidaci_att_read_by_type_resp_event(uint16_tConnection_Handle,uint8_tHandle_Value_Pair_Length,uint8_tData_Length,uint8_tHandle_Value_Pair_Data[]){根据保密协议–不可复制PM0257服务和特征发现PM0257-Rev3page50/76/*Connection_Handle:connectionhandlerelatedtotheresponse;Handle_Value_Pair_Length:sizeofeachattributehandle-valuePair;Pair;Data_Length:lengthofHandle_Value_Pair_Datainoctets.
Handle_Value_Pair_Data:AttributeDataListasdefinedinBluetoothCorespecifications.
BluetoothCorespecifications.
Asequenceofhandle-valuepairs:[2octetsforAttributeHandle,(Handle_Value_Pair_Length-2octets)forAttributeValue].
*//*AddusercodefordecodingtheHandle_Value_Pair_Datafieldandgetthecharacteristichandle,properties,characteristicvaluehandle,characteristicUUID*/*/}/*aci_att_read_by_type_resp_event()*/就BLE传感器感测演示而言,GAP中央设备应用应获取两个读取类型响应事件(通过相关aci_att_read_by_type_resp_event()事件回调),并具有以下回调参数值.
按类型响应事件回调参数的第一次读取:conn_handle:0x0801(连接句柄);Handle_Value_Pair_Length:0x15(每个已发现特征数据(特征句柄、属性、特征值句柄、特征UUID)的长度);Data_Length:0x16(事件数据的长度);Handle_Value_Pair_Data:0x15字节如下:表53.
按类型响应事件回调参数的第一次读取特征句柄特征属性特征值句柄特征UUID注释0x000D0x10(通知)0x000E0xE23E78A0CF4A11E18FFC0002A5D5C51B128位特征专有UUID的自由落体特征按类型响应事件回调参数的第二次读取:conn_handle:0x0801(连接句柄);Handle_Value_Pair_Length:0x15(每个已发现特征数据(特征句柄、属性、特征值句柄、特征UUID)的长度);Data_Length:0x16(事件数据的长度);Handle_Value_Pair_Data:0x15字节如下:表54.
按类型响应事件回调参数的第二次读取特征句柄特征属性特征值句柄特征UUID注释0x00100x12(通知并读取)0x00110x340A1B80CF4B11E1AC360002A5D5C51B128位特征专有UUID的加速特征就传感器感测演示而言,当发现所有主要服务流程完成时,在GAP中央设备应用上调用aci_gatt_proc_complete_event()事件回调,并具有以下参数:Connection_Handle:0x0801(连接句柄);Error_Code:0x00.
根据保密协议–不可复制PM0257服务和特征发现PM0257-Rev3page51/76可以执行类似步骤,以便发现环境服务的所有特征(表47.
BLE传感器感测演示服务和特征句柄).
3.
7特征通知/指示、写入、读取本节介绍用于访问BLE设备特征的主要函数.
表55.
特征更新、读取、写入API发现服务API说明调用设备aci_gatt_update_char_value_ext()如果服务器端对特征启用了通知(或指示),该API向客户端发送通知(或指示).
GATT服务器aci_gatt_read_char_value()启动读取属性值的流程.
GATT客户端aci_gatt_write_char_value()启动写入属性值的流程(当流程完成时,生成GATT流程完成事件).
GATT客户端aci_gatt_write_without_resp()启动写入特征值的流程,不等待服务器的任何响应.
GATT客户端aci_gatt_write_char_desc()启动写入特征描述符的流程.
GATT客户端aci_gatt_confirm_indication()确认指示.
当应用接收到特征指示时,必须发送该指令.
GATT客户端就传感器感测演示而言,GAP中央设备可以使用下面的伪代码,去设置服务器端自由落体和加速度特征中的叫做"客户端特征配置描述符(clientcharacteristicconfigurationdescriptors)"的特征描述符以启用服务器端相关特征的通知功能(notification).
tBleStatusret;uint16_thandle_value=0x000F;/*Enablethefreefallcharacteristicclientdescriptorconfigurationforret=aci_gatt_write_charac_desc(conn_handle,handle_value/*handleforfreefallclientdescriptorconfiguration*/0x02,/*attributevaluelength*/0x0001,/*attributevalue:1fornotification*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");handle_value=0x0012;/*Enabletheaccelerationcharacteristicclientdescriptorconfigurationfornotification*/ret=aci_gatt_write_char_desc(conn_handle,handle_value/*handleforaccelerationclientdescriptorconfiguration*0x02,/*attributevaluelength*/0x0001,/*attributevalue:1fornotification*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");一旦从GAP中央设备启用了特征通知,GAP外设就可以通知自由落体和加速特征的新值,如下所示:tBleStatusret;uint8_tval=0x01;uint16_tservice_handle=0x000C;uint16_tcharac_handle=0x000D;/*GAPperipheralnotifiesfreefallcharacteristictoGAPcentral*/ret=aci_gatt_update_char_value_ext(connection_handle,/*connectionhandle*/service_handle,/*acceleration根据保密协议–不可复制PM0257特征通知/指示、写入、读取PM0257-Rev3page52/76servicehandle*/charac_handle,/*freefallcharacteristichandle*/1,/*updatedtype*/1,/*CharLength*/0,/*characteristicvalueoffset*/0x01,/*characteristicvaluelength*/&val/*characteristicvalue*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");tBleStatusret;uint8_tbuff[6];uint16_tcharac_handle=0x0010;/*Setthememsaccelerationvaluesonthreeaxisx,y,zonbuffarray*/.
.
.
.
/*GAPperipheralnotifiesaccelerationcharacteristictoGAPCentral*/ret=aci_gatt_update_char_value_ext(connection_handle,/*connectionhandle*/service_handle,/*accelerationservicehandle*/charac_handle,/*accelerationcharacteristichandle*/1,/*updatedtype*/1,/*CharLength*/0,/*characteristicvalueoffset*/0x06,/*characteristicvaluelength*/buff/*characteristicvalue*/);if(ret!
=BLE_STATUS_SUCCESS)PRINTF("Failure.
\n");在GAP中央设备上,在从GAP外设收到特征通知(加速或自由落体)时发起aci_gatt_notification_event()事件回调.
下面是aci_gatt_notification_event()回调的伪代码:voidaci_gatt_notification_event(uint16_tConnection_Handle,uint16_tAttribute_Handle,uint8_tAttribute_Value_Length,uint8_tAttribute_Value[]){/*aci_gatt_notification_event()eventcallbackparameters:Connection_Handle:connectionhandlerelatedtotheresponse;Attribute_Handle:thehandleofthenotifiedcharacteristic;Attribute_Value_Length:lengthofAttribute_Valueinoctets;Attribute_Value:thecurrentvalueofthenotifiedcharacteristic.
*//*Addusercodeforhandlingthereceivednotificationbasedontheapplicationscenario.
*/}/*aci_gatt_notification_event()*/3.
8基本/典型错误条件描述在BlueNRG-1、BlueNRG-2BLE栈API框架上定义了tBleStatus类型,以返回BlueNRG-1、BlueNRG-2栈错误状态.
头文件"ble_status.
h"中定义了错误代码.
在调用栈API时,为了追踪潜在错误状态,建议获取API返回状态并对其进行监控.
当API成功执行时,返回BLE_STATUS_SUCCESS(0x00).
有关与每个ACIAPI有关的错误条件列表,请参考第5节参考中的BlueNRG-1、BlueNRG-2蓝牙LE栈API和事件通知第5节参考根据保密协议–不可复制PM0257基本/典型错误条件描述PM0257-Rev3page53/763.
9BLE同时作为主、从设备的场景BlueNRG-1、BlueNRG-2BLE栈可同时支持多个角色.
因此,同一设备既可作为一个或多个连接上的主设备(最多支持八个连接),也可作为另一个连接上的从设备.
下面的伪代码描述了如何初始化BLE栈设备以便能够同时支持中央设备和外设角色:uint8_trole=GAP_PERIPHERAL_ROLE|GAP_CENTRAL_ROLE;ret=aci_gap_init(role,0,0x07,&service_handle,&dev_name_char_handle,&appearance_char_handle);同时作为主、从设备的测试场景如下:根据保密协议–不可复制PM0257BLE同时作为主、从设备的场景PM0257-Rev3page54/76图11.
BLE同时作为主、从设备的场景从设备A(3)从设备B(3)(1)BLEGAPcentral(2)BLEGAPcentral&peripheral(3)BLEGAPperipheralMaster(1)Master&SlaveisaGAPperipheralMaster&Slave(2)Master&SlaveisaGAPcentralMaster&SlaveisaGAPcentral主设备和从设备为GAP外设主设备(1)主/从设备(2)主设备和从设备为GAP中央设备(1)BLEGAP中央设备(2)BLEGAP中央设备与外设(3)BLEGAP外设主设备和从设备为GAP中央设备根据保密协议–不可复制PM0257BLE同时作为主、从设备的场景PM0257-Rev3page55/76Step1.
通过在GAP_Init()API上将角色设置为GAP_PERIPHERAL_ROLE|GAP_CENTRAL_ROLE,将一个BLE设备(称为"主/从设备")配置为中央设备及外设.
假设该设备也定义了相关的服务和特征.

Step2.
通过在GAP_Init()API上将角色设置为GAP_PERIPHERAL_ROLE,将两个BLE设备(称为Slave_A、Slave_B)配置为外设.
Slave_A和Slave_B均作为"主/从设备"定义了相同的服务和特征.
Step3.
通过在GAP_Init()API上将角色设置为GAP_CENTRAL_ROLE,将一个BLE设备(称为主设备)配置为中央设备.
Step4.
Slave_A和Slave_B设备均进入发现模式,如下所示:ret=aci_gap_set_discoverable(Advertising_Type=0x00,Advertising_Interval_Min=0x20,Advertising_Interval_Max=0x100,Own_Address_Type=0x0;Advertising_Filter_Policy=0x00;Local_Name_Length=0x05,Local_Name=[0x08,0x74,0x65,0x73,0x74],Service_Uuid_length=0;Service_Uuid_length=NULL;Slave_Conn_Interval_Min=0x0006,Slave_Conn_Interval_Max=0x0008);Step5.
主/从设备执行发现流程,以便发现外设Slave_A和Slave_B:ret=aci_gap_start_gen_disc_proc(LE_Scan_Interval=0x10,LE_Scan_Window=0x10,Own_Address_Type=0x0,Filter_Duplicates=0x0);通过使用hci_le_advertising_report_event()事件回调通知的广告报告事件发现这两个设备.

Step6.
在发现两个设备后,主/从设备启动两个连接流程(作为中央设备),以便分别连接到Slave_A和Slave_B设备:/*ConnecttoSlave_A:Slave_AaddresstypeandaddresshavebeenfoundduringthediscoveryprocedurethroughtheAdvertisingReportevents.
duringthediscoveryprocedurethroughtheAdvertisingReportevents.
*/ret=aci_gap_create_connection(LE_Scan_Interval=0x0010,LE_Scan_Window=0x0010Peer_Address_Type="Slave_A地址类型"Peer_Address="Slave_A地址,Own_Address_Type=0x0;Conn_Interval_Min=0x6c,Conn_Interval_Max=0x6c,Conn_Latency=0x00,Supervision_Timeout=0xc80,Minimum_CE_Length=0x000c,Maximum_CE_Length=0x000c);/*ConnecttoSlave_B:Slave_BaddresstypeandaddresshavebeenfoundduringthediscoveryprocedurethroughtheAdvertisingReportevents.
duringthediscoveryprocedurethroughtheAdvertisingReportevents.
*/ret=aci_gap_create_connection(LE_Scan_Interval=0x0010,LE_Scan_Window=0x0010,Peer_Address_Type="Slave_B地址类型",Peer_Address="Slave_B地址",Own_Address_Type=0x0;Conn_Interval_Min=0x6c,Conn_Interval_Max=0x6c,根据保密协议–不可复制PM0257BLE同时作为主、从设备的场景PM0257-Rev3page56/76Conn_Latency=0x00,Supervision_Timeout=0xc80,Minimum_CE_Length=0x000c,Maximum_CE_Length=0x000c);Step7.
一旦连接,主/从设备使用aci_gatt_write_char_desc()API对二者启用特征通知.
Slave_A和Slave_B设备使用aci_gatt_upd_char_val()API启动特征通知.
Step8.
在该阶段,主/从设备进入发现模式(作为外设):/*PutMaster&SlavedeviceinDiscoverableModewithName='Test'=[0x08,0x74,0x65,0x73,0x74*/ret=aci_gap_set_discoverable(Advertising_Type=0x00,Advertising_Interval_Min=0x20,Advertising_Interval_Max=0x100,Own_Address_Type=0x0;Advertising_Filter_Policy=0x00;Local_Name_Length=0x05,Local_Name=[0x08,0x74,0x65,0x73,0x74],Service_Uuid_length=0;Service_Uuid_List=NULL;Slave_Conn_Interval_Min=0x0006,Slave_Conn_Interval_Max=0x0008);由于主/从设备也是中央设备,它接收与分别从Slave_A和Slave_B设备通知的特征值相关的通知事件.
Step9.
一旦主/从设备进入发现模式,它还等待来自被配置为GAP中央设备的其他BLE设备(称为主设备)的连接请求.
主设备启动发现流程,以便发现主/从设备:ret=aci_gap_start_gen_disc_proc(LE_Scan_Interval=0x10,LE_Scan_Window=0x10,Own_Address_Type=0x0,Filter_Duplicates=0x0);Step10.
一旦发现主/从设备,主设备启动连接流程以便与之连接:/*MasterdeviceconnectstoMaster&Slavedevice:Master&SlaveaddresstypeandaddresshavebeenfoundduringthediscoveryprocedurethroughtheAdvertisingReportevents*/ret=aci_gap_create_connection(LE_Scan_Interval=0x0010,LE_Scan_Window=0x0010,Peer_Address_Type="Master&Slaveaddresstype",Peer_Address="Master&Slaveaddress",Own_Address_Type=0x0;Conn_Interval_Min=0x6c,Conn_Interval_Max=0x6c,Conn_Latency=0x00,Supervision_Timeout=0xc80,Minimum_CE_Lenght=0x000cMaximum_CE_Length=0x000c);通过使用hci_le_advertising_report_event()事件回调函数可得知主/从设备被发现.
Step11.
一旦连接,主设备使用aci_gatt_write_char_desc()API在主/从设备上启用特征通知.
Step12.
在该阶段,由于是GAP中央设备,主/从设备接收来自从设备A、从设备B的特征通知,而作为GAP外设,它还能将这些特征值通知主设备.
提示BlueNRGGUI软件包(参见第版本历史)中提供了一组测试脚本,用于练习上述BLE同时为主、从设备的场景.
这些脚本可以使用BlueNRGGUI运行,并可作为使用BlueNRG-1和BlueNRG-2同时作为主、从设备功能实现固件应用的参考.
根据保密协议–不可复制PM0257BLE同时作为主、从设备的场景PM0257-Rev3page57/763.
10低能耗蓝牙私有1.
2BLE栈v2.
x支持低功耗蓝牙私有1.
2.
私有功能通过频繁修改相关BLE地址来降低跟踪特定BLE的能力.
频繁修改的地址被称为私有地址,受信任的设备可以解析它.
为使用该功能,通信中涉及的设备需要先经过配对:使用在先前的配对/绑定过程期间交换的设备IRK创建私有地址.
私有功能有两种变体:1.
基于主机的隐私私有地址通过主机解析和生成2.
基于控制器的隐私私有地址通过控制器解析和生成,在主机提供控制器设备身份信息后,不再涉及主机.

当支持控制器隐私时,可进行设备过滤,因为在控制器中执行地址解析(可在检查对等设备是否处于白名单中之前解析对等设备的身份地址).
3.
10.
1基于控制器的私有与设备过滤方案在BLE栈v2.
x上,aci_gap_init()API支持用于privacy_enabled参数的以下选项:0x00:私有禁用0x01:主机私有启用0x02:控制器私有启用当从设备想要解析可解析私有地址并希望能够过滤私有地址以重新连接已绑定和受信任的设备时,它必须执行以下步骤:1.
在aci_gap_init()上启用私有控制器:将0x02用作privacy_enabled参数.
2.
使用允许的安全方法之一连接、配对和绑定候选可信设备:使用设备IRK创建私有地址.
3.
调用aci_gap_configure_whitelist()API,以将绑定设备的地址添加到BLE设备控制器的白名单中.
4.
使用aci_gap_get_bonded_devices()API获取绑定的设备身份地址和类型.
5.
使用aci_gap_add_devices_to_resolving_list()API将绑定设备的身份地址和类型添加到用于解析控制器中的可解析私有地址的地址转换列表中.
6.
通过使用Own_Address_Type=0x02(可解析私有地址)和Adv_Filter_Policy=0x03(只允许来自白名单的扫描请求,只允许来自白名单的连接请求)来调用aci_gap_set_undirected_connectable()API,设备进入了非定向可连接模式.
7.
当绑定的主设备执行用于重新连接到从设备的连接过程时,从设备能够解析并过滤主设备的地址并与之连接.

提示BlueNRGGUI软件包中提供了一组测试脚本,用于执行所述的私有控制器和设备过滤方案(参见第5节参考).
这些脚本可以使用BlueNRGGUI运行,并可作为使用私有控制器和设备过滤功能实现固件应用的参考.
3.
10.
2解析地址在与绑定设备重新连接之后,不必通过严格解析对等设备的地址来加密链路.
事实上,BlueNRG-1、BlueNRG-2栈将通过自动寻找正确的LTK来加密链路.
但是,在某些情况下必须解析对等设备的地址.
当设备收到可解析私有地址时,可通过主机或控制器来解析该地址(即链路层).
基于主机的私有如果启用控制器私有,则可以使用aci_gap_resolve_private_addr()来解析可解析的私有地址.
如果可以在绑定设备存储的IRK中找到相应的IRK,则解析该地址.
可通过以下方式接收可解析的私有地址,当BlueNRG-1与BlueNRG-2正在扫描时,通过hci_le_advertising_report_event(),或当连接已建立时,通过hci_le_connection_complete_event().
基于控制器的私有如果在链路层启用了地址解析,则在收到可解析的私有地址时使用解析列表.
要将绑定设备添加到解析列表,必须调用aci_gap_add_devices_to_resolving_list().
此函数搜索相应的IRK并将其添加到解析列表中.
当启用私有时,如果已将设备添加到解析列表,则其地址通过链路层自动解析并报告给应用,而无需明确调用任何其他功能.
在与设备连接后,返回hci_le_enhanced_connection_complete_event().
如果已成功解析,则该事件报告设备的身份地址(如果hci_le_enhanced_connection_complete_event()被屏蔽,则只返回hci_le_connection_complete_event()).
在扫描时,如果该设备使用可解析的私有地址并且其地址已正确解析,则hci_le_advertising_report_event()包含广告中的设备身份地址.
在这种情况下,报告的地址类型为0x02根据保密协议–不可复制PM0257低能耗蓝牙私有1.
2PM0257-Rev3page58/76或0x03.
如果找不到可解析该地址的IRK,则报告可解析的私有地址.
在广告设备使用了定向广告的情况下,如果已取消屏蔽,并将扫描过滤策略设为0x02或0x03,则通过hci_le_advertising_report_event()或通过hci_le_direct_advertising_report_event()报告已解析的私有地址.
3.
11ATT_MTU和交换MTUAPI事件ATT_MTU定义为在客户端和服务器之间发送的任何数据包的最大大小:默认ATT_MTU值:23字节这决定了用于执行特征操作时的当前最大属性值的大小(通知/写入最大值的大小为ATT_MTU-3).
客户端和服务器可以交换使用交换MTU请求和响应消息所能接收的最大数据包大小.
两个设备均使用这些交换值的最小值来进行所有的进一步通信:tBleStatusaci_gatt_exchange_config(uint16_tConnection_Handle);为响应交换MTU请求,在两个设备上触发aci_att_exchange_mtu_resp_event()回调:voidaci_att_exchange_mtu_resp_event(uint16_tConnection_Handle,uint16_tServer_RX_MTU);Server_RX_MTU指定了服务器和客户端之间所商定的ATT_MTU值.
3.
12LE数据包长度扩展API和事件在BLE规范v4.
2中,包数据单元(PDU)的大小已从27字节增加到251字节.
这允许通过降低数据包所需的开销(数据头,MIC)来提高数据率.
因此,由于降低了开销,可实现更快的OTA固件升级操作和更高的效率.
支持BLE栈v2.
1或更高版本的BlueNRG-2设备支持LE数据包长度扩展功能和相关API事件:HCILEAPI(bluenrg1_api.
h上的API原型)–hci_le_set_data_length()–hci_le_read_suggested_default_data_length()–hci_le_write_suggested_default_data_length()–hci_le_read_maximum_data_length()HCILE事件(bluenrg1_events.
h上的事件回调原型)–hci_le_data_length_change_event()hci_le_set_data_length()API使用户应用程序能够建议用于给定连接的最大传输数据包大小(TxOctets)和最大数据包(TxTime)传输时间:tBleStatushci_le_set_data_length(uint16_tConnection_Handle,uint16_tTxOctets,uint16_tTxTime);支持的TxOctets值在[27-251]的范围内,TxTime按以下方式提供:(TxOctets+14)*8.
在设备连接后,一旦在BlueNRG-2设备上执行hci_le_set_data_length()API,如果连接的对等设备支持LE数据包长度扩展,则会在两个设备上引发以下事件:hci_le_data_length_change_event(uint16_tConnection_Handle,uint16_tMaxTxOctets,uint16_tMaxTxTime,uint16_tMaxRxOctets,uint16_tMaxRxTime)该事件通知主机更改最大链路层载荷长度或链路层数据通道PDU在任一方向(TX和RX)的最长时间.
所报告的值(MaxTxOctets,MaxTxTime,MaxRxOctets,MaxRxTime)是在更改后实际用于连接的最大值.
3.
13无数据包重试功能BLE栈v2.
1提供了用于禁用对等设备链路层未确认特征通知的标准BLE链路层重传机制的功能.
仅处于最大允许链路层数据包长度范围以内的通知才支持此功能.
根据保密协议–不可复制PM0257ATT_MTU和交换MTUAPI事件PM0257-Rev3page59/76当使用标准低功耗蓝牙协议时,不会丢失数据包,因为协议采用了无限重试次数.
在具有大量错误和重试的弱链路中,发送一定数量的数据包所花费的时间可能随错误数量增加.
如果应用了"无数据包重试功能",则协议不会重试损坏的数据包,因此,传递所选数量的数据包所花费的时间相同,但丢失数据包的数量从0到某个数字所花费的时间与错误率成比例.
通过设置参数发送通知时,无法启用数据包重试功能Update_Type=aci_gatt_update_char_value_ext()API上的0x05:aci_gatt_update_char_value_ext(uint16_tConn_Handle_To_Notify,uint16_tService_Handle,uint16_tChar_Handle,uint8_tUpdate_Type,uint16_tChar_Length,uint16_tValue_Offset,uint8_tValue_Length,uint8_tValue[]);有关API使用及其参数值的详细信息,请参考aci_gatt_update_char_value_ext()API描述.
根据保密协议–不可复制PM0257无数据包重试功能PM0257-Rev3page60/764BLE多连接时序策略本节提供当多个主设备和从设备连接处于激活状态时,BlueNRG-1、BlueNRG-2栈的连接时序管理策略的概述.
4.
1关于低功耗蓝牙时序的基本概念本节介绍与广告、扫描和连接操作相关的低功耗蓝牙时序管理的基本概念.

4.
1.
1广告时序广告状态的时序由3个时序参数来定义,它们通过以下公式串联:T_advEvent=advInterval+advDelay其中:T_advEvent:两个连续广告事件的启动时间之间的时间;如果广告事件类型为可扫描非定向事件类型或不可连接非定向类型,advInterval应不小于100ms;如果广告事件类型为低占空比模式下使用的可连接非定向事件类型或可连接定向事件类型,advInterval可大于等于20ms.
advDelay:链路层为每个广告事件生成的虚拟随机值,范围为0ms至10ms.
图12.
广告时序4.
1.
2扫描时序扫描状态的时序由2个时序参数来定义:scanInterval:两个连续扫描事件的启动时间之间的间隔scanWindow:链路层在这一时间内监听广告通道索引scanWindow和scanInterval参数小于等于10.
24s.
scanWindow小于等于scanInterval.
4.
1.
3连接时序连接事件的时序取决于2个参数:连接事件间隔(connInterval):两个连续连接事件的启动时间之间的间隔,绝不重叠;连接事件启动的时间点被称为锚点.
主设备在锚点开始向从设备发送数据通道PDU,而从设备监听其主设备在锚点发送的数据包.
主设备确保连接事件在下一个连接事件的锚点的至少T_IFS=150s(帧间间隔时间,即相同通道索引上连续数据包之间的时间间隔)前结束.
connInterval是1.
25ms的倍数,范围为7.
5ms至4.
0s.
从设备延迟(connSlaveLatency):允许从设备使用更少的连接事件.
该参数定义了从设备无需监听主设备的连续连接事件数量.
当主机想要创建连接时,它为控制器提供连接间隔(Conn_Interval_Min、Conn_Interval_Max)和连接长度(Minimum_CE_Length、Maximum_CE_Length)的最大和最小值,从而在选择当前参数方面给予了控制器一定的灵活性,以便满足其他时序限制,例如有多个连接时.
根据保密协议–不可复制PM0257BLE多连接时序策略PM0257-Rev3page61/764.
2BLE栈时序和时隙分配概念BlueNRG-1,BlueNRG-2BLE协议栈采用了一种时间槽分配机制,以实现为多个从设备与同一个主设备间已建立的多个连接分配通讯时间.
其基本控制参数,如下表所述:表56.
时隙算法的时序参数参数说明锚定周期循环时间间隔,最多可划分出8个时隙.
在这8个时隙中,同一时间只有一个时隙可用于扫描/广告事件(各时隙彼此互斥).

时隙持续时间时间间隔,在此期间发生完整事件(即广告或扫描及连接);时隙持续时间是分配给连接时隙的持续时间,与连接事件的最长持续时间有关时隙偏移锚定周期的开始时间与连接时隙的开始时间之间的延时对应的时间值时隙延迟代表连续锚定周期内特定连接时隙的实际利用率的值.
(例如,时隙延迟等于'1'表示在每个锚定周期内实际使用了特定连接时隙;时隙延迟等于n表示每n个锚定周期内只实际使用一次特定连接时隙)时序分配概念允许对多个连接进行明确的时间处理,但同时对控制器可以接受的实际连接参数强加了一些限制.
时基参数和连接时隙分配的示例如下图所示图13.
三个连接时隙的分配示例时隙1就锚定周期而言的偏移为0,时隙2的时隙延迟=2,所有时隙相隔1.
25ms的保护时间.
4.
2.
1为第一个主设备连接设置时序上述时基机制在创建首个主设备连接时实际启动.
此类首个连接的参数决定了锚定周期的初始值,并影响与首个连接同步的任何其他主设备连接可以接受的时序设置.
尤其是:选择的初始锚定周期等于主机请求的最大和最小连接周期的平均值第一个连接时隙位于锚定周期开始处第一个连接时隙的持续时间设置为等于请求的连接长度的最大值很明显,此类首个连接时隙与锚定周期相比的相对持续时间,限制了为其他主设备连接分配其他连接时隙的可能性.
4.
2.
2为其他主设备连接设置时序在配置并启动了时基(如上文所述)后,时隙分配算法将尝试在一定范围内动态地重新配置时基,以分配其他主机请求.
具体来说,考虑下列三种情况:1.
当前锚定周期处于为新连接指定的Conn_Interval_Min至Conn_Interval_Max的范围内.
这种情况下,不能修改时基,将新连接的连接间隔设置为等于当前锚定周期.
根据保密协议–不可复制PM0257BLE栈时序和时隙分配概念PM0257-Rev3page62/762.
当前锚定周期小于新连接所要求的Conn_Interval_Min.
这种情况下,算法搜索满足下列条件的整数m:Conn_Interval_Min≤Anchor_Period*m≤Conn_Interval_Max如果找到这样的值,则维持当前锚定周期,并将新连接的连接间隔设置为等于Anchor_Periodm,时隙延迟等于m.
3.
当前锚定周期大于新连接所要求的Conn_Interval_Max.
这种情况下,算法搜索满足下列条件的整数k:Conn_InterVal_M关n≤Ancor_Per关odk≤Conn_InterVal_Max如果找到这样的值,则将当前锚定周期缩短为:Ancor_Per关odk将新连接的连接间隔设置为:Ancor_Per关odk将现有连接的时隙延迟乘以因数k.
注意,这种情况下还必须满足下列条件:–Anchor_Period/k必须是1.
25ms的倍数–Anchor_Period/k必须足够大,以包含已分配给之前的连接的所有连接时隙一旦找到符合上述标准的合适锚定周期,在其中为实际连接时隙分配时间间隔.
一般而言,如果锚定周期内有足够间隔,算法将分配最大请求连接事件长度,否则将缩短为实际可用间隔.
如果创建了多个连续连接,通常按顺序排列相对连接时隙,中间以很短的保护时间(1.
5ms)隔开;当连接关闭时,通常在两个连接时隙之间产生未使用的间隙.
在之后创建新连接时,算法尝试将新连接时隙安插到现有间隙之一;如果间隙不够宽,则直接将连接时隙排列在最后一个连接时隙之后.
图14.
三个连续连接的时序分配示例所示为创建连续连接时如何管理时基参数的示例.
图14.
三个连续连接的时序分配示例4.
2.
3广告事件时序广告事件的周期(由advInterval控制)是基于下列参数计算的,这些参数由从设备通过主机在HCI_LE_Set_Advertising_parameters指令中指定:Advertising_Interval_Min,Advertising_Interval_Max;Advertising_Type;根据保密协议–不可复制PM0257BLE栈时序和时隙分配概念PM0257-Rev3page63/76如果将Advertising_Type设置为高占空比定向广告,则将广告间隔设置为3.
75ms,无论Advertising_Interval_Min和Advertising_Interval_Max的值为多少;这种情况下,超时也设置为1.
28s,即这种情况下广告事件的最长持续时间;在所有其他情况下,选择的广告间隔等于(Advertising_Interval_Min+5ms)和(Advertising_Interval_Max+5ms)的平均值.
在前一种情况下,广告没有最长持续时间,只在连接建立时或主机明确请求时停止.

每个广告事件的长度由软件默认设置为等于14.
6ms(即允许的最大广告事件长度),并且不能缩短.
在主设备时隙的相同时基内分配广告时隙(即扫描和连接时隙).
因此,将由软件在至少一个主设备时隙时接受的广告启用指令处于激活状态,广告间隔必须是实际锚定周期的整数倍.
4.
2.
4扫描时序主设备通过下列参数(由主机在HCI_LE_Set_Scan_parameters指令中指定)请求扫描时序:LE_Scan_Interval:用于计算扫描时隙的周期LE_Scan_Window:用于计算要分配到主设备时基中的扫描时隙的长度分配的扫描时隙位于其他激活的主设备时隙(即连接时隙)和广告时隙(如果有一个处于激活状态)的相同时基内.
如果已存在活动时隙,则扫描间隔始终适应锚定周期.
鉴于扫描参数只是BT官方规范提供的建议(v.
4.
1第2卷E部分第7.
8.
10节),每当LE_Scan_Interval大于实际锚定周期时,为了维持主机要求的相同占空比,软件自动尝试二次采样LE_Scan_Interval并缩短分配的扫描时隙长度(最多达到LE_Scan_Window的).
4.
2.
5从设备时序就上述时基机制而言,从设备时序由主设备在连接创建时定义,因此从设备链路的连接时隙是异步管理的.
从设备假设主设备可以使用与连接间隔一样长的连接事件长度.
每当在从设备和主设备时隙之间预测到冲突条件时,时序安排算法采用循环调度仲裁策略.
此外,调度器还可以对从设备连接时隙持续时间使用动态限制,以保留主设备和从设备连接.
尤其是:如果主设备连接时隙的末端与从设备连接时隙的起始端重叠,则交替保留/取消主设备和从设备连接如果从设备连接时隙的末端与主设备连接时隙的起始端重叠,则强行限制从设备连接时隙长度以避免此类重叠.
如果产生的时间间隔过小而不允许至少两个数据包的交换,则使用循环调度仲裁策略.

4.
3多个主设备和从设备连接指南为了使用BlueNRG-1和BlueNRG-2设备正确处理多个主设备和从设备连接,应遵循下列指南:1.
避免分配过长的连接事件长度:选择尽可能小的Minimum_CE_Length和Maximum_CE_Length以严格满足应用需求.
这样做有助于分配算法在锚定周期内分配多个连接并缩短锚定周期,如果需要,为连接分配较小的连接间隔.
2.
对于第一个主设备连接:a.
如可能,创建具有最短连接间隔的连接作为第一个连接,以便为其他连接分配为初始锚定周期倍数的连接周期.
b.
如可能,为Conn_Interval_Min=Conn_Interval_Max选择10ms的倍数,以便为其他连接分配既是初始锚定周期的2、4和8(或更多)倍的约数又是1.
25ms的倍数的连接间隔.
3.
对于其他主设备连接:a.
使ScanInterval等于现有主设备连接之一的连接间隔b.
选择ScanWin,使已分配主设备时隙之和(包括广告(如激活))小于最短已分配连接间隔c.
选择Conn_Interval_Min和Conn_Interval_Max,使间隔包含:最短已分配连接间隔的倍数最短已分配连接间隔的因数也是1,25ms的倍数d.
选择Maximum_CE_Length=Minimum_CE_Length,使已分配主设备时隙之和(包括广告(如激活))加上Minimum_CE_Length后小于最短已分配连接间隔4.
每次开始广告时:a.
如果是定向广告,选择Advertising_Interval_Min=Advertising_Interval_Max=最短已分配连接间隔的整数倍b.
如果是定向广告,选择Advertising_Interval_Min=Advertising_Interval_Max,使(Advertising_Interval_Min+5ms)等于最短已分配连接间隔的整数倍根据保密协议–不可复制PM0257多个主设备和从设备连接指南PM0257-Rev3page64/765.
每次开始扫描时:a.
每次开始扫描时:a)选择使ScanInterval等于现有主设备连接之一的连接间隔b.
选择ScanWin,使已分配主设备时隙之和(包括广告(如激活))小于最短已分配连接间隔6.
注意,创建多个连接然后关闭其中一些连接并重新创建新连接的过程,随着时间的推移,会降低时隙分配算法的总体效率.
如果在分配新连接时遇到困难,可将时基重置为初始状态(将关闭所有现有连接).

4.
4多个主设备和从设备连接公式BlueNRG-1、BlueNRG-2BLE栈多主/从功能为一个设备(在本文中称为Master_Slave)提供同时处理多达8个连接的功能,如下所示:1.
作为多个从设备的主设备:–Master_Slave连接多达8个从设备(Master_Slave设备不是任何其他主设备的从设备)2.
在作为多个从设备的主设备时,同时作为从设备进行广告和扫描:a.
Master_Slave设备作为从设备连接到一个主设备,并作为主设备最多连接7个从设备b.
Master_Slave设备作为从设备连接到两个主设备,并作为主设备最多连接6个从设备为应对突出场景,用户必须正确定义广告/扫描和连接参数,这些参数用于计算允许处理所需的多个Master_Slave连接场景的最佳锚定周期.
可通过特定公式计算突出场景的所需广告/扫描和连接参数,其中一个设备(Master_Slave)可管理多达Num_Masters个主设备以及多达Num_Slaves个从设备,并能按Scan_window长度执行广告和扫描.
在STSW-BLUENRG1-DK软件包的Library\BLE_Application\Utils\src\ble_utils.
c文件中,定义了以下公式:GET_Master_Slave_device_connection_parameters(Num_Masters,Num_Slaves,Scan_Window,Sleep_Time)用户需要根据其特定应用场景提供以下输入参数:表57.
用于定义Master_Slave设备连接参数的输入参数输入参数说明允许范围注释Num_Masters主/从设备应作为从设备连接的主设备数量,包括不可连接广告对应的主设备.
[0-2]如果为0,则主设备不是任何其他主设备的从设备:它最多可以连接8个从设备Num_Slaves主/从设备应作为主设备连接的从设备数量[0–Allowed_Slaves]最大从设备的数量取决于Master_Slave设备预计要连接的主设备数量:Allowed_Slaves=8-Num_MastersScan_WindowMaster_Slave设备的扫描窗口长度以毫秒为单位[2.
5-10240]ms该输入值定义了Master_Slave设备的最小选定扫描窗口Sleep_time要添加到所需的最小锚定周期的附加时间(ms)[0-N]ms0:没有向最小锚定周期(定义了吞吐量的最佳配置)添加附加时间当用户选择Sleep_Time=0时,GET_Master_Slave_device_connection_parameters()公式定义了最佳Master_Slave设备连接参数,这些参数用于满足所需的多个连接场景,并保持了最佳数据吞吐量.
如果用户想要增强功耗曲线,他可以通过Sleep_Time参数添加特定时间,这会提高设备连接参数中的功耗优势,但会降低数据吞吐量.
根据提供的输入参数,公式计算以下Master_Slave设备连接参数:Connection_IntervalCE_LengthAdvertising_IntervalScan_IntervalScan_WindowAnchorPeriodLength根据保密协议–不可复制PM0257多个主设备和从设备连接公式PM0257-Rev3page65/76表58.
Master_Slave设备多连接输出参数输出参数说明允许的范围/时间(ms)如何使用Connection_Interval连接事件间隔的连接事件间隔最小值值:0x0006(7.
50ms).
.
.
0x0C80(4000.
00ms)时间=N*1.
25ms该值将用于创建的连接API的Conn_Interval_Min、Conn_Interval_Max参数(即ACI_GAP_CREATE_CONNECTION())CE_Length此LE连接所需的连接长度.
时间=N*0.
625ms该值将用于创建的连接API的Minimum_CE_Length、Maximum_CE_Length参数(即ACI_GAP_CREATE_CONNECTION())Advertising_Interval广告间隔值:0x0020(20.
000ms).
.
.
0x4000(10240.
000ms).
时间=N*0.
625ms该值将用于发现模式、可连接模式API的Advertising_Interval_Min、Advertising_Interval_Max参数(即ACI_GAP_SET_DISCOVERABLE()等)Scan_Interval扫描间隔值:0x0004(2.
500ms).
.
.
0x4000(10240.
000ms)时间=N*0.
625ms该值将用于发现流程的LE_Scan_Interval参数(即:ACI_GAP_CREATE_CONNECTION()、ACI_GAP_START_GENERAL_DISCOVERY_PROC()等)Scan_Window扫描窗口值:0x0004(2.
500ms).
.
.
0x4000(10240.
000ms)时间=N*0.
625ms该值将用于发现流程的LE_Scan_Window参数(即:ACI_GAP_CREATE_CONNECTION()、ACI_GAP_START_GENERAL_DISCOVERY_PROC()等)AnchorPeriodLength用于表示与Master_Slave设备有关的所有周期性主设备时隙的最小时间间隔它根据输入参数,通过GET_Master_Slave_device_connection_parameters()公式计算,用于定义设备连接输出参数假设:公式从内部定义了在每个连接间隔可交换到每个从设备的最大长度数据包数量.

pacificrack:$12/年-1G内存/1核/20gSSD/500g流量/1Gbps带宽

pacificrack在最新的7月促销里面增加了2个更加便宜的,一个月付1.5美元,一个年付12美元,带宽都是1Gbps。整个系列都是PR-M,也就是魔方的后台管理。2G内存起步的支持Windows 7、10、Server 2003\2008\2012\2016\2019以及常规版本的Linux!官方网站:https://pacificrack.com支持PayPal、支付宝等方式付款7月秒杀VP...

Dynadot COM特价新注册48元

想必我们有一些朋友应该陆续收到国内和国外的域名注册商关于域名即将涨价的信息。大概的意思是说从9月1日开始,.COM域名会涨价一点点,大约需要单个9.99美元左右一个。其实对于大部分用户来说也没多大的影响,毕竟如今什么都涨价,域名涨一点点也不要紧。如果是域名较多的话,确实增加续费成本和注册成本。今天整理看到Dynadot有发布新的八月份域名优惠活动,.COM首年注册依然是仅需48元,本次优惠活动截止...

福州云服务器 1核 2G 2M 12元/月(买5个月) 萤光云

厦门靠谱云股份有限公司 双十一到了,站长我就给介绍一家折扣力度名列前茅的云厂商——萤光云。1H2G2M的高防50G云服务器,依照他们的规则叠加优惠,可以做到12元/月。更大配置和带宽的价格,也在一般云厂商中脱颖而出,性价比超高。官网:www.lightnode.cn叠加优惠:全区季付55折+满100-50各个配置价格表:地域配置双十一优惠价说明福州(带50G防御)/上海/北京1H2G2M12元/月...

文件服务器硬件配置为你推荐
国内域名注册国内比较出名的域名注册商有哪些?虚拟主机推荐有哪些好的虚拟主机推荐查询ip怎样查别人的ip地址?美国服务器托管美国服务器租用时要注意什么?100m虚拟主机100M虚拟主机有多大,能放多少东西山东虚拟主机能否在虚拟机与主机之间建立局域网,让主机与虚拟机同时上网?美国免费虚拟主机美国虚拟主机怎么样?美国虚拟主机那个比较好?长沙虚拟主机长沙虚拟主机租用 哪里的比较靠谱 朋友介绍湘域互联的 有谁用过shopex虚拟主机我有一个PHP1G的虚拟主机,请问做什么站比较合适?域名网谁能帮我推荐一些较好的免费域名的申请网站。。。谢谢了啊。。。
.cn域名注册 企业域名备案 132邮箱 vultr美国与日本 站群服务器 流媒体服务器 免费mysql 日本bb瘦 刀片服务器的优势 北京双线 国外代理服务器地址 cdn加速原理 免费私人服务器 西安服务器托管 国外的代理服务器 个人免费邮箱 金主 空间申请 域名和主机 闪讯网 更多