摘要:本文的目的只针对蓝牙应用开发,对一些常识性知识点进行说明,只能算科普性质的文章。
目录
1、蓝牙简介
2、BLE 体系结构
3、蓝牙事件
4、蓝牙参数属性
5、蓝牙广播
6、设备地址
7、MTU交换
8、DFU固件更新
9、开发套路
10、参考文章
蓝牙的创始人是瑞典爱立信公司,爱立信早在 1994 年就已进行研发。1997 年爱立信与其他设备生产商联系,并激发了他们对该项技术的浓厚兴趣。1998 年 2 月,5 个跨国大公司,包括爱立信、诺基亚、IBM、东芝及 Intel 组成了一个特殊兴趣小组(SIG),他们共同的目标是建立一个全球性的小范围无线通信技术,即现在的蓝牙。
蓝牙技术是以 10 世纪的一位丹麦国王命名的。“蓝牙(Bluetooth)”一词来源于 10 世纪的丹麦国王 Harald Blåtand(英文姓名为 Harold Bluetooth)。这位国王将四分五裂的局面统一起来的行为,与这种传输技术将各种设备无线连接起来,有相似的地方。为了纪念他,SIG 将自己的无线技术取名“蓝牙”。
BLE 是蓝牙低功耗的简称(Bluetooh Low Energy)。蓝牙低功耗(BLE)技术是低成本、短距离、可互操作的鲁棒性无线技术,工作在免许可的 2.4GHz ISM 射频频段。它从一开始就设计为超低功耗(ULP)无线技术。它利用许多智能手段最大限度地降低功耗。
低成本,低功耗。
快速启动,瞬间连接。最快 3ms 低延迟。
传输距离的提高。
高安全性,使用 AES-128 加密算法进行数据报加密认证。
蓝牙低功耗在短距离无线通信领域占据着越来越重要的地位,在很多应用场合均可见到蓝牙低功耗的身影。
医疗和健康设备,如血糖仪、数字血压计、血气计、心率监视器等。
运动休闲,如心率监测仪、体温计、计步器等。
鼠标、键盘、遥控器。
Beacons 蓝牙信标。
智能家居,如灯光控制、温湿度控制、安全锁控制等。
蓝牙技术联盟 : (Bluetooth Special Interest Group, SIG),是蓝牙核心规格版本及蓝牙技术的管理者,本身不负责具体的蓝牙产品的设计和生产等。蓝牙技术的发展经历了下面几个主要的版本:
1、蓝牙 1.0:基本码率,Basic Rate,BR。
2、蓝牙 2.0:增强码率,Enhanced Data Rata,EDR。
3、蓝牙 3.0:引入全新的交替射频技术(AMP: Alternate MAC/PHY),允许蓝牙协议栈针对任一任务动态地选择正确射频,通过瞬间使用消费者设备中已存在的辅助无线电提供更快的吞吐量。
4、蓝牙 4.0 是第一个综合性规范,其加入了全新的蓝牙低功耗技术BLE(Bluetooth Low Energy),即蓝牙 4.0 集三种规格于一体。
5、蓝牙 4.2 提升了 BLE 数据传输速度,支持长包传输,单个数据包最大可传输 255 个字节,同时改善了隐私保护程度。
6、蓝牙 5.0 相对于蓝牙 4.2,具有 2 倍的数据速率、4 倍的覆盖范围和 8 倍的广播能力。
高速模式:支持 2Mbps 数据速率,实现了数据吞吐量翻倍。
远距模式:通过 500kbps 和 125kbps 速率的全新编码物理层 (PHY) 实现远距离覆盖。
广播扩展:蓝牙 BLE 有 3 个广播信道(具体见2.1),之前的蓝牙 BLE 版本中广播载荷通过全部三个广播通道进行发送,蓝牙 5.0 中这三个通道仅用于发送指针,显示发送载荷的时间和地点,广播载荷仅在一个数据通道上传输一次。
为了更好地区分蓝牙的版本,SIG 发布了三种标志Logo用于人们分辨这三个版本之间的区别和兼容性。
Bluetooth Smart Ready:适用于任何双模蓝牙 4.0 的电子产品,如苹果公司 iPhone 4S
及以后的产品和安装了安卓 4.3 以上的系统,并且蓝牙芯片支持 4.0 的手机。
Bluetooth Smart:单模设备,如智能手环。
标准Bluetooth:传统蓝牙设备,如用于传输语音的蓝牙耳机。
低功耗蓝牙分为单模(Bluetooth Smart)和双模(Bluetooth Smart Ready)两种设备:
单模设备:只支持蓝牙低功耗 (BLE),单模设备对低功耗的要求很高。
双模设备:既支持经典蓝牙也支持蓝牙低功耗,这两种技术使用同一个射频前端和天线,双模设备一般都有足够的供电能力,对低功耗要求不高。
双模设备之间:可以通过 LE 通信,也可以通过传统蓝牙通信;双模设备和单模设备通
过 LE 通信;双模设备和传统蓝牙通过传统蓝牙通信。
单模设备之间:通过 LE 通信。
传统蓝牙:通过传统蓝牙通信。
单模设备和传统蓝牙:不能通信。
蓝牙低功耗包含三个部分:控制器、主机和应用程序。
链路层负责广播、扫描、建立和维护连接,以及确保数据包按照正确的方式组织、正确地校验值和加密序列等。
链路层信道映射
广播信道:37 、38、39,对应的中心频率是 2402MHz,2426MHz,2480MHz。广播信道之间至少相差 24MHz。每次广播,都会在 3 个信道上将广播数据发送一次,有效地避免干扰,即使一个信道存在干扰,另外的信道也可以很好地工作,而三个信道同时被干扰的情况极少。
为什么广播信道是 3 个,而不是更多?
广播信道越多,各个信道同时受到干扰的几率越小,抗干扰性越强。但是广播信道越多,> 发射数据占用的时间就越长,功耗也就越高。
所以,综合考虑抗干扰性和功耗的情况, SIG 将广播设定为 3 个。
主机控制器接口 HCI(Host controller interface)在 Host 和 Controller 之间提供一个标准化的接口,该层可以由应用程序接口 API 实现或者使用硬件接口 UART、SPI 或 USB 来控制。控制器通过 HCI 发送数据和事件给主机,主机通过 HCI 发送命令和数据给控制器。
L2CAP 层向上层提供数据封装服务,从而使逻辑上允许端到端的数据通信。
L2CAP 提供可复用,分割和重组的面向连接或者无连接的数据服务。L2CAP 数据包可以达到 64K。L2CAP 允许每个 L2CAP 通道流控和重传。
安全管理层 SM(Security Manager)提供配对和密钥的分发。
属性协议(ATT)规定了怎样去访问对端设备的数据,数据存储在属性服务器的“属性”里,供属性客户端进行读写操作。
通用属性配置文件(GATT)建立在属性协议的基础上,GATT 通过使用 ATT 协议层定义 了如何发现与使用服务、特征和描述符的标准方法。
客户端与服务器架构:GATT 定义了两个角色:服务器和客户端。
服务器:客户端提供数据服务,就是数据中心。
客户端:从服务器读写应用数据,就是访问数据者。
特别注意:下面三个概念是完全独立的,针对是不同的层不同称呼。如主机既可以是 GATT客户端,也可以是 GATT 服务器。而从机也一样,既可以是 GATT 客户端,也可以是GATT 服务器。
服务器:客户端提供数据服务,就是数据中心。客户端:从服务器读写应用数据,就是访问数据者。
主机、从机:针对链接层。
外围设备、中央设备:GAP 定义的角色。
GAP 层负责处理设备的接入方式和过程,包括设备发现,链路建立,链路终止以及实现绑定。
应用层定义了三种种类型:特征(characteristic)、服务(service)和配置文件(profile)。
特征:采用已知格式、以通用唯一识别码(UUID)作为表示的一个小块数据,由于特征要求能够重复使用,因而设计时没有涉及行为,特征被定义为计算机的可读格式,当计算机遇到一个从未接触过的特征时,计算机可以去更新这个特征的读取规则,从而正确读取特征,并向用户展示读取的特征。
服务:服务是人类可读的一组特征及其相关的行为规范,只定义了位于服务器上的相关特性和行为,而不定义客户端的行为。服务有两种类型,首要服务和次要服务,一个服务是首要服务还是次要服务取决于服务的定义,首要服务表征一个给定的设备主要做些什么。正是通过这些服务,用户才了解到该设备是做什么的。次要服务是那些协助主要业务或其他次要服务的服务。
配置文件:是用例或应用的最终体现。配置文件是描述一个或多个设备的说明,每一个设备提供一个或多个服务,配置文件描述了如何发现和连接设备,从而为每台设备确定了拓展结构,配置文件还描述的客户端的行为,用于发现服务和服务特性。
基于SDK的软件开发,前面基本都是使用既有API,主要app逻辑是在应用层,也就一般软件工程师的发挥余地。
BLE 广播间隔:是指两次广播事件之间的最小时间间隔,一般取值范围在 20ms-10.24S之间,链路层会在每次广播时间期间产生一个随机广播延时时间(0ms-10ms)。
每次扫描,设备打开接收器去监听广播设备,这称为一个扫描事件,扫描事件有两个时间参数扫描窗口和扫描间隔:
扫描窗口(scan window):一次扫描进行的时间宽度。
扫描间隔(scan interval):两个连续的扫描窗口的起始时间之间的时间差,包括扫描休息的时间和扫描进行的时间。
通俗的解释就是,每隔一段时间(扫描间隔)开启扫描一段时间(扫描窗口),在低功耗应用中需要考虑,扫描是比较耗电的,但是扫描间隔太长又会出现可能扫描不到指定的广播。
关于扫描,分为主动扫描和被动扫描 ,如果仅需要广播数据则设置为被动扫描,主动扫描可以获得广播数据和扫描回应数据,广播者会额外回复扫描回复包内容,例如iBeacon的电量信息。有些传感器会在3个信道广播不同消息,还需多次扫描才能获取完整信息。
一个连接事件是指主设备和从设备之间相互发送数据包的过程,所有的数据交换都是通过连接事件来完成,每个事件发生在某个数据通道(0~36)。
一个连接中,主从设备依靠连接事件交换数据。设备连接后,无论有无数据收发,连接事件都在按照设置的连接参数周而复始的进行着,直到一方停止响应。主机与从机可在单次连接事件,即连接后,可以进行多次数据传输。
连接间隔:必须是 1.25ms 的倍数,范围是从最小值 6(7.5ms)到最大值 3200(4.0s)。
监督超时:这是两个成功的连接事件之间间隔的最大值。如果超过这个时间还未出现成功的连接事件,那么设备将会考虑失去连接,返回一个未连接状态。这个参数值使用10ms 的步进(10ms 的倍数)。监督超时时间从最小 10(100ms)到最大 3200(32.0s)。
不同的应用也许需要不同的连接间隔,一个长时间的连接间隔将会节约更多的能量,因为设备可以在两个连接事件之间睡眠更长的时间。但是他会导致数据发送不及时,如果有数据要发送那么他只能够在下一次连接事件到来时才能被发送。
profile 是 Service 的集合,它是预定义的,并不是实际存在于设备中,所以在外围设备的代码中,我们看不到 profile 的实现代码。Profile 分为标准的和自定义的,标准的 profile是由 SIG 定义和发布的,如心率 profile、防丢 profile,自定义的 profile 是由开发者自己定义。
标准的 profile 可以在 SIG 的网站上查到,网址https://www.bluetooth.com/specifications/gatt
一个 profile 文件可以包含一个或者多个服务,如心率 profile 包含了 Heart Rate Service(心率服务)和 Device Information Service(设备信息服务),从 SIG 网站上下载心率 profile,打开后可以看到心率传感器服务需求表格,由表中可以看到心率 profile 规定必须包含 HeartRate Service 和 Device Information Service。
服务是一组特征和它们公开的行为的集合,一个服务可以包含一个或多个特性。Service也分为标准的和自定义的,标准的 Service 是由 SIG 定义和发布的,如心率 Service、防丢Service,自定义的 Service 是由开发者自己定义。标准的 Service 可以在 SIG 的网站上查到(网址同 profile)。
特征是具有特定意义的数值,如心率、温度值等等。BLE 主从机之间的数据传输实际传输的就是特征值。
UUID(Universally Unique Identifier)是一个 128 位的数字,用来标志属性的类型。Service和 Characteristic 都是一种属性,都需要一个唯一的 UUID 来标识。
既然 UUID 是 128 位的数字,那么为什么有 16 位的 UUID?
因为 128 位的 UUID 相当长,设备间为了识别数据的类型需要发送长达 16 字节的数据。为了提高传输效率,蓝牙技术联盟(SIG)定义了一个“UUID 基数”,结合一个较短的 16 位数使用。二者仍然遵循通用唯一识别码的分配规则,只不过在设备间传输常用的 UUID 时,只发送较短的 16 位版本,接收方收到后补上蓝牙 UUID 基数即可。
UUID 分为标准的 UUID 和厂商自定义的 UUID。
标准的 UUID:由 SIG 发布,采用 UUID 基数+16 位 UUID 的形式,如心率服务的 UUID
是 0x180D,使用的 UUID 基数是:00000000 - 0000 - 1000 - 8000 – 00805F9B34FB。
厂商自定义的 UUID:同样采用 UUID 基数+16 位 UUID 的形式,由厂商定义。为了方便管理,增加 UUID 的可读性,蓝牙低功耗使用的那部分 UUID 被分为下列几组:
0x1800 ~ 0x26FF:用作服务类通用唯一识别码。
0x2700 ~ 0x27FF:用于标识计量单位。
0x2800 ~ 0x28FF:用于区分属性类型。
0x2900 ~ 0x29FF:用作特征描述。
0x2A00 ~ 0x7FFF:用于区分特征类型。
对于开发标准蓝牙产品,如心律监测,需要参考SIG标准,但一般物联网设备使用蓝牙,都是自定义,其参数没有明确要求,不要和标准定义冲突即可。一般自定义服务,以及在服务下自定义成对的UUID属性,分别用于收发交互。
对外广播的目的,是为了像周边的设备显示自己的存在和“我是谁”,所以广播包必须按照规定的格式填充。
设备每次广播时,会在 3 个广播信道上发送相同的报文。这些报文被称为一个广播事件。除了定向报文以外,其他广播事件均可以选择“20ms ~ 10.28s”不等的间隔。
广播就是设备将自身愿意展示的信息按照一定的间隔以“扫描者”可理解的方式向周边发射。广播有如下四种类型,广播报文的报头中有 4 个位专门用于指示广播报文的类型。
通用广播:最常用的广播方式,可以被扫描,接收到连接请求时可以作为从设备进入一个连接。
定向广播:针对于快速建立连接的需求,定向广播会占满整个广播信道,定向广播的数据净荷只包含广播者和发起者地址,发起者收到发给自己的定向广播后,会立即发送连接请求。定向广播最长时间不能超过1.28 秒,并且不能被主动扫描。
不可连接广播:广播数据,而不进入连接态,也不响应扫描,这是唯一一个允许硬件设备只有发射机的广播类型,因为它不需要接收任何数据。
可发现广播:不可连接,但可以响应扫描。
BLE 报文结构如下:
1、前导
前导是一个 8 比特的交替序列。他不是 01010101 就是 10101010,取决于接入地址的第
一个比特。
若接入地址的第一个比特为 0:01010101
若接入地址的第一个比特为 1:10101010
接收机可以根据前导的无线信号强度来配置自动增益控制。
2、接入地址
接入地址有两种类型:广播接入地址和数据接入地址。
广播接入地址:固定为 0x8E89BED6,在广播、扫描、发起连接时使用。
数据接入地址:随机值,不同的连接有不同的值。在连接建立之后的两个设备间使用。
对于数据信道,数据接入地址是一个随机值。
3、报头
报头的内容取决于该报文是广播报文还是数据报文。广播报文的报头包含 4bit 广播报文类型、2bit 保留位、1bit 发送地址类型和 1bit 接收地址类型。
广播报文类型
内核协议中定义了 7 种类型:
发送地址类型和接收地址类型
发送地址类型和接收地址类型,俗称蓝牙MAC,指示设备使用公共地址(Public Address)还是随机地址
(Random Address)。公共地址和随机地址的长度一样,都包含 6 个字节共 48 位。BLE 设备
至少要拥有这两种地址类型中的一种,也可以同时拥有这两种地址类型。具体见第6章。
4、长度
广播报文:长度域包含 6 个比特,有效值的范围是 6~37。
数据报文:长度域包含 5 个比特,有效值的范围是 0~31。
广播报文和和数据报文的长度域有所不同,主要原因是:广播报文除了最多 31 个字节
的数据之外,还必须要包含 6 个字节的广播设备地址。6+31=37,所以需要 6 比特的长度域。
5、 数据(AdvData)
广播和扫描响应的数据格式如下图所示,由有效数据部分和无效数据部分组成。
有效数据部分:包含 N 个 AD Structure,每个 AD Structure 由 Length,AD Type 和 AD Data
组成。 对于应用层开发,实际可见或者操作的只是有效数据部分,其格式为:
Length:AD Type 和 AD Data 的长度。
AD Type:指示 AD Data 数据的含义。
AD Data:数据内容。
其中AD Type表示的意义,可以查看SIG标准。
https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
参照前一节的数据(AdvData)格式,广播中的有效数据,按SIG规定的添加部分。一般情况下,建议广播包中至少包含:设备名称、Flags、外观和首要服务的 UUID,如果需连接IOS手机的包括MAC地址。内容总长度不得大于31字节。
目前与广播应用较多的,诸如蓝牙传感器,苹果的iBeacon信标,都是设备扫描它,从广播中获取传感器结果等信息。更多细节请关注微信公众号【嵌入式系统】。
BLE 设备地址可以使用公共地址(Public Device Address)或随机地址(Random Device Address)两种地址类型,一个 BLE 至少使用一种地址类型,当然也可以同时具备两种地址类型。公共地址和随机地址的长度一样,都是 48 位(6 个字节)的。BLE 设备地址类型的关系如下图所示。
设备地址一共有如下 4 种类型:
公共地址:从 IEEE 申请(购买),IEEE 保证地址分发的唯一性。
随机静态地址(Static Device Address):自定义,上电初始化完成后不能修改。
随机不可解析私有地址(Non-resolvable private address):定时更新地址,蓝牙内核协议建议 15 分钟更新一次。
随机可解析私有地址(RPA:Resolvable Private Address):通信双方使用共享的身份解析密钥(IRK:Identity Resolving Key),生成和解析可解析私有地址。只有一台设备拥有另一台广播设备的 IRK 时,才能跟踪该广播设备的活动。
公共地址由两部分组成,如下图所示。公共地址由制造商从 IEEE 申请(购买),由 IEEE注册机构为该制造商分配的机构唯一标识符 OUI(Organizationally Unique Identifier)。这个地址是独一无二,不能修改的。
公共地址能明确的指示出设备,同时具有唯一性,但是安全度不够,为了加强隐私保护,蓝牙内核协议中提供了另外一种地址:随机地址,随机地址是随机产生的,不是固定分配的,随机地址又分为多种类型,以适应不同的应用场景对隐私的需求。
随机静态地址是随机生成的 48 位地址,随机静态地址必须符合以下要求:
静态地址的最高 2 位有效位必须是 1。
静态地址最高 2 位有效位之外的其余部分不能全为 0。
静态地址最高 2 位有效位之外的其余部分不能全为 1。
一个上电周期内不变。
静态地址的格式如下,共 48 位,最高 2 位是固定的,必须是 1。
设备生成不可解析私有地址时必须符合以下要求:
地址的最高 2 位有效位必须是 0。
地址最高 2 位有效位之外的其余部分不能全为 0。
地址最高 2 位有效位之外的其余部分不能全为 1。
不可解析私有地址不能和公共地址一样。
不可解析私有地址的格式如下,共 48 位,最高 2 位是固定的,必须是 0。
不可解析私有地址相当于周期性改变的随机静态地址,不可解析私有地址一直在变化,并且该地址是个随机数,没有提供任何可解析的信息,因此,很难通过跟踪地址来跟踪设备,所以具有很高的安全性。
但是因为地址一直变化,在隐私上“敌我”不分,实际应用中使用的不多。
设备生成可解析私有地址时必须符合以下要求:
地址的最高 2 位有效位必须是 0 和 1。
Prand 中地址最高 2 位有效位之外的其余部分不能全为 0。
Prand 中地址最高 2 位有效位之外的其余部分不能全为 1。
不可解析私有地址不能和公共地址一样。
不可解析私有地址的格式如下,共 48 位,最高 2 位是固定的,必须是 01。
蓝牙 4.2 之前,BLE 的 MTU(Maximum Transmission Unit,最大传输单元)为 23 个字节,这 23 个字节中包含了 1 个字节的操作码(op code)和 2 个字节的属性句柄(attribute handle),因此一次最多传输 20 个字节。从蓝牙 4.2 开始,BLE 支持长包传输,MTU 扩展到了 247 个字节,除去 op code 和 attribute handle,一次可传输的最大长度为 244 个字节。
两种 MTU 存在,那么客户端和服务器是如何知道使用什么样的 MTU 的?客户端和服务器是通过协商来交换各自支持的 MTU 的长度的,这个过程称为 MTU 交换(Exchange MTU),通过 MTU 交换,客户端和服务器具备了自适应 MTU 的功能,但是注册每个建立的连接只能在连接建立时交换一次,而不能实时通过 MTU 交换协商数据传输长度。
产品交付后,使用中可能发现隐藏的BUG 或者需要增加新功能,重新召回产品使用编程器更新软件,对成本是个考验,最好的方式使用空中升级,DFU(Device Firmware Upgrade)固件更新就是非接触解决软件版本升级的问题。
一般芯片SDK都提供了完整的DFU方案,支持对 SD、Bootloader 或 APP 升级,DFU 的核心是Bootloader,接收新固件、更新应用程序。
自定义升级方案可参考终端设备在线升级一文。
本文主要参考 艾克姆科技的蓝牙低功耗开发指南。
文中提到的物联网可以读读物联网之移动通讯的演化史。
关于AES加密算法可参考嵌入式算法6—AES加密/解密算法。