现在的位置: 首页 > 综合 > 正文

android_wifi读书笔记之2-wifi framework分析

2018年08月23日 ⁄ 综合 ⁄ 共 6773字 ⁄ 字号 评论关闭

本文为读书笔记,整理自网络文献和源码

2 wifi framework分析

WIFI Settings应用程序位于

packages/apps/Settings/src/com/android/settings/wifi/

涉及到的文件:

WifiSettings.java

 

frameworks部分:

frameworks/base/services/java/com/android/server/

frameworks/base/wifi/java/android/net/wifi/

涉及到的文件有:

SystemServer.java

WifiManager.java

WifiService.java

WifiStateMachine.java

WifiMonitor.java

Wifinative.java

 

2.1、注册WifiService

frameworks/base/services/java/com/android/server/SystemServer.java

线程class ServerThread extends Thread中注册WifiService

  try{

                Slog.i(TAG, "Wi-FiService");

                wifi = newWifiService(context);

                ServiceManager.addService(Context.WIFI_SERVICE, wifi);

     } catch (Throwable e) {

                reportWtf("starting Wi-FiService", e);

           }

try {

                Slog.i(TAG, "ConnectivityService");

                connectivity = newConnectivityService(

                        context,networkManagement, networkStats, networkPolicy);

                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

               networkStats.bindConnectivityManager(connectivity);

               networkPolicy.bindConnectivityManager(connectivity);

                wifi.checkAndStartWifi();

               wifiP2p.connectivityServiceReady();

    } catch (Throwable e) {

                reportWtf("startingConnectivity Service", e);

           }

 

2.2、WifiService

frameworks/base/services/java/com/android/server/WifiService.java

wifiservice是整个框架的核心部分,application层触发事件后,会调用这个service里面的方法来处理事件,包括加载驱动,开启wpa_supplicant,扫描AP都是调用这个service里面的方法实现的,实际上这些方法最终调用的是wifistatemachine里面的方法去发送消息。由wifistatemachine里面的描述wifi事件的内部类去处理这些消息。

在这个类的构造方法中主要就是实例化了一个描述wifi状态机的类WifiStateMachine,重写了广播事件的onReceive方法。

 

 

2.3、WifiStateMachine

frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

wifiservice中的方法最终是调用WifiStateMachine这个service里面的方法来实现的,WifiStateMachine主要就是对sendmessage()的封装。在这个service中,需要传递到wpa_supplicant来实现wifi功能的命令,都在这个service中做了定义。针对每一个wifi状态,都声明了一个内部类去描述,比如描述加载驱动,开启wpa_supplicant等,每一个状态类都有三个方法构成enter(),processmessage(), 不过不同类的这三个方法里面的程序不同而已。WifiStateMachine的构造方法里面,主要的工作是实例化了wifi的监视器mWifiMonitor
= new WifiMonitor(this),这个监视器的作用下面再做解释,简单地讲,就是通过这个监视器,阻塞监听wpa_supplicant传递上来的信息,对信息进行处理后通知上层采取相应的形式去实现。在这个构造方法中,对每一个描述wifi状态的内部类的实例,都使用add()方法把这些内部类的实例添加到状态机中,这两项主要工作对应的代码如下:

mWifiMonitor = new WifiMonitor(this);

……

    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(mConnectingState, mConnectModeState);

                        addState(mConnectedState, mConnectModeState);

                        addState(mDisconnectingState,mConnectModeState);

                        addState(mDisconnectedState, mConnectModeState);

                        addState(mWaitForWpsCompletionState,mConnectModeState);

               addState(mDriverStoppingState,mSupplicantStartedState);

                addState(mDriverStoppedState, mSupplicantStartedState);

           addState(mSupplicantStoppingState,mDefaultState);

           addState(mSoftApStartingState,mDefaultState);

           addState(mSoftApStartedState,mDefaultState);

                addState(mTetheringState, mSoftApStartedState);

                addState(mTetheredState, mSoftApStartedState);

           addState(mSoftApStoppingState,mDefaultState);

           addState(mWaitForP2pDisableState, mDefaultState);

 

之后,使用setInitialState(mInitialState)使wifi状态机进入初始化状态,并通过方法start()开启状态机。通过把各种wifi状态类的实例添加到wifi状态机,以后通过sendmessage(Message message)方法发送消息,参数message会写进消息队列汇总,wifi状态机会根据相应的message调用相应的wifi状态类里面的方法对消息进行处理。例如wifi驱动的加载。sendmessage(CMD_LOAD_DRIVER)发送加载驱动的消息到消息队列后,会触发wifi状态机的里面的状态类DriverLoadingState,调用里面的方法去加载驱动。

2.4 WifiMonitor

frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java

前面已经简单介绍过,WifiMonitor这个类主要功能就是阻塞等待(监控)wpa_supplicant传上来的命令后根据命令来进行相应的处理。那么这个监视器是什么时候打开的呢,我们来分析它的打开流程。

在系统起来之后,systemserver把wifiservice 和connectivity的实例添加到android的service管理器,这前面已经介绍过,之后,调用wifiservice的方法

wifi.checkAndStartWifi();实际上调用了WifiStateMachine的方法setWifiEnabled(wifiEnabled),在这个方法里面,加载驱动,开启wpa_supplicant,对应的代码如下:

public void setWifiEnabled(boolean enable){

       mLastEnableUid.set(Binder.getCallingUid());

       if (enable) {

           /* Argument is the state that is entered prior to load */

           sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));

           sendMessage(CMD_START_SUPPLICANT);

       } else {

           sendMessage(CMD_STOP_SUPPLICANT);

           /* Argument is the state that is entered upon success */

           sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));

       }

}

 

之后wifi状态机WifiStateMachine就会进入DriverLoadedState状态,通过native层调用wifi.c开启wpa_supplicant的方法后就开启wifimonitor,也就是说,监视器的开启必须是

在驱动加载成功以及开启wpa_supplicant后才开启,相应的代码如下:

if(WifiNative.startSupplicant()) {

                        if (DBG) log("Supplicant startsuccessful");

                       mWifiMonitor.startMonitoring();

                       transitionTo(mSupplicantStartingState);

                    } else {

                        loge("Failed tostart supplicant!");

                       sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));

                    }

 

介绍下wifimonitor是如何阻塞监听wpasupplicant传过来的信息的,在监视器开启之后:在监视线层的循环体里面,调用wifi.c里面的waitForEvent()方法来监听接收

wpa_supplicant传过来的消息,相应的代码如下:

   public void startMonitoring() {

       new MonitorThread().start();

    }

   class MonitorThread extends Thread {

       public MonitorThread() {

           super("WifiMonitor");

       }

       public void run() {

           if (connectToSupplicant()) {

                // Send a message indicatingthat 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 (;;) {

                String eventStr =WifiNative.waitForEvent();

……

根据字符串eventStr的不同值调用相应的处理流程来对事件进行不同的处理,上层做出相应的回应。

 

2.5 WifiNative

frameworks/base/wifi/java/android/net/wifi/WifiNativejava

这一个类里面是调用native层里面的对应方法的接口的集合,当我们在frameswork层希望与下层进行交互调用下层的方法的时候,都是先调用这个类里面相应的接口,比如开启wpa_supplicant,就是通过WifiNative.startSupplicant()这个方式来调用native层的android_net_wifi_startSupplicant,最终调用HAL层中的wifi.c里面的wifi_start_supplicant()来开启wpa_supplicanat。

 

抱歉!评论已关闭.