android_wifi读书笔记之5-WPA_SUPPLICANT分析
来源:互联网 发布:字符串反转 java用哪个 编辑:程序博客网 时间:2024/05/10 22:58
本文为读书笔记,整理自网络文献和源码
5 WPA_SUPPLICANT分析
5.1、WPA_SUPPLICANT 分析1:
参考文献:
http://www.cnblogs.com/chenbin7/p/3266032.html
http://blog.chinaunix.net/uid-26585427-id-4051479.html
wpa_supplicant软件架构分析http://blog.csdn.net/fxfzz/article/details/6176414
wpa_supplicant本是开源项目源码,被谷歌修改后加入android移动平台,它主要是用来支持WEP,WPA/WPA2和WAPI无线协议和加密认证的,而实际上的工作内容是通过socket(不管是wpa_supplicant与上层还是wpa_supplicant与驱动都采用socket通讯)与驱动交互上报数据给用户,而用户可以通过socket发送命令给wpa_supplicant调动驱动来对WiFi芯片操作。简单的说,wpa_supplicant就是WiFi驱动和用户的中转站外加对协议和加密认证的支持。
wpa_supplicant.c
首先定义一个驱动操作数组externstructwpa_driver_ops*wpa_supplicant_drivers[],然后是系列wpa_supplicant_XXX()方法,很多方法里面调用 wpa_drv_XXX()方法,这些方法是wpa_supplicant_i.h中实现的方法。几乎每个方法都需要一个wpa_supplicant结构,对其进行所有的控制和通信操作。
Wpa_supplicant_i.h
其中定义了一个重要数据结构wpa_supplicant,其中有一个重要的driver成 员,它是wpa_driver_ops类型,可以被用来调用抽象层的接口。接下来是系列方法声明,这些方法声明在wpa_supplicant.c中实现,然后就是wpa_drv_XXX方法,这些方法就是在 wpa_supplicant.c中被wpa_supplicant_xxx方法调用的,而这些wpa_drv_xxx方法也都有一个wpa_supplicant结构的变量指针,用来调用封装的抽象接口,而这些抽象接口的实现在driver_wext.c中(如果使用的汉斯WEXT驱动)。
这里要注意的是:在wpa_suppliant.c文件中定义的很多方法是在该头文件中声明的,而不是在wpa_supplicant.h中声明的。
上行接口:
wpa_supplicant提供两种方式的上行接口。一种基于传统dbus机制实现与其他进程间的IPC通信;另一种通过Unix domain socket机制实现进程间的IPC通信。
(1) Dbus
(2) Socket
该接口主要在文件”wpa_ctrl.h”,“wpa_ctrl.c”,“ctrl_iface_unix.c”,“ctrl_iface.h”和“ctrl_iface.c”实现。
1. “wpa_ctrl.h”,“wpa_ctrl.c”完成对controlinterface的封装,对外提供统一的接口。其主要的工作是通过Unix domainsocket建立一个controlinterface 的client结点,与作为server的wpa_supplicant结点通信。
wpa_supplicant 提供两种由外部模块获取信息的方式:一种是外部模块通过发送request 命令然后获取response的问答模式,另一种是wpa_supplicant主动向外部发送event事件,由外部模块监听接收。
一般的常用做法是外部模块通过调用wpa_ctrl_open()两次,分别建立两个controlinterface接口。一个为ctrl interface,用于发送命令,获取信息。然后,将另外一个接口作为参数,调用wpa_ctrl_attach,成为 monitor interface,用于监听接收来自于wpa_supplicant的event事件。此举可以降低通信的耦合性,避免response和event的相互干扰。
2. “ctrl_iface_unix.c”实现wpa_supplicant的Unix domainsocket通信机制中server结点,完成对client结点的响应。
3. “ctrl_iface.h”和“ctrl_iface.c”主要实现了各种request命令的底层处理方法。
下行接口:
wpa_supplicant提供的下行接口主要用于和kernel(driver)进行通信,下发命令和获取信息。
wpa_supplicant下行接口主要包括三种重要的接口:
1. PF_INET socket接口,主要用于向kernel发送ioctl命令,控制并获取相应信息。
2. PF_NETLINK socket接口,主要用于接收kernel发送上来的event 事件。
3. PF_PACKET socket接口,主要用于向driver传递802.1X报文。
(1)“driver.h”,“drivers.c”主要用于封装底层差异对外显示一个相同的wpa_driver_ops接口。wpa_supplicant可支持atheros, broadcom, madwifi, ndis,nl80211, wext等多种驱动。
(2)“driver_nl80211.c”实现了nl80211形式的wpa_driver_ops,并创建了PF_INETsocket接口和PF_NETLINK socket接口,然后通过这两个接口完成与kernel的信息交互。
wpa_driver_nl80211_event_receive方法:处理kernel主动发送的event事件的 callback 方法。
(3)“l2_packet.h”和“l2_packet_linux.c”主要用于实现PF_PACKET socket接口,通过该接口,wpa_supplicant可以直接将802.1X packet发送到L2层,而不经过TCP/IP协议栈。
WEXT(WirelessExtension):使用WEXT的工具通过ioctl和驱动通信,典型工具ifconfig等;NL80211(Netlink 80211):使用NL80211的工具通过一个特殊的socket( Netlink技术)和驱动打通信,典型工具包括IW、iwconfig等。
nl80211接口逐渐替代wext接口的原因主要是使用netlink技术在应用层和内核层数据交换上相比ioctl方式具有优势。 Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用 netlink。
wpa_supplocant服务开启:
service wpa_supplicant/system/bin/wpa_supplicant -Dnl80211 -iwlan0-c/data/misc/wifi/wpa_supplicant.conf
socket wpa_wlan0 dgram 660 wifi wifi
group wifi inet
disabled
oneshot
5.2 WPA_SUPPLICANT分析2,主要涉及下行接口
在drivers.h中定义了一个wpa_driver_ops结构体,结构体成员是一个个方法指针。在driviers.c里面都是不同驱动操作接口的集合wpa_driver_XXX_ops变量;然后就是定义一个驱
动操作接口集合的数组,根据宏定义添加对应的驱动操作接口集合的变量。不同的驱动接口采用不同的文件来实现,如果wpa_supplicant使用的是wext接口与驱动进行通信,那么
就在external/wpa_supplicant_8/src/drivers/driver_nl80211.c文件里面对wpa_driver_ops结构体里面的成员赋值,这些成员指针指向的方法也在这个文件里面实现。代码如下:
const struct wpa_driver_opswpa_driver_nl80211_ops = {
.name= "nl80211",
.desc= "Linux nl80211/cfg80211",
.get_bssid= wpa_driver_nl80211_get_bssid,
.get_ssid= wpa_driver_nl80211_get_ssid,
.set_key= wpa_driver_nl80211_set_key,
.scan2= wpa_driver_nl80211_scan,
.get_scan_results2= wpa_driver_nl80211_get_scan_results,
.deauthenticate= wpa_driver_nl80211_deauthenticate,
.disassociate= wpa_driver_nl80211_disassociate,
.authenticate= wpa_driver_nl80211_authenticate,
.associate= wpa_driver_nl80211_associate,
.global_init= nl80211_global_init,
.global_deinit= nl80211_global_deinit,
.init2= wpa_driver_nl80211_init,
.deinit= wpa_driver_nl80211_deinit,
.get_capa= wpa_driver_nl80211_get_capa,
.set_operstate= wpa_driver_nl80211_set_operstate,
.set_supp_port= wpa_driver_nl80211_set_supp_port,
.set_country= wpa_driver_nl80211_set_country,
.set_beacon= wpa_driver_nl80211_set_beacon,
.if_add= wpa_driver_nl80211_if_add,
.if_remove= wpa_driver_nl80211_if_remove,
.send_mlme= wpa_driver_nl80211_send_mlme,
.get_hw_feature_data= wpa_driver_nl80211_get_hw_feature_data,
.sta_add= wpa_driver_nl80211_sta_add,
.sta_remove= wpa_driver_nl80211_sta_remove,
.hapd_send_eapol= wpa_driver_nl80211_hapd_send_eapol,
.sta_set_flags= wpa_driver_nl80211_sta_set_flags,
#ifdef HOSTAPD
.hapd_init= i802_init,
.hapd_deinit= i802_deinit,
.set_wds_sta= i802_set_wds_sta,
#endif /* HOSTAPD */
#if defined(HOSTAPD) || defined(CONFIG_AP)
.get_seqnum= i802_get_seqnum,
.flush= i802_flush,
.read_sta_data= i802_read_sta_data,
.get_inact_sec= i802_get_inact_sec,
.sta_clear_stats= i802_sta_clear_stats,
.set_rts= i802_set_rts,
.set_frag= i802_set_frag,
.set_cts_protect= i802_set_cts_protect,
.set_preamble= i802_set_preamble,
.set_short_slot_time= i802_set_short_slot_time,
.set_tx_queue_params= i802_set_tx_queue_params,
.set_sta_vlan= i802_set_sta_vlan,
.set_ht_params= i802_set_ht_params,
.set_rate_sets= i802_set_rate_sets,
.sta_deauth= i802_sta_deauth,
.sta_disassoc= i802_sta_disassoc,
#endif /* HOSTAPD || CONFIG_AP */
.set_freq= i802_set_freq,
.send_action= wpa_driver_nl80211_send_action,
.send_action_cancel_wait= wpa_driver_nl80211_send_action_cancel_wait,
.remain_on_channel= wpa_driver_nl80211_remain_on_channel,
.cancel_remain_on_channel=
wpa_driver_nl80211_cancel_remain_on_channel,
.probe_req_report= wpa_driver_nl80211_probe_req_report,
.disable_11b_rates= wpa_driver_nl80211_disable_11b_rates,
.deinit_ap= wpa_driver_nl80211_deinit_ap,
.resume= wpa_driver_nl80211_resume,
.send_ft_action= nl80211_send_ft_action,
.signal_monitor= nl80211_signal_monitor,
.signal_poll= nl80211_signal_poll,
.send_frame= nl80211_send_frame,
.set_intra_bss= nl80211_set_intra_bss,
.set_param= nl80211_set_param,
.get_radio_name= nl80211_get_radio_name,
.add_pmkid= nl80211_add_pmkid,
.remove_pmkid= nl80211_remove_pmkid,
.flush_pmkid= nl80211_flush_pmkid,
#ifdef ANDROID_BRCM_P2P_PATCH
.get_noa= wpa_driver_get_p2p_noa,
.set_noa= wpa_driver_set_p2p_noa,
.set_p2p_powersave= wpa_driver_set_p2p_ps,
.set_ap_wps_ie= wpa_driver_set_ap_wps_p2p_ie,
#endif
#ifdef ANDROID
.driver_cmd= wpa_driver_nl80211_driver_cmd, //处理DRIVER开头的命令
#endif
};
在启动wpa_supplicant服务时,带了很多参数
Service wpa_supplicant/system/bin/wpa_supplicant -Dnl80211 -iwlan0-c/data/misc/wifi/wpa_supplicant.conf
其中-D<driver>: 驱动类型代表的是驱动类型。也就是-Dnl80211
wpa_supplicant的主方法main中会将驱动类型参数赋给iface->driver
case'D':
iface->driver= optarg;
之后调用wpa_supplicant_add_iface(global,&ifaces[i]),wpa_supplicant_add_iface调用的是wpa_supplicant_init_iface。在wpa_supplicant_init_iface(struct
wpa_supplicant *wpa_s,struct wpa_interface*iface)方法里面
driver = iface->driver;
之后调用wpa_supplicant_set_driver(wpa_s,driver)来设置wpa_supplicant使用哪个接口与驱动进行通信:
wpa_s->driver= wpa_drivers[i];
wpa_s->global_drv_priv= wpa_s->global->drv_priv[i];
之后调用wpa_supplicant_driver_init初始化。
- android_wifi读书笔记之5-WPA_SUPPLICANT分析
- android_wifi读书笔记之6-wpa_supplicant 与kernel交互
- android_wifi读书笔记之2-wifi framework分析
- android_wifi读书笔记之3-JNI层 分析
- android_wifi读书笔记之4-HAL层分析
- android_wifi读书笔记之1-wifi简介
- android_wifi读书笔记之7-wifi驱动解析
- android_wifi读书笔记之8-SDIO驱动架构
- android_wifi读书笔记之9-wifi开启流程
- android_WIFI
- android_wifi
- Android4.4 wpa_supplicant深入分析之初识wpa_supplicant
- Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程
- Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程续
- Android4.4 wpa_supplicant深入分析之初识wpa_supplicant
- Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程
- Android4.4 wpa_supplicant深入分析之wpa_supplicant初始化流程续
- Android4.4 wpa_supplicant深入分析之初识wpa_supplicant
- 推荐一个比较好的.net论坛,http://bbs.netluntan.com
- 多参多线程
- 形状类族的中的纯虚函数
- 请放下你的无效社交
- wifidog 认证
- android_wifi读书笔记之5-WPA_SUPPLICANT分析
- Java对象池示例
- RestEasy简介
- js重写window.alert
- eclipse 阅读代码 快捷键
- 快速排序法
- Java线程池
- Hypertable源码解读之Hypertable.RangeServer目录
- BZOJ 1385: [Baltic2000]Division expression