目标:

1. 通过蓝牙协议了解BLE蓝牙的广播帧结构

2.了解蓝牙比特流处理流程

3.使用matlab重现白噪化和CRC校验


1.蓝牙的广播帧结构:

通过蓝牙BLE协议我们可以看到,蓝牙的广播帧结构如下:

这是非编码类型的广播帧结构,在实际学习中,我们可以用wireshark软件来对蓝牙抓包,进而分析协议,wireshark的使用可以参考以下文章:

使用nRF52832开发板用作dongle抓取蓝牙数据包 - 简书 (jianshu.com)

以下是我用wireeshark抓取到的蓝牙处于扫描态时候的广播帧:

上图是ADV_IND包的广播帧结构,我们可以看到,preamble的0x55或0xAA系列并没有显示在wireshark抓取的文件中,蓝牙在发送过程中的发射顺序为D6 BE 89 6E 60 16 A7 AC F3 DD 67 F3 02 01 05 0C 09 4E 6F 72 64 69 63 5F 55 41 52 54 9D B9 A3(D6前面的数据非蓝牙数据,是wireshark加上的);我们可以通过该软件看到广播帧结构中各个部分的具体数据,非常方便。例如,Access Address为 D6 BE 89 6E。由于蓝牙的发射顺序为LSB低位先发送,因此,wireshark显示的实际的蓝牙Access Address是倒着的,在广播帧的其他部分也一样。


2.蓝牙的比特流处理

蓝牙数据在发送时,并不是直接发送原码,而是将数据进行一定的处理后再发送出去,蓝牙协议对非编码的广播包的比特流处理如下:

其中,encryption和decryption只在有些数据包才会用到,这篇文章主要分析CRC和whitening两个过程。

官方蓝牙协议对CRC处理的对象介绍如下:

 应在所有链路层数据包的PDU字段上计算CRC。如果PDU已加密,则CRC应在加密后计算已执行PDU。

        CRC多项式为24位CRC,PDU中的所有位应从最低有效位开始按传输顺序进行处理。多项式的形式为x24+x10+x9+x6+x4+x3+x+1。对于每个数据通道PDU,移位寄存器应预设为链路层连接设置的CRC初始化值,并在连接PDU中通信。

        对于AUX_SYNC_IND PDU及其附属集,移位寄存器应预设为描述定期广播AUX_ADV_IND PDU中SyncInfo字段中设置的CRCInit值。对于所有其他广告频道PDU,移位寄存器应预设为0x555555。

 操作过程如下

位置0应设置为最低有效位,位置23应设置为初始化值的最高有效位。CRC首先传输最高有效位,即从位置23传输到位置0  

蓝牙官方协议对whitenig的介绍如下:

        数据白化用于避免长序列的0或1,例如。0000000 B或1111111 B,在数据位流中。白化应应用于所有链路层分组的PDU和CRC字段,并在CRC之后执行。在接收器中的CRC之前执行去白化

        白化和去白化的定义方式相同,使用7位线性多项式x7+x4+1的反馈移位寄存器。在白化或去白之前,移位寄存器根据频道索引(数据频道索引或广播频道索引),其中分组以以下方式传输:

•位置0设置为1。

•位置1至6设置为数据频道索引或广播频道索引。    

       例如,如果通道索引=23(0x17),则位置将设置如下:

位置0=1

位置1=0

位置2=1

位置3=0

位置4=1

位置5=1

位置6=1

大概了解了比特流处理过后,我们可以通过软件无线电设备截取蓝牙发射的01信号来进行进一步分析。

我使用的是USRP B210设备,在gunradio companion上搭建以下流图,并在外部使蓝牙处于扫描态,就可以接收到蓝牙的01信号了。

把中心频点设置在2.426GHz,这样就可以接收到38信道的数据。在上面对蓝牙协议的解读中,我们发现,CRC只是在PDU后面加一段校验码,而白化的对象是PDU和CRC码,所以,比特流处理并没有改变preamble和access address的值。Access Address的值是0x8e89bed6,二进制是1000 1110 1000 1001 1011 1110 1101 0110,所以,按照LSB的发送顺序,是0110 1011 0111 1101 1001 0001 1110 0001,我们先用Notepad++打开gnuradio生成的文件(哲理Notepad++要先安装Hex-Editor插件),看下是否能找到这段序列。在Notepad++中搜索 00 01 01 00 01 00 01 01 00 01 01 01 01 01 00 01 01 00 00 01 00 00 00 01 00 01 01 01 00 00 00 01,结果如下:

成功找到了这段序列,并且前面的序列是00 01 00 01 00 01 00 01,符合preamble的要求,因此,基本可以确定这个就是蓝牙发送的帧了,Access Address之后就是白化完的PDU和CRC校验码。


3.用matlab实现比特流处理

前面我们已经得到了白化前和白化后的蓝牙广播帧数据,现在我们可以按照蓝牙协议编写matlab代码以验证数据正确性。

1.白化

白化和解白的代码是一样的,我们根据以下官方给的白化电路结构编写一个matlab代码:

clear;
Data_in_hex = 'a3b99d545241555f636964726f4e090c050102f367ddf3aca71660';
Data_in_bin = str_bin(Data_in_hex);
Data_in_bin_LSB =  Data_in_bin(4*length(Data_in_hex):-1:1);
Channel_index = 38;
Whitening_INIT = dec2bin (Channel_index+64);
Whitening_INIT_BIN =  bitget(bin2dec(Whitening_INIT),7:-1:1);
Data_out= zeros(1,4*length(Data_in_hex));
for i = 1:4*length(Data_in_hex)Whitening_INIT_BIN_temp = Whitening_INIT_BIN(7);Data_out(i)= xor(Data_in_bin_LSB(i),Whitening_INIT_BIN(7));Whitening_INIT_BIN(7)=Whitening_INIT_BIN(6);Whitening_INIT_BIN(6)=Whitening_INIT_BIN(5);Whitening_INIT_BIN(5)=xor(Whitening_INIT_BIN_temp,Whitening_INIT_BIN(4));Whitening_INIT_BIN(4)=Whitening_INIT_BIN(3);Whitening_INIT_BIN(3)=Whitening_INIT_BIN(2);Whitening_INIT_BIN(2)=Whitening_INIT_BIN(1);Whitening_INIT_BIN(1)=Whitening_INIT_BIN_temp;
end

上面代码中的str_bin函数是一个译码器,将输入的十六进制字符串转化为二进制:

function [bin] = str_bin(in)
bin= zeros(1,4*length(in));
for i=1:length(in)switch in(i)case '1'bin(4*i-3:4*i)=[0 0 0 1];case '2'bin(4*i-3:4*i)=[0 0 1 0];case '3'bin(4*i-3:4*i)=[0 0 1 1];case '4'bin(4*i-3:4*i)=[0 1 0 0];case '5'bin(4*i-3:4*i)=[0 1 0 1];case '6'bin(4*i-3:4*i)=[0 1 1 0];case '7'bin(4*i-3:4*i)=[0 1 1 1];case '8'bin(4*i-3:4*i)=[1 0 0 0];case '9'bin(4*i-3:4*i)=[1 0 0 1];case 'a'bin(4*i-3:4*i)=[1 0 1 0];case 'b'bin(4*i-3:4*i)=[1 0 1 1];case 'c'bin(4*i-3:4*i)=[1 1 0 0];case 'd'bin(4*i-3:4*i)=[1 1 0 1];case 'e'bin(4*i-3:4*i)=[1 1 1 0];case 'f'bin(4*i-3:4*i)=[1 1 1 1];end
end
end

白化和解白的顺序也是一样的,例如按照下图wiresharp中的广播帧,应该先白化和解白化60,最后再是a3。

上面matlab代码最终得到data_out的值如下:

0  1  1  0  1  1  0  1  1  1  0  0  1  0  1  1  1  1  0  0  0  1  1  1  0  0  1  1  0  0  0  1  0  1  0  1  0  1  0  1  1  1  0  0  0  0  0  0  0  1  1  0  0  0  0  1  0  0  1  1  1  1  1  0  1  0  0  1  1  0  0  0  0  0  1  0  0  1  0  1  0  1  0  1  0  1  0  1  0  1  1  1  0  0  1  0  0  1  0  0  1  1  1  0  0  0  0  0  0  0  0  0  0  1  0  0  0  1  0  1  0  1  0  0  1  0  0  0  1  1  1  1  0  0  0  1  1  1  0  1  0  0  0  0  1  0  0  0  0  0  1  0  1  1  1  1  0  0  1  1  1  0  0  1  1  1  1  0  0  1  1  1  0  1  0  1  0  1  0  0  0  1  0  1  1  1  0  0  1  0  0  1  0  0  0  0  1  0  0  0  1  1  0  1  0  1  1  0  0  0  1  0  1  1  1  1

我们把这段序列放到Notepad++中搜索:

找到了这一串序列,这就验证了我们收到的蓝牙序列和whitening的正确性。

2.CRC校验

CRC校验可以使用该网站验证CRC校验的正确性:CRC校验;

我们先将PDU输入,看下校验结果是否和wireshark对得上,多项式x24+x10+x9+x6+x4+x3+x+1对应00065B,初始值为55555,注意把输入数据翻转勾上:

和前面wiresharp结果对比下:

看得出来,一模一样。

接下来,我们用下图的LFSR结构实现CRC校验,这里也是60先进行校验,最后是54(54后面的数据就是校验完的CRC码)。注意要LSB输入LFSR中,如60的输入顺序是00000110:

clear;
Data_in_hex='545241555f636964726f4e090c050102f367ddf3aca71660';
Data_in_bin= str_bin(Data_in_hex);
Data_in_bin_LSB =  Data_in_bin(4*length(Data_in_hex):-1:1);
CRC_LFSR=[1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];
for i = 1:4*length(Data_in_hex)X=xor(CRC_LFSR(24),Data_in_bin_LSB(i));CRC_LFSR(24)=CRC_LFSR(23);CRC_LFSR(23)=CRC_LFSR(22);CRC_LFSR(22)=CRC_LFSR(21);CRC_LFSR(21)=CRC_LFSR(20);CRC_LFSR(20)=CRC_LFSR(19);CRC_LFSR(19)=CRC_LFSR(18);CRC_LFSR(18)=CRC_LFSR(17);CRC_LFSR(17)=CRC_LFSR(16);CRC_LFSR(16)=CRC_LFSR(15);CRC_LFSR(15)=CRC_LFSR(14);CRC_LFSR(14)=CRC_LFSR(13);CRC_LFSR(13)=CRC_LFSR(12);CRC_LFSR(12)=CRC_LFSR(11);CRC_LFSR(11)=xor(CRC_LFSR(10),X);CRC_LFSR(10)=xor(CRC_LFSR(9),X);CRC_LFSR(9)=CRC_LFSR(8);CRC_LFSR(8)=CRC_LFSR(7);    CRC_LFSR(7)=xor(CRC_LFSR(6),X);CRC_LFSR(6)=CRC_LFSR(5); CRC_LFSR(5)=xor(CRC_LFSR(4),X);CRC_LFSR(4)=xor(CRC_LFSR(3),X);CRC_LFSR(3)=CRC_LFSR(2); CRC_LFSR(2)=xor(CRC_LFSR(1),X);CRC_LFSR(1)=X;
end
CRC_LFSR(1:24)=CRC_LFSR(24:-1:1);

运行查看CRC_LFSR寄存器结果如下:1    0    1    1    1    0    0    1    1    0    0    1    1    1    0    1    1    1    0    0    0    1    0    1,和网址算出来的一样。

4.结语

本文按照协议内容用matlab实现了蓝牙比特流处理流程。如果有误,欢迎指出。

