Android WIFI 详解
这些函数的功能从名字上能看出,open函数就是创建一个socket接口,并绑定连接wpa_supplicant,attach函数用于定义一个控制 接口为监听接口,pending函数用于查询有无消息可读处理,request和recv分别用来发送和读取消息。
其实,这里就是一个使用socket通信的封装,具体内容可以参考socket编程。
2)wpa_ctrl.c:
这里首先定义了一个wpa_ctrl结构,里面根据UDP,UNIX和命名管道三种domain类型来定义通信实体:
struct wpa_ctrl {
#ifdefCONFIG_CTRL_IFACE_UDP
int s;
struct sockaddr_in local;
struct sockaddr_in dest;
char *cookie;
#endif /*CONFIG_CTRL_IFACE_UDP */
#ifdefCONFIG_CTRL_IFACE_UNIX
int s;
struct sockaddr_un local;
struct sockaddr_un dest;
#endif /*CONFIG_CTRL_IFACE_UNIX */
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
HANDLE pipe;
#endif /*CONFIG_CTRL_IFACE_NAMED_PIPE */
};
然后是根据上面三个类型分别实现了wpa_ctrl.h中声明的接口函数,这里就不做介绍了。
3)wpa_supplicant.h:
首先,定义了一个枚举wpa_event_type,罗列了系列wpa的事件类型,然后就是wpa_event_data类型,随后是两个函数:wpa_supplicant_event和wpa_supplicant_rx_eapol。
wpa_supplicant.c: 首先定义一个驱动操作数组externstruct wpa_driver_ops *wpa_supplicant_drivers[],然后是系列wpa_supplicant_XXX()函数,很多函数里面调用 wpa_drv_XXX()函数,这些函数是wpa_supplicant_i.h中实现的函数。几乎每个函数都需要一个wpa_supplicant结 构,对其进行所有的控制和通信操作。
4)wpa_supplicant_i.h:
开头定义了几个结构, 如:wpa_blacklist,wpa_interface,wpa_params,wpa_global,wpa_client_mlme和 wpa_supplicant等结构,其中wpa_supplicant最为重要,wpa_supplicant结构里有一个重要的driver成员,它 是wpa_driver_ops类型,可以被用来调用抽象层的接口。
接下来是系列函数声明,这些函数声明在wpa_supplicant.c中实现,然后就是wpa_drv_XXX函数,这些函数就是在 wpa_supplicant.c中被wpa_supplicant_xxx函数调用的,而这些wpa_drv_xxx函数也都有一个 wpa_supplicant结构的变量指针,用来调用封装的抽象接口。
这里要注意的是:在wpa_suppliant.c文件中定义的很多函数是在该头文件中声明的,而不是在wpa_supplicant.h中声明的。
5)driver.h:
该文件中定义了一个重要的数据结构:wpa_scan_result,这是一个从驱动发来的数据被封装成的通用的扫描结果数据结构,每个驱动结构的实现都 要遵循的扫描结果格式,比如driver_wext.c中的实现。后面还有定义了很多的数据结构,这里不具表。
文件中最重要的一个数据结构是:wpa_driver_ops,这是所有驱动接口层必须为之实现的API,是所有驱动类型的一个接口封装包,wpa_supplicant就是通过该接口来和驱动交互的。
6)driver_wext.h:
该文件很简单,就是声明了该驱动的一些对应驱动API接口的函数。
driver_wext.c:
此文件就是实现了上面的一些函数,最后初始化了一个wpa_drv_ops变量。
三,Wifi模块解析
1)框架分析
图示1:Wifi框架
首先,用户程序使用WifiManager类来管理Wifi模块,它能够获得Wifi模块的状态,配置和控制Wifi模块,而所有这些操作都要依赖Wifiservice类来实现。
WifiService和WifiMonitor类是Wifi框架的核心,如图所示。下面先来看看WifiService是什么时候,怎么被创建和初始化的。
在systemServer启动之后,它会创建一个ConnectivityServer对象,这个对象的构造函数会创建一个WifiService的实例,代码如下所示:
framework/base/services/java/com/android/server/ConnectivityService.java
{
……
case ConnectivityManager.TYPE_WIFI:
if (DBG) Slog.v(TAG, Starting Wifi Service.);
WifiStateTracker wst = new WifiStateTracker(context, mHandler); //创建WifiStateTracker实例
WifiService wifiService = newWifiService(context, wst);//创建WifiService实例
ServiceManager.addService(Context.WIFI_SERVICE, wifiService); //向服务管理系统添加Wifi服务
wifiService.startWifi(); //启动Wifi
mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
wst.startMonitoring(); //启动WifiMonitor中的WifiThread线程
……
}
WifiService的主要工作:WifiMonitor和Wpa_supplicant的启动和关闭,向Wpa_supplicant发送命令。
WifiMonitor的主要工作:阻塞监听并接收来自Wpa_supplicant的消息,然后发送给WifiStateTracker。
上面两个线程通过AF_UNIX套接字和Wpa_supplicant通信,在通信过程中有两种连接方式:控制连接和监听连接。它们创建代码如下:
ctrl_conn =wpa_ctrl_open(ifname);
.. .. ..
monitor_conn = wpa_ctrl_open(ifname);
2)Wifi启动流程
(1)使能Wifi
要想使用Wifi模块,必须首先使能Wifi,当你第一次按下Wifi使能按钮时,WirelessSettings会实例化一个WifiEnabler对象,实例化代码如下:
packages/apps/settings/src/com/android/settings/WirelessSettings.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
……
CheckBoxPreferencewifi = (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI);
mWifiEnabler= new WifiEnabler(this, wifi);
……
}
WifiEnabler类的定义大致如下,它实现了一个监听接口,当WifiEnabler对象被初始化后,它监听到你按键的动作,会调用响应函数 onPreferenceChange(),这个函数会调用WifiManager的setWifiEnabled()函数。
评论