BLE传输WiFi列表的问题分析

背景

BLE配网过程中,最重要的一个环节是通过BLE给手机上报设备扫描的WiFi列表信息,手机展示WiFi列表。在这个上报过程中,用户或测试反馈存在WiFi列表接收或显示异常,中文乱码等各种问题。

下面对上述问题进行分析和总结,并给出相关的优化方案。

WiFi列表上报

WiFi列表上报指WiFi设备将扫描到的路由器或热点信息,上报给手机APP的过程。下面介绍下BLE配网的方式。

图1、设备WiFi扫描拓扑图

WiFi列表信息上报的过程包括以下几个方面。

  1. WiFi设备对周边环境进行WiFi信号扫描,收集路由器(或者AP)信息,每个路由器信息包括SSID(WiFi名称),RSSI(信号强度),mode(加密模式),bssid(WiFi唯一识别码,每个SSID不同,一般使用WiFi的MAC地址)。
  2. WiFi设备将扫描到的路由器信息,可能是20个或者30个,统一发送给BLE,这个过程中不对WiFi列表信息进行解析。
  3. BLE将路由器信息,按照SSID,RSSI,Mode,BSSID等内容进行JSON格式组合,具体内容不做解析,只做合法性校验,比如SSID的长度是否超过允许最大长度等。
  4. BLE将JSON格式的WiFi列表信息上报给手机。手机接收到BLE发送的路由器信息,进行JSON格式解析,并且展示WiFi列表。

图2、WiFi列表上报链路

中文乱码问题

路由器前期由于需要兼容性老版本window系统的中文格式(GB2312),老的路由器对中文编码并不统一,存在使用GB2312的编码格式。目前新的路由器,基本上都已经使用UTF-8对中文进行编码,一个中文汉字占用3个字节,路由器名称最大可输入10个汉字。

这种中文不同编码方式,只由路由器本身决定,即中文使用GB2312格式的路由器,不管使用任何终端进行设置都是这种编码。

xxAPP demo验证只支持UTF-8的中文显示,ANSI格式中文显示乱码。但是对于手机默认的蓝牙扫描不会存在中文乱码的情况,因此实际上xxAPP对ANSI编码的中文支持即可。

模拟测试

基于上述的路由器编码背景,实际测试只需要考虑UTF-8和GB2312的中文编码即可。

UTF-8编码格式测试

BLE模拟上报的WiFi的SSID的中文使用UTF-8格式。SecureCRT字符编码使用UTF-8,SSID内容可以正常显示。

xxAPP demo显示UTF-8中文编码正常和CRT上显示相同。

ANSI或GB2312编码格式测试

GB2312是ANSI编码的一种,对ANSI编码进行扩充,支持中文汉字。

如果BLE模拟的WiFi SSID使用ANSI编码格式,默认Window中文格式,进行发送SSID内容"CMC-ansi中文测试网络显示乱码测试",长度是32字节。

SecureCRT字符编码使用UTF-8,SSID内容不可以正常显示,只能显示"CMC-ansi",无法显示中文。

SecureCRT字符编码使用default或GB2312,SSID内容可以正常显示,同时UTF-8的中文显示乱码。验证使用GB2312的编码可以正常解析对于的中文信息。

xxAPP demo上UTF-8的中文显示正常,ANSI格式的中文显示乱码。这里也可以验证xxAPP不支持ANSI格式的中文,只支持UTF-8的中文显示。

手机WiFi列表异常问题

异常问题包括列表获取异常和列表展示异常2个方面的问题。为了验证这两个问题需要借助2个不同的APP,一个是xxAPP demo,一个是xx正式APP。

xxAPP demo只有简单的功能测试,没有用户UI界面和应用层逻辑,可以查询APP接收到的原始数据,一般用于调试APP的底层SDK功能。

xx正式APP就是正式发布版本的APP,和用户使用的APP一样。

列表获取异常

对极端的SSID进行测试验证,包括最大长度的SSID,ANSI格式的中文等情况测试。实际测试发现,只要JSON格式的长度正确,测试的APP demo都可以正常接收WiFi列表。测试过程中,如果设备的bssid信息是NULL的情况下,设备可能存在JSON长度计算错误的问题,这种情况导致APP demo获取异常。其他情况下,测试均正常。设备端对该缺陷修复后,APP demo接收WiFi列表正常。

SecureCRT上编码显示存在问题,如果11个汉字UTF-8显示长度是33字节,如截断32字节,即最后一个字节不能正常显示。这种情况下,SecureCRT显示错误,但是手机app可以正常显示。因此在不同编码方式下,SecureCRT的显示同样可能存在缺陷,这点调试也需要注意下。

