基于wpa_supplicant库的WIFI连接功能实现--wpa_cli命令代码改写
来源:互联网 发布:考研英语时间分配知乎 编辑:程序博客网 时间:2024/06/03 19:34
上一篇博客我们一起看了怎样使用wpas的命令后,接下来就利用这些命令来实现我们的代码。这些命令的实现都在wpa_cli.c文件中,以status命令为例,发生如下调用:
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[]){ int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0; return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");}
wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd) _wpa_ctrl_command(ctrl, cmd, 1); char buf[2048]; wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,wpa_cli_msg_cb); if (print) printf("%s", buf);
从上面可以看出,最终是调用wpa_ctrl_request函数完成命令,而最终结果是存在buf里,通过函数参数print来觉得是否输出到终端。所以我们最终需要取得的结果就是buf,只要拿到buf内容,我们就可以分析其内容实现我们需要的代码。为了实现上述目的,需要对源码进行下修改:我们把输出buf作为参数传入_wpa_ctrl_command函数,这样就可以拿到输出内容了。改写后代码如下:
static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *buf, const char *cmd){ return _wpa_ctrl_command(ctrl, buf, cmd, 0);}
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *buf, const char *cmd, int print){ char ret_buf[2048]; int ret; size_t ret_len; ret_len = sizeof(ret_buf) - 1; ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), ret_buf, &ret_len, wpa_cli_msg_cb); if (ret == -2) { printf("'%s' command timed out.\n", cmd); return -2; } else if (ret < 0) { printf("'%s' command failed.\n", cmd); return -1; } ret_buf[ret_len] = '\0'; memcpy(buf, ret_buf, 2048); if (print) { ret_buf[ret_len] = '\0'; printf("%s", ret_buf); } return 0;}
static void wpa_cli_msg_cb(char *msg, size_t len){ printf("%s\n", msg);}
对于各个命令呢,我们同样需要加入buf,还是以status为例:
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, char *buf, int argc, char *argv[]){ int verbose = argc > 0 && strcmp(argv[0], "verbose") == 0; return wpa_ctrl_command(ctrl, buf, verbose ? "STATUS-VERBOSE" : "STATUS");}
这样各个命令就达到了我们的目的。最后我们对命令进行一下封装,方便统一管理。
#define CFG_MAXARGS 10/** * @brief 对wpa_supplicant中处理命令进行封装 */class HanleCmd : public QObject{ Q_OBJECTpublic: HanleCmd(); void printCmd(); int hanleCmd(struct wpa_ctrl *ctrl, char *buf, char *cmd);private: //命令封装 struct wpa_cli_cmd { const char *cmd; //命令名称 int (*handler)(struct wpa_ctrl *ctrl, char *buf, int argc, char *argv[]); //命令处理函数 }; QList<wpa_cli_cmd> listCmd; //命令链表 //私有函数 void addCmd(); int wpaRequest(struct wpa_ctrl *ctrl, char *buf, int argc, char *argv[]); int parseLine (char *line, char *argv[]);};
HanleCmd::HanleCmd(){ qDebug("init cmd list"); addCmd();}
void HanleCmd::addCmd(){ struct wpa_cli_cmd cmd; //状态命令 cmd.cmd = "status"; cmd.handler = wpa_cli_cmd_status; listCmd.append(cmd); //扫描命令 cmd.cmd = "scan"; cmd.handler = wpa_cli_cmd_scan; listCmd.append(cmd); //扫描结果命令 cmd.cmd = "scan_results"; cmd.handler = wpa_cli_cmd_scan_results; listCmd.append(cmd); //选择AP命令 cmd.cmd = "select_network"; cmd.handler = wpa_cli_cmd_select_network; listCmd.append(cmd); //增加AP命令 cmd.cmd = "add_network"; cmd.handler = wpa_cli_cmd_add_network; listCmd.append(cmd); //列出配置文件中已经保存的AP信息 cmd.cmd = "list_network"; cmd.handler = wpa_cli_cmd_list_networks; listCmd.append(cmd); //设置AP cmd.cmd = "set_network"; cmd.handler = wpa_cli_cmd_set_network; listCmd.append(cmd); //移除AP cmd.cmd = "remove_network"; cmd.handler = wpa_cli_cmd_remove_network; listCmd.append(cmd); //使能某个AP cmd.cmd = "enable_network"; cmd.handler = wpa_cli_cmd_enable_network; listCmd.append(cmd); //关闭某个AP cmd.cmd = "disable_network"; cmd.handler = wpa_cli_cmd_disable_network; listCmd.append(cmd); //保存配置 cmd.cmd = "save_config"; cmd.handler = wpa_cli_cmd_save_config; listCmd.append(cmd);}
int HanleCmd::parseLine (char *line, char *argv[]){ int nargs = 0; while (nargs < CFG_MAXARGS) { /* skip any white space */ while ((*line == ' ') || (*line == '\t')) { ++line; } if (*line == '\0') /* end of line, no more args */ { argv[nargs] = NULL; return (nargs); } argv[nargs++] = line; /* begin of argument string */ /* find end of string */ while (*line && (*line != ' ') && (*line != '\t')) { ++line; } if (*line == '\0') /* end of line, no more args */ { argv[nargs] = NULL; return (nargs); } *line++ = '\0'; /* terminate current arg */ } return (nargs);}
int HanleCmd::hanleCmd(struct wpa_ctrl *ctrl, char *buf, char *cmd){ int argc; char bufTmp[1024]; char *argv[CFG_MAXARGS]; strncpy(bufTmp, cmd, 1024); bufTmp[1023] = '\0'; argc = parseLine(bufTmp, argv); return wpaRequest(ctrl, buf, argc, argv);}
封装完毕后,只需要在执行某个命令时候调用如下代码即可:
char buf[2048];handleCmd->hanleCmd(ctrl_conn, buf, "status");
这样buf中存入的就是status命令的结果了。
至于参数中的ctrl_conn是底层的操作接口,需要读者自己去分析下wpa_cli的源码,这里只贴一下代码:
int WifiService::initWpa(){ qDebug()<<"initWpa"; //1.变量初始化 int conectNum = 0; ctrl_iface = NULL; ctrl_conn = NULL; monitor_conn = NULL; ctrl_iface_dir = strdup("/var/run/wpa_supplicant"); //2.与wpa_supplicant建立连接 while(true) { wpa_cli_get_default_ifname(); if(ctrl_iface == NULL){ qDebug("failed to wpa_cli_get_default_ifname"); return -1; } wpa_cli_open_connection(ctrl_iface); if (ctrl_conn || monitor_conn){ //ActionThread未启用情况下只用ctrl_conn就可以 qDebug("wpa_supplicant connection established"); break; }else{ if(conectNum++ >=2){ //最多试三次 qDebug("wpa_supplicant connection established err"); return -1; } qDebug("wpa_supplicant connection established err, we will try agin"); usleep(10000); continue; } } return 0;}
0 0
- 基于wpa_supplicant库的WIFI连接功能实现--wpa_cli命令代码改写
- 基于wpa_supplicant库的WIFI连接功能实现--wpa_cli命令解析
- 基于wpa_supplicant库的WIFI连接功能实现--wifi扫描功能实现
- 基于wpa_supplicant库的WIFI连接功能实现--应用层碎片式对象内存管理算法
- wifi连接wpa_supplicant和wpa_cli的使用实例
- Wpa_supplicant与wpa_cli实现wifi调试的无线配置
- wifi,WLAN,wpa_supplicant,wpa_cli
- wpa_cli与wpa_supplicant的交互命令
- wpa_cli 连接 wifi
- 运用wpa_cli连接wifi
- wpa_cli 连接wifi
- wpa_supplicant & wpa_cli
- wpa_supplicant/wpa_cli
- 有关wifi配置工具wpa_cli以及wpa_supplicant简单分析
- wpa_cli 命令连接网络过程
- Android 下使用wpa_cli 连接 wifi
- Android 下使用wpa_cli 连接 wifi
- 【转】Android 下使用wpa_cli 连接 wifi
- 三个二维数组的比较
- 汽水瓶
- Big-Endian and Little-Endian Test in ARM and PowerPC SoC
- java面试经常遇到的
- Android ContentProvider 完全解析及简单DEMO
- 基于wpa_supplicant库的WIFI连接功能实现--wpa_cli命令代码改写
- CSS伪类before,after制作左右横线中间文字效果
- fastjson 序列化枚举问题
- 使用contiperf进行压测
- RxJava的坑
- 【Github教程】史上最全github使用方法:github入门到精通
- 希望zf 严厉整一下百度,不能只是收钱就给谁都做广告
- php编译安装添加pdo_mysql.so扩展
- Android中常见的adb命令