1.蓝牙基础
1.1 概述
瑞典爱立信公司在1994年进行研究,旨在在移动电话及其附件之间探求一种新的低功耗、低成本的空中接口。爱立信将这项新的无线通信技术命名为蓝牙(Bluetooth)。1998年5月,爱立信联合诺基亚(Nokia)、英特尔(Intel)、IBM 、东芝(Toshiba)这4家公司一起成立了蓝牙技术联盟(Bluetooth Special Interest Group,SIG),负责蓝牙技术标准的制定、产品测试,并协调各国蓝牙的具体使用。
蓝牙的名字来源于10世纪丹麦国王Harald Blatand-英译为Harold Bluetooth(因为他十分喜欢吃蓝莓,所以牙齿每天都带着蓝色)。Blatand国王将现在的挪威、瑞典和丹麦统一起来,他的口齿伶俐,善于交际,就如同这项即将面世的技术,允许不同工业领域之间的协调工作、保持个各系统之间的良好交流,于是就这么定下来了。
蓝牙是一种短距无线通信的技术规范,它最初的目标是取代现有的掌上电脑、移动电话等各种数字设备上的有线电缆连接。蓝牙工作频段为全球统一开放的2.4GHz工业、科学和医学(Industrial, Scientific and Medical, ISM)频段。由于蓝牙体积小、功率低,几乎可以被集成到任何数字设备之中,特别是移动设备和便携设备。蓝牙技术的特点可归纳为如下几点:
(1)全球范围适用:蓝牙工作在2.4GHz的ISM频段,全球大多数国家ISM频段的范围是2.4-2.4835GHz。使用该频段无需向各国的无线电资源管理部门申请许可证;
(2)可建立临时对等连接:主设备是组网连接主动发起连接请求的蓝牙设备,几个蓝牙设备连接成一个Pico网(Piconet)时,其中只有一个主设备,其余的均为从设备;
(3)很好的抗干扰能力:蓝牙采用了跳频(Frequency Hopping)方式来扩展频谱(Spread Spectrum),将2.402~2.48GHz频段分成79个频点,相邻频点间隔1MHz。频点的排列顺序则是伪随机的,每秒钟频率改变1600次,即每个跳频点上停留的时间为625us,这625us就是蓝牙的一个时隙;
(4)近距离通信:蓝牙技术通信距离为10m,可根据需要扩展至100m,以满足不同设备的需要;
(5)功耗低,体积小:CLASS1蓝牙模块发射功率+20dBm,即100mW;标准的CLASS2 蓝牙模块发射功率<6dBm,即小于4mW。
1.2 蓝牙认证
蓝牙认证将使OEM(Original Equipment Manufacturer)的产品列入蓝牙官方网站,并允许他们在产品中使用蓝牙商标。认证可以帮助不同厂商的蓝牙产品实现互通并使其符合蓝牙规范。整个认证流程完全由蓝牙品质认证委员会(Bluetooth Qualification Review Board,BQRB)监控和管理。认证基于一套参考测试系统的一致性测试以及与其他符合标准的蓝牙产品之间的互通性测试。测试由已得到SIG下属的BQRB授权的蓝牙认证测试部门(Bluetooth Qualification Test Facility ,BQTF)实施。
除了获得蓝牙认证组织(BQB)的认证外,蓝牙产品还需要获得其他一些认证,如FCC、CE。
1.3 蓝牙版本变迁
蓝牙诞生之初,使用的是BR(Basic Rate)技术,此时蓝牙的理论传输速率,只能达到721.2Kbps。在那个年代,56Kbps的Modem就是高大上了,这个速度可以说是惊为天人了啊!但是科技变化太快了,BR技术转眼就过时了。那怎么办呢?缝缝补补一下,增强速度呗,EDR(Enhanced Data Rate)就出现了。使用EDR技术的蓝牙,理论速率可以达到2.1Mbps。这一次的升级换代,还算优雅,因为没有任何的硬件架构、软件架构和使用方式上的改变。也许你也猜到了,很快EDR又落伍了,看看人家WIFI(WLAN),几十Mbps,上百Mbps,咱们才2.1Mbps,也太寒酸了吧!那怎么办呢?蓝牙组织想了个坏主意:哎,WIFI!把你的PHY层和MAC(Media Access Control)层借我用用呗!这就·是AMP(Alternate MAC and PHY layer extension)。艾玛,终于松口气了,我们可以达到54Mbps了。不过呢,由于蓝牙自身的物理层和AMP技术差异太明显了,这次扩展只能是交替使用(Alternate)的,也就是说,有我(BR/EDR)没你(AMP)。
这里特别强调了optional和alternate这两个字眼,这是蓝牙Spec的原话。它意味着,BR和EDR是可以同时存在的,但BR/EDR和AMP只能二选一。总的来说,BR是正宗的蓝牙技术,可以包括可选(optional)的EDR技术,以及AMP(交替使用(Alternate)的MAC层和PHY层扩展)。
上面所讲的蓝牙技术的进化路线,就是传输速率的加快、加快、再加快。但能量是守恒的,你想传的更快,代价就是消耗更多的能量。而有很多的应用场景,并不关心传输速率,反而非常关心功耗。这就是BLE(低功耗蓝牙)产生的背景。
有些人一直认为蓝牙4.0就是蓝牙BLE,其实并不正确。准确来说4.0是双模的,既包括经典蓝牙又包括低功耗蓝牙。经典蓝牙和蓝牙BLE虽然都是蓝牙,但其实还是存在很大区别的。蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0+HS标准的基础上增加了对低功耗蓝牙(Bluetooth Low Energy, BLE)的支持。
2. 蓝牙核心协议简介
2.1 底层协议
射频协议(Radio Frequency Protocol):蓝牙射频协议处于蓝牙协议栈的最底层,主要包括频段与信道安排、发射机特性和接收机特性等,用于规范物理层无线传输技术,实现空中数据的收发。
基带协议(Base Band Protocol):基带层在蓝牙协议栈中位于蓝牙射频层之上,同射频层一起构成了蓝牙的物理层。基带层的主要功能包括:链路控制;管理物理链路、SCO(Synchronous Connection Oriented)链路和ACL(Asynchronous Connectionless)链路;定义基带分组格式和分组类型等;另外还有处理数据包、寻呼、查询接入和查询蓝牙设备等功能。
链路管理协议(Link Manager Protocol,LMP):是一个数据链路层协议,负责设备链路的建立和拆除及链路的安全和控制,执行链路设置、认证、链路配置。
2.2 中间层协议
主机控制器接口协议(Host Controller Interface Protocol,HCI):为上层协议提供了进入链路管理器的统一接口和进入基带的统一方式,是蓝牙协议中软硬件之间的接口。SIG规定了四种与硬件连接的物理总线方式,即四种HCI传输层:USB、RS232、UART和PC卡。
逻辑链路控制与适配协议(Logical Link Control and Adaptation Protocol,L2CAP):是蓝牙协议栈的核心组成部分,也是其他协议实现的基础。位于基带之上,向上层提供面向连接的和无连接的数据服务。主要完成数据的拆装、服务质量控制,协议的复用、分组的分割和重组及组提取等功能。
串口仿真协议(RFCOMM):位于L2CAP协议层和应用层协议层之间,它在蓝牙基带上仿真RS-232的控制和数据信号,为使用串行连接的上层业务提供传送能力。
电话控制协议(Telephony Control Protocol,TCS):基于ITU-T Q.931采用面向比特的协议,定义了用于蓝牙设备之间建立语音和数据呼叫的控制信令,并负责处理蓝牙设备组的移动管理过程。
服务发现协议(Service Discovery Protocol,SDP):是所有应用模型的基础。任何一个蓝牙应用模型的实现都是利用某些服务的结果。蓝牙服务发现协议可以动态地查询到设备信息和服务类型,从而建立起一条对应所需要服务的通信信道。
2.3 简单硬件结构
2.4 蓝牙上层Profile
为了保持蓝牙设备之间的兼容性,Bluetooth规范中定义了Profile。可以把Profile理解为连接层或者应用层协议,定义了设备如何实现一种连接或者应用。
蓝牙的一个很重要特性,就是所有的蓝牙产品都无须实现全部的Bluetooth Profile。
在所有的Profile中,有四种是最基本的Profile,这些Profile会被其它的Profile使用,它们是GAP/SDAP/SPP/GOEP Profile。
2.4.1 四个基本Profile
(1) GAP(Generic Access Profile):保证不同的Bluetooth产品可以互相发现对方并建立连接。GAP定义了蓝牙设备如何发现和建立与其他设备的连接。GAP具有强制性,是其它蓝牙应用规范的基础。
(2) SDAP(Service Discovery Application Profile):SDAP描述了应用程序如何使用SDP发现远程设备上的服务。通过该Profile,一个Bluetooth设备可以找到其它Bluetooth设备提供的服务,以及查询相关的信息。
(3) SPP(Serial Port Profile):定义了如何在两台BT设备之间建立虚拟串口并进行连接。
(4) GOEP(Generic Object Exchange Profile):定义的是数据的传输,包括同步,文件传输或者推送其它的数据。可以理解为与内容无关的传输层协议,可以被任何应用用来传输自己定义的数据对象。
2.4.2 常用Profile
Core Specification(核心规范),用于规定蓝牙设备必须实现的通用功能和协议层次。它由软件和硬件模块组成,两个模块之间的信息和数据通过主机控制接口(HCI)的解释才能进行传递。
Profiles(蓝牙应用规范),它从应用场景的角度为蓝牙技术的使用制定了不同的规范。这也是和大众日常生活接触最多的一部分。蓝牙支持很多Profiles,下面介绍几种比较常见的蓝牙应用规范。
A2DP(Advanced Audio Distribution Profile):规定了使用蓝牙非同步传输信道方式,传输高质量音乐文件数据的协议堆栈软件和使用方法,基于该协议就能通过以蓝牙方式传输高品质的音乐了。这个技术可以利用立体声蓝牙耳机来收听手机中的音乐了。
AVRCP(Audio/Video Remote Control Profile):定义了如何控制流媒体的特征。包括暂停、停止、启动重放、音量控制及其它类型的远程控制操作。
OPP(Object Push Profile)定义了推送服务器和推送客户端两种角色。这些角色与 GOEP(Generic Object Exchange Profile) 定义的服务器和客户端设备角色类似且必须能与之互操作。OPP 可用于发送对象,如vCard、vCalendar、图片等。
HFP(Hands-Free Profile):描述了免提设备如何使用网关设备拨打和接听电话。HFP包括两个角色:Audio Gateway(AG,音频网关)和Hands-Free Unit(HF,免提设备)。AG是音频输入和输出的设备,典型配置如汽车使用手机作为网关设备。和HFP相关的profile有HSP和PBAP(Phonebook Access Profile电话号码簿访问协议)。
HSP(Headset Profile):描述了蓝牙耳机如何与计算机或其它蓝牙设备(如手机)通信。连接和配置好后,耳机可以作为远程设备的音频输入和输出接口。
DUN(Dial-up Networking Profile):实现一台蓝牙设备通过另外一个带无线功能的蓝牙设备共享上网。
PAN(Personal Area Networking Profile):个人局域网配置文件。它描述了两个或更多个蓝牙设备如何构成一个即时网络,以及如何使用同一机制通过网络接入点接入远程网络。
AVDTP(Audio Video Distribution Transport Protocol):音视频分发传输协议。
AVCTP(Audio Video Control Transport Protocol):音视频控制传输协议。
HID(Human Interface Device Profile):人机接口设备,定义了蓝牙在人机接口设备中的协议、特征和使用规程。典型的应用包括蓝牙鼠标、蓝牙键盘、蓝牙游戏手柄等。
MAP(Message Access Profile):短信访问规范。
PBAP(Phonebook Access Profile):电话号码簿访问协议。
2.5 蓝牙的拓扑结构
蓝牙通常采用点对点的配对连接方式,主动提出通信要求的设备是主设备(master),被动进行通信的设备为从设备(slave)。
Piconet(微微网):共享相同信道;8个蓝牙设备可在小型网络内通信(7个slave节点)。
Scatternet(散射网):多达256个时间和空间层叠的Piconet可连接成更大的网络;几个Master连接到同一个slave;一个Master可以是另一个微微网络的slave。
1.8 蓝牙无线接入过程状态
蓝牙两大主要状态为:待机(standby)和连接(connection)。
两个蓝牙设备接入过程中的状态:
1.查询inquiry;查询扫描inquiry scan;查询响应Inquiry response
2.寻呼page ;寻呼扫描page scan;主机响应 master response;从机响应slave response
2.6 蓝牙的四种工作模式
四种工作模式都属于连接态(Connection)。
- 活动(Active)
被分配活动成员地址AM_Addr;传递数据或一直监听信道是否有数据需要传输。
- 呼吸(Sniff)
每隔一段时间间隔监听特定的时隙。
- 保持(Hold)
不释放AM_Addr地址,主从设备协商在保持状态下持续的时间;停止ACL传输,但可交换SCO分组。
- 休眠(Park)
设备仍旧是该piconet的成员;保持信道同步,周期性的在一个时隙上保持相互之间的通信;释放AM_Addr地址但获得一个PM_Addr(Parked Member Address)地址。
连接状态分为四种模式主要目的:减小提高蓝牙设备的功耗、提高待机时间。
功耗角度比较:四种模式功耗从高到低的顺序依次为:Active>Sniff≥Hold>Parked.
器件工作的程度比较:Active为全速工作;Hold和Sniff为部分工作;Parked为基本不工作。
根本差别:高速时钟信号、低速时钟是否运行、功放是否打开。
3. Android蓝牙框架
3.1 蓝牙BLE架构概览
一般而言,我们把某个协议的实现代码称为协议栈(protocol stack),BLE协议栈就是实现低功耗蓝牙协议的代码,理解和掌握BLE协议是实现BLE协议栈的前提。在深入BLE协议栈各个组成部分之前,我们先看一下BLE协议栈整体架构。
如上图所述,要实现一个BLE应用,首先需要一个支持BLE射频的芯片,然后还需要提供一个与此芯片配套的BLE协议栈,最后在协议栈上开发自己的应用。可以看出BLE协议栈是连接芯片和应用的桥梁,是实现整个BLE应用的关键。那BLE协议栈具体包含哪些功能呢?简单来说——BLE协议栈主要用来对你的应用数据进行层层封包,以生成一个满足BLE协议的空中数据包,换句话说,就是把应用数据包裹在一系列的帧头(header)和帧尾(tail)中。具体来说,BLE协议栈主要由如下几部分组成:
· PHY层(Physical layer物理层)。PHY层用来指定BLE所用的无线频段,调制解调方式和方法等。PHY层做得好不好,直接决定整个BLE芯片的功耗,灵敏度以及selectivity等射频指标。
· LL层(Link Layer链路层)。LL层是整个BLE协议栈的核心,也是BLE协议栈的难点和重点。像Nordic的BLE协议栈能同时支持20个link(连接),就是LL层的功劳。LL层要做的事情非常多,比如具体选择哪个射频通道进行通信,怎么识别空中数据包,具体在哪个时间点把数据包发送出去,怎么保证数据的完整性,ACK如何接收,如何进行重传,以及如何对链路进行管理和控制等等。LL层只负责把数据发出去或者收回来,对数据进行怎样的解析则交给上面的GAP或者GATT。
· HCI(Host controller interface)。HCI是可选的(具体请参考文章: 三种蓝牙架构实现方案(蓝牙协议栈方案)),HCI主要用于2颗芯片实现BLE协议栈的场合,用来规范两者之间的通信协议和通信命令等。
· GAP层(Generic access profile)。GAP是对LL层payload(有效数据包)如何进行解析的两种方式中的一种,而且是最简单的那一种。GAP简单的对LL payload进行一些规范和定义,因此GAP能实现的功能极其有限。GAP目前主要用来进行广播,扫描和发起连接等。
· L2CAP层(Logic link control and adaptation protocol)。L2CAP对LL进行了一次简单封装,LL只关心传输的数据本身,L2CAP就要区分是加密通道还是普通通道,同时还要对连接间隔进行管理。
· SMP(Secure manager protocol)。SMP用来管理BLE连接的加密和安全的,如何保证连接的安全性,同时不影响用户的体验,这些都是SMP要考虑的工作。
· ATT(Attribute protocol)。简单来说,ATT层用来定义用户命令及命令操作的数据,比如读取某个数据或者写某个数据。BLE协议栈中,开发者接触最多的就是ATT。BLE引入了attribute概念,用来描述一条一条的数据。Attribute除了定义数据,同时定义该数据可以使用的ATT命令,因此这一层被称为ATT层。
· GATT(Generic attribute profile )。GATT用来规范attribute中的数据内容,并运用group(分组)的概念对attribute进行分类管理。没有GATT,BLE协议栈也能跑,但互联互通就会出问题,也正是因为有了GATT和各种各样的应用profile,BLE摆脱了ZigBee等无线协议的兼容性困境,成了出货量最大的2.4G无线通信产品。
我相信很多人看了上面的介绍,还是不懂BLE协议栈的工作原理,以及每一层具体干什么的,为什么要这么分层。下面我以如何发送一个数据包为例来讲解BLE协议栈各层是如何紧密配合,以完成发送任务的。
4. 简述BLE如何发送数据包
假设有设备A和设备B,设备A要把自己目前的电量状态83%(十六进制表示为0x53)发给设备B,该怎么做呢?作为一个开发者,他希望越简单越好,对他而言,他希望调用一个简单的API就能完成这件事,比如send(0x53),实际上我们的BLE协议栈就是这样设计的,开发者只需调用send(0x53)就可以把数据发送出去了,其余的事情BLE协议栈帮你搞定。很多人会想,BLE协议栈是不是直接在物理层就把0x53发出去,就如下图所示:
这种方式初看起来挺美的,但由于很多细节没有考虑到,实际是不可行的。首先,它没有考虑用哪一个射频信道来进行传输,在不更改API的情况下,我们只能对协议栈进行分层,为此引入LL层,开发者还是调用send(0x53),send(0x53)再调用send_LL(0x53,2402M)(注:2402M为信道频率)。这里还有一个问题,设备B怎么知道这个数据包是发给自己的还是其他人的,为此BLE引入access address概念,用来指明接收者身份,其中,0x8E89BED6这个access address比较特殊,它表示要发给周边所有设备,即广播。如果你要一对一的进行通信(BLE协议将其称为连接),即设备A的数据包只能设备B接收,同样设备B的数据包只能设备A接收,那么就必须生成一个独特的随机access address以标识设备A和设备B两者之间的连接。
广播方式
我们先来看一下简单的广播情况,这种情况下,我们把设备A叫advertiser(广播者),设备B叫scanner或者observer(扫描者)。广播状态下设备A的LL层API将变成send_LL(0x53,2402M, 0x8E89BED6)。由于设备B可以同时接收到很多设备的广播,因此数据包还必须包含设备A的device address(0xE1022AAB753B)以确认该广播包来自设备A,为此send_LL参数需要变成(0x53,2402M, 0x8E89BED6, 0xE1022AAB753B)。LL层还要检查数据的完整性,即数据在传输过程中有没有发生窜改,为此引入CRC24对数据包进行检验 (假设为0xB2C78E) 。同时为了调制解调电路工作更高效,每一个数据包的最前面会加上1个字节的preamble(前导帧),preamble一般为0x55或者0xAA。这样,整个空中包就变成(注:空中包用小端模式表示!):
上面这个数据包还有如下问题:
没有对数据包进行分类组织,设备B无法找到自己想要的数据0x53。为此我们需要在access address之后加入两个字段:LL header和长度字节。LL header用来表示数据包的LL类型,长度字节用来指明payload的长度
设备B什么时候开启射频窗口以接收空中数据包?如上图case1所示,当设备A的数据包在空中传输的时候,设备B把接收窗口关闭,此时通信将失败;同样对case2来说,当设备A没有在空中发送数据包时,设备B把接收窗口打开,此时通信也将失败。只有case3的情况,通信才能成功,即设备A的数据包在空中传输时,设备B正好打开射频接收窗口,此时通信才能成功,换句话说,LL****层还必须定义通信时序。
当设备B拿到数据0x53后,该如何解析这个数据呢?它到底表示湿度还是电量,还是别的意思?这个就是GAP层要做的工作,GAP层引入了LTV****(Length-Type-Value)结构来定义数据,比如020105,02-长度,01-类型(强制字段,表示广播flag,广播包必须包含该字段),05-值。由于广播包最大只能为31个字节,它能定义的数据类型极其有限,像这里说的电量,GAP就没有定义,因此要通过广播方式把电量数据发出去,只能使用供应商自定义数据类型0xFF,即04FF590053,其中04表示长度,FF表示数据类型(自定义数据),0x0059是供应商ID(自定义数据中的强制字段),0x53就是我们的数据(设备双方约定0x53就是表示电量,而不是其他意思)。
最终空中传输的数据包将变成:
AAD6BE898E600E3B75AB2A02E102010504FF5900538EC7B2
o AA – 前导帧(preamble)
o D6BE898E – 访问地址(access address)
o 60 – LL帧头字段(LL header)
o 0E – 有效数据包长度(payload length)
o 3B75AB2A02E1 – 广播者设备地址(advertiser address)
o 02010504FF590053 – 广播数据
o 8EC7B2 – CRC24值
有了PHY,LL和GAP,就可以发送广播包了,但广播包携带的信息极其有限,而且还有如下几大限制:
无法进行一对一双向通信 (广播是一对多通信,而且是单方向的通信)
由于不支持组包和拆包,因此无法传输大数据
通信不可靠及效率低下。广播信道不能太多,否则将导致扫描端效率低下。为此,BLE只使用37(2402MHz) /38(2426MHz) /39(2480MHz)三个信道进行广播和扫描,因此广播不支持跳频。由于广播是一对多的,所以广播也无法支持ACK。这些都使广播通信变得不可靠。
扫描端功耗高。由于扫描端不知道设备端何时广播,也不知道设备端选用哪个频道进行广播,扫描端只能拉长扫描窗口时间,并同时对37/38/39三个通道进行扫描,这样功耗就会比较高。
而连接则可以很好解决上述问题,下面我们就来看看连接是如何将0x53发送出去的。
连接方式
到底什么叫连接(connection)?像有线UART,很容易理解,就是用线(Rx和Tx等)把设备A和设备B相连,即为连接。用“线”把两个设备相连,实际是让2个设备有共同的通信媒介,并让两者时钟同步起来。蓝牙连接有何尝不是这个道理,所谓设备A和设备B建立蓝牙连接,就是指设备A和设备B两者一对一“同步”成功,其具体包含以下几方面:
· 设备A和设备B对接下来要使用的物理信道达成一致
· 设备A和设备B双方建立一个共同的时间锚点,也就是说,把双方的时间原点变成同一个点
· 设备A和设备B两者时钟同步成功,即双方都知道对方什么时候发送数据包什么时候接收数据包
· 连接成功后,设备A和设备B通信流程如下所示:
如上图所示,一旦设备A和设备B连接成功(此种情况下,我们把设备A称为Master或者Central,把设备B称为Slave或者Peripheral),设备A将周期性以CI(connection interval)为间隔向设备B发送数据包,而设备B也周期性地以CI为间隔打开射频接收窗口以接收设备A的数据包。同时按照蓝牙spec要求,设备B收到设备A数据包150us**后,设备B切换到发送状态,把自己的数据发给设备A;设备A则切换到接收状态,接收设备B发过来的数据。由此可见,连接状态下,设备A和设备B的射频发送和接收窗口都是周期性地有计划地开和关,而且开的时间非常短,从而大大降低系统功耗并大大提高系统效率。
现在我们看看连接状态下是如何把数据0x53发送出去的,从中大家可以体会到蓝牙协议栈分层的妙处。
· 对上层开发者来说,很简单,他只需要调用send(0x53)
· GATT层定义数据的类型和分组,方便起见,我们用0x0013表示电量这种数据类型,这样GATT层把数据打包成130053(小端模式!)
· ATT层用来选择具体的通信命令,比如读/写/notify/indicate等,这里选择notify命令0x1B,这样数据包变成了:1B130053
· L2CAP用来指定connection interval(连接间隔),比如每10ms同步一次(CI不体现在数据包中),同时指定逻辑通道编号0004(表示ATT命令),最后把ATT数据长度0x0004加在包头,这样数据就变为:040004001B130053
· LL层要做的工作很多,首先LL层需要指定用哪个物理信道进行传输(物理信道不体现在数据包中),然后再给此连接分配一个Access address(0x50655DAB)以标识此连接只为设备A和设备B直连服务,然后加上LL header和payload length字段,LL header标识此packet为数据packet,而不是control packet等,payload length为整个L2CAP字段的长度,最后加上CRC24字段,以保证整个packet的数据完整性,所以数据包最后变成:
AAAB5D65501E08040004001B130053D550F6
AA – 前导帧(preamble)
0x50655DAB – 访问地址(access address)
1E – LL帧头字段(LL header)
08 – 有效数据包长度(payload length)
04000400 – ATT数据长度,以及L2CAP通道编号
1B – notify command
0x0013 – 电量数据handle
0x53 – 真正要发送的电量数据
0xF650D5 – CRC24值
虽然上层开发者只调用了 send(0x53),但由于蓝牙BLE协议栈层层打包,最后空中实际传输的数据将变成下图所示的模样,这就既满足了低功耗蓝牙通信的需求,又让用户API变得简单,可谓一箭双雕!
5. 蓝牙问题处理思路
5.1 蓝牙相关log和工具介绍
5.1.1 蓝牙hci log
蓝牙hci log可通过frontline或者Ellisys Bluetooth Analyzer工具打开。
通过frontline打开可以通过加载方式发开.log文件,也可通过修改log后缀为cfa后直接打开。这种方式打开的log时间点要+8,海外抓的log要具体再看。
通过Ellisys打开.log后缀蓝牙log的步骤:
1、选中菜单栏“File”里的“Import”按钮(快捷方式:Ctrl+P),调出Import会话框
2、点击完“Finish”完成文件加载动作,界面如下
界面上的功能很多,能满足不同角度对蓝牙交互过程的分析。
以传统蓝牙设备创建连接的指令Create Connection Command来分析下该软件能解析到何种程度。查看蓝牙协议可以知道传统蓝牙的连接指令需包含以下参数:
那从协议分析软件上可否直观知道各参数的具体值尼,答案是肯定的,见下图
5.2 蓝牙问题常见处理思路
5.2.1 连接类
包含: 连接/配对失败,断连等
如手机间配对失败,连接不上手环(BLE),媒体音频连接失败(AVDTP signaling),回连/拉锯重连(对端发起connection request没有),上下电重连,异常断开(disconnection, reason)等。
关键字: a2dpstatemachine/headsetstatemachine connection state
正常配对连接:
178 Command 0x0405 2017/5/30 05:24:56.645405 Create_Connection 13 17 00:00:00.054284
179 Event 0x0405 2017/5/30 05:24:56.653133 Create_Connection Command Status Success 4 7 00:00:00.007728
198 Event 2017/5/30 05:24:59.762037 Connection Complete Success 0x0032 11 14 00:00:01.825339
252 Command 0x0411 2017/5/30 05:25:00.189845 Authentication_Requested 0x0032 2 6 00:00:00.006471
253 Event 0x0411 2017/5/30 05:25:00.193610 Authentication_Requested Command Status Success 4 7 00:00:00.003765
254 Event 2017/5/30 05:25:00.194803 Link Key Request 6 9 00:00:00.001193
255 Command 0x040b 2017/5/30 05:25:00.196197 Link_Key_Request_Reply 22 26 00:00:00.001394
256 Event 0x040b 2017/5/30 05:25:00.200560 Link_Key_Request_Reply Command Complete Success 10 13 00:00:00.004363
257 Event 2017/5/30 05:25:00.287660 Authentication Complete Success 0x0032 3 6 00:00:00.087100
258 Command 0x0413 2017/5/30 05:25:00.289038 Set_Connection_Encryption 0x0032 3 7 00:00:00.001378
259 Event 0x0413 2017/5/30 05:25:00.292124 Set_Connection_Encryption Command Status Success 4 7 00:00:00.003086
260 Event 2017/5/30 05:25:00.427665 Encryption Change Success 0x0032 4 7 00:00:00.135541
媒体音频 AVDTP signaling
396 50 Single Packet Master DISCOVER 0 11 2017/5/30 05:25:04.011291
398 1 50 Single Packet Slave DISCOVER 0 13 00:00:00.031523 2017/5/30 05:25:04.042814
400 1 50 Single Packet Master GET_CAPABILITIES 1 12 00:00:00.004477 2017/5/30 05:25:04.047291
407 50 Single Packet Slave GET_CAPABILITIES 1 25 00:00:00.023680 2017/5/30 05:25:04.070971
414 1 50 1 Single Packet Master SET_CONFIGURATION 2 27 00:00:00.016982 2017/5/30 05:25:04.087953
423 50 Single Packet Slave SET_CONFIGURATION 2 11 00:00:00.030274 2017/5/30 05:25:04.118227
425 1 50 Single Packet Master OPEN 3 12 00:00:00.002070 2017/5/30 05:25:04.120297
434 50 Single Packet Slave OPEN 3 11 00:00:00.018034 2017/5/30 05:25:04.138331
493 1 50 Single Packet Master START 4 12 00:00:16.664210 2017/5/30 05:25:20.802541
496 50 Single Packet Slave START 4 11 00:00:00.033991 2017/5/30 05:25:20.836532
需要的log:
手机间配对的话,提供与测试机相同要求的对端手机log
一般ap log,hci log。如果配对连接异常出现在L2CAP,LMP层,断开为connection timeout等需要OTA log,fw log,如果是高通平台还会需要QXDM log
5.2.2 搜索
主要有:出问题后必现搜索不到指定设备,搜索慢等。
关键字:startDiscovey|start_discovery|Extended Inquiry Result event (rssi)
遇到的问题有:
- 搜索不到一款山水音响(空口log显示是因为对端设备频偏不规范导致的对端无回复)
- 搜索不到任何蓝牙设备,空口确认discovery包没有发出,fw log确认为芯片端tx卡住。因共芯片,TDD模式,同时造成wifi异常。
- 蓝牙通话过程中无法搜索到ble设备,芯片限制(MTK),高通待确认
所需log:
ap log确认apk指令下发ok
hci log查看返回的搜索结果
ota log查看发和收包
fw log 芯片厂商确认问题,enhanced hci log或者qxdm log
5.2.3 稳定性和性能
主要有tombstone,crash,打开/关闭失败,打开蓝牙时间超标
tombstone要结合异常发生时的业务逻辑来看,有些不需要根据symbol去解析堆栈,如蓝牙打开失败造成的tombstone
打开/关闭失败,对照正常流程去看 bt-enable/bt-disable, adapter state change, timeout
STATE_OFF = 10
STATE_TURNING_ON = 11
STATE_ON = 12
STATE_TURNING_OFF = 13
STATE_BLE_TURNING_ON = 14
STATE_BLE_ON = 15
STATE_BLE_TURNING_OFF = 16
耗时的话,拆解时间,看耗时异常点
主要log:ap kernel log,dump
5.2.4 声音类
包含有:通道切换时的漏声;音乐,通话包括微信语音等不从蓝牙设备输出;音乐卡顿;通话杂音;音乐/inbandring铃音无声等
分析:
设备连接包含hdp,a2dp是否ok connection state 0到1,1到2
音频设备选择有问题,主要由phonestate和forceuse决定
关键字setMode|setBluetoothScoOn|startOutput/stopOutput|getNewoutputdevice
通话杂音需要解析音频dump,哪个节点的问题,原因较多
音乐卡顿原因也很多:
1.手机打印日志(特别是HCI日志)导致卡顿。
2.蓝牙wifi共存问题,wifi正在高速下载或者传输P2P文件。
3.测试环境比较噪杂(2.4GHz信号较多,蓝牙跳频以及重传概率增加)干扰较多。
4.导出A2DP音频文件或用ellisys import打开hci log查看是否有卡顿
5.查找到HCI日志中AVDTP Media列中两个音频数据包间隔较大的异常数据,然后跳转到HCI列中确认NOCP
主要log:ap log,hci log卡顿类需要qxdm ota,可能的话还需要抓pcm流
5.2.5 其他
avrcp
hid
功耗
...
6. 参考资料
Bluetooth Core Specification v5.0;
各Profile Spec;
blogs,如https://blog.csdn.net/pashanhu6402/article/details/72905626;
芯片商资料:如QC 80-y7674-180_b,80-y8502-1sc_a;
…