招标项目对接过程中的问题解决过程,特此记录分享。
最开始按照招标方SDK的相关接口和注释,实现关于ssl、wifi、和无线的代码。
收款机的开机流程:根据配置信息决定是采用无线还是wifi上网,连接好网络之后验证机器是否绑定,如果绑定则 显示按键收款界面,否则显示绑定二维码页面,在此页面使用商户账号扫码后即可完成绑定流程,与服务器交互将绑定信息加密写入至文件系统。最终完成绑定进入按键收款界面。
同时机器为了能进行收款播报,需要使用MQTT连接腾讯的服务器。而本次招标方关于通讯的问题重点就是MQTT的2个问题。
1:MQTT连接不上。
2:MQTT连接上去后会经常断开。
首先先说明下问题的难点:
1:招标方对接的人提供的帮助几乎没有。
2:SDK代码庞大,短期查看学习很耗时间。
3:编译下载过程慢,整个过程需将近5分钟。
4:测试麻烦,由于只借到一个商家号,一次只能测一台机器。
5:wolfSSL相关问题百度基本找不到。
6:招标方的SDK接口注释不详细。
MQTT采用的是SSL PSK方式上网,关于psk可以简单看看这篇文章,https://blog.csdn.net/mrpre/article/details/79337506
那么首先排查的方法便是查看我们的输入参数是否正确。
基本的排查便是将输入参数打印出来,看是否有明显不对的地方。
然后便是查看psk这个函数的调用关系。分析psk函数的参数如何获取的。
仔细分析后发现psk函数的参数是在绑定的时候写入文件中,后续开机从文件中读取绑定信息中的一个参数,再将此函数进行base64解密得到psk值,那么我该如何确认这个参数是对的呢,将绑定信息的写入和读取过程都打印出来,对比看是否信息不一致,再将加密内容使用在线解密工具解密对比程序的解密是否不一致。
但后面分析这些参数应该是没有问题的,毕竟此SDK已经量产过。
那么接下就是开始怀疑是不是woflSSL并没有配置此功能,询问了相关人员一遍后发现以前从未使用过PSK的方式进行通讯。
于是接下来就有2种方式同时进行分析:
1:移植最新版的wolfSSL。
2:使用官方的示例程序测试。
移植最新版的wolfSSL,看是不是旧版的不支持PSK功能,因为查看了git的修改日志,新版的有很多关于PSK的修改项。但此方案在耗费很多时间移植修改了大量代码后编译却不成功,于是就此放弃了。
此时问了一下招标方的对接人员,只提供了一点点信息:PSK通讯的协议版本是1.1,并且需要支持psk的加密方式
但我看了一下官方的wolfSSL库是有采用psk方式联网的示例程序,而且也在程序中看到相对应的代码,细心查看之后发现是没有开启PSK的一个宏定义。于是将其打开后重新编译。结果显然还是不可以。
好在wolfSSL官方的程序文档比较完善,决定参考相应的文档和示例程序自行在linux平台搭建一个PSK的服务端和客户端进行测试。也进行了抓包分析。大致的过程就是客户端在client hello的时候将自己所支持的所有加密方式发送给服务端,服务端收到后在其中选择一个,并回复server hello。
所以这时候将之前打开了PSK宏的程序进行抓包,发现客户端发了一大堆加密方式,但server hello返回的加密方式不是psk加密。于是怀疑是否是客户端发送的加密方式太多导致的。最终修改代码仅发送psk的加密方式后终于连接上了MQTT服务器。
接下来便是第二个问题,MQTT频繁断开连接。此问题相对第一个问题好解决一点。抓日志发现MQTT总是莫名的调用了断开连接函数,初步分析是由于传入的超时时间100ms过短导致tls_read函数读取不到。于是在里面强行将超时时间改大。进过测试还是未解决。于是仔细分析SDK的MQTT代码,最终发现是因为read函数在读取超时时返回了读取超时导致。而SDK在收到超时后会执行断开连接过程。所以将read函数读取超时时返回了读取不到数据。从而解决了问题。此问题的根本原因是SDK提供的接口说明内容太过简单,而且刚好又有个timeout输入参数,被误导返回了错误的返回值。