BLE协议栈为什么要分层?怎么理解BLE“连接”?如果BLE协议只有ATT层没有GATT层会发生什么?
一般而言,我们把某个协议的实现代码称为协议栈(protocol stack),BLE协议栈就是实现低功耗蓝牙协议的代码,理解和掌握BLE协议是实现BLE协议栈的前提。在深入BLE协议栈各个组成部分之前,我们先看一下BLE协议栈整体架构。
如上图所述,要实现一个BLE应用,首先需要一个支持BLE射频的芯片,然后还需要提供一个与此芯片配套的BLE协议栈,最后在协议栈上开发自己的应用。可以看出BLE协议栈是连接芯片和应用的桥梁,是实现整个BLE应用的关键。那BLE协议栈具体包含哪些功能呢?简单来说,BLE协议栈主要用来对你的应用数据进行层层封包,以生成一个满足BLE协议的空中数据包,也就是说,把应用数据包裹在一系列的帧头(header)和帧尾(tail)中。具体来说,BLE协议栈主要由如下几部分组成:
视频参考,可只看第二集。
【CC2540】TI官方低功耗蓝牙BLE协议栈说明(TI官方)
我相信很多人看了上面的介绍,还是不懂BLE协议栈的工作原理,以及每一层具体干什么的,为什么要这么分层。下面我以如何发送一个数据包为例来讲解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。这样,整个空中包就变成:(注:空中包用小端模式表示!)
上面这个数据包还有如下问题:
关于报头第三部分还会详细介绍。
有了PHY,LL和GAP,就可以发送广播包了,但广播包携带的信息极其有限,而且还有如下几大限制:
而连接则可以很好解决上述问题,下面我们就来看看连接是如何将0x53发送出去的。
到底什么叫连接(connection)? 像有线UART,很容易理解,就是用线(Rx和Tx等)把设备A和设备B相连,即为连接。用“线”把两个设备相连,实际是让2个设备有共同的通信媒介,并让两者时钟同步起来。蓝牙连接有何尝不是这个道理,所谓设备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),但由于低功耗蓝牙协议栈层层打包,最后空中实际传输的数据将变成下图所示的模样,这就既满足了低功耗蓝牙通信的需求,又让用户API变得简单,可谓一箭双雕!
关于报头第三部分还会详细介绍。
上面只是对BLE协议栈实现原理做了一个简单概述,即便如此,由于都是关于BLE协议栈底层的东西,很多开发者还是会觉得比较枯燥和晦涩,而且对很多开发者来说,他们也不关心BLE协议栈是如何实现的,他们更关心的是BLE协议栈的使用,即怎么开发一个BLE应用。BLE应用是实打实的东西,不能像上面讲述协议栈一样泛泛而谈,必须结合具体的蓝牙芯片和蓝牙协议栈来讲解,为此后面将以Nordic芯片及协议栈作为范例,来具体讲解如何开发BLE应用,以及如何通过代码去理解BLE协议中定义的一些概念和术语。
标签: ATT, GAP, Link layer, GATT, L2CAP, BLE stack, 广播, 连接, BLE协议栈, 链路层
共有5中状态:
协议栈内容请参考:Understanding Bluetooth Advertising Packets一文。
中文版:http://blog.csdn.net/ooakk/article/details/7302425
BLE 工作在 ISM 频带,定义了两个频段,2.4GHz 频段和 896/915MHz 频带。在IEEE802.15.4 中共规定了 27 个信道:
在 2.4GHz 频段,共有 16 个信道,信道通信速率为 250kbps:
在 915MHz 频段,共有 10 个信道,信道通信速率为 40kbps:
在 868MHz 频段,有 1 个信道,信道通信速率为 20kbpS。
BLE 工作在 2.4GHz 频段,仅适用 3 个广播通道,适用所有蓝牙规范版本通用的自适应调频技术。
BlueTooth 有79个射频信道,按0-78排序,并于2402 MHz开始,以1 MHz分隔:
channel 00 : 2.402000000 Ghz
channel 01 : 2.403000000 Ghz
…
channel 78 : 2.480000000 Ghz
BTLE有40个频道(也称为信道),按37在第一个,后面由0-36,然后第39信道(那么38呢 )第38信道位于10和11之间:
channel 37 : 2.402000000 Ghz
channel 00 : 2.404000000 Ghz
channel 01 : 2.406000000 Ghz
channel 02 : 2.408000000 Ghz
channel 03 : 2.410000000 Ghz
channel 04 : 2.412000000 Ghz
channel 05 : 2.414000000 Ghz
channel 06 : 2.416000000 Ghz
channel 07 : 2.418000000 Ghz
channel 08 : 2.420000000 Ghz
channel 09 : 2.422000000 Ghz
channel 10 : 2.424000000 Ghz
channel 38 : 2.426000000 Ghz
channel 11 : 2.428000000 Ghz
channel 12 : 2.430000000 Ghz
channel 13 : 2.432000000 Ghz
channel 14 : 2.434000000 Ghz
channel 15 : 2.436000000 Ghz
channel 16 : 2.438000000 Ghz
channel 17 : 2.440000000 Ghz
channel 18 : 2.442000000 Ghz
channel 19 : 2.444000000 Ghz
channel 20 : 2.446000000 Ghz
channel 21 : 2.448000000 Ghz
channel 22 : 2.450000000 Ghz
channel 23 : 2.452000000 Ghz
channel 24 : 2.454000000 Ghz
channel 25 : 2.456000000 Ghz
channel 26 : 2.458000000 Ghz
channel 27 : 2.460000000 Ghz
channel 28 : 2.462000000 Ghz
channel 29 : 2.464000000 Ghz
channel 30 : 2.466000000 Ghz
channel 31 : 2.468000000 Ghz
channel 32 : 2.470000000 Ghz
channel 33 : 2.472000000 Ghz
channel 34 : 2.474000000 Ghz
channel 35 : 2.476000000 Ghz
channel 36 : 2.478000000 Ghz
channel 39 : 2.480000000 Ghz
40个频道中:37、38、39为广播信道,另外37个频道用于数据的传输:
使用德州仪器(TI)CC2540蓝牙低功耗模块配合官方的SmartRF协议软件包监听器:PACKET-SNIFFER,可对三个蓝牙广播信道进行嗅探。
使用方法可参考:Ti.com.cn/packet-sniffer 这种嗅探方案优点是廉价,不足是只能嗅探到广播信道的数据包,无法捕获连接完成后也就是设备通信过程中的数据包:
基于HackRF嗅探蓝牙数据包实际上也是可行的:
其方法参考jxj童鞋的BTLE packet sniffer based on HACKRF (function and performance similar to TI’s packet sniffer)
HackRF.NET 中文版:基于HACKRF的低功耗蓝牙(BTLE)packet sniffer/scanner
关于其他LL层的相关概念,可以参考这篇博文,限于文章篇幅。
BLE-3の蓝牙4.0协议栈の空口包格式 https://blog.csdn.net/qq_34740116/article/details/106274889
详解BLE空口包格式—兼BLE Link layer协议解析
蓝牙跳频算法分析【经典蓝牙 vs BLE 4.x vs BT 5.0 BLE部分】
上面介绍了数据包和各层协议,接下来我们将使用Ubertooth One来捕获通信过程中的蓝牙数据包。
apt-get install python-software-properties
add-apt-repository ppa:pyside
apt-get update
apt-get install libnl-dev libusb-1.0-0-dev pyside-tools
wget https://github.com/greatscottgadgets/libbtbb/archive/2015-09-R2.tar.gz -O libbtbb-2015-09-R2.tar.gz
tar xf libbtbb-2015-09-R2.tar.gz
cd libbtbb-2015-09-R2
mkdir build
cd build
cmake ..
make
sudo make install
wget https://github.com/greatscottgadgets/ubertooth/releases/download/2015-09-R2/ubertooth-2015-09-R2.tar.xz -O ubertooth-2015-09-R2.tar.xz
tar xf ubertooth-2015-09-R2.tar.xz
cd ubertooth-2015-09-R2/host
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig
sudo apt-get install checkinstallwget https://www.wireshark.org/download/src/wireshark-2.0.3.tar.bz2tar -xvf wireshark-2.0.3.tar.bz2cd wireshark-2.0.3./configuremakemake install
wget https://kismetwireless.net/code/kismet-2013-03-R1b.tar.xz
tar xf kismet-2013-03-R1b.tar.xz
cd kismet-2013-03-R1b
ln -s ../ubertooth-2015-09-R2/host/kismet/plugin-ubertooth .
./configure
make && make plugins
sudo make suidinstall
sudo make plugins-install
crackle (开源项目地址)
git clone https://github.com/mikeryan/crackle.git
cd crackle
make
make install
找到kismet的配置文件kismet.conf ,把"pcapbtbb"加入到kismet.conf的logtypes= 里边
spectool_curses
spectool_raw RAW中文解释是“原材料”或“未经处理的东西”,这里猜测是显示设备捕获到的未经处理的信号数据:
spectool_net 将Ubertooth One作为一台“硬件服务器”,并监听TCP:30569端口,局域网内任何可以跟主机建立通信的PC可通过Ubertoothe主机IP+30569共享设备。连接方式:在另外一台主机终端上执行:spectool_gtk
—>选择Open Network Device —>输入ip、端口。
root@0xroot:~# hcitool --help
hcitool - HCI Tool ver 4.99
Usage:
hcitool [options] [command parameters]
Options:
--help Display help
-i dev HCI device
Commands:
dev Display local devices
inq Inquire remote devices
scan Scan for remote devices
name Get name from remote device
info Get information from remote device
spinq Start periodic inquiry
epinq Exit periodic inquiry
cmd Submit arbitrary HCI commands
con Display active connections
cc Create connection to remote device
dc Disconnect from remote device
sr Switch master/slave role
cpt Change connection packet type
rssi Display connection RSSI
lq Display link quality
tpl Display transmit power level
afh Display AFH channel map
lp Set/display link policy settings
lst Set/display link supervision timeout
auth Request authentication
enc Set connection encryption
key Change connection link key
clkoff Read clock offset
clock Read local or remote clock
lescan Start LE scan
lewladd Add device to LE White List
lewlrm Remove device from LE White List
lewlsz Read size of LE White List
lewlclr Clear LE White list
lecc Create a LE Connection
ledc Disconnect a LE Connection
lecup LE Connection Update
hcitool scan :扫描附近蓝牙设备
hcitool lescan :扫描附近低功耗蓝牙设备
root@0xroot:~# gatttool -h
Usage:
gatttool [OPTION...]
Help Options:
-h, --help Show help options
--help-all Show all help options
--help-gatt Show all GATT commands
--help-params Show all Primary Services/Characteristics arguments
--help-char-read-write Show all Characteristics Value/Descriptor Read/Write arguments
Application Options:
-i, --adapter=hciX Specify local adapter interface
-b, --device=MAC Specify remote Bluetooth address
-m, --mtu=MTU Specify the MTU size
-p, --psm=PSM Specify the PSM for GATT/ATT over BR/EDR
-l, --sec-level=[low | medium | high] Set security level. Default: low
-I, --interactive Use interactive mode
gatttool -b 1C:96:5A:FF:4B:E7 -I
[ ][1C:96:5A:FF:4B:E7][LE]> help
help Show this help
exit Exit interactive mode
quit Exit interactive mode
connect [address] Connect to a remote device
disconnect Disconnect from a remote device
primary [UUID] Primary Service Discovery
characteristics [start hnd [end hnd [UUID]]] Characteristics Discovery
char-desc [start hnd] [end hnd] Characteristics Descriptor Discovery
char-read-hnd [offset] Characteristics Value/Descriptor Read by handle
char-read-uuid [start hnd] [end hnd] Characteristics Value/Descriptor Read by UUID
char-write-req Characteristic Value Write (Write Request)
char-write-cmd Characteristic Value Write (No response)
sec-level [low | medium | high] Set security level. Default: low
mtu Exchange MTU for GATT/ATT
[ ][1C:96:5A:FF:4B:E7][LE]>
root@0xroot:~# ubertooth-scan --help
ubertooth-scan: invalid option -- '-'
ubertooth-scan - active(bluez) device scan and inquiry supported by Ubertooth
Usage:
-h this Help
-U<0-7> set ubertooth device to use
-s hci Scan - perform HCI scan
-t scan Time (seconds) - length of time to sniff packets. [Default: 20s]
-x eXtended scan - retrieve additional information about target devices
-b Bluetooth device (hci0)
ubertooth-scan -s
ubertooth-btle - passive Bluetooth Low Energy monitoring
Usage:
-h this help
Major modes:
-f follow connections
-p promiscuous: sniff active connections
-a[address] get/set access address (example: -a8e89bed6)
-s faux slave mode, using MAC addr (example: -s22:44:66:88:aa:cc)
-t set connection following target (example: -t22:44:66:88:aa:cc)
Interference (use with -f or -p):
-i interfere with one connection and return to idle
-I interfere continuously
Data source:
-U<0-7> set ubertooth device to use
Misc:
-r capture packets to PCAPNG file
-q capture packets to PCAP file (DLT_BLUETOOTH_LE_LL_WITH_PHDR)
-c capture packets to PCAP file (DLT_PPI)
-A advertising channel index (default 37)
-v[01] verify CRC mode, get status or enable/disable
-x allow n access address offenses (default 32)
If an input file is not specified, an Ubertooth device is used for live capture.
In get/set mode no capture occurs.
ubertooth-btle -f -c test.pcap抓包&保存到本地
使用这条命令我们可以把设备捕获到的数据包保存到本地,完成后可导入wireshark进行数据包、协议分析。
wireshark导入嗅探到的蓝牙数据包需要处理一下才能正常查看,不然无法正常分析数据:
Edit → Preferences → Protocols → DLT_USER → Edit → New
在payload protocol中输入btle
使用规则过滤数据包:参考Capturing BLE in Wireshark
btle.data_header.length > 0 || btle.advertising_header.pdu_type == 0x05
如果捕获到足够的数据包尤其是btsmp,那接下来便可以用crackle来破解tk和ltk:
crackle -i .pcap>
解密数据包,并把解密后的包另存:
crackle -i .pcap> -o
参考书:Robin Heydon. Bluetooth Low Energy the Developer’s Handbook 《低功耗蓝牙开发权威指南》,网盘密码公众号回复“8001” 链接:https://pan.baidu.com/s/1xneDTzdejtA91go5YuDhnQ
Sniffing and decoding NRF24L01+ and Bluetooth LE packets for under $30
Bluetooth sniffing with Ubertooth : https://dominicspill.com/kiwicon/Spill-Ubertooth-Kiwicon-2012.pdf
Now I wanna sniff some Bluetooth: Sniffing and Cracking Bluetooth with the UbertoothOne
http://j2abro.blogspot.com.au/2014/06/understanding-bluetooth-advertising.html
路人甲@乌云drops:Bluetooth Low Energy 嗅探
疯狗@乌云drops:物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探
http://j2abro.blogspot.com.au/2014/06/understanding-bluetooth-advertising.html
http://j2abro.blogspot.com.au/2014/06/analyzing-bluetooth-advertising-with.html
http://cerescontrols.com/tutorials-3/sniffing-bluetooth-packets-with-kismet-and-wireshark-in-ubuntu-12-04/
https://github.com/greatscottgadgets/ubertooth/wiki/Build-Guide
https://github.com/greatscottgadgets/ubertooth/wiki/Capturing-BLE-in-Wireshark
http://stackoverflow.com/questions/23877761/sniffing-logging-your-own-android-bluetooth-traffic
https://lacklustre.net/bluetooth/wireshark.html
https://blog.lacklustre.net/posts/BLE_Fun_With_Ubertooth:_Sniffing_Bluetooth_Smart_and_Cracking_Its_Crypto/
http://superuser.com/questions/947593/how-can-i-sniff-bluetooth-traffic-coming-from-my-and-another-device
http://www.backtrack-linux.org/forums/showthread.php?t=41552
http://www.splitbits.com/2014/05/14/ubertooth-spectools-chromebook/
http://ubertooth.sourceforge.net/usage/start/
http://hackerific.net/2012/01/28/Spectrum-Tools-and-Ubertooth-One/
https://penturalabs.wordpress.com/2014/02/20/ubertooth-updated-for-2014/
https://blog.lacklustre.net/
推荐阅读(点击标题可跳转阅读)
[1] 机器学习实战 | 逻辑回归应用之“Kaggle房价预测”
[2] 机器学习实战 | 逻辑回归应用之“Kaggle泰坦尼克之灾”
[3] 本科生晋升GM记录:Kaggle比赛进阶技巧分享
[4] 表情识别FER | 基于深度学习的人脸表情识别系统(Keras)
[5] PyTorch实战 | 使用卷积神经网络对CIFAR10图片进行分类(附源码)
[6] 有了这些珍藏的实用工具/学习网站,自学更快乐!
关注公众号迈微电子研发社,文章首发与公众号。
知识星球:社群旨在分享AI算法岗的秋招/春招准备攻略(含刷题)、面经和内推机会、学习路线、知识题库等。