背景
- 首先贴上官方github地址https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library
- 本次修改基于官方SDK 2.4.1版本.
- 阅读此文章之前,我们默认您对蓝牙mesh协议已经有了一定了解.
- 本次修复了一个问题,该问题是关于设备节点扫描唯一性进行判断的一个优化.
问题分析
此问题的根源是发现设备偶尔不能控制发现的问题,进过一系列排查,发现最后导出来的mesh json节点数据中uuid并不是我们配网时候出现的uuid.下面展示部分mesh json数据:
我们配网的时候出现的uuid是DD70开头的,然而最后导出的时候出现的uuid是01A8开头的.
为什么会出现这个问题?
经过排查,原来固件在触发配网的时候同时会发两个becon包,一个包是我们需要的uuid,另一个是我们不需要的(比如我们业务出现的是天猫精灵的becon包).问题就在于我们在扫描节点的时候,SDK判断节唯一性的逻辑上是根据mac地址进行判断的,很明显,这两个包的mac地址都是同一个,所以uuid会随机被赋值一个.因此才会出现uuid对应不上的问题.
我们贴出最后进行设备唯一性判断的代码:
fun matches(scanResult: ScanResult): Boolean {
return device?.address == scanResult.device.address
}
从上面代码可以看出,很明显,只要mac地址相同,就会被认为是同一个设备.因此,如果一个设备同时发两个配网becon包,那么就会出问题了.
修改内容
找到问题的根源,那么解决办法就很容易想到了,我们只要修改一下比较的方法就可以区分一下,同一个设备发出的两个becon包了.
/**
* match with address and uuid
*/
fun matches(scanResult: ScanResult, resultBeacon: MeshBeacon?): Boolean {
var deviceUUID = beacon?.beaconData?.let { UnprovisionedBeacon(it).uuid.toString() }
var resultDeviceUUID = resultBeacon?.beaconData?.let { UnprovisionedBeacon(it).uuid.toString() }
return device?.address == scanResult.device.address
&& deviceUUID == resultDeviceUUID
}
我们添加了一个重载方法,加入了一个参数,用来传入uuid,我们在比较mac地址的同时,再对uuid进行一下比较,来确认它是唯一的配网becon就可以解决上述问题了.
因此,问题得到迎刃而解.
如果任何疑问,请联系邮箱:569133338@qq.com