Android wifi打開流程(Android O)

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

一. Android O wifi 架構:
由於Android O的Treble化,Android O上Wifi架構變動也比較大,尤其是JNI層、Hal層、HIDL層。

下圖是Android O Treble HIDL大致結構:

下圖是Android O wifi架構:

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

二. 函數調用流程:
1. 在wifisettings activity的onStart函數中,創建一個WifiEnabler對象,用於實現wifi開關功能。

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

    onStart()

        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 := ""

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章