赞
踩
关于广播和扫描报文的解析如果想从协议本身就了解可以从头看起,如果想直接看看芯片的开发怎么使用,可以直接从第2节,报文解析开始。
图1 BLE报文结构
1.1 前导
前导是一个8比特的交替序列。根据接入地址的第一个比特为0或者1,分01010101和10101010两种。接收机可以根据前导的无线信号强度来配置自动增益控制。
1.2 接入地址
接入地址有两种类型:广播接入地址和数据接入地址。
1.3 报头
1.3.1 广播报文报头
图2 广播报文报头 图3 Advertising channel PDU Header(core_v4.2 page 2583)
1)广播报文类型
图3 广播报文类型
2) 发送地址类型和接收地址类型
发送地址类型和接收地址类型指示了设备使用公共地址(Public Address)还是随机地址(Random Address)。公共地址和随机地址的长度一样,都包含6个字节共48位。BLE设备至少要拥有这两种地址类型中的一种,当然也可以同时拥有这两种地址类型。
公共地址由两部分组成,如下图。公共地址由制造商从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节描述了静态地址。
随机地址有包含两种:静态地址(Static Device Address)和私有地址(PrivateDevice Address)。Core_v4.2 P2577的1.3.2.1节描述了静态地址。
静态地址有如下要求:
a) 静态地址的最高2位有效位必须是1。
b) 静态地址最高2位有效位之外的其余部分不能全为0和1。
在私有地址的定义当中,又包含了两个子类:不可解析私有地址(Non-resolvable Private Address)和可解析私有地址(Resolvable Private Address,RPA)。CH57x使用的是静态地址,芯片在出厂时自带全球唯一的48位MAC地址。在提供的driver代码中,有获取MAC的接口,可以直接调用。
图5 CH57x 获取芯片MAC接口函数
1.4 长度
广播报文:长度域包含6个比特,有效值的范围是6~37。
数据报文:长度域包含5个比特,有效值的范围是0~31。
广播报文和和数据报文的长度域有所不同,主要原因是:广播报文除了最多31个字节的数据之外,还必须要包含6个字节的广播设备地址。6+31=37,所以需要6比特的长度域。
再次强调:广播时必须要包含6个字节的广播设备地址。
1.5 数据(AdvData)
广播和扫面响应的数据格式如下图所示,由有效数据部分和无效数据部分组成。
图6广播和扫描响应的数据格式
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
查看WCH的SDK中的定义,AD type的定义在程序的“CH57xBLE_LIB.h”头文件中。定义如下:
// GAP_ADTYPE_DEFINES GAP Advertisement Data Types
#define GAP_ADTYPE_FLAGS 0x01 //!< Discovery Mode: @ref GAP_ADTYPE_FLAGS_MODES
#define GAP_ADTYPE_16BIT_MORE 0x02 //!< Service: More 16-bit UUIDs available
#define GAP_ADTYPE_16BIT_COMPLETE 0x03 //!< Service: Complete list of 16-bit UUIDs
#define GAP_ADTYPE_32BIT_MORE 0x04 //!< Service: More 32-bit UUIDs available
#define GAP_ADTYPE_32BIT_COMPLETE 0x05 //!< Service: Complete list of 32-bit UUIDs
#define GAP_ADTYPE_128BIT_MORE 0x06 //!< Service: More 128-bit UUIDs available
#define GAP_ADTYPE_128BIT_COMPLETE 0x07 //!< Service: Complete list of 128-bit UUIDs
#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 //!< Shortened local name
#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 //!< Complete local name
#define GAP_ADTYPE_POWER_LEVEL 0x0A //!< TX Power Level: 0xXX: -127 to +127 dBm
#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D //!< Simple Pairing OOB Tag: Class of device (3 octets)
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E //!< Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets)
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F //!< Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets)
#define GAP_ADTYPE_SM_TK 0x10 //!< Security Manager TK Value
#define GAP_ADTYPE_SM_OOB_FLAG 0x11 //!< Security Manager OOB Flags
#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 //!< Min and Max values of the connection interval (2 octets Min, 2 octets Max) (0xFFFF indicates no conn interval min or max)
#define GAP_ADTYPE_SIGNED_DATA 0x13 //!< Signed Data field
#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 //!< Service Solicitation: list of 16-bit Service UUIDs
#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 //!< Service Solicitation: list of 128-bit Service UUIDs
#define GAP_ADTYPE_SERVICE_DATA 0x16 //!< Service Data - 16-bit UUID
#define GAP_ADTYPE_PUBLIC_TARGET_ADDR 0x17 //!< Public Target Address
#define GAP_ADTYPE_RANDOM_TARGET_ADDR 0x18 //!< Random Target Address
#define GAP_ADTYPE_APPEARANCE 0x19 //!< Appearance
#define GAP_ADTYPE_ADV_INTERVAL 0x1A //!< Advertising Interval
#define GAP_ADTYPE_LE_BD_ADDR 0x1B //!< LE Bluetooth Device Address
#define GAP_ADTYPE_LE_ROLE 0x1C //!< LE Role
#define GAP_ADTYPE_SIMPLE_PAIRING_HASHC_256 0x1D //!< Simple Pairing Hash C-256
#define GAP_ADTYPE_SIMPLE_PAIRING_RANDR_256 0x1E //!< Simple Pairing Randomizer R-256
#define GAP_ADTYPE_SERVICE_DATA_32BIT 0x20 //!< Service Data - 32-bit UUID
#define GAP_ADTYPE_SERVICE_DATA_128BIT 0x21 //!< Service Data - 128-bit UUID
#define GAP_ADTYPE_3D_INFO_DATA 0x3D //!< 3D Information Data
#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF //!< Manufacturer Specific Data: first 2 octets contain the Company Identifier Code followed by the additional manufacturer specific data
// GAP_ADTYPE_FLAGS_MODES GAP ADTYPE Flags Discovery Modes
#define GAP_ADTYPE_FLAGS_LIMITED 0x01 //!< Discovery Mode: LE Limited Discoverable Mode
#define GAP_ADTYPE_FLAGS_GENERAL 0x02 //!< Discovery Mode: LE General Discoverable Mode
#define GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED 0x04 //!< Discovery Mode: BR/EDR Not Supported
图7 广播类型定义
1.6 校验
BLE采用的是24位CRC校验。CRC对报头、长度和数据进行计算。24位CRC的生成多项式如下:
2. 广播包解析
通过上文的描述,我们对BLE广播包有了大致的了解,接下来我们用沁恒的BLE Analyzer捕获一个peripheral的广播包,通过对实际广播包的分析来理解BLE报文结构和广播。广播包捕获实验的硬件连接如下。
WCH_BLEAnalyzer.zip - 南京沁恒微电子股份有限公司(包含安装软件和使用说明)
3. 实例解析
以EXAM\BLE\Peripheral为例,进行广播和扫描报文的解释
3.1 代码部分
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[ ] =
{
// complete name
0x12, // length of this data AD Structure
GAP_ADTYPE_LOCAL_NAME_COMPLETE, len + GAP_ADTYPE + data
'S', 'i', 'm', 'p', 'l','e',' ','P','e','r','i','p','h','e','r','a','l',
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms AD Structure
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), len + GAP_ADTYPE + data
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
// Tx power level
0x02, // length of this data AD Structure GAP_ADTYPE_POWER_LEVEL, len + GAP_ADTYPE + data
0 // 0dBm
};
// GAP - Advertisement data (max size = 31 bytes, though this is best kept short to conserve power while advertising)
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable mode (advertises for 30 seconds at a time) instead of general discoverable mode (advertises indefinitely)
0x02, // length of this data AD Structure
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ), AD Structure
HI_UINT16( SIMPLEPROFILE_SERV_UUID )
};
准备好广播和扫描报文数据,使用时需要将这些信息通过RF发出去,具体在代码中实现方式如下,使用到的函数如下:
蓝牙初始化函数如下:
BLE分析仪抓包
从上图可以看到:
第一行广播包,间隔时间约(Time:+54394us)50ms
广播包数据
看看PDU(Packet data)报头*1B+长度*1B+MAC*6B+数据
数据部分与advertData定义相同,如果需要添加数据部分,需要按照AD Structure的构造去添加。
后面2行是主机向地址0x84C2E4030252发起扫描请求(SCAN_REQ),然后设备对于扫描请求的响应(SCAN_RSP).
响应数据如下:
看看PDU(Packet data)报头*1B+长度*1B +MAC*6B+数据。
数据部分与scanRspData相同,如果修改需要按照AD Structure的构造去改造,并且保证长度不超过31B。
其他的AD Structure不过多的讲,着重说一下UUID:
UUID定义:
“GATT层”中定义的所有属性都有一个UUID值,UUID是全球唯一的128位的号码,它用来识别不同的特性。
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被分为下列几组:
l 0x1800 ~ 0x26FF:用作服务类通用唯一识别码。
l 0x2700 ~ 0x27FF:用于标识计量单位。
l 0x2800 ~ 0x28FF:用于区分属性类型。
l 0x2900 ~ 0x29FF:用作特性描述。
l 0x2A00 ~ 0x7FFF:用于区分特性类型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。