失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android wpa_supplicant源码分析--启动之全局初始化

Android wpa_supplicant源码分析--启动之全局初始化

时间:2019-06-02 08:02:42

相关推荐

Android wpa_supplicant源码分析--启动之全局初始化

1. wpa_supplicant简介

wpa_supplicant是用来用来支持无线中各种加密方式的,包括WEP、WPA/WPA2和WAPI(中国特有)、EAP(8021x)。wpa_s通过socket与上层(framework)和底层(driver)通信,向上接收命令和传递当前状态,向下发送命令到驱动并接收驱动上传的各种event,严格来讲wap_s和driver中还有一层cfg80211,cfg80211可以理解为linux定义的80211管理控制层的框架,例如扫描、连接这些通用的过程,各个厂商按照cfg80211提供的框架编写各自的驱动,实现具体的帧发送与接收。wpa_s是如何处理各个socket中数据的请看 eloop sun章节。

下图是网页(http://zwz94./blog/static/320603950149580531/)上的一张图片,可以清晰的看到wpa_s早整个wifi架构中的位置

2. wpa_supplicant的启动

在Android手机中,wpa_supplicant的启动是由framework控制的,frameowork设置property来启动写在init rc文件的中service, 同时会生成两条socket,一条向wpa_s发送命令,一条接收wpa_s上传的event

service p2p_supplicant /system/bin/wpa_supplicant \

-ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \

-I/system/etc/wifi/p2p_supplicant_overlay.conf -N \

-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \

-I/system/etc/wifi/wpa_supplicant_overlay.conf \

-O/data/misc/wifi/sockets -puse_p2p_group_interface=1 -dd \

-e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0

class main

socket wpa_wlan0 dgram 660 wifi wifi

disabled

oneshot

其中 socket wpa_wlan0 dgram 660 wifi wifi创建了一个socket,wpa_s使用该socket接收framework的命令和向上传递event。framework同样会调用连接该socket,后面会讲到

3. wpa_supplicant启动参数

wpa_s允许传入很多参数, 参数区分大小写

参数一共有3中类型,

3.1 不带后续内容的参数

有 –BdhKLqstuvW

-h:帮助文件

-L:输出license

-q:提升wpa_s调试级别(输出log减少),与-d相反

-v:输出wpa_s版本号

-W:等到control interface monitor再运行

-N:当需要设置两个network interface时,需要在两个网口参数中间插入 –N, 例如 一个网口为p2p0,需要插入-N后,再新添加另一个wlan0

wpa_supplicant通过为每一个网络接口设置不同的参数的方式,来实现对多网卡的支持。

3.2 带后续内容的全局参数

结构体 wpa_params在调用 wpa_supplicant_init() 初始化wpa_s使用,控制wpa_s运行

struct wpa_params {

//-B:当做守护进程运行在后台

int daemonize;

//-W:等到control interface monitor再运行

int wait_for_monitor;

//-P: pid_file - Path to a PID (process ID) file

char *pid_file;

//-d:输出log的级别,-d为默认级别,-dd级别降低一级(输出log会增加一级),依次类推,设置代码为params.wpa_debug_level

int wpa_debug_level;

//-K:在log中打印key

int wpa_debug_show_keys;

//-t:调试信息中增加时间戳

int wpa_debug_timestamp;

//ctrl_interface - Global ctrl_iface path/parameter

//-g:global ctrl_interface(字符串为@android+SOCK_NAME, SOCK_NAME是由init.rc)

char *ctrl_interface;

//ctrl_interface_group - Global ctrl_iface group

//-G:global ctrl_interface group

char *ctrl_interface_group;

//-u:支持dbus控制接口

int dbus_ctrl_interface;

//-f:将log输出到file中

const char *wpa_debug_file_path;

//-s:输出log到 syslog, 默认输出到stdout

int wpa_debug_syslog;

//-T:log增加linux trace

int wpa_debug_tracing;

//-o:设置linux网口的目录

char *override_driver;

//-O:设置wpa_s控制sockets的目录

char *override_ctrl_interface;

//-e:entropy_file - Optional entropy file

char *entropy_file;

};

3.3 带后续内容的网络接口参数

存放到结构体 struct wpa_interface 中,运行wpa_supplicant_add_iface()需要传入该结构体

struct wpa_interface {

//-c:conf配置文件,里面定义了一些参数和一些network节点,一般为wpa_supplicant.conf

const char *confname;

//-I:conf配置文件的补充选项,一般为wpa_supplicant_overlay.conf/

const char *confanother;

//-m:p2p网口的配置文件

const char *conf_p2p_dev;

//-C:控制端口socket的参数

//功能等同conf 文件

const char *ctrl_interface;

//-D:driver的类型,可以设置多个,例如 nl80211,wext

const char *driver;

//driver_param - Driver interface parameters

const char *driver_param;

//-i:linux的网口,可以定义多个,例如wlan0

const char *ifname;

//-b:桥接的interface

const char *bridge_ifname;

//p2p_mgmt - Interface used for P2P management (P2P Device operations)

int p2p_mgmt;

};

4. wpa_supplicant全局初始化

主要包括 EAP各种方法的注册,eloop(wpa_s运行的主体)参数,与framework通信socket的初始化

struct wpa_global * wpa_supplicant_init(struct wpa_params *params)

{

//全局信息,params中的内容都会拷贝到该结构体中

struct wpa_global *global;

//初始化eap方法,每种eap方式都有对应的方法

ret = eap_register_methods();

//将params中的信息复制到global中

global = os_zalloc(sizeof(*global));

//初始化 struct eloop_data,该结构体是个全局变量

if (eloop_init())

random_init(params->entropy_file);

//连接与FWKS通信socket(init.rc中定义的),并注册接收cmd的函数

global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);

{

//初始化控制socket

wpas_global_ctrl_iface_open_sock(global, priv) < 0)

{

//获取-g传进来的socket名称,与init.rc中相对应

os_strncmp(ctrl, "@android:", 9) == 0) {

priv->sock = android_get_control_socket(ctrl + 9);

//注册接收socket数据的函数,分发处理传入的命令

eloop_register_read_sock(priv->sock, wpa_supplicant_global_ctrl_iface_receive, global, priv);

//注册发送event到FWKS的函数wpa_supplicant_ctrl_iface_send

wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);

}

}

