由于之前没接触过PC上蓝牙编程,走了很多弯路。
1 自定义功能不可占用系统服务。
最初客户设备的蓝牙功能特征在1812服务下,结果发现在代码每次连接服务都报错,问客户说没有问题,设备连接手机时是正常,于是自己反复尝试,并找了些蓝牙的测试demo,后来使用沁恒的蓝牙测试程序发现,该服务是不能访问的,于是询问客户,把功能的服务使用自定义的服务试下,客户更换了设备的服务后,连接正常。
2 访问遍历sevice下特征崩溃
开始使用的qt自带的蓝牙库,编写完代码,访问特征获取数据都是正常的。但客户在测试时,每次都是崩溃。后来有次更新设备固件,自己删除了电脑上的蓝牙设备并重新匹配后,发现程序也会崩溃,于是使用沁恒的demo测试,发现通信是正常的,之前再用我的程序测试时,发现又是正常的。反复实验,发现在使用沁恒测试demo对我们使用的特征做notify监听后,我的程序就能正常使用。在新匹配的设备时,debug发现是调用ble service的discoverDetails函数后,获取服务特征时崩溃。查了许多资料,也没找到原因,于是准备弃用qt自带的蓝牙接口。
3 使用沁恒的lib wchbleldll
即然沁恒的demo对新加的设备是正常的,那就用他们的库试下,但刚开始,就发现一个问题。wchbledll在查找设备时,只能查找没有在系统连接上的设备,对于已经匹配的设备则无法获取。于是又开始查资料,自己写了个获取蓝牙设备的函数,并过滤为取当前已连接上的设备,用这个获取的设备id来调用wchbledll的接口,至此,一切正常。
4 win7和win11的适配。
问题总在以为大功告成时出现。
首先,有人测试出程序在win7上启动崩溃,这是由于win7没有蓝牙,接口调用导致崩溃。增加windows版本判断,win7上不调用蓝牙接口。
后来,又发现,在win11上程序使用蓝牙会卡死。由于我个人没有win11环境,于是写了个测试程序,调用wchbledll的每个接口,让在win11上测试,结果发现在调用WCHBLEOpenDevice会卡住,但单独使用wchble的demo在win11上又是没问题的。后来以沁恒社区发现有人提出过同样问题qt中调用open函数会导致卡死,沁恒技术同学给出了新的dll供其测试,于是我也留言要了一份新的dll, 但测试结果并未改善。
5 blewinrtdll
找了许多示例,结果除了把VS开发环境不断升级sdk外,并没有解决问题。忽然想到,最初枚举蓝牙设备是参考的blewindll的开源代码,只是由于其读取数据接口不理想才放弃的,何不自己加个数据监听接口试下呢。
于是仿照其读特征数据的接口自己写了个回调的接口,但测试发现,我每次监听特征时,调用GetCharacteristicsForUuidAsync 获取特征都会失败,返回accessdenied,在stackoverflow上发现了答案,GetCharacteristicsForUuidAsync只允许调用一次,后面使用时需要自己做缓存。后面也有人说,可以用dispose来解决这个问题,但我看微软的文档中有这个接口,但在自己代码时调用,却编译不过,提示没有这个接口。于是又升了一波VS,结果还是不行,倒把自己电脑C盘空间占满了。检查自己代码,在监听特征前,有做查询特征的操作,所以后面蓝听时,再次获取特征就报错了,于是修改在查询时,缓存发现的特征。再监听时直接使用。改好测试程序后,在win11上一试,果然不再卡了.
小结
之前没弄过PC上蓝牙的开发,许多东西其实多与别人沟通一下就可能有结果的,但开始总以为自己的代码哪里少写了什么,反复查代码浪费了许多时间。其次,感觉windows蓝牙编程的资料好少,资料查找十分困难。最后,自己写的蓝牙接口功能太少,不过这段时间修这个蓝牙问题修的有点厌倦了,后面有机会再搞。