Android Wifi子系统(一)

对几个网站关于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后,会调用setInitialStateInitialState设为初始状态。最后就调用start()方法,让WifiStateMachine运行起来。这里的start()方法并不是新建一个thread之类的运行,而是根据InitialState去构建好从最上层StateInitialState这条分支上面的所有State信息,然后发送一个SM_INIT_CMDSmHandler让其做初始化处理。第一次调用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);

  1. 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_connwpa_supplicant发送命令ATTACH。用于将自己的socket信息注册到wpa_supplicant(由于数据报方式)。对于存在于wpa_supplicant的服务器端,它是所有客户端共享的。由于它需要主动向monitor_conn客户端发送事件,所以它必须先记录下客户端的详细信息。wpa_supplicant就可以将EVENT发向该socket


然后java层会通过JNI循环调用函数android_net_wifi_waitForEvent,即wifi.cwifi_wait_for_event。其会阻塞地接收从wpa_supplicant模块传来的事件,一旦接收到事件,wifi_wait_for_event会将包含事件的buf通过函数参数的方式回传到java层。java收到时间后,再继续调用wifi_wait_for_event函数阻塞等待接收。

Monitor.javahandleEvent()函数会用来处理接收到的事件


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 handleNetworkStateChangeNetworkINfo.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用于监控无线网络的信号质量,它在WifiServicecheckAndStartWifi函数中被创建,其创建函数是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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值