Android wifi打開流程(Android O)

 

根據本身的理解整理了Android O的wifi啓動流程,爲便於理解,繪製了Android O wifi架構圖。有理解不到之處和錯誤之處,請各位指出,一塊兒學習。
一. Android O wifi 架構:java

因爲Android O的Treble化,Android O上Wifi架構變更也比較大,尤爲是JNI層、Hal層、HIDL層。android

下圖是Android O Treble HIDL大體結構:架構

下圖是Android O wifi架構:app

下圖是Android Wlan架構(from android官網)函數

二. 函數調用流程:oop

1. 在wifisettings activity的onStart函數中,建立一個WifiEnabler對象,用於實現wifi開關功能。學習

packages/apps/Settings/src/com/android/settings/wifi/WifiSettings.javathis

    onStart()server

        mWifiEnabler = createWifiEnabler();對象

 

2. WifiEnabler開關SwitchToggled中會調用WifiManager.setWifiEnabled方法。

packages/apps/Settings/src/com/android/settings/wifi/WifiEnabler.java

    onSwithToggled(boolean isCkecked)

        mWifiManager.setWifiEnabled(isChecked)

 

3. WifiManager調用WifiService的方法。

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

    setWifiEnabled(boolean enabled)

        mService.setWifiEnabled(mContext.getOpPackageName(), enabled)

 

4. WiFiManager使用aidl方式和WifiService進行通訊。

frameworks/base/wifi/java/android/net/wifi/IWifiManager.aidl

     boolean setWifiEnabled(String packageName, boolean enable);

 

5. WifiServiceImpl中實現WifiService的方法,像WifiController發消息:CMD_WIFI_TOGGLED.

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

    public synchronized boolean setWifiEnabled(String packageName, boolean enable)

        mWifiController.sendMessage(CMD_WIFI_TOGGLED);

 

6. WifiController狀態機處理消息:CMD_WIFI_TOGGLED

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiController.java

WifiController狀態機的狀態變化,這裏咱們只說softap關閉狀態下打開sta的狀況;有時間的話,能夠跟一下softap打開狀態下打開sta的流程。這裏只需關注「Turn ON STA」 .

     *                 ------------------

     *                  ApStaDisabledState

     *                   ------------------

     *                     /      \

     *   -> Turn ON STA   /        \ Turn on SAP <-

     *                   /          \

     *                  /            \

     *         ---------------     --------------

     *         StaEnabledState     ApEnabledState

     *         ---------------     --------------

     *                 \               /

     *                  \             /

     *    -> Turn ON SAP \           /  Turn on STA <-

     *                    \         /

     *                   ---------------

     *                   QcApStaEnablingState

     *                   ---------------

     *                        |     |

     *                        |     |

     * -> CMD_AP_STARTED      |     |    CMD_STA_STARTED <-

     *(SAP turn on completed) |     |    (STA turn on completed)

     *                        |     |

     *                  ---------------------

     *                   QcApStaEnabledState

     *                  ----------------------

     *                         /  \

                              /    \

     * -> Turn on OFF STA    /      \     Turn OFF SAP

     *                      /        \

     *                 ------------------------

     *                  QcApStaDisablingState

     *                 ------------------------

     *                           /\

     *                          /  \

     * -> CMD_WIFI_DISABLED    /    \    CMD_AP_STOPPED <-

     *(STA turn OFF completed)/      \   (SAP turn OFF completed)

     *                       /        \

     *                      /          \

     *      -------------------      -------------

     *         ApEnabledState        StaEnabledState

     *      -------------------      ---------------

 

6.1 ApStaDisabledState 狀態下,不對CMD_WIFI_TOGGLED消息處理

6.2 轉向StaEnabledState狀態,在該狀態的enter()函數中啓動supplicant, processMessage中會根據掃描、sta/ap共存等條件作相應的狀態處理。

    class StaEnabledState extends State

        enter()

            mWifiStateMachine.setSupplicantRunning(true);

        public boolean processMessage(Message msg)

            case CMD_WIFI_TOGGLED:

 

7. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java

    public void setSupplicantRunning(boolean enable)

        sendMessage(CMD_START_SUPPLICANT);

 

8. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachine.java

又是狀態機,這裏簡單給出wifi狀態機的各狀態及結構。感受有必要專門講一下狀態機。

    WifiStateMachine state:

        |- DefaultState

            |-- InitialState

            |-- SupplicantStartingState

            |-- SupplicantStartedState

                |--- ScanModeState

                |--- ConnectModeState

                    |---- L2ConnectedState

                        |----- ObtainingIpState

                        |----- ConnectedState

                        |----- RoamingState

                    |---- DisconnectingState

                    |---- DisconnectedState

                    |---- WpsRunningState

                    |---- FilsState

                |--- WaitForP2pDisableState

            |-- SupplicantStoppingState

            |-- SoftApstate

