这个例子展示了如何使用蓝牙协议的通信工具箱™库生成和解码蓝牙®低能量(BLE)链路层包。
蓝牙核心规范[1]包括用于低速率无线个人区域网络的低能耗版本,即蓝牙低能耗(BLE)或蓝牙智能。BLE栈由GATT (Generic Attribute Profile)、ATT (Attribute Protocol)、SMP (Security Manager Protocol)、L2CAP (Logical Link Control and Adaptation Protocol)、LL (Link layer)和物理层组成。BLE被添加到产生少量数据的低能耗设备的标准中,如用于家庭自动化、医疗保健、健身和物联网(IoT)等应用的通知警报。
蓝牙核心规范[1为BLE定义了两种PHYs。每个PHY都有自己的数据包格式。
(i)未编码的物理速率(1mbps和2mbps)
(ii)编码物理(125 kbps和500 kbps)
编码物理对报文使用前向纠错(FEC)编码(编码方案S = 8或S = 2)。图中显示了未编码和编码的PHY包格式。
无编码PHY的LE空中接口包格式
编码PHY的LE空中接口包格式
蓝牙协议的通信工具箱™库生成由PHY数据包中显示的协议数据单元(PDU)和循环冗余校验(CRC)组成的LL报文。
BLE将40个射频信道分为3个广告信道(信道指数:37,38,39)和37个数据信道(信道指数:0 - 36)。BLE链路层定义了两类pdu:发布通道pdu和数据通道pdu。这两类PDU中有不同的PDU类型。空中接口报文格式中的访问地址字段用来区分数据通道PDU和发布通道PDU。每种PDU都有自己的格式。
广告通道pdu(见[1)在创建LL连接之前使用。这些pdu仅在发布通道上传输,用于建立LL连接。广告通道PDU具有16位头和可变大小的有效载荷。
广告通道PDU的报文格式如下:
本示例演示了广告指示PDU的生成和解码。有关支持的其他发布通道pdu的列表,请参阅金宝appPDUType
的属性bleLLAdvertisingChannelPDUConfig
对象。
广告显示:当设备需要发布自己时,使用广告指示PDU。该PDU包含与设备的应用程序概要文件相关的广告数据。
%检查“蓝牙协议的通信工具箱库”%支金宝app持包是否安装。comm金宝appSupportPackageCheck (“蓝牙”);
你可以使用bleLLAdvertisingChannelPDU
命令,生成发布通道PDU。这个函数接受一个配置对象bleLLAdvertisingChannelPDUConfig
.配置生成发布通道PDU所需的字段。
广告显示一代
要生成“公告指示”PDU,请创建bleLLAdvertisingChannelPDUConfig
对象与PDUType
设置为广告显示的
.
cfgLLAdv = bleLLAdvertisingChannelPDUConfig (“PDUType”,...广告显示的);
配置的字段:
%广告客户地址cfgLLAdv。AdvertiserAddress ='012345abcdef';%的广告数据cfgLLAdv。AdvertisingData =“0201060 d09426174746572792056312e30”
cfgLLAdv = bleLLAdvertisingChannelPDUConfig with properties: PDUType: 'Advertising indication' ChannelSelection: 'Algorithm1' AdvertiserAddressType: 'Random' AdvertiserAddress: '012345ABCDEF' AdvertisingData: [17x2 char] Read-only properties:无属性。
生成一个“广告指示”PDU。
llAdvPDU = bleLLAdvertisingChannelPDU (cfgLLAdv);
你可以使用bleLLAdvertisingChannelPDUDecode
命令,解码发布通道PDU。该函数输出以下信息:
状态
:类型的枚举blePacketDecodeStatus
,指定LL解码是否成功。
cfgLLAdv
: LL发布通道PDU配置对象bleLLAdvertisingChannelPDUConfig
,其中包含已解码的LL属性。
向bleLLAdvertisingChannelPDUDecode功能提供发布通道PDU和指定输入数据PDU格式的可选名称-值对。默认输入格式为'bits'。
解码广告显示
[llAdvDecodeStatus, cfgLLAdv] = bleLLAdvertisingChannelPDUDecode(llAdvPDU);观察输出%解码成功如果比较字符串(llAdvDecodeStatus“成功”)fprintf('链路层解码状态为:%s\n\n', llAdvDecodeStatus);流('已接收的广告通道PDU配置为:\n');cfgLLAdv%解码失败其他的流('链路层解码状态为:%s\n', llAdvDecodeStatus);结束
链接层解码状态是:已成功接收广告频道PDU配置是:CFGLLAdv = BlelladvertisingChannelpduconfig具有属性:Pdutype:'algorithm1'广告商频道:'随机'广告商:'012345abcdef'advertisingdata:[17x2 char]读取属性:没有属性。
数据通道pdu(见第2.4节,Part-B, Vol-6 in [1)在创建LL连接后使用。数据通道pdu包括两大类:将数据pdu和会控制pdu.LL控制pdu用于管理LL连接,LL数据pdu用于承载上层数据。数据通道PDU具有16位头和可变大小的有效载荷。
数据通道pdu的报文格式如下:
这个示例演示了以下pdu的生成和解码。有关支持的其他控制PDU类型和数据PDU类型的列表,请参见金宝app操作码
和LLID
属性bleLLControlPDUConfig
和bleLLDataChannelPDUConfig
对象,分别。
通道地图指示:此LL控制PDU用于更新对等设备处的通道映射。此PDU包含更新的频道映射,指示良好和频道的频道。
数据(开始片段/完成): LL数据PDU用于向对端设备携带L2CAP数据。
你可以使用bleLLDataChannelPDU
函数生成数据通道PDU。这个函数接受一个配置对象bleLLDataChannelPDUConfig
,配置生成数据通道PDU所需的字段。的bleLLControlPDUConfig
是一个子配置对象bleLLDataChannelPDUConfig
,控制PDU有效负载字段使用此配置对象的设置填充。
数据通道pdu使用在“连接指示”包中获得的CRC初始化值。在生成和解码数据包时使用的CRC初始化值。
% CRC初始化值crcInit =“ED321C”;
LL数据PDU生成
要生成数据PDU,请创建bleLLDataChannelPDUConfig
对象与LLID
设置为的数据(片段开始/完成)
.
cfgLLData = bleLLDataChannelPDUConfig ('llid',...的数据(片段开始/完成));
配置的字段:
% CRC初始化值cfgLLData。CRCInitialization = crcInit;%序列号cfgLLData。SequenceNumber = 0;%下一个期望序列号cfgLLData。公布= 1
cfgLLData = bleLLDataChannelPDUConfig with properties: LLID: 'Data (start fragment/complete)' NESN: 1 SequenceNumber: 0 MoreData: 0 CRCInitialization: 'ED321C' Read-only properties:无属性。
数据PDU用于向上层传输有效载荷。本例中使用了一个18字节的有效负载。
%的有效载荷有效载荷=“0 e00050014010a001f004000170017000000”;
使用负载和配置生成数据PDU。
llDataPDU = bleLLDataChannelPDU(cfgLLData, payload);
LL控制PDU的产生
要生成控制PDU,请创建bleLLDataChannelPDUConfig
对象与LLID
设置为'控制'
.
cfgLLData = bleLLDataChannelPDUConfig ('llid','控制');
配置的字段:
% CRC初始化值cfgLLData。CRCInitialization = crcInit
cflldata = blelldatachannelpduconfig具有属性:llid:'control'nesn:0 semencenumber:0 moredata:0 crcinitialization:'ed321c'controlconfig:[1x1 blellcontrolpduconfig]只读属性:无属性。
配置LL控制PDU的内容bleLLControlPDUConfig
.
创建一个控制PDU配置对象操作码
设置为“通道地图指示”
.
cfgControl = bleLLControlPDUConfig (“操作码”,“通道地图指示”);
配置的字段:
%使用渠道cfgControl。UsedChannels = [9, 10, 12, 24, 28, 32];%连接事件即时cfgControl。即时= 245
cfgControl = bleLLControlPDUConfig with properties: Opcode: 'Channel map indication' Instant: 245 UsedChannels: [9 10 12 24 28 32] Read-only properties:没有属性。
将更新后的控制PDU配置对象分配给ControlConfig
属性在数据通道PDU配置对象中。
%更新数据通道PDU配置cfgLLData。ControlConfig = cfgControl;
使用更新的配置生成控制PDU。
llControlPDU = bleLLDataChannelPDU (cfgLLData);
你可以使用bleLLDataChannelPDUDecode
用于解码数据通道PDU的功能。该函数输出以下信息:
状态
:类型的枚举blePacketDecodeStatus
,指定LL解码是否成功。
cfgLLData
: LL数据通道PDU配置对象bleLLDataChannelPDUConfig
,其中包含已解码的LL属性。
有效载荷
:一个n×2字符阵列,表示由LL数据PDU承载的上层有效载荷。
提供数据通道PDU、CRC初始化值和指定输入数据PDU格式的可选名称-值对bleLLDataChannelPDUDecode
函数。默认输入格式为'bits'。
LL数据PDU解码
[llDataDecodeStatus, cfgLLData, payload] =...bleLLDataChannelPDUDecode (llDataPDU crcInit);观察输出%解码成功如果比较字符串(llDataDecodeStatus“成功”)fprintf('链路层解码状态为:%s\n\n', llDataDecodeStatus);流('接收数据通道PDU配置为:\n');cfgLLData流(接收到的上层有效负载的大小为:%d\n',...元素个数(载荷)/ 2);%解码失败其他的流('链路层解码状态为:%s\n', llDataDecodeStatus);结束
链路层解码状态为:Success Received Data channel PDU configuration is: cfgLLData = bleLLDataChannelPDUConfig with properties: LLID: 'Data (start fragment/complete)' NESN: 1 SequenceNumber: 0 MoreData: 0 CRCInitialization: '012345' Read-only properties:无属性。接收到的上层负载大小为:18
解码LL控制PDU
[llControlDecodeStatus, cfgLLData] =...bleLLDataChannelPDUDecode (llControlPDU crcInit);观察输出%解码成功如果比较字符串(llControlDecodeStatus“成功”)fprintf('链路层解码状态为:%s\n\n', llControlDecodeStatus);流('接收数据通道PDU配置为:\n');cfgLLData流('接收控制PDU配置为:\n');cfgControl = cfgLLData。ControlConfig%解码失败其他的流('链路层解码状态为:%s\n', llControlDecodeStatus);结束
链路层解码状态为:Success Received Data channel PDU configuration is: cfgLLData = bleLLDataChannelPDUConfig with properties: LLID: 'Control' NESN: 0 SequenceNumber: 0 MoreData: 0 CRCInitialization: '012345' ControlConfig: [1x1 bleLLControlPDUConfig] Read-only properties:无属性。接收到的控制PDU配置为:cfgControl = bleLLControlPDUConfig with properties: Opcode: 'Channel map indication' Instant: 245 UsedChannels: [9 10 12 24 28 32] Read-only properties:无属性。
这个示例使用blePCAPWriter
对象导出生成的pdu到扩展名为。pcap或。pcapng的文件。要分析和可视化该文件,可以使用第三方包分析器,如Wireshark。
预先考虑访问地址
PCAP格式是希望在LL报文的前面加上访问地址。辅助函数helperBLEPrependAccessAddress在生成的LL报文前添加访问地址。
%发布通道pdu使用默认接入地址advAccessAddress =“8 e89bed6”;%数据通道pdu使用从“连接”获取的访问地址%显示的包。本例中使用了一个随机访问地址connAccessAddress =“E213BC42”;%添加访问地址llPkts{1} = helperBLEPrependAccessAddress(llAdvPDU, advAccessAddress);llPkts{2} = helperBLEPrependAccessAddress(llDataPDU, connAccessAddress);llPkts{3} = helperBLEPrependAccessAddress(llControlPDU, connAccessAddress);
导出到PCAP文件
创建类型的对象blePCAPWriter
并指定抓包文件名。
%创建BLE PCAP Writer文件对象pcapObj = blePCAPWriter (“文件名”,“bleLLPackets”);
使用写
函数将所有BLE LL pdu写入PCAP文件。常数时间戳
指定PDU的捕获时间。在本例中,所有pdu的捕获时间是相同的。
时间戳= 124800;%时间戳(以微秒计)%将所有LL pdu写入PCAP文件为pcapObj, llPkts{idx}, timestamp,“PacketFormat”,“位”);结束清除对象清除pcapObj;
您可以在包分析器中打开包含生成LL包的PCAP文件。包分析器解码的数据包与通信工具箱™库为蓝牙协议生成的符合标准的LL数据包匹配。捕获的数据包分析如下所示。
广告显示
LL数据PDU(携带L2CAP负载)
LL控制PDU(通道图指示)
本例演示了蓝牙标准中LL包的生成和解码[1].使用包分析器可以查看生成的LL报文。
这个例子使用了这些特性:
bleLLAdvertisingChannelPDU
:生成LL发布通道PDU
bleLLAdvertisingChannelPDUDecode
:解码LL发布通道PDU
bleLLAdvertisingChannelPDUConfig
:创建配置对象,用于生成和解码LL发布通道PDU
bleLLDataChannelPDU
:生成LL数据通道PDU
bleLLDataChannelPDUDecode
:译码LL数据通道PDU
bleLLDataChannelPDUConfig
:创建配置对象,用于LL数据通道PDU的生成和解码
bleLLControlPDUConfig
:创建用于生成和解码数据通道PDU的子配置对象
blePCAPWriter
:创建BLE PCAP或PCAPNG文件写入对象
下面的例子使用了这个助手:
helperBLEPrependAccessAddress:在链路层PDU上附加访问地址
蓝牙®技术的网站。蓝牙技术网站|蓝牙技术官方网站2020年7月8日通过。https://www.bluetooth.com/.
开发/LibpcapFileFormat - The Wireshark Wiki。2020年7月8日通过。https://wiki.wireshark.org/Development/LibpcapFileFormat.
集团Tcpdump。“Tcpdump / Libpcap公共库。”2020年7月8日通过。https://www.tcpdump.org..