蓝牙4.0 BLE 广播包解析
本文转自:蓝牙4.0BLE抓包(二) – 广播包解析 - 强光手电 - 博客园
感谢原创作者!
SleepingBug评论:这篇文档写的相当好,受教了,多谢了!
所有图片水印均是CSDN自动标上的,并非本人所作,都是原创作者"强光手电[艾克姆科技-无线事业部]"在博客中提供的。
作者:强光手电[艾克姆科技-无线事业部]
在使用EN-Dongle捕获和解析广播包之前,我们先了解一下BLE报文的结构,之后,再对捕获的广播包进行分析。在学习BLE的时候,下面两个文档是极其重要的,这是SIG发布的蓝牙的核心协议和核心协议增补。
- 核心协议Core_v4.2。
- 核心协议增补CSS v6。
虽然这两个文档是蓝牙技术的根本,但是遗憾的是:通过这两个文档学习蓝牙并不是那么容易的,阅读和理解起来很费力。尤其是初学者在阅读这两个文档的时候,感觉无从下口。所以,本文在分析报文的过程中,会明确指出协议文档在什么地方定义了他们,让我们有目的的去查阅协议文档,做到知其然也知其所以然,这样,学习起来就会轻松很多。
1. BLE报文结构
BLE报文结构如下,他由下图所示的各个域组成。因为有的域的长度超过了一个字节,所以在传输的过程中就涉及到多字节域中哪个字节先传输的问题,BLE报文传输时的字节序和比特序如下:
- 字节序:大多数多字节域是从低字节开始传输的。注意,并不是所有的多字节域都是从低字节开始传输的。
- 比特序:各个字节传输时,每个字节都是从低位开始。
图1:BLE报文结构
1.1 前导
前导是一个8比特的交替序列。他不是01010101就是10101010,取决于接入地址的第一个比特。
- 若接入地址的第一个比特为0:01010101
- 若接入地址的第一个比特为1:10101010
接收机可以根据前导的无线信号强度来配置自动增益控制。
1.2 接入地址
接入地址有两种类型:广播接入地址和数据接入地址。
- 广播接入地址:固定为0x8E89BED6,在广播、扫描、发起连接时使用。
- 数据接入地址:随机值,不同的连接有不同的值。在连接建立之后的两个设备间使用。
对于数据信道,数据接入地址是一个随机值,但需要满足下面几点要求:
1) 数据接入地址不能超过6个连续的“0”或“1”。
2) 数据接入地址的值不能与广播接入地址相同。
3) 数据接入地址的4个字节的值必须互补相同。
4) 数据接入地址不能有超24次的比特翻转(比特0到1或1到0,称为1次比特翻转)。
5) 数据接入地址的最后6个比特需要至少两次的比特翻转。
6) 符合上面条件的有效随机数据接入地址大概有231个。
1.3 报头
1.3.1 广播报文报头
报头的内容取决于该报文是广播报文还是数据报文。广播报文的报头如下图所示:
图2:广播报文报头
广播报文的报头包含4bit广播报文类型、2bit保留位、1bit发送地址类型和1bit接收地址类型。
1) 广播报文类型
Core_v4.2的2583页描述了广播报文类型,共有7种类型,如下图所示。
图3:广播报文类型
每种广播报文类型都具有不同的数据格式及行为。Core_v4.2的2584页的2.3.1节详细的描述了各个广播报文类型,大家可以阅读此章节进一步了解。
2) 发送地址类型和接收地址类型
发送地址类型和接收地址类型指示了设备使用公共地址(Public Address)还是随机地址(Random Address)。公共地址和随机地址的长度一样,都包含6个字节共48位。BLE设备至少要拥有这两种地址类型中的一种,当然也可以同时拥有这两种地址类型。
- 公共地址(Public Address)
公共地址由两部分组成,如下图。公共地址由制造商从IEEE申请,由IEEE注册机构为该制造商分配的机构唯一标识符OUI(Organizationally Unique Identifier)。这个地址是独一无二,不能修改的。Core_v4.2 P2576的1.3.1节描述了公共地址。
图4:公共地址结构
- 随机地址
随机地址有包含两种:静态地址(Static Device Address)和私有地址(PrivateDevice Address)。Core_v4.2 P2577的1.3.2.1节描述了静态地址。
图5:静态地址格式
静态地址有如下要求:
a) 静态地址的最高2位有效位必须是1。
b) 静态地址最高2位有效位之外的其余部分不能全为0。
c) 静态地址最高2位有效位之外的其余部分不能全为1。
在私有地址的定义当中,又包含了两个子类:不可解析私有地址(Non-resolvable Private Address)和可解析私有地址(Resolvable Private Address,RPA)。nRF51822使用的是静态地址,芯片在出厂时已经设置好了48位地址,我们可以从下面两个寄存器读出地址类型和地址。
a) DEVICEADDRTYPE寄存器。
DEVICEADDR[n]寄存器:包含DEVICEADDR[0]和DEVICEADDR[1]两个寄存器。
图6:地址类型寄存器
图7:地址寄存器
1.4 长度
- 广播报文:长度域包含6个比特,有效值的范围是6~37。
- 数据报文:长度域包含5个比特,有效值的范围是0~31。
广播报文和和数据报文的长度域有所不同,主要原因是:广播报文除了最多31个字节的数据之外,还必须要包含6个字节的广播设备地址。6+31=37,所以需要6比特的长度域。
再次强调:广播时必须要包含6个字节的广播设备地址。
1.5 数据(AdvData)
广播和扫面响应的数据格式如下图所示,由有效数据部分和无效数据部分组成。
图8:广播和扫描响应的数据格式
1) 有效数据部分:包含N个AD Structure,每个AD Structure由Length,AD Type和AD Data组成。其中:
- Length:AD Type和AD Data的长度。
- AD Type:指示AD Data数据的含义。
问题来了,我们怎么知道有哪些AD Type?他们又表示什么意义?可以通过下面2种方式查看AD Type和他们表示的意义。
- 从官网查询,但是需要是会员才可以查询。
https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
- 查看Nordic的SDK中的定义,AD type的定义在程序的“ble_gap.h”头文件中。定义如下:
#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */
#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */
#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */
#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */
#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */
#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */
#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */
#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */
#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */
#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */
#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */
#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */
#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */
#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */
#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */
#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */
#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */
1.6 校验
BLE采用的是24位CRC校验。CRC对报头、长度和数据进行计算。24位CRC的生成多项式如下:
2. 广播包解析
通过上文的描述,我们对BLE广播包有了大致的了解,接下来我们用EN-Dongle捕获一个心率计的广播包,通过对实际广播包的分析来理解BLE报文结构和广播。广播包捕获实验的硬件连接如下。
图9:硬件连接
2.1 心率计程序下载
2.1.1 下载协议栈
SoftDevice必须使用nRFgo Studio下载,打开nRFgo Studio,切换到“Program SoftDevice”选项卡。点击“Browse…”按钮打开SoftDevice的HEX文件(位于“…\BLE实验\蓝牙协议栈(SoftDevice)目录下的” s110)。点击“Program”下载程序。
2.1.1 下载应用程序
应用程序可以用nRFgo Studio下载,也可以在MDK中直接下载调试,在这里我们用nRFgo Studio下载。切换到“Program Application”选项卡。点击“Browse…”按钮打开应用程序的HEX文件(位于“…\BLE实验\ ble_app_beacon \pca10028\s110\arm5\_build”目录下的 nrf51822_xxaa_s110.hex)。点击“Program”下载程序。
2.2 捕获广播包
按照《蓝牙4.0BLE抓包(一)》中的描述进行抓包,下面是我们捕获一个心率计的广播包。
图10:捕获的心率计广播包
图11:查看广播包传输的数据
2.3 分析广播包
为了方便分析,我们先取出这个广播包实际传输的数据,如图9中所示。心率计完整的广播报文如下:
D6 BE 89 8E 40 21 60 BF 8A B9 CD C5 0B 09 4E 6F 72 64 69 63 5F 48 52 4D 03 19 41 03 02 01 06 07 03 0D 18 0F 18 0A 18 EF A6 F0
2.3.1 接入地址
D6 BE 89 8E:接入地址,对广播来说是固定值。注意一下这里的字节序,接入地址传输时是低字节在前的。
2.3.2 PDU
- 40:广播报文报头。
bit0~bit3是0000,说明广播类型是ADV_IND,即通用广播指示。
bit7(RxAdd)是0,bit7(TxAdd)是1,说明使用的是随机地址(random address)。Core_V4.2 P2584的2.3.1有详细的描述。
- 21:长度,表示这个广播的长度是33个字节。
- 9A 3F 20 FB 74 C5:设备地址,这里使用的是随机静态地址。
接下来就是广播包最重要的部分了,称之为AdvData,前面我们说过AdvData是N个AD Structure组层成,每个AD Structure的格式都是Length |AD Type|AD Data组成。
0B 09 4E 6F 72 64 69 63 5F 48 52 4D 03 19 41 03 02 01 06 07 03 0D 18 0F 18 0A 18
第一个字节0B表示第一个AD Structure的长度是11个字节,即第一个AD Structure是由0B加上紧跟着0B后面的11个字节组成,因此,第一个AD Structure是:
0B 09 4E 6F 72 64 69 63 5F 48 52 4D
表1:第1个AD Structure的意义
Length |
AD Type |
AD Data |
0B |
09 |
4E 6F 72 64 69 63 5F 48 52 4D |
11字节 |
AD type为“完整的本地名称” |
程序中定义的为”Nordic_HRM”对应的十六进制就是4E 6F 72 64 69 63 5F 48 52 4D |
第2个AD Structure是:03 19 41 03
表2:第2个AD Structure的意义
Length |
AD Type |
AD Data |
03 |
19 |
41 03 |
3字节 |
AD type为“外观特性” |
外观特性是一个16位的数值,由SIG定义,用来列举设备的外观样式,指示设备是普通手机,手环什么的。 |
第3个AD Structure是:02 01 06
表3:第3个AD Structure的意义
Length |
AD Type |
AD Data |
02 |
01 |
06 |
2字节 |
AD type为“Flag” |
flag说明了物理连接功能,比如有限发现模式,不支持经典蓝牙等。 l bit 0: LE 有限发现模式。 l bit 1: LE 普通发现模式。 l bit 2: 不支持 BR/EDR。 l bit 3: 对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDR。 l bit 4: 对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDR。 bit 5..7: 预留。 |
第4个AD Structure是:07 03 0D 18 0F 18 0A 18
表4:第4个AD Structure的意义
Length |
AD Type |
AD Data |
07 |
03 |
0D 18 0F 18 0A 18 |
7字节 |
AD type为“16bit Service uuid列表” |
该设备支持的完整的16bit Service uuid列表。 l 180D:Heart Rate service UUID(心率服务UUID) l 180F:Battery service UUID(电池服务UUID) l 180A:Device Information service UUID(设备信息服务UUID) |
16bit UUID:
128位的UUID相当长,设备间为了识别数据的类型需要发送长达16字节的数据。为了提高传输效率,蓝牙技术联盟(SIG)定义了一个称为“UUID基数”的128位通用唯一识别码,结合一个较短的16位数使用。二者仍然遵循通用唯一识别码的分配规则,只不过在设备间传输常用的UUID时,只发送较短的16位版本,接收方收到后补上蓝牙UUID基数即可。
蓝牙UUID基数如下:
00000000 – 0000 – 1000 – 8000 – 008059B34FB
如要发送的16位UUID为0x2A01,完整的128的UUID便是:
00002A01 – 0000 – 1000 – 8000 – 008059B34FB
低功耗蓝牙使用的那部分UUID被分为下列几组:
- 0x1800 ~ 0x26FF:用作服务类通用唯一识别码。
- 0x2700 ~ 0x27FF:用于标识计量单位。
- 0x2800 ~ 0x28FF:用于区分属性类型。
- 0x2900 ~ 0x29FF:用作特性描述。
- 0x2A00 ~ 0x7FFF:用于区分特性类型。
在程序的“ble_srv_common.h”文件中定义了16bit service UUID,如下,当然也可以在SIG官网上查询:
#define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811 /**< Alert Notification service UUID. */
#define BLE_UUID_BATTERY_SERVICE 0x180F /**< Battery service UUID. */
#define BLE_UUID_BLOOD_PRESSURE_SERVICE 0x1810 /**< Blood Pressure service UUID. */
#define BLE_UUID_CURRENT_TIME_SERVICE 0x1805 /**< Current Time service UUID. */
#define BLE_UUID_CYCLING_SPEED_AND_CADENCE 0x1816 /**< Cycling Speed and Cadence service UUID. */
#define BLE_UUID_DEVICE_INFORMATION_SERVICE 0x180A /**< Device Information service UUID. */
#define BLE_UUID_GLUCOSE_SERVICE 0x1808 /**< Glucose service UUID. */
#define BLE_UUID_HEALTH_THERMOMETER_SERVICE 0x1809 /**< Health Thermometer service UUID. */
#define BLE_UUID_HEART_RATE_SERVICE 0x180D /**< Heart Rate service UUID. */
#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE 0x1812 /**< Human Interface Device service UUID. */
#define BLE_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 /**< Immediate Alert service UUID. */
#define BLE_UUID_LINK_LOSS_SERVICE 0x1803 /**< Link Loss service UUID. */
#define BLE_UUID_NEXT_DST_CHANGE_SERVICE 0x1807 /**< Next Dst Change service UUID. */
#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE 0x180E /**< Phone Alert Status service UUID. */
#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE 0x1806 /**< Reference Time Update service UUID. */
#define BLE_UUID_RUNNING_SPEED_AND_CADENCE 0x1814 /**< Running Speed and Cadence service UUID. */
#define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813 /**< Scan Parameters service UUID. */
#define BLE_UUID_TX_POWER_SERVICE 0x1804 /**< TX Power service UUID. */
2.3.3 校验
EF A6 F0:24位CRC。24位CRC的生成多项式如下,对CRC算法感兴趣的朋友可以研究一下:
蓝牙4.0 BLE 广播包解析相关推荐
- java 蓝牙4.0_《蓝牙4.0 BLE开发完全手册---物联网开发技术实战
图书目录: 第1章 蓝牙4.0 BLE简介 1.1 无线网络数据传输协议对比 1.2 短距离无线网络的分类 1.2.1 什么是蓝牙4.0 BLE 1.2.2 蓝牙4.0 BLE的特点 1.3 蓝牙4. ...
- 蓝牙4.0BLE抓包(二) – 广播包解析
转自: http://www.cnblogs.com/aikm/p/5022502.html 版权声明:本文为博主原创文章,转载请注明作者和出处. 作者:强光手电[艾克姆科技-无线事业部] 在使 ...
- 蓝牙4.0 BLE协议结构图详解
随着智能硬件的发展,嵌入式和物联网这类专业越发受到大家的追捧,而不管是学习嵌入式还是学习物联网,蓝牙4.0 BLE协议结构都是必须重点掌握的知识点,今天和大家分享的就只这部分内容,一起来看看吧. 第一 ...
- 针对蓝牙4.0 BLE通讯过程的逆向和攻击
本文讲的是针对蓝牙4.0 BLE通讯过程的逆向和攻击,从6个月前,我就开始针对BLE设备进行学习和研究,其中接触到了一些关于BLE逆向的博客和文章,但是相关内容都没有给出很好的方案.因此通过我的这篇文 ...
- iOS开发 之 可穿戴设备 蓝牙4.0 BLE 开发
1 前言 当前有越来越多的可穿戴设备使用了蓝牙4.0 BLE(Bluetooth Low Energy).对于iOS开发而言,Apple之前专门推出CoreBluetooth的Framework来支持 ...
- android ble蓝牙接收不到数据_Android蓝牙4.0 Ble读写数据详解 -2
Android蓝牙4.0 Ble读写数据详解 -2 上一篇说了如何扫描与链接蓝牙 这篇文章讲讲与蓝牙的数据传输,与一些踩到的坑. 先介绍一款调试工具,专门调试Ble蓝牙的app.名字叫:nRF-Con ...
- 蓝牙BLE5.0扩展广播介绍
蓝牙BLE5.0扩展广播介绍 前言 广播包基本介绍 扩展广播包结构 总结 author :cbk 前言 在2016年12月更新的蓝牙Core_v5.0中,更新了LE Advertising Exten ...
- android蓝牙4.0 BLE低功耗应用
转自 http://www.cnblogs.com/zdz8207/archive/2012/10/17/bluetooth_ble_android.html 谈谈几个月以来开发android蓝 ...
- 谈谈几个月以来开发android蓝牙4.0 BLE低功耗应用的感受
谈谈几个月以来开发android蓝牙4.0 BLE低功耗应用的感受 谈谈几个月以来开发android蓝牙4.0 BLE低功耗应用的感受,注明下时间:2012-10-17写的博客,后期更新的也注明了时间 ...
最新文章
- LeetCode简单题之最少操作使数组递增
- c++笔试题两道,求解当中一道
- 程序员面试题精选100题(20)-最长公共子串[算法]
- 《Web前端工程师修炼之道(原书第4版)》——我该从哪里开始呢
- Asp默认的上传文件大小限制是200K
- python中列表数据汇总和平均值_对数据进行分类,计算每个类别的平均值和标准差...
- 【笔试题】京东2017秋招笔试真题
- ubantu实现linux命令的实验_C语言实现linux命令---ls
- 在JDK 12精简数字格式中使用最小分数数字
- 她16岁因汶川地震改志学医,仅27岁当上浙大博导!她说:科研是“止不住想念到失眠的对象”...
- 用Python DBUtils安全连接mssql
- poj 2560 Freckles
- 与朋友分享的生活日记
- ads1278_ADS1278
- 浅谈Md5+Salt加密
- lua游戏代码_在游戏中如何使用LUA脚本语言
- 【算法】快速排序算法原理及实现
- MATLAB程序设计与应用 4.1 M文件
- Hadoop流程---从tpch到hive
- [转帖]江湖经验:喝酒的学问技巧,社会新人一定要看~!
热门文章
- Hudson 持续集成服务器的安装配置与使用
- 【java初学】面向对象继承
- 成为计算机网络管理员必修课(一)
- Linux使用mailx通过第三方SMTP发送邮件,带附件操作
- windows下的wsl-kail
- Linux如何检测到僵尸进城,如何在linux下查看僵尸进程
- 代正通_ChromeBook怎么刷windows系统||Linux教程
- 影视剧广告植入,对于品牌宣传有怎样的效果?
- /phalcon.zep.c:130892: error: ‘ZEND_FE_END’ undeclared here (not in a function)
- initial、inherit、unset、revert和all的区别