InitialState狀態中處理消息:CMD_START_SUPPLICANT, 作加載驅動、啓動supplicant操做,而後轉向SupplicantStartingState狀態。

    class InitialState extends State

        case CMD_START_SUPPLICANT:

            mClientInterface = mWifiNative.setupForClientMode();  // loadDriver

            mWifiNative.enableSupplicant()                    // start supplicant

            transitionTo(mSupplicantStartingState);

 

9. frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

    public IClientInterface setupForClientMode()

        startHalIfNecessary(true))                            // start Hal

IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode();

 

//啓動Hal層。若是支持STA/AP共存,startConcurrentVendorHal;若是不支持共存:isStaMode=true啓動sta模式,isStaMode=false啓動ap模式。

    private boolean startHalIfNecessary(boolean isStaMode)

        if (mStaAndAPConcurrency)

// start ap & sta Concurrent Hal

            return mWifiVendorHal.startConcurrentVendorHal(isStaMode);

return mWifiVendorHal.startVendorHal(isStaMode); // start Hal. Here

 

10. 不一樣於android N,wifinative會調用JNI層com_android_server_wifi_WifiNative.cpp. Android O在framework增長了調用Hal層的相關接口及hal設備管理接口。

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java

    public boolean startVendorHal(boolean isStaMode)

        mHalDeviceManager.start()  //start wifi vendor hal

        mIWifiStaIface = mHalDeviceManager.createStaIface(null, null); //loadDriver

 

11. 這個代碼跟的有些凌亂

frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java

    public IWifiStaIface createStaIface(InterfaceDestroyedListener destroyedListener,

            Looper looper) {

        return (IWifiStaIface) createIface(IfaceType.STA, destroyedListener, looper);

    }

 

    private IWifiIface createIface(int ifaceType, InterfaceDestroyedListener destroyedListener, Looper looper)

         IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, destroyedListener, looper);

    

    private IWifiIface createIfaceIfPossible(WifiChipInfo[] chipInfos, int ifaceType, InterfaceDestroyedListener destroyedListener, Looper looper)

         IWifiIface iface = executeChipReconfiguration(bestIfaceCreationProposal, ifaceType);

 

    private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData, int ifaceType)

        WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(ifaceCreationData.chipModeId);

 

12. Android O不在使用以前版本的JNI com_android_server_wifi_WifiNative.cpp。而是用HIDL,其實如今/hardware/interfaces/.

hardware/interfaces/wifi/1.1/default/wifi_chip.cpp

    Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb)

        return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::configureChipInternal, hidl_status_cb, mode_id);

 

    WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id)

         WifiStatus status = handleChipConfiguration(mode_id);

 

    WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id)

        if (mode_id == kStaChipModeId) {

            success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);

        } else {

            success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);

        }

 

 

13. hardware/interfaces/wifi/1.0/default/wifi_mode_controller.cpp

    bool WifiModeController::changeFirmwareMode(IfaceType type)

        driver_tool_->LoadDriver()

        driver_tool_->ChangeFirmwareMode(convertIfaceTypeToFirmwareMode(type))

 

14. 最後調到hal層,android O的hal層也進行了重寫。位置也從以前的版本中的hardware/libhardware_legacy/wifi/移到了frameworks/opt/net/wifi/libwifi_hal/

frameworks/opt/net/wifi/libwifi_hal/driver_tool.cpp

    bool DriverTool::LoadDriver()

        return ::wifi_load_driver() == 0;

 

15 frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp

int wifi_load_driver()

if (is_wifi_driver_loaded())  return 0;

        insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)

 

除了一些打開wifi時的消息通知、廣播、狀態變化,這裏沒有詳細描述;至此,wifi打開的相關工做已經完成。

Qcom平臺把加載wifi驅動的動做放在了開機時,在init.target.rc文件中:

insmod /vendor/lib/modules/qca_cld3_wlan.ko

根據實際狀況,可能須要將開機加載驅動改成原來的動態加載。只須要作兩處改動:

A. init腳本中刪除加載wlan driver的行

B. 確認以下幾個宏是打開和正肯定義,在產品平臺對應的makefile文件中加入便可:

    WIFI_DRIVER_MODULE_PATH := "/vendor/lib/modules/wlan.ko"

    WIFI_DRIVER_MODULE_NAME := "wlan"

    WIFI_DRIVER_MODULE_ARG := ""  

相關文章
相關標籤/搜索