概述
目录
1 说明
2 参考
2.1 函数基本说明
2.2 逻辑说明
3 应用程序的处理
3.1 事件通知消息说明
3.2 代码示例
1 说明
本文旨在用wpa_supplicant提供的API控制wifi模块以STA工作模式连接热点。wpa_supplicant程序一般运行在后台(./wpa_supplicant -B -cwpa_0_8.conf -iwlan0),用户通过它提供的接口让它做各种连接操作。
2 参考
http://w1.fi/wpa_supplicant/devel/wpa__ctrl_8h.html#a4e48c0a662d9150ea603e75365748b0b
wpa_supplicant-devel.pdf
https://www.kancloud.cn/alex_wsc/android-wifi-nfc-gps/414067
2.1 函数基本说明
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
打开wpa_supplicant的一个控制接口,参数ctrl_path一般为/var/run/wpa_supplicant/wlan0,wlan0为对应的网络节点。成功时返回控制结构体指针,后续的一系列函数都以该指针为参数。失败时返回NULL。
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
注册一个事件通知监视器。成功时返回。失败时返回-1。超时则返回-2。该函数成功之后,可以通过wpa_ctrl_pending和wpa_ctrl_recv处理事件通知。
int wpa_ctrl_pending(struct wpa_ctrl *ctrl);
检查是否有待处理的事件通知,如果有返回1,没有返回0,出错返回-1。
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
接收一条待处理的事件通知,将内容保存在reply指向的空间,内容的长度保存在reply_len指向的空间。
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
char *reply, size_t *reply_len,
void (*msg_cb)(char *msg, size_t len));
发送一条命令给wpa_supplicant。cmd和cmd_len描述该条命令。reply和reply_len用于保存本次命令的响应。msg_cb一般为NULL即可。成功时返回0,出错(发送或接收失败)返回-1,超时则返回-2。
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
注销事件通知监视器。成功时返回0,出错返回-1,超时则返回-2。
void wpa_ctrl_close(struct wpa_ctrl *ctrl);
关闭控制接口。
2.2 逻辑说明
wpa_supplicant处理命令的结果分成两种:状态信息和事件通知。状态信息可以理解成命令的响应很快,可以立即拿到结果,比如"PING"、"LIST_NETWORKS"、"STATUS"、"ADD_NETWORK"、
"SET_NETWORK"、"ENABLE_NETWORK"、"SAVE_CONFIG"等,成功时能立即返回并将结果保存在相应的函数参数中。事件通知可以理解成异步事件,比如发送了"ENABLE_NETWORK",该命令能成功且立即返回,但连接热点的过程比较复杂且耗时较长,连接是否成功则通过事件通知告诉用户。
3 应用程序的处理
找出跟wpa_cli相关的文件,将这些文件做成库文件
通过查看编译过程信息,结合makefile,找到了wpa_cli相关的源文件,将这些源文件编译成库文件。在makefile中的wpa_cli: $(OBJS_c)下面添加一行
AR -crv wpa_cli.a $(OBJS_c),AR的值由开发环境决定,如arm-himix100-linux-ar,即可得到想要的库文件。
应用程序使用上述生成的wpa_cli.a和wpa_supplicant包中的wpa_ctrl.h即可控制各种连接操作。
3.1 事件通知消息说明
热点连接成功或者失败的响应消息依赖于驱动程序的实现,比如用户给出错误的SSID或密码不能连接时的打印:
WPA: 4-Way Handshake failed - pre-shared key may be incorrect
CTRL-EVENT-DISCONNECTED bssid=ec:41:18:45:06:5a reason=0
连接成功时的打印:
CTRL-EVENT-CONNECTED
发送命令太频繁会导致消息紊乱,可能导致wpa_0_8.conf内容不完整,
所以建议不要自动发送命令,等待用户通过GUI调用API发送命令或者需要某个功能时才发送命令。
3.2 代码示例
通过函数user_wifiConnectAP_func连接指定的wifi热点(pu8EncryptType可以为NULL),通过线程user_wifiHdlEvent_thread不断地监听事件通知。
int user_wifiConnectAP_func(char *pu8SSID, char *pu8Secret, char *pu8EncryptType)
{
char au8ReplyBuf[2048] = {"