列表展示异常

验证完成获取异常问题后,进一步使用xx正式APP验证WiFi列表的显示问题。由于xx正式APP展示WiFi列表需要正式的入网流程,但是测试过程中可能只是BLE的模块,并非是正式的产品。

使用发布版本xx云视频APP验证蓝牙配网方法:

1、测试demo中使用支持蓝牙配网的量产设备的序列号和验证码作为本地认证参数,这样APP就能根据序列号在云平台上正常查询到设备的能力集,走正式蓝牙配网流程;

2、由于demo板没有二维码,所以需要在APP上手动输入设备序列号,方法:扫一扫/添加设备 -> 点击右上角图标 -> 手动输入设备序列号,点击确认;

通过上述的方式,在正常的情况下,WiFi列表都可以展示出来,注意BLE上报的WiFi列表都是BLE模拟测试的WiFi信息。

在系统测试过程中,手机端出现无法解析特殊字符的问题,例如特殊SSID字符,如" !@#$$%^&*()_-=+?~{[[<.<>]};\",经过排查和验证测试,由于设备端使用手动拼接JSON字符的原因,导致部分需要转译的符号没有转译。 如上述字符中"\"是实际用户需要展示的符号,按照JSON格式需要进行转译"\\",但是手动拼接并没有考虑这个问题。所以手动拼接的JSON字符串,使用标准的JSON解析库上无法解析,导致WiFi列表拉取失败。

图1,手动拼接JSON

图2,JSON库生成

类似的需要转译的字符串还包括如下一些字符,因此后期设备上不再使用手动拼接JSON,而使用JSON标准库进行自动生成和校验。

但是这种情况下,手机APP demo是可以正常接收WiFi列表,但是实际上这个WiFi的列表的JSON是异常的格式。所有对这个异常格式,APP在展示时会对这个JSON进行解析,这时候会出现JSON格式错误,导致无法正确展示,从而出现APP展示WiFi列表失败。

解决方案

  1. 设备端使用JSON库进行JSON生成;解决JSON长度不对,格式不对,没有转译的问题。
  2. 设备测试代码增加JSON特殊字符,尤其是转译字符测试,中文字符,异常bssid,空ssid等情况进行异常测试;
  3. 设备端JSON接收端,增加JSON正确性检查。前期只关注JSON数据,对于准确进行人工检查,对于转译错误情况并不能测试覆盖。

测试如下:

JSON手动拼接,没有转译的情况,JSON格式检查失败。

JSON自动生成,自动转译,JSON格式检查通过。解析JSON所有信息,并进行打印展示。

方案优化

根据上述情况,BLE对于WiFi列表传输都使用标准的JSON库。在本地验证时候,由于JSON库在使用过程中都是malloc内存,因此在测试过程中难以察觉内存最大使用情况。

用户问题反馈如下,在WiFi列表获取时,可以使用内存在7KB左右,但是只有进行WiFi列表获取立即出现malloc分配异常,问题必现。

因此在本地使用相同的WiFi测试列表,即上述的模拟WiFi的测试数据,如果使用JSON库组合后再进行传输,确认内存使用情况,Malloc内存分配最高峰可以达到10KB左右(20个WiFi列表)。

因此对于内存资源不足的芯片,可能无法正常使用,例如bl702l芯片应用使用过程中,剩余内存可能不到10KB,因此可能无法正常使用。因此对于应用内存小于15KB的情况,不推荐使用JSON库发送WiFi列表,只能使用手动拼接JSON数据,同时需要对特殊字符进行转译。手动JSON拼接,同时增加特殊字符转译和可以通过JSON解析测试验证,但是这种还是存在未知风险。

WiFi列表目前是用户通过调用设备端WiFi扫描接口获取附近的WiFi热点,然后再将扫描到的WiFi列表信息,如20个WiFi热点信息,使用定义的结构体方式传入BLE的发送接口。由于BLE上报列表给手机,方便手机端解析和使用,所以BLE会将传入的WiFi列表信息全部转换成约定的JSON格式。

但是这个过程中,就如上诉描述,内存充足的情况下,推荐直接使用JSON库。但是对于只有BLE功能的芯片,大部分剩余内存不足,还是需要使用手动拼接JSON的问题,同时还要考虑特殊字符转译。这个过程中,手动拼接的过程和转译比较容易出现考虑不足和引入缺陷。

WiFi目前主要有2种方式,一种是常电透传模块,另一种是IOT-WiFi模块,这两种情况下,基本上都默认自带JSON库,同时也在使用JSON库相关功能。因此JSON库组装和解析部分建议合并到WiFi(IOT本身或者CPU主机上)这边比较合适,这样总体方案来说,可以有效降低内存消耗,BLE端无需再进行JSON拼接消耗多余内存,WiFi或主机端也不会增加额外内存消耗。这种情况下,BLE拿到WiFi列表信息直接将数据透传给手机即可。

总结

从前期的WiFi列表接收异常到展示异常,前期注意问题还是手动JSON格式拼接存在缺陷,要不就是拼接长度不对,要不就是没有考虑特殊字符转译。

目前通过JSON库拼接WiFi列表解决问题,目前在IPC,bl618等平台上可以正常使用。但是在单BLE的IOT模块上,使用JSON库内存可能存在问题,对于多连接的情况下,应用在实际使用中内存往往不到10KB,这种情况还是需要手动JSON拼接,以及字符转译等问题。

从方案来看,后期可以通过方案优化,将JSON数据组合和解析全部放到主机上进行,BLE只对数据进行透传,这样可以预留更多的内存让应用使用。

附录

关于JSON库组合JSON包消耗内存分析。JSON数据创建中每个字段都会创建一个JSON头结构体,结构体的长度40字节。举例,如果创建下面一个JSON结构体{"ssid":"CMCC-utf8中文测试网络","rssi":-22,"mode":4,"bssid":"11:22:33:44:55:66"}

  1. 创建JSON,结构体长度40字节;
  2. 创建第一个key-value键值对,即"ssid":"CMCC-utf8中文测试网络"。JSON头申请40字节,"ssid"字符创建申请5个字节,"CMCC-utf8中文测试网络"字符串申请28字节,一共申请40+5+28=73字节。
  3. 创建第二个key-value键值对,即"rssi":-22。JSON头申请40字节,"rssi"字符创建申请5个字节,一共申请45字节。
  4. 创建第三个key-value键值对,即"mode":4。JSON头申请40字节,"mode"字符创建申请5个字节,一共申请40+5=45字节。
  5. 创建第四个key-value键值对,即"bssid":"11:22:33:44:55:66"。JSON头申请40字节," bssid "字符创建申请6个字节,"11:22:33:44:55:66"字符串申请18字节,一共申请40+6+18=64字节。
  6. 按照上述理论分析最少需要申请的内存是40+73+45+45+64=267字节。

但是实际测试发现申请的内存大于上述的理论计算的内存??对内存申请进一步分析和确认,由于FreeRTOS中使用了pvPortMalloc接口申请内存,存在内存对齐情况,默认使用8字节对齐,62位系统使用16字节对齐。申请的内存+内存申请头(16字节),然后再进行8字节对齐。

上述的JSON头结构体时间大小是40字节,实际申请内存如下。

申请40字节内存,实际申请40+16=56,刚好是8字节对齐,因此申请56字节。

申请5字节内存,实际申请5+16=21,再进行8字节对齐,因此申请24字节。

所以上诉JSON格式实际申请内存56+(56+24+32)+(56+24)+(56+24)+(56+24+40)=408字节

上诉的JSON格式是一个WiFi热点的信息,一般情况下一次传输20个WiFi信息,即需要分配的大小是408*20=8160字节,因此再加上外部的JSON头以及JSON数据打印输出,整体占用内存超过10KB。

相关推荐
灰子学技术4 小时前
Envoy与Istio HTTP流量故障转移机制介绍
网络·网络协议·http·云原生·istio
Coisinilove4 小时前
数通第一次培训(10.13)
网络·数通·现代网络通信
Trouvaille ~4 小时前
【Linux】TCP可靠性与性能优化详解:从确认应答到拥塞控制
linux·运维·服务器·网络·tcp/ip·性能优化·操作系统
kuankeTech13 小时前
“数改智转”加速跑:外贸ERP助力钢铁智能工厂“提质增效”
大数据·人工智能·经验分享·软件开发·erp
IT利刃出鞘14 小时前
SSL证书--手动生成自签名IP证书
网络·网络协议·ssl
wanhengidc14 小时前
私有云具体是指什么
服务器·网络·游戏·智能手机·云计算
一个人旅程~16 小时前
Linux Fcitx5输入法这么难念的由来?
linux·经验分享·电脑·ai写作
开开心心就好16 小时前
一键加密隐藏视频,专属格式播放工具
java·linux·开发语言·网络·人工智能·macos
末日汐17 小时前
TCP编程简单回显服务
服务器·网络·tcp/ip