目录

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] = {"\0"};size_t reply_len;int ret;int i;int s32NetId = -1;char au8Path[128] = {"\0"};/* wpa_ctrl_open */sprintf(au8Path, "/var/run/wpa_supplicant/wlan0");g_pstWpaCtrl = wpa_ctrl_open(au8Path);if(g_pstWpaCtrl == NULL){printf("\x1b[31m""%s %d, wpa_ctrl_open failed:%s!\n""\x1b[0m", __FILE__, __LINE__, strerror(errno));return -1;}/* wpa_ctrl_request ADD_NETWORK */memset(au8ReplyBuf, '\0', sizeof(au8ReplyBuf));reply_len = sizeof(au8ReplyBuf)-1;ret = wpa_ctrl_request(g_pstWpaCtrl, "ADD_NETWORK", strlen("ADD_NETWORK"), au8ReplyBuf, &reply_len, user_msgCb_func);if(ret == 0){au8ReplyBuf[reply_len] = '\0';}s32NetId = atoi(au8ReplyBuf);/* wpa_ctrl_request SET_NETWORK */char au8SsidBuf[128] = {"\0"};snprintf(au8SsidBuf, sizeof(au8SsidBuf)-1, "SET_NETWORK %d ssid \"%s\"", s32NetId, pu8SSID);memset(au8ReplyBuf, '\0', sizeof(au8ReplyBuf));reply_len = sizeof(au8ReplyBuf)-1;ret = wpa_ctrl_request(g_pstWpaCtrl, au8SsidBuf, strlen(au8SsidBuf), au8ReplyBuf, &reply_len, user_msgCb_func);if(ret == 0){au8ReplyBuf[reply_len] = '\0';printf("\x1b[32m""%s %d, reply_len:%d, au8ReplyBuf:%s\n""\x1b[0m", __FILE__, __LINE__, reply_len, au8ReplyBuf);}else{return -1;}/* wpa_ctrl_request SET_NETWORK */char au8PskBuf[128] = {"\0"};snprintf(au8PskBuf, sizeof(au8PskBuf)-1, "SET_NETWORK %d psk \"%s\"", s32NetId, pu8Secret);memset(au8ReplyBuf, '\0', sizeof(au8ReplyBuf));reply_len = sizeof(au8ReplyBuf)-1;ret = wpa_ctrl_request(g_pstWpaCtrl, au8PskBuf, strlen(au8PskBuf), au8ReplyBuf, &reply_len, user_msgCb_func);if(ret == 0){au8ReplyBuf[reply_len] = '\0';printf("\x1b[32m""%s %d, reply_len:%d, au8ReplyBuf:%s\n""\x1b[0m", __FILE__, __LINE__, reply_len, au8ReplyBuf);}else{return -1;}/* wpa_ctrl_request ENABLE_NETWORK */char au8EnableBuf[64] = {"\0"};snprintf(au8EnableBuf, sizeof(au8EnableBuf)-1, "ENABLE_NETWORK %d", s32NetId);memset(au8ReplyBuf, '\0', sizeof(au8ReplyBuf));reply_len = sizeof(au8ReplyBuf)-1;ret = wpa_ctrl_request(g_pstWpaCtrl, au8EnableBuf, strlen(au8EnableBuf), au8ReplyBuf, &reply_len, user_msgCb_func);if(ret == 0){au8ReplyBuf[reply_len] = '\0';printf("\x1b[32m""%s %d, reply_len:%d, au8ReplyBuf:%s\n""\x1b[0m", __FILE__, __LINE__, reply_len, au8ReplyBuf);}else{return -1;}return ret;
}void *user_wifiHdlEvent_thread(void *arg)
{char au8ReplyBuf[2048] = {"\0"};size_t reply_len;int ret;char au8Cmdline[64] = {"\0"};while(1){if(wpa_ctrl_pending(g_pstWpaCtrl) > 0){char buf[2048];size_t len = sizeof(buf) - 1;if(wpa_ctrl_recv(g_pstWpaCtrl, buf, &len) == 0){buf[len] = '\0';if(strstr(buf, "CTRL-EVENT-CONNECTED") != NULL){sprintf(au8Cmdline, "udhcpc -i wlan0 -t 5 -T 2 -A 5 -q");system(au8Cmdline);/* wpa_ctrl_request SAVE_CONFIG */wpa_ctrl_request(g_pstWpaCtrl, "SAVE_CONFIG", strlen("SAVE_CONFIG"), au8ReplyBuf, &reply_len, user_msgCb_func);}}}}else{usleep(100000);}pthread_exit(NULL);
}