BLE蓝牙广播包的比特流处理之白噪化和CRC校验相关推荐

  1. [ 利器篇 ] - 抓取蓝牙广播包数据

    实际项目中,需要抓取蓝牙广播包数据进行调试,除了专有的设备之外,也可以通过手机专用的蓝牙APP进行抓包测试,这里主要介绍 LightBlue 和 nRF Toolbox for BLE , 通过Goo ...

  2. AD fmcomms5 踩坑笔记+蓝牙广播包(2)

    2-带CTE蓝牙广播包的发送 环境准备 环境准备 AD fmcomms5 + Xillinx zc706开发板 Analog Devices ADALM-Pluto Radio MATLAB(预装上面 ...

  3. 程序员知道如何抓取蓝牙广播包很正常吧?

    大家对于蓝牙应该都不陌生,现在的手机基本上都有蓝牙功能,而且蓝牙耳机.蓝牙手环等智能设备在市场上也很常见了. 这么多的蓝牙设备都是使用了蓝牙协议的,而蓝牙广播数据包又是蓝牙协议中最经常用到的. 不管是 ...

  4. 三.非协议栈实现BLE蓝牙广播(2.4G实现BLE广播)

    非协议栈实现BLE广播(2.4G实现BLE广播) 现在的人啊,用协议栈用多了,BLE物理层是怎么广播都不知道了,且听我慢慢道来 这里实现的BLE广播包是基于上一章介绍的,我要通过2.4G来发出这个广播 ...

  5. BLE 蓝牙抓包分析

    1. 抓包工具 Ellisys & Ellisys Bluetooth Analyzer  ​使用方法:https://blog.csdn.net/weixin_44260005/articl ...

  6. BLE蓝牙广播入门(一)

    一.概述 BLE广播是低功耗蓝牙协议最重要的组成部分之一.深入理解如何使用广播可以有效降低蓝牙模块的功率.提高连接速度以及改善连接的可靠性. BLE蓝牙协议一共有三层,分别是应用层,主机层和控制器层. ...

  7. 2021/9/2 BLE PRA 广播包

    1. RPA 广播包 RPA:  Resolvable private address 可解析私密地址 RAL: Resolvable address  list 可解析地址列表 IRK :ident ...

  8. BLE蓝牙广播和扫描主要数据设置解析与总结

    (一)蓝牙之广播: 1 广播参数之广播名称 typedef enum {BLE_ADVDATA_NO_NAME, /**< Include no device name in advertisi ...

  9. 蓝牙广播包中自定义厂家数据的设置及获取

    硬件: Nordic nrf52840 SoC 软件: Nordic nRF5_SDK_15.2.0_9412b96 1. 蓝牙 perihperal 设备广播自定义数据设定 蓝牙广播相关数据结构定义 ...

最新文章

  1. java扫描包内所有类_第20天|Java入门有野,修饰符
  2. zhihu 知乎社区里点击了Ctrl + C组合键的技术实现
  3. mysql yum安装和 rpm安装_yum 和 rpm安装mysql彻底删除
  4. Java Socket编程基础实例
  5. 为什么在 Windows 7系统下无法显示 STEP 7 MicroWin SP9的帮助文件?
  6. SiamFC复现结果
  7. cisco思科模拟器中断translating域名翻译快捷键
  8. MySQL数据库服务器、数据库和表的关系
  9. Integer 十六进制
  10. Vertica的那些事
  11. 评价页面html,利用html与css制作5星好评页面
  12. EDVR和FastDVD
  13. 如何定位公众号形象,有什么方法
  14. html利用表格制作个人简历
  15. CocosCreator做摄像机跟随主角移动
  16. Android MTK 放电曲线以及库轮值矫正
  17. Latex 论文插入copyright
  18. 一站式解决方案,华为云CDN这波双十一很强!
  19. 【暑假实践总结】大学生暑假社会实践-关于社区人口老龄化的实践报告
  20. 【New Star】LeetCode 数组学习

热门文章

  1. Vue开发电子书app
  2. 15从零开始学Java之详解计算机中的进制转换
  3. 4.4 使用曲线命令修复图像色偏问题 [原创Ps教程]
  4. iPhone数据丢失怎么办?如何恢复iPhone数据?iPhone数据恢复的三种方法
  5. Global Illumination_Real-Time Volumetric Cloud(实时体积云)
  6. 互联网早报:字节跳动内测抖音拍卖 拟用于珠宝、酒水、奢品等类目
  7. 华为鸿蒙多屏互动,本报记者体验华为首款鸿蒙产品
  8. 与利润有关的背包问题(贪心算法,深度优先搜索)
  9. 解决城市内涝的措施有哪些?需要用到哪些监测设备?
  10. jquery左右箭头切换