本示例展示了使用蓝牙®协议的通信工具箱™库对具有心率配置文件的蓝牙®低能耗设备进行建模。
蓝牙核心规范[1]包括用于低速率无线个人区域网络的低能耗版本,称为蓝牙低能耗(BLE)或智能蓝牙。BLE协议栈包括:GATT (Generic Attribute Profile)、ATT (Attribute Protocol)、SMP (Security Manager Protocol)、L2CAP (Logical Link Control and Adaptation Protocol)、LL (Link Layer)和PHY (Physical Layer)。BLE被添加到产生少量数据的低能耗设备标准中,例如用于家庭自动化、医疗保健、健身和物联网(IoT)等应用的通知警报。
ATT建立在BLE的L2CAP层之上。ATT定义了一组协议数据单元(pdu),用于基于ATT的配置文件中的数据交换。
GATT是基于ATT协议构建的业务框架,根据上层的应用数据或下层接收到的ATT PDU处理请求或响应的生成。它以服务、特征和特征描述符的形式存储信息。它使用客户机-服务器体系结构。
关贸总协定的术语:
服务:服务是完成特定功能或特性的数据和相关行为的集合。示例:允许测量心率的心率服务。
特点:特征是服务中使用的值及其权限。例如:心率测量特征包含有关所测量的心率值的信息。
特征描述符:特征行为的描述符。例如:客户端特征配置描述符(CCCD),描述服务器是否必须在包含特征值的响应中通知客户端。
GATT-Client:向服务器发起命令和请求,并接收服务器发送的响应、指示和通知。
GATT-Server:接受来自客户端的传入命令和请求,并向客户端发送响应、指示和通知。
心率剖面
心率谱[2]是蓝牙特殊兴趣小组(SIG)定义的基于gatt的低能量配置文件。HRP定义了心率传感器设备(如腕带)的gatt服务器和智能手机、平板电脑等gatt客户端之间的通信。HRP在健身应用中广泛用于收集心率测量。
检查“蓝牙协议的通信工具箱库”%支金宝app持包是否安装。comm金宝appSupportPackageCheck (“蓝牙”);
在此场景中,gatt服务器是带心率传感器的腕带,gatt客户端是智能手机。
为gatt服务器和gatt客户端设备创建对象。gattServer = helperBLEGATTServer;gatclient = helperBLEGATTClient;
最初,HRP客户端发现服务器上定义的服务、特征和特征描述符。发现后,客户端订阅心率测量通知。
客户端执行服务发现操作以获取有关可用服务的信息。在服务发现中,客户端调用“发现所有主要服务”
通过发送按组类型请求读取攻击力PDU。服务器通过发送一个“按组类型读取响应”ATT PDU来响应可用的服务及其相关句柄。一个处理是由服务器动态分配的属性的唯一标识符。
客户端请求服务器上的服务
的generateATTPDU函数生成一个ATT PDU,对应于蓝牙核心规范中指定的给定子过程。
预分配一个变量存储生成的链路层报文。pcapPackets = cell(1,9);Count = 1;配置GATT客户端发现服务器上可用的服务。gattClient。子过程=“发现所有主要服务”;service离散qpdu = generateATTPDU(gatclient);%将应用数据(| service离散qpdu |)通过%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(service离散qpdu);Count = Count +1;
在服务器接收客户端请求
服务器接收一个按组类型请求读取类中发送可用服务的列表按组类型响应读取攻击力PDU。
的receiveData函数将传入的PDU解码为gatt服务器,并返回相应的ATT PDU配置对象和相应的响应PDU。
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[attServerRespPDU, serviceDiscReqCfg, gattServer] = receiveData(gattServer, receivedPDU);流("服务器收到的服务发现请求:\n") serviceDiscReqCfg%向客户端发送应用响应数据(|attServerRespPDU|)%通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(attServerRespPDU);Count = Count +1;
Received service discovery request at the server: serviceDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Read by group type request' StartHandle: '0001' EndHandle: 'FFFF' AttributeType: '2800' Read-only properties: No properties。
在客户端接收服务器响应
的receiveData函数将传入的PDU解码为gatt客户端,并返回相应的ATT PDU配置对象和适当的响应PDU(如果适用)。
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[~, service离散spcfg] = receiveData(gatclient, receivedPDU);gattClient。StartHandle = servicedisspcfg .StartHandle;gattClient。EndHandle = service离散spcfg .EndHandle;%期望服务器响应:|'按组类型读取响应'|或% |'错误响应'|. %如果比较字符串(serviceDiscRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") service离散spcfg service离散spmsg = [“错误响应(“”serviceDiscRespCfg。ErrorMessage“‘)’];其他的流("客户端收到的服务发现响应:\n") service离散spcfg service = helperBluetoothID.getBluetoothName(service离散spcfg . attributevalue);service离散spmsg = [服务发现响应(")服务“‘)’];结束
Received service discovery response at the client: serviceDiscRespCfg = bleATTPDUConfig with properties: Opcode: 'Read by group type response' StartHandle: '0001' EndHandle: '0006' AttributeValue: [2x2 char] Read-only properties: No properties。
服务由多个特征组成。对于每个服务,客户机和服务器之间都有信息元素交换。每个信息元素都可以包含其行为的描述符。一个特征包含一个值及其相关的描述符。发现服务后,客户端执行特征发现了解服务中定义的特征。在特征发现中,客户端调用“发现服务的所有特征”
通过发送“按类型读取请求”ATT PDU。服务器通过发送一个“按类型读取响应”ATT PDU来响应可用的特征及其相关句柄。
客户端请求服务器的特性
配置GATT客户端以发现所有可用的特性%服务器。gattClient。子过程=“发现服务的所有特征”;chrstic离散qpdu = generateATTPDU(gatclient);%发送应用数据(| chrstic离散qpdu |)到服务器%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticdiscrete qpdu);Count = Count +1;
在服务器接收客户端请求
解析接收到的请求并返回可用特征的列表按类型响应读取攻击力PDU。
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[chrsticdissppdu, chrsticdisqcfg, gattServer] = receiveData(gattServer, receivedPDU);流("已收到服务器上的特征发现请求:\n") chrsticDiscReqCfg将应用程序响应数据(| chrsticdissppdu |)发送到%客户端通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticdissppdu);Count = Count +1;
Received characteristic discovery request at the server: chrsticDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Read by type request' StartHandle: '0001' EndHandle: '0006' AttributeType: '2803' Read-only properties: No properties。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[~, chrsticdisspcfg] = receiveData(gatclient, receivedPDU);%期望服务器响应:|'读取类型响应'|或|'错误”| %响应。如果比较字符串(chrsticDiscRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") chrsticDescRespMsg = [“错误响应(“”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' CharacteristicValueHandle: '0003' CharacteristicType: '心率测量'只读属性:无属性。
一个特征可以由多个特征描述符组成。发现特征后,客户端执行特征描述符发现要了解描述符及其句柄的列表。在特征描述符发现中,客户端调用“发现所有描述符”
通过发送“信息请求”ATT PDU。服务器通过发送一个“信息响应”ATT PDU来响应可用的特征描述符及其相关句柄。
客户端请求服务器上的特征描述符
配置GATT客户端发现所有可用特性%描述符。gattClient。子过程=“发现所有描述符”;gattClient。StartHandle = dec2hex(hex2dec(chrsticdisspcfg . attributehandle)+ 1,4);chrsticdesc离散qpdu = generateATTPDU(gatclient);%向客户端发送应用数据(| chrsticdesc离散qpdu |)%通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticDescDiscReqPDU);Count = Count +1;
在服务器接收客户端请求
类中的可用特征描述符列表信息的反应攻击力PDU。
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[chrsticdesc离散sppdu, chrsticdesc离散qcfg, gattServer] = receiveData(gattServer, receivedPDU);流("在服务器上收到的特征描述符发现请求:\n") chrsticDescDiscReqCfg将应用程序响应数据(| chrsticdesc离散sppdu |)发送到%客户端通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(chrsticDescDiscRespPDU);Count = Count +1;
Received characteristic descriptor discovery request at the server: chrsticDescDiscReqCfg = bleATTPDUConfig with properties: Opcode: 'Information request' StartHandle: '0003' EndHandle: '0006' Read-only properties: No properties。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[~, chrsticdesc离散spcfg] = receiveData(gatclient, receivedPDU);来自服务器的期望响应:|'信息响应'|或|'错误”| %响应。如果比较字符串(chrsticDescDiscRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") chrsticdesc离散spcfg chrsticdesc离散spmsg = [“错误响应(“”chrsticDescDiscRespCfg。ErrorMessage“‘)’];其他的流("在客户端收到的特征描述符发现响应:\n") chrsticdesc离散spcfg描述符= helperBluetoothID.getBluetoothName(chrsticdesc离散spcfg . attributetype);chrsticDescDiscRespMsg = [特征描述符发现响应("描述符“‘)’];结束
在客户端收到的特征描述符发现响应:chrsticDescDiscRespCfg = bleATTPDUConfig with properties: Opcode: 'Information response' Format: '16 bit' AttributeHandle: '0004' AttributeType: '2902' Read-only properties: No properties。
发现特征描述符后,客户端可以启用或禁用通知求它的特征值。要启用通知,客户端必须设置的通知位(第一个位)客户端特征配置描述符(CCCD)值,通过调用“写特征值”
子过程。
客户端在服务器上订阅通知
配置GATT客户端启用心率通知%测量特性。gattClient。子过程=“写特征值”;gattClient。一个ttributeHandle = chrsticDescDiscRespCfg.AttributeHandle; gattClient.AttributeValue =“0100”;enableNotificationReqPDU = generateATTPDU(gatclient);%向客户端发送应用数据(|enableNotificationReqPDU|)%通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(enableNotificationReqPDU);Count = Count +1;
在服务器接收客户端请求
对接收到的请求进行解码,并以写回应攻击力PDU。
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[enableNotificationRespPDU, enableNotificationReqCfg, gattServer] = receiveData(gattServer, receivedPDU);流("已收到服务器上的启用通知请求:\n") enableNotificationReqCfg发送应用响应数据(|enableNotificationRespPDU|)到%客户端通过PHY。[ble波形,pcapPackets{count}] = helperBLETransmitData(enableNotificationRespPDU);Count = Count +1;
Received enable notification request at the server: enableNotificationReqCfg = bleATTPDUConfig with properties: Opcode: 'Write request' AttributeHandle: '0004' AttributeValue: [2x2 char] Read-only properties: No properties。
在客户端接收服务器响应
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[~, enableNotificationRespCfg] = receiveData(gatclient, receivedPDU);服务器期望的响应:|'写响应'|或|'错误”| %响应。如果比较字符串(enableNotificationRespCfg。操作码,“错误响应”)流("在客户端收到错误响应:\n") enablenotificrespcfg = [“错误响应(“”enableNotificationRespCfg。ErrorMessage“‘)’];其他的流("在客户端收到启用通知响应:\n") enableNotificationRespCfg =“启用通知(“心率测量”)”;结束
Received enable notification response at the client: enableNotificationRespCfg = bleATTPDUConfig with properties: Opcode: 'Write response' Read-only properties: No properties。
当客户端为某个特性启用通知时,服务器会定期通知characteristic的值(心率测量)发给客户。
客户端订阅后,HRP服务器会通知客户端心跳测量结果。
服务器向客户端发送通知
的notifyHeartRateMeasurement函数生成蓝牙核心规范中指定的通知PDU。
重置随机数生成器种子。rng默认的使用传感器测量心率值(为心脏生成一个随机数%率测量值)。heartratemmeasurementvalue = randi([65 95]);通知心率测量。[gattServer, notificationPDU] = notifyheartratemmeasurement (gattServer, notificationPDU)...heartRateMeasurementValue);%通过发送应用数据(|notificationPDU|)到客户端%体育。[ble波形,pcapPackets{count}] = helperBLETransmitData(notificationPDU);Count = Count +1;
在客户端接收服务器通知
解码接收到的BLE波形并检索应用程序数据。receivedPDU = helperBLEDecodeData(ble波形);解码接收到的ATT PDU并生成响应PDU(如果适用)。[~, notificationCfg] = receiveData(gatclient, receivedPDU);流("已收到客户端通知:\n")解码接收到的心率测量特征值。heartRateCharacteristicValue = helperBLEDecodeAttributeValue(...notificationCfg。AttributeValue,“心率测量”);heartRateCharacteristicValue heartRateMeasurementValue = heartRateCharacteristicValue. heartratevalue;可视化BLE GATT客户-服务器模型。helperBLEVisualizeHRPFrame (serviceDiscRespMsg chrsticDescRespMsg,...chrsticDescDiscRespMsg, enableNotificRespMsg, heartRateMeasurementValue);
在客户端收到的通知:heartRateCharacteristicValue = helperBLEAttributeValueConfig with properties: AttributeType: '心率测量' HeartRateValueFormat: 'UINT8' SensorContactStatus: 'Contact detected' EnergyExpendedFieldFlag: 'Present,单位:Kilo Joules' RRIntervalFieldFlag: 'Present' HeartRateValue: 90 energyconsumended: 100 RRInterval: 10 Read-only properties: No properties。
这个例子使用了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;流("打开生成的pcap文件'bleHRP。在协议分析器中查看生成的帧。\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文件写入器对象
下面的例子使用了这些helper:
helperBLEGATTClient:提供通用属性概要的方法
helperBLEGATTServer:创建GATT服务器对象
helperBLEAttributeValueConfig:为BLE属性值创建配置对象
helperBLEGenerateAttributeValue: BLE属性值生成
helperBLEDecodeAttributeValue: BLE属性值解码器
helperBLEDecodeData:对接收到的波形进行解码,检索应用数据
helperBLEPrependAccessAddress:在链路层PDU前配置访问地址
helperBLETransmitData:通过产生BLE波形传输应用数据
helperBluetoothID:蓝牙标识符及其名称由Bluetooth Special Interest Group (SIG)分配。
helperBLEVisualizeHRPFrame:在“HRP举例”中显示交换的HRP帧
helperBLEPlotHRPFrames:绘制心率配置文件服务器和客户端之间的数据帧交换
Bluetooth®技术网站。“蓝牙技术网站|蓝牙技术官网。”2020年7月8日访问。https://www.bluetooth.com/.
开发/LibpcapFileFormat - Wireshark Wiki2020年7月8日访问。https://wiki.wireshark.org/Development/LibpcapFileFormat.
组,Tcpdump。“Tcpdump/Libpcap公共存储库。”2020年7月8日访问。https://www.tcpdump.org.