wpa_supplicant的控制接口简单说明相关推荐

  1. STM32单片机学习笔记(七)-RCC时钟控制:简单了解时钟树(一)

    写在前面:本系列内容均为自学笔记,参考资料为野火指南者开发板资料及芯片参考手册等,使用野火指南者开发板进行学习,该系列内容仅用于记录笔记,不做其他用途,笔记的内容可能会存在不准确或者错误等,如有大佬看 ...

  2. 微信分享后端接口简单实现

    微信分享后台接口简单实现 此接口大致的流程是:用户创建时间戳,随机字符串,当前需要分享的页面的url三个变量,接着将自己的appid和APPsecret作为请求参数获取access_token,再根据 ...

  3. 微信分享小功能后端接口简单实现

    微信分享后台接口简单实现 此接口大致的流程是:用户创建时间戳,随机字符串,当前需要分享的页面的url三个变量,接着将自己的appid和APPsecret作为请求参数获取access_token,再根据 ...

  4. Type-C接口简单介绍-面向单片机应用

    Type-C接口简单介绍-面向单片机应用 1.绪论 用单片机做一些东西时,Type-C接口逐渐替代了MicroUSB接口.但不像MicroUSB那样只有5V.GND.D+.D-.ID五个接口,Type ...

  5. libuv抽象接口简单梳理

    libuv抽象接口简单梳理 抽象类型 libuv虽然看起来代码没有几行,但是初略过了下文件,功能非常丰富,至少比boost.asio功能要多得多,当前只分析几个基础类型和网络相关的类型. UVErro ...

  6. 微机原理—定时计数控制接口

    别看题目很高深,其实就是很简单的定时器和计数器而已. 通常用手机定个闹钟,就是定时器的使用. 工厂里通过传送带上安装传感器,传感器传输给计算机的信号用来计数. 这是一些很简单的应用,通过很小的一个芯片 ...

  7. EasyNVR网页Chrome无插件播放摄像机视频功能二次开发之云台控制接口示例代码

    随着多媒体技术和网络通信技术的迅速发展,视频监控技术在电力系统.电信行业.工业监控.工地.城市交通.水利系统.社区安防等领域得到越来越广泛的应用.摄像头直播视频监控通过网络直接连接,可达到的世界任何角 ...

  8. 计算机控制电机启动接线图,用PC机并口控制一个简单电路

    所谓PC机并口控制,就是要用打印机接口来控制一些外部设备,达到自动化的目的.如学校早操及课间操音乐的自动播放.公共场所照明的自动控制.小型的彩灯的控制.按照课程表进行自动打铃.简易机械加工设备的自动控 ...

  9. EasyNVR二次开发云台控制接口实例

    1.背景需求 通过EasyNVR接口,二次开发集成在自己的原有的web业务系统上云台控制及实时直播功能,demo效果入下. demo是通过vue-cli脚手架搭建起来,简单说一下,目录结构 对easy ...

最新文章

  1. 阿里秋招面试全解析(含内推岗)
  2. POJ2528 计算可见线段(线段树)
  3. 代码:CSS——reset.css
  4. boost::type_erasure::param相关的测试程序
  5. PHP文件上传类及其使用实例教程
  6. 一次性通过软考网工方案
  7. 【复习】快速幂算法详解
  8. 数学怪兽-法国数学家庞加莱
  9. 年轻人,你的发展上限,取决于这3种能力
  10. 网络游戏防沉迷的理想与现实
  11. 苹果youtube无法连接网络_当手机无信号或者无法连接网络时的正确解决步骤
  12. Java基础知识(十) 多线程
  13. 方根法公式_方根的简易算法
  14. 适合学计算机学生喝的茶,学生喝什么茶能够提高记忆力
  15. zeppelin使用shiro进行权限验证
  16. 迅速处理多个ts转mp4格式 - 无需安装
  17. IM互通新方案-GTalk to VoIP回拨服务
  18. 夜神模拟器连接手柄无反应_夜神安卓模拟器怎么连接手柄 夜神模拟器连接手柄教程...
  19. 教学资源库建设计算机专业,教学资源库建设计算机应用论文
  20. EPB电子驻车制动系统Simulink模型(参考VDA305_100标准进行模型搭建)

热门文章

  1. adobe 10.1用不了金山词霸2009翻译解决
  2. 如何做到图片无损压缩?speedpdf在线转换操作步骤
  3. Android room操作数据库
  4. var、let与const的区别
  5. Python 单词数 统计一篇文章里不同单词的总数
  6. apr各个版本工具包下载及安装教程
  7. 【WebSocket】断连问题排查
  8. linux 硬链接占空间吗,硬链接到底占不占用磁盘空间?
  9. Numerical Analysis 教材下载地址
  10. 学JS的心路历程-函式(五)箭头函式