return global;

}

下图是简易的全局初始化过程

wpa_supplicant_global_ctrl_iface_receive()可以接受两类命令,接口命令和全局命令。一类命令前面有“IFNAME= ”指明处理该命令的接口,然后调用每个接口对应的 wpa_supplicant_ctrl_iface_process()来进行相应处理。另一类未指定接口,由wpa_supplicant_global_ctrl_iface_process()直接处理。

5 Framework与wpa_supplicant通信

framework新建了两条socket,并与init rc中的socket相关联,一条用于发送CMD,一条用接收event

代码在wifi.c中。

//path 内容为"@android:wpa_wlan0", wpa_wlan0是由init.rc启动的socket

int wifi_connect_on_socket_path(const char *path)

{

ctrl_conn = wpa_ctrl_open(path);

monitor_conn = wpa_ctrl_open(path);

}

在该函数中会调用wpa_ctrl_open()在wpa_s中,具体操作如下

static struct wpa_ctrl *ctrl_conn = wpa_ctrl_open(path);

{

//新建一个UNIX域的socket

struct wpa_ctrl *ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);

//经socket与文件系统的地址绑定,就是手机目录下的 /data/misc/wifi/sockets

os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), CONFIG_CTRL_IFACE_CLIENT_DIR "/" CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d", (int) getpid(), counter);

bind(ctrl->s, (struct sockaddr *) &ctrl->local, sizeof(ctrl->local))

//将新创建的socket和init.rc启动的socket连接起来

socket_local_client_connect( ctrl->s, ctrl_path + 9, NDROID_SOCKET_NAMESPACE_RESERVED, SOCK_DGRAM)

}

wifi_send_command()用于向wpa_s发送命令

wifi_wait_on_socket()接收wpa_s向上传递的event

---------------------

作者:cuijiyue

来源:CSDN

原文:/cuijiyue/article/details/51357263

版权声明:本文为博主原创文章,转载请附上博文链接!

如果觉得《Android wpa_supplicant源码分析--启动之全局初始化》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。