Mesh网络抓包解析
- 准备
- 说明
- 配置
- 过滤
- 解密
- 分析
准备
1)nRF52840 Dongle
2)Mesh节点
3)手机作为配网器(苹果手机安装nRF Mesh APP)
说明
1)节点使用的例程目录:nrf5sdkformeshv500src\examples\light_switch\client
2)抓包使用的软件:Wireshark
3)抓包方法:使用Nordic的nRF52840 Dongle配合Wireshark对蓝牙设备抓包(BLE)
配置
先打开Wireshark,这时候能收到节点的未配网设备信标,在Device一栏选择自己的节点,避免抓到无效的数据。
在Debug模式下可以通过MCU寄存器看到设备地址,对应例程advertiser.c中的advertiser_address_default_get()函数:
然后通过set_gap_addr_type()函数修改之后就是实际的设备地址。
nRF Mesh APP的Settings中先使用Forget Network复位Mesh网络,然后在Applications Keys中生成自己需要数量的Appkey。
配置手机(既是节点,也是配网器)主元素的通用开关服务器模型订阅和发布地址如下:
通过手机(配网器)配置使未配网设备成为Mesh节点,配置其第二个元素通用开关客户端模型订阅和发布地址如下:
配置完成后如下:
另外说一下,只要不使用Forget Network复位Mesh网络,那么新配置的节点单播地址自动往上增加。这个时候通过按下按键发送Mesh消息,可以在Wireshark中抓到包:
可以看到网络层PDU因为经过加密和混淆处理,是看不到具体的数据的。
网络层PDU字段定义:
网络层PDU格式:
所以在抓到的包里面可以看到网络层PDU由IVI,NID,Obfuscated,Encrypted data和NetMIC组成。
过滤
通过Wireshark抓到的包比较多,输入(pbadv)||(provisioning)||(btmesh)||(beacon)可以对数据进行过滤。
解密
在抓到的Mesh包右键→协议首选项→Bluetooth Mesh→Mesh Keys,然后输入当前使用的NetKey和AppKey。
NetKey和AppKey可以通过App的Settings中获取:
同样也可以输入设备密钥DevKey,SRC Address输入的是设备的单播地址。
DevKey和SRC Address可以通过App的Network中选择对应节点获取:
分析
经过上面的处理,就可以对Mesh消息进行分析。
以上面这条消息为例,可以看到消息的序列号是20,源地址是4,目的地址是1,节点的单播地址是0x0003,所以它第二个元素的单播地址就是0x0004,手机(配网器)的单播地址是0x0001,所以其主元素的单播地址就是0x0001,这样就知道这条Mesh消息的流向。
访问层的操作码是0x8202,参数是0009010a。其中操作码为Generic OnOff Set,这个是SIG官方定义的:
通用开关模型的字段定义:
那么这条消息的意思就是开关状态设置为关,事务ID为0x09,渐变时间是0x01,延迟是0x0a。
TID:可以在应用层判断消息是否重复,每传输一次消息,TID的值就会增加1。在例程中的按键事件处理函数button_event_handler()中可以看到:
至于Transition Time和Delay参数,如果Transition Time参数存在,那么Delay参数也应该存在,如果Transition Time参数不存在,那么Delay参数也不应该存在。
渐变时间表示一个设备从一个状态转换为另一个状态的时间,长度1字节,低6位表示渐变时间的具体数值,高2位表示渐变时间的步长,字段定义如下:
其中渐变时间的具体数值,取值范围0x00至0x3E,定义如下:
渐变时间的步长定义如下:
根据抓到的包中值0x01,则步长为100ms,数值为0x01,结果为100ms;而延迟时间默认的步长是5ms,抓到的包中值0x0a,那么延迟时间就是50ms,和例程中定义的一致。
由于二进制状态不支持渐变,当转换为0x01 (On)时,转换开始时立即改变Generic OnOff状态,当转换为0x00 (Off)时,渐变时间结束时改变状态。我的理解就是可以通过渐变时间来控制灯延时熄灭,当关灯时,灯状态改变的时间比开灯时状态改变的时间多出来一个渐变时间。
当转换为0x01 (On)时:
当转换为0x00 (Off)时: