这个例子展示了使用蓝牙协议的通信工具箱™库对蓝牙低能耗设备进行建模,并使用心率配置文件。
蓝牙核心规范[1]包括用于低速无线个人区域网络的低能量版本,称为蓝牙低能量(BLE)或蓝牙智能。BLE堆栈包括:通用属性配置文件(GATT)、属性协议(ATT)、安全管理器协议(SMP)、逻辑链路控制和适配协议(L2CAP)、链路层(LL)和物理层(PHY)。BLE被添加到标准中,用于产生少量数据的低能设备,如家庭自动化、医疗保健、健身和物联网(IoT)等应用中使用的通知警报。
ATT构建在BLE的L2CAP层之上。ATT定义了一组协议数据单元(PDU),用于基于GATT的概要文件中的数据交换。
GATT是一个使用ATT构建的服务框架。GATT根据来自上层的应用程序数据或从下层接收的ATT PDU处理请求或响应的生成。它以服务、特征和特征描述符的形式存储信息。它使用客户机-服务器体系结构。
关贸总协定的术语:
服务:服务是完成特定功能或特性的数据和相关行为的集合。示例:允许测量心率的心率服务。
特点:特征是服务中使用的值及其权限。例如:一个心率测量特征包含了关于被测量的心率值的信息。
特征描述符:特征行为的描述符。示例:客户端特征配置描述符(CCCD),描述服务器是否必须在包含特征值的响应中通知客户端。
GATT-Client:向服务器发起命令和请求,并接收服务器发送的响应、指示和通知。
关贸总协定服务器:接收来自客户端的传入命令和请求,并向客户端发送响应、指示和通知。
心率概要
心率曲线(HRP) [2是蓝牙特殊兴趣组(SIG)定义的基于gatt的低能耗配置文件。HRP定义了心率传感器设备的GATT-server(如腕带)和GATT-client(如智能手机、平板电脑)之间的通信。HRP被广泛应用于健身应用中,用于收集心率测量。
%检查“蓝牙协议的通信工具箱库”%支金宝app持包是否安装。comm金宝appSupportPackageCheck(“蓝牙”);
在这种情况下,GATT服务器是一个带心率传感器的腕带,而GATT客户端是一个智能手机。
%为GATT服务器和GATT客户端设备创建对象。gattServer = helperBLEGATTServer;gattClient = helperBLEGATTClient;
最初,HRP客户端发现在服务器上定义的服务、特征、特征描述符。发现后,客户端订阅心率测量通知。
客户端执行服务发现操作以获取可用服务的信息。在服务发现中,客户端调用“发现所有主要服务”
通过发送一个按组类型请求阅读攻击力PDU。服务器通过发送一个“Read by group type response”ATT PDU来响应可用的服务及其相关句柄。一个手柄是由服务器动态分配的属性的唯一标识符。
客户端在服务器上请求服务
的generateATTPDU函数生成与蓝牙核心规范中指定的给定子程序相对应的ATT PDU。
%预分配一个变量来存储生成的链路层包。pcapPackets = cell(1,9); / /发送数据包数= 1;%配置GATT客户端以发现服务器上可用的服务。gattClient。子过程=“发现所有主要服务”;serviceDiscReqPDU = generateATTPDU (gattClient);%将应用程序数据(| servicedisqpdu |)通过%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(servicedisqpdu);数=计数+ 1;
在服务器端接收客户端请求
服务器接收到按组类型请求阅读从客户端发送可用服务列表按小组类型阅读攻击力PDU。
的receiveData函数将传入的PDU解码为GATT-server,返回相应的ATT PDU配置对象和相应的响应PDU。
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[attServerRespPDU, servicedisqcfg, gattServer] = receiveData(gattServer, receivedPDU);流("服务器接收到服务发现请求:\n") serviceDiscReqCfg%向客户端发送应用程序响应数据(|attServerRespPDU|)通过体育%。[BLEVERVA波形,pcapPackets{count}]=HelperBletTransmitData(attServerRespPDU);count=count+1;
在服务器上收到的服务发现请求:servicedisqcfg = bleATTPDUConfig with properties: Opcode: 'Read by group type request' StartHandle: '0001' EndHandle: 'FFFF' AttributeType: '2800'只读属性:没有属性。
在客户端接收服务器响应
的receiveData函数将传入的PDU解码为GATT-client,并返回相应的ATT PDU配置对象和相应的响应PDU(如果适用)。
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[~, servicedisspcfg] = receiveData(gattClient, receivedPDU);gattClient。StartHandle = serviceDiscRespCfg.StartHandle;gattClient。EndHandle = serviceDiscRespCfg.EndHandle;来自服务器的预期响应:|'Read by group type response'|或% | |错误响应。如果strcmp(servicespcfg.Opcode,“错误响应”)流("在客户端收到错误响应:\n") servicedisspcfg servicedisspmsg = [“错误响应(“”serviceDiscRespCfg。ErrorMessage“‘)’];其他的流("在客户端接收到的服务发现响应:\n") servicedisspcfg service = helperBluetoothID.getBluetoothName(servicedisspcfg . attributevalue);serviceDiscRespMsg = [“服务发现的反应(“”服务“‘)’];结束
在客户端接收到服务发现响应:serviceDiscRespCfg=bleATTPDUConfig,属性为:操作码:“按组类型读取响应”StartHandle:“0001”EndHandle:“0006”AttributeValue:[2x2 char]只读属性:无属性。
一个服务由多个特征组成。对于每个服务,客户机和服务器之间都有交换的信息元素。每个信息元素都可能包含其行为的描述符。特征包含一个值及其相关的描述符。发现服务后,客户端执行特征发现了解服务中定义的特征。在特征发现中,客户端调用“发现服务的所有特征”
通过发送“Read by type request”ATT PDU。服务器通过发送一个“Read by type response”ATT PDU来响应可用的特征及其相关句柄。
客户端请求服务器上的特征
%配置GATT客户机,以便在%的服务器。gattClient。子过程=“发现服务的所有特征”;chrsticDiscReqPDU = generateATTPDU (gattClient);%通过以下方式将应用程序数据(| chrsticqpdu |)传输到服务器%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticdisqpdu);数=计数+ 1;
在服务器端接收客户端请求
对接收到的请求进行解码,并返回可用特性的列表按类型读出反应攻击力PDU。
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[chrsticdissppdu, chrsticdisqcfg, gattServer] = receiveData(gattServer, receivedPDU);流("在服务器接收到特征发现请求:\n") chrsticDiscReqCfg%将应用程序响应数据(| chrsticdiscressppdu |)传输到%客户通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticdissppdu);数=计数+ 1;
操作码:'Read by type request' StartHandle: '0001' EndHandle: '0006' AttributeType: '2803' Read-only properties:没有属性。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[~, chrsticdisspcfg] = receiveData(gattClient, receivedPDU);来自服务器的预期响应:|'Read by type response'| or |'错误”| %响应。如果比较字符串(chrsticDiscRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") chrsticdiscrespmsg = [/ cn“错误响应(“”chrsticDiscRespCfg。ErrorMessage“‘)’];其他的流(“客户端接收到的特征发现响应:\n”) attributeValueCfg = helperBLEDecodeAttributeValue(...chrsticDiscRespCfg。AttributeValue,“特征”);attributeValueCfg chrsticDescRespMsg = [“发现响应特征(“”attributeValueCfg。CharacteristicType“‘)’];结束
在客户端接收到特征发现响应:attributeValueCfg = helperBLEAttributeValueConfig with properties: AttributeType: ' characteristic ' BroadcastFlag: 'False' ReadFlag: 'False' WriteWithoutResponseFlag: 'False' WriteFlag: 'False' NotifyFlag: 'True' IndicateFlag: 'False' AuthenticatedSignedWritesFlag:'False' ExtendedPropertiesFlag: 'False'特征值处理:'0003'特征类型:'心率测量'只读属性:没有属性。
一个特征可以由多个特征描述符组成。发现特征后,客户端执行操作特征描述符发现以了解描述符及其句柄的列表。在特征描述符发现中,客户端调用发现所有描述符的
发送“信息请求”ATT PDU。服务器通过发送一个“信息响应”ATT PDU来响应可用的特征描述符及其相关句柄。
客户端对服务器特征描述符的请求
%配置GATT客户端以发现所有可用特性%服务器上的描述符。gattClient。子过程=发现所有描述符的;gattClient。StartHandle = dec2hex(hex2dec(chrsticdisspcfg . attributehandle)+ 1,4);chrsticDescDiscReqPDU = generateATTPDU (gattClient);%将应用程序数据(| chrsticDescDiscrestQPDU |)传输到客户端通过体育%。[BLEVERVARME,pcAppackes{count}]=HelperBletTransmitData(chrsticDescDiscrestQPDU);count=count+1;
在服务器端接收客户端请求
对接收的请求进行解码,并返回可用的特征描述符列表信息的反应攻击力PDU。
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[chrsticdescdissppdu, chrsticdescdisqcfg, gattServer] = receiveData(gattServer, receivedPDU);流("在服务器收到特征描述符发现请求:\n") chrsticDescDiscReqCfg%发送应用程序响应数据(| chrsticdescdissppdu |)到%客户通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticdescdissppdu);数=计数+ 1;
接收到服务器上的特征描述符发现请求:chrsticdescdisqcfg = bleATTPDUConfig with properties: Opcode: 'Information request' StartHandle: '0003' EndHandle: '0006' Read-only properties:无属性。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[~, chrsticdescdisspcfg] = receiveData(gattClient, receivedPDU);来自服务器的预期响应:|'信息响应'|或|'错误”| %响应。如果比较字符串(chrsticDescDiscRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n")chrsticDescDiscRespCfg chrsticDescDiscRespMsg=[“错误响应(“”chrsticDescDiscRespCfg。ErrorMessage“‘)’];其他的流("客户端接收到特征描述符发现响应:\n") chrsticdescdisspcfg描述符= helperBluetoothID.getBluetoothName(chrsticdescdisspcfg . attributetype);chrsticDescDiscRespMsg = [“特征描述符发现响应(”描述符“‘)’];结束
在客户端接收到特征描述符发现响应:chrsticDescDiscRespCfg=blettpduconfig,属性:操作码:“信息响应”格式:“16位”属性句柄:“0004”属性类型:“2902”只读属性:无属性。
发现特征描述符后,客户端可以启用或禁用特征描述符通知为其特征值。要启用通知,客户端必须设置通知位(第一个位)客户端特征配置描述符价值通过调用“写特征值”
子过程。
客户端在服务器上订阅通知
%配置GATT客户端以启用心率通知%测量的特点。gattClient。子过程=“写特征值”;gattClient。一个ttributeHandle = chrsticDescDiscRespCfg.AttributeHandle; gattClient.AttributeValue =“0100”;enableNotificationReqPDU = generateATTPDU (gattClient);%将应用程序数据(| enableNotificationReqPDU |)传输到客户端通过体育%。[ble波形,pcapPackets{count}] = helperBLETransmitData(enableNotificationReqPDU);数=计数+ 1;
在服务器端接收客户端请求
对接收到的请求进行解码并发送响应写回应攻击力PDU。
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[enableNotificationRespPDU, enableNotificationReqCfg, gattServer] = receiveData(gattServer, receivedPDU);流("在服务器上收到启用通知请求:\n") enableNotificationReqCfg%发送应用响应数据(|enableNotificationRespPDU|)到%客户端通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(enableNotificationRespPDU);数=计数+ 1;
在服务器上收到启用通知请求:enableNotificationReqCfg = bleATTPDUConfig with properties: Opcode: 'Write request' AttributeHandle: '0004' AttributeValue: [2x2 char] Read-only properties:无属性。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[~, enableNotificationRespCfg] = receiveData(gattClient, receivedPDU);%服务器的预期响应:|'写响应'|或|'错误”| %响应。如果比较字符串(enableNotificationRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") enableNotificationRespCfg enableNotificRespMsg = [“错误响应(“”enableNotificationRespCfg。ErrorMessage“‘)’];其他的流("在客户端收到启用通知响应:\n") enableNotificationRespCfg enableNotificRespMsg =“启用通知(“心率测量”)”;结束
在客户端收到启用通知响应:enableNotificationRespCfg = bleATTPDUConfig with properties: Opcode: 'Write response' Read-only properties:无属性。
当客户端启用某个特征的通知时,服务器定期通知特征值(心率测量)。
HRP服务器订阅完成后,通知客户端进行心率测量。
服务器向客户端发送通知
的notifyHeartRateMeasurement函数生成蓝牙核心规范中指定的通知PDU。
重置随机数生成器种子。rng默认的%使用传感器测量心率值(为心脏生成一个随机数%率测量值)。heartatemeasurementvalue = randi([65 95]);通知心率测量。[gattServer,notificationPDU]=notifyHeartRateMeasurement(gattServer,...heartRateMeasurementValue);%发送应用程序数据(|notificationPDU|)给客户端%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(notificationPDU);数=计数+ 1;
在客户端接收服务器通知
解码接收到的BLE波形并检索应用数据。receivedPDU = helperBLEDecodeData (bleWaveform);%解码收到的ATT PDU并生成响应PDU(如果适用)。[~, notificationCfg] = receiveData(gattClient, receivedPDU);流("在客户端收到通知:\n")解码接收到的心率测量特征值。heartRateCharacteristicValue=HelperBledeCodeAttribute值(...notificationCfg。AttributeValue,“心率测量”); heartRateCharacteristicValue heartRateMeasurementValue=heartRateCharacteristicValue.HeartRateValue;可视化BLE GATT客户端-服务器模型。HelperLevisualizeHrpFrame(服务离散消息、chrsticDescRespMsg、,...chrsticDescDiscRespMsg、enableNotificRespMsg heartRateMeasurementValue);
在客户端收到通知:heartRateCharacteristicValue = helperBLEAttributeValueConfig属性:AttributeType:“心率测量”HeartRateValueFormat:“UINT8”SensorContactStatus:“接触检测”EnergyExpendedFieldFlag:“现在,单位:千焦耳”RRIntervalFieldFlag:“礼物”HeartRateValue: 90 EnergyExpended:100 RRInterval: 10只读属性:无属性。
这个示例使用blePCAPWriter
对象导出生成的pdu到扩展名为。pcap或。pcapng的文件。要分析和可视化该文件,可以使用第三方包分析器,如Wireshark。
创建一个类型的对象blePCAPWriter
并指定抓包文件名。
%创建BLE PCAP Writer文件对象pcapObj = blePCAPWriter (“文件名”,“bleHRP”);
使用写
函数将所有BLE LL pdu写入PCAP文件。常数时间戳
指定PDU的捕获时间。在本例中,所有pdu的捕获时间是相同的。
时间戳= 124800;%时间戳(以微秒计)%将所有LL pdu写入PCAP文件为idx = 1:numel(pcapPackets) write(pcapObj, pcapPackets{idx}, timestamp,“PacketFormat”,“位”);结束清除对象清晰的pcapObj; fprintf(“在协议分析器中打开生成的pcap文件'bleHRP.pcap'以查看生成的帧。\n”)
打开生成的pcap文件bleHRP。在协议分析器中查看生成的帧。
由于生成的心率配置文件数据包符合蓝牙标准,您可以使用Wireshark等第三方数据包分析仪打开、分析和可视化PCAP文件[3.].这些图中显示的数据使用本例中生成的心率剖面数据包。
服务发现请求
服务发现响应
通知心率测量值
该示例演示了使用蓝牙核心规范中指定的GATT客户端-服务器场景使用心率配置文件的BLE设备建模[1]。您可以使用数据包分析器查看生成的帧。
这个例子使用了这些特性:
bleATTPDUConfig
:创建BLE ATT PDU的配置对象
bleATTPDU
:BLE ATT PDU生成
bleATTPDUDecode
:BLE ATT PDU解码
blePCAPWriter
:创建BLE PCAP或PCAPNG文件写入对象
这个例子使用了这些助手:
HelperLegatClient:提供通用属性配置文件的方法
helperBLEGATTServer:创建GATT服务器对象
helperBLEAttributeValueConfig:为BLE属性值创建配置对象
helperBLEGenerateAttributeValue: BLE属性值生成
helperBLEDecodeAttributeValue: BLE属性值解码器
helperBLEDecodeData:解码接收到的波形并检索应用数据
helperBLEPrependAccessAddress:在链路层PDU上附加访问地址
helperBLETransmitData:通过生成BLE波形传输应用数据
helperBluetoothID:蓝牙特殊兴趣组(Bluetooth Special Interest Group, SIG)分配的蓝牙标识符及其名称。
helperBLEVisualizeHRPFrame:查看HRP举例中交换的HRP帧
helperBLEPlotHRPFrames:绘制心率配置文件服务器和客户端之间的数据帧交换
Bluetooth®技术网站。“Bluetooth技术网站| Bluetooth技术的官方网站。”于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.