对几个网站关于Wifi的整理和对Android代码的跟踪修改
AndroidWifi子系统
1.相关文件
1)Wifi Settings应用程序
packages/apps/Settings/src/com/android/settings/wifi
2)Wifi Framework
frameworks/base/wifi/java/android/net/wifi(UI通过android.net.wifipackage发送命令给wifi.c)
frameworks/base/core/java/android/net(更高一级的网络管理、dhcp)
frameworks/base/services/java/com/android/server
3)Wifi JNI
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
4)Wifi Hardware (wifi管理库)
hardware/libhardware_legacy/wifi/wifi.c
5)wpa_supplicant(wifi tool)
external/wpa_supplicant8
(1) wpa_client (生成库libwpa_client.so:android/out/target/product/sugar-evb/system/lib/libwpa_client.so)
external/wpa_supplicant_8/wpa_supplicant/src/common/wpa_ctrl.c
(2)wpa_server (生成守护进程wpa_supplicant)
external/wpa_supplicant_8/wpa_supplicant/main.c
6) Wifi kernel
net/wirelessdrivers/wlan_xxx arch/arm/mach-xxx/wlan_pm.c
2.两个重要的类
2.1WifiStateMachine
(frameworks/base/wifi/java/android/net/wifi/WifiStateMachine)
publicclass WifiStateMachine extends StateMachine {
mWifiNative= new WifiNative(mInterfaceName);
mSupplicantStateTracker= new SupplicantStateTracker(context, this, mWifiConfigStore,
getHandler());
IntentscanIntent = new Intent(ACTION_START_SCAN, null);
mScanIntent= PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0);
。。。。
addState(mDefaultState);
addState(mInitialState,mDefaultState);
addState(mDriverUnloadingState,mDefaultState);
addState(mDriverUnloadedState,mDefaultState);
addState(mDriverFailedState,mDriverUnloadedState);
addState(mDriverLoadingState,mDefaultState);
addState(mDriverLoadedState,mDefaultState);
addState(mSupplicantStartingState,mDefaultState);
addState(mSupplicantStartedState,mDefaultState);
addState(mDriverStartingState,mSupplicantStartedState);
addState(mDriverStartedState,mSupplicantStartedState);
addState(mScanModeState,mDriverStartedState);
addState(mConnectModeState,mDriverStartedState);
addState(mL2ConnectedState,mConnectModeState);
addState(mObtainingIpState,mL2ConnectedState);
addState(mVerifyingLinkState,mL2ConnectedState);
addState(mCaptivePortalCheckState,mL2ConnectedState);
addState(mConnectedState,mL2ConnectedState);
addState(mDisconnectingState,mConnectModeState);
addState(mDisconnectedState,mConnectModeState);
addState(mWpsRunningState,mConnectModeState);
addState(mWaitForP2pDisableState,mSupplicantStartedState);
addState(mDriverStoppingState,mSupplicantStartedState);
addState(mDriverStoppedState,mSupplicantStartedState);
addState(mSupplicantStoppingState,mDefaultState);
addState(mSoftApStartingState,mDefaultState);
addState(mSoftApStartedState,mDefaultState);
addState(mTetheringState,mSoftApStartedState);
addState(mTetheredState,mSoftApStartedState);
addState(mSoftApStoppingState,mDefaultState);
setInitialState(mInitialState);
start();
在WifiStateMachine构造函数中添加完所有的state后,会调用setInitialState将InitialState设为初始状态。最后就调用start()方法,让WifiStateMachine运行起来。这里的start()方法并不是新建一个thread之类的运行,而是根据InitialState去构建好从最上层State到InitialState这条分支上面的所有State信息,然后发送一个SM_INIT_CMD给SmHandler让其做初始化处理。第一次调用start函数时,mIsConstructionCompleted将为false,等处理完SM_INIT_CMD后,mIsConstructionCompleted将变为true,以后处理所有的消息将进入到processMsg当中。
StateMachine的状态切换方法:
在StateMachine中切换状态是通过transitionTo(IStatedestState)来实现的,状态的变换则意味着mStateStack的变化.
StateMachine消息的发送和处理
消息发送:
Publicfinal void sendMessage(int what);
Publicfinal void sendMessage(int what,Object obj);
Publicfinal void sendMessage(int what,int arg1);
Publicfinal void sendMessage(int what,int arg1,int arg2);
Publicfinal void sendMessage(int what,int arg1,int arg2,Object obj)
protectedfinal void deferMessage(Message msg);
消息处理:(先在当前状态中调用,如果returnfalse,继续递归地在当前状态的父状态调用)
processMessage()方法在sendMessage之后会回调该方法。
在AndroidWifi子系统中,WifiStateMachine上与WifiService通信,下则调用JNI接口向Wpa_supplicant发送命令,起到了承上启下的关键作用。
所有和JNI层的通信都是有WifiStateMachine完成的:
例一:
(frameworks/base/wifi/java/android/net/wifi)
WifiNative.java
publicnative static boolean loadDriver()
进入JNI
(android/frameworks/base/core/jni/android_net_wifi_Wifi.cpp)
staticjboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
return(jboolean)(::wifi_load_driver() == 0);
}
然后到wifi.c处理
(android/hardware/libhardware_legacy/wifi.c):
intwifi_load_driver() {
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {
例二:
publicboolean setScanMode(boolean setActive) {
if(setActive) {
returndoBooleanCommand("DRIVER SCAN-ACTIVE");
}
privateboolean doBooleanCommand(String command) {
if(DBG) Log.d(mTAG, "doBoolean: " + command);
returndoBooleanCommand(mInterface, command);
}
privatenative boolean doBooleanCommand(String iface, String command);
JNI
staticjboolean doBooleanCommand(const char *ifname, const char* expect,const char* fmt, ...)
{
if (doCommand(ifname, buf, reply, sizeof(reply)) != 0) {
returnJNI_FALSE;
}
staticint doCommand(const char *ifname, const char *cmd, char *replybuf,int replybuflen)
{
size_treply_len = replybuflen - 1;
if(::wifi_command(ifname, cmd, replybuf, &reply_len) != 0)
return-1;
wifi.c
这里是wpa_supplicant的另一个最重要的接口之一:其封装了wifi_send_command(通过wpa_ctrl_request直接将命令转发给wpa_supplicant进程,并返回结果),
intwifi_command(const char *ifname, const char *command, char *reply,size_t *reply_len)
{
if(is_primary_interface(ifname)) {
returnwifi_send_command(PRIMARY, command, reply, reply_len);
}else {
returnwifi_send_command(SECONDARY, command, reply, reply_len);
}
}
intwifi_send_command(int index, const char *cmd, char *reply, size_t*reply_len)
{
intret;
ret= wpa_ctrl_request(ctrl_conn[index], cmd, strlen(cmd), reply,reply_len, NULL);
wpa_ctrl.c
if(send(ctrl->s, _cmd, _cmd_len, 0) < 0)
2.2WifiMonitor
(frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java)
classMonitorThread extends Thread {
publicMonitorThread() {
super("WifiMonitor");
}
publicvoid run() {
if (connectToSupplicant()) { --------------------------------------------->
//Send a message indicating that it is now possible to send commands
//to the supplicant
mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
}else {
mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
return;
}
//noinspection InfiniteLoopStatement
for (;;) {
StringeventStr = mWifiNative.waitForEvent();
handleEvent(event,eventData);
}
connectToSupplicant()调用mWifiNative.connectToSupplicant():
privateboolean connectToSupplicant() {
intconnectTries = 0;
while(true) {
if(mWifiNative.connectToSupplicant()) { //JNI
returntrue;
}
mWifiNative.connectToSupplicant()这个函数很重要,java层通过connectToSupplicant调用wifi_connect_tosupplicant函数,在该函数中调用wifi_connect_on_socket_path(SECONDARY,path);其会通过wpa_ctrl_open函数(android/external/wpa_supplicant_8/src/common/wpa_ctrl.c)分别创建两个UNIX域的数据报socket。
一个是ctrl_conn,用于向wpa_supplicant发送命令并接收response,
另一个是monitor_conn,它移植阻塞等待从wpa_supplicant过来的event。
intwifi_connect_on_socket_path(int index, const char *path)
{
。。。。。。
ctrl_conn[index]= wpa_ctrl_open(path);
monitor_conn[index]= wpa_ctrl_open(path);
if(wpa_ctrl_attach(monitor_conn[index]) != 0) {
。。。。
if(socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets[index]) == -1)
}
通过monitor_conn向wpa_supplicant发送命令ATTACH。用于将自己的socket信息注册到wpa_supplicant(由于数据报方式)。对于存在于wpa_supplicant的服务器端,它是所有客户端共享的。由于它需要主动向monitor_conn客户端发送事件,所以它必须先记录下客户端的详细信息。wpa_supplicant就可以将EVENT发向该socket。
然后java层会通过JNI循环调用函数android_net_wifi_waitForEvent,即wifi.c的wifi_wait_for_event。其会阻塞地接收从wpa_supplicant模块传来的事件,一旦接收到事件,wifi_wait_for_event会将包含事件的buf通过函数参数的方式回传到java层。java收到时间后,再继续调用wifi_wait_for_event函数阻塞等待接收。
Monitor.java的handleEvent()函数会用来处理接收到的事件
voidhandleEvent(int event, String remainder) {
switch(event) {
caseDISCONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED,remainder);
break;
caseCONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);
break;
caseSCAN_RESULTS:
mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
break;
caseUNKNOWN:
break;
}
}
privatevoid handleNetworkStateChange(NetworkINfo.DetailedStatenewState, String data){
notifyNetworkStateChange(newState,BSSID, networkId);
voidnotifyNetworkStateChange(NetworkInfo.DetailedState newState, StringBSSID, int netId) {
if(newState == NetworkInfo.DetailedState.CONNECTED) {
Messagem = mStateMachine.obtainMessage(NETWORK_CONNECTION_EVENT,
netId, 0, BSSID);
mStateMachine.sendMessage(m);
2.3WifiWatchdogStateMachine
(android/frameworks/base/wifi/java/android/net/wifi)
WifiWatchdogStateMachine用于监控无线网络的信号质量,它在WifiService的checkAndStartWifi函数中被创建,其创建函数是makeWifiWatchdogStateMachine:
publicstatic WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Contextcontext) {
ContentResolvercontentResolver = context.getContentResolver();
ConnectivityManagercm = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
sWifiOnly= (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);
//Watchdog is always enabled
putSettingsGlobalBoolean(contentResolver,Settings.Global.WIFI_WATCHDOG_ON, true);
WifiWatchdogStateMachinewwsm = new WifiWatchdogStateMachine(context);
wwsm.start();
returnwwsm;
}
privateWifiWatchdogStateMachine(Context context) {
super(TAG);
mContext= context;
mContentResolver= context.getContentResolver();
mWifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mWsmChannel.connectSync(mContext,getHandler(),
mWifiManager.getWifiStateMachineMessenger());
setupNetworkReceiver();
////关键函数:setupNetworkReceiver将创建一个广播接收对象,用于接收NETWORK_STATE_CHANGED_ACTION