#创作者激励#【FFH】OpenHarmony轻量化系统ANY技术实践 原创 精华
【本文正在参加2023年第一期优质创作者激励计划】
概述
ANY功能是一种华为私有的短数据通信功能,允许处于同一信道的2个Wi-Fi设备进行直接的点对点无连接通信。
ANY可以应用于智能开关控制灯泡、传感器数据采集、遥控器控制家用电器等无线控制场景。
ANY功能特点
- 每个设备可以选择一个接口(例如:wlan0或ap0)用于ANY报文的收发。
- ANY报文采用接口当前所在信道进行收发,和通信对端需要处于同一信道。
- 单个ANY报文最多可以支持250byte的用户层数据。
- 单个ANY设备最多支持同时和16个ANY对端设备进行通信,其中最多允许和6个对端进行加密通信。
- ANY设备可以收发ANY单播报文和ANY广播报文,不支持组播报文。
- ANY设备可以扫描发现附近的其他ANY设备。
环境
- OpenHarmony-3.1
- 润和hispark_pegasus Hi3861开发板
- DevEco Device Tool
- 串口调试助手
总体流程
总体流程为:
- ANY功能初始化
- 注册收发回调函数
- 创建收发线程T1处理收发回调(将收发回调函数用此线程完成,避免长期占用主线程)
- 进行ANY设备扫描
- 调用
hi_wifi_any_deinit
,去初始化ANY
1.初始化
首先设备需要完成STA或者SoftAP的初始化;再以此作为ANY收发通信的接口,初始化ANY功能。初始化ANY功能之后,ANY会采用其所在的信道进行通信,并采用MAC地址作为发送接收的地址。
- 对于SoftAP模式下,所在的信道就是创建的时候指定的信道
- 对于STA模式,若已连接到了SoftAP,所在信道为该SoftAP指定的信道
- 对于STA模式,若未连接,可以采用设置信道的API函数
hi_wifi_set_channel
给STA指定一个信道。
对于ANY功能初始化,步骤为:
启动STA或SoftAP
调用hi_wifi_any_init
,选择STA接口(wlan0)或AP接口(ap0)作为ANY通信接口
调用
hi_wifi_any_deinit
,去初始化ANY(关闭WiFi会自动关闭ANY)
对于初始化函数,返回值为0即执行成功,1则为执行失败
2.注册ANY收发回调函数
ANY设备能够与同信道的其他ANY设备进行通信。其中单个ANY报文最多支持250Byte的用户数据。支持加密通信或不加密通信,加密通信需要要求双方提前配置同样的16Byte长度密钥。
在通信前需要确保:ANY功能初始化,以及通信双方处于同一个信道
接受和发送回调函数同样是运行于驱动线程,建议新建一个线程T1(第三步骤)处理收发报文,所以回调函数内的任务只是将msg数据通过消息队列传到收发线程T1
- 实现接收回调函数&& 发送完成回调函数,
hi_wifi_any_recv_cb
&&hi_wifi_any_send_complete_cb
- 回调函数内调用
write_any_msg
函数,msg数据将会在收发线程T1里面处理 - 调用
hi_wifi_any_set_callback
向驱动注册回调函数,其中发送回调函数反馈发送结果(成功为1),若不需要该函数,注册时可以设置为HI_NULL
ANY只在当前信道通信,想要与其他信道设备通信,需要下调用切信道API
一个ANY设备支持和16个对端通信,最多6个对端加密通信,并且需要双方配置相同密钥。
接收回调函数的数据内存由驱动自行管理
3.处理子线程T1
由于接收回调、发送回调、扫描回调都不易过多占用主线程的运行,所以我们需要创建一个新的线程用于实现接收回调、发送回调、扫描回调的活。
创建线程&&线程实现:
真正的接收回调、发送回调、扫描回调(可参考文章末尾的源码):
4.ANY设备扫描
完成ANY初始化后,STA端可以进行设备的扫描:
- 首先实现
hi_wifi_any_scan_result_cb
扫描回调函数,用于处理扫描完成之后的结果。对于该回调函数,驱动传入的输入参数为发现的ANY设备的指针数组和数组元素个数,每个元素指向一个发现的ANY设备相关信息 - 调用
hi_wifi_any_discover_peer
,向驱动注册回调函数,并**启动一次ANY扫描
扫描过程中,发现的设备是SoftAP,则设备信息会包括SSID信息,STA则为空字符串
回调函数运行于驱动线程,不能阻塞或长时间等待,使用第三步骤的处理子线程T1进行处理。
单次扫描最多通过回调函数返回32个对端设备信息,回调函数传入的数组内存由驱动自行管理,在回调函数中不应释放。
5.加密
ANY设备支持加密通信,要求通信双方采用同样的16byte长度密钥进行加解密,一个密钥对应一个对端MAC地址,即采用该密钥加解密来自该MAC地址的ANY报文。用户应根据产品应用场景确定ANY设备之间如何产生和共享同样的密钥。
设备1和设备2的配对协商消息均是采用ANY报文。协商请求消息中携带了随机数R1,协商应答消息携带了随机数R2和Cookie值。参与协商的2个设备需要采用同样的预共享密钥PSK,设备获取到随机数R1和R2之后结合PSK生成一个临时密钥用于加密密钥协商消息。设备1采用该临时密钥加密密钥请求消息,密钥请求消息中包括来自设备2的Cookie和随机生成的密钥因子K1。设备2采用临时密钥解密消息之后验证Cookie是否正确,验证通过则回复密钥应答消息。密钥应答消息中包含随机生成密钥因子K2,并采用临时密钥加密。双方完成上述交互之后,通过随机数R1和R2、密钥因子K1和K2采用同样的算法生成用于通信的最终的密钥。
6.发送函数
向指定MAC地址的设备发送ANY数据
- mac:6字节长度目的MAC地址, 可为单播或者广播地址, 不支持组播地址.
- mac_len:MAC地址长度, 需为6字节.
- data:待发送数据的缓存地址.
- len:待发送的数据长度, 最大为250字节.
- seqnum:待发送的ANY帧的序列号,范围0-255.
效果
此样例连接后互相发送信息
这里可以看到AP端的mac地址为0x8e,STA端的mac地址为0x32
STA端扫描发现ANY设备:
互相发送信息:
对着附件的源码来读学到不少
这是功能是华为特有的吗
对学习多线程很有帮助
华为私有的短数据传输功能,目前也还没在其他地方见到过噢。
这个ANY连接比wifi连接快,反应速度比使用tcp快很多
感觉这个功能很适合智能家居
`hi_wifi_any_init`函数所属库代码在哪里呢,没有库怎么编译?
你好,API接口在hi_any_api.h,其文件目录已经在BUILD.gn内写出