Android wifi service layer

android wifi应用层通信大致可由一图说明。
Android wifi service layer_第1张图片
图中所调用的源文件如下,以本人的android6.0为准,其他版本可能会有不同

系统启动会开始调用SystemService,在上层的代码就不跟踪了,systemserver启动了众多server其中就有wifiservice,在我的android6.0的代码如下,其他版本有些许不同

mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
                mSystemServiceManager.startService(
                            "com.android.server.wifi.WifiScanningService");

                mSystemServiceManager.startService("com.android.server.wifi.RttService");

                if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
                    mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
                    mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
                }

                try {
                    Slog.i(TAG, "Connectivity Service");
                    connectivity = new ConnectivityService(
                            context, networkManagement, networkStats, networkPolicy);
                    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
                    networkStats.bindConnectivityManager(connectivity);
                    networkPolicy.bindConnectivityManager(connectivity);
                } catch (Throwable e) {
                    reportWtf("starting Connectivity Service", e);

可以看到启动了wifiservice(),而wifiservice的类又很简单,只是为了实例化WifiServiceImpl类,代码如下。

public final class WifiService extends SystemService {

    private static final String TAG = "WifiService";
    final WifiServiceImpl mImpl;

    public WifiService(Context context) {
        super(context);
        mImpl = new WifiServiceImpl(context);
    }

    @Override
    public void onStart() {
        Log.i(TAG, "Registering " + Context.WIFI_SERVICE);
        publishBinderService(Context.WIFI_SERVICE, mImpl);
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            mImpl.checkAndStartWifi();
        }
    }

接下来具体看WifiServiceImpl实现,其中会实例化三个类如上图所示,其中WifiStateMachine是核心,WifiController也是一个状态机,主要接收从wifiManage传输过来从命令,最后还是调用WifiStateMachine,来控制wpa_supplicant,这里以setWifiEnabled()开启wifi命令为例简述WifiManage直接调用WifiServiceImpl过程,当app开始wifi,则调用WifiManage的setWifiEnabled()函数,代码如下

    public boolean setWifiEnabled(boolean enabled) {
        try {
            return mService.setWifiEnabled(enabled);
        } catch (RemoteException e) {
            return false;
        }
    }

mservice及wifimanage构造函数实例化的WifiServiceImpl,所以直接调用WifiServiceImpl下的函数,

    public synchronized boolean setWifiEnabled(boolean enable) {
        enforceChangePermission();
        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid());
        if (DBG) {
            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
        }

        /*
        * Caller might not have WRITE_SECURE_SETTINGS,
        * only CHANGE_WIFI_STATE is enforced
        */

        long ident = Binder.clearCallingIdentity();
        try {
            if (! mSettingsStore.handleWifiToggled(enable)) {
                // Nothing to do if wifi cannot be toggled
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
        return true;

mSettingsStore.handleWifiToggled(enable)会调用SettingsStore类的函数,给app传输wifion的值,之后发送message给WifiController状态机,handle的连接函数在WifiServiceImpl的构造函数里面完成,代码如下。

 public WifiServiceImpl(Context context) {
        mContext = context;

        mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");

        mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
        mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName, mTrafficPoller);
        mWifiStateMachine.enableRssiPolling(true);
        mBatteryStats = BatteryStatsService.getService();
        mPowerManager = context.getSystemService(PowerManager.class);
        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
        mUserManager = UserManager.get(mContext);

        mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
        mSettingsStore = new WifiSettingsStore(mContext);

        HandlerThread wifiThread = new HandlerThread("WifiService");
        wifiThread.start();
        //建立handle connect
        mClientHandler = new ClientHandler(wifiThread.getLooper());
        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
        mWifiController = new WifiController(mContext, this, wifiThread.getLooper());
        }

其中mClientHandler为接收wifimanage所发信息的handle函数。mWifiStateMachineHandler为接收WifiStateMachine所发信息的函数。
接下来看下WifiController构造函数。

WifiController(Context context, WifiServiceImpl service, Looper looper) {
        super(TAG, looper);
        mContext = context;
        mWifiStateMachine = service.mWifiStateMachine;
        mSettingsStore = service.mSettingsStore;
        mLocks = service.mLocks;

        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
        Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
        mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);

        addState(mDefaultState);
            addState(mApStaDisabledState, mDefaultState);
            addState(mStaEnabledState, mDefaultState);
                addState(mDeviceActiveState, mStaEnabledState);
                addState(mDeviceInactiveState, mStaEnabledState);
                    addState(mScanOnlyLockHeldState, mDeviceInactiveState);
                    addState(mFullLockHeldState, mDeviceInactiveState);
                    addState(mFullHighPerfLockHeldState, mDeviceInactiveState);
                    addState(mNoLockHeldState, mDeviceInactiveState);
            addState(mStaDisabledWithScanState, mDefaultState);
            addState(mApEnabledState, mDefaultState);
            addState(mEcmState, mDefaultState);

        boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
        boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
        boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();

        log("isAirplaneModeOn = " + isAirplaneModeOn +
                ", isWifiEnabled = " + isWifiEnabled +
                ", isScanningAvailable = " + isScanningAlwaysAvailable);

        if (isScanningAlwaysAvailable) {
            setInitialState(mStaDisabledWithScanState);
        } else {
            setInitialState(mApStaDisabledState);
        }

        setLogRecSize(100);
        setLogOnlyTransitions(false);

        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_DEVICE_IDLE);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();
                        if (action.equals(ACTION_DEVICE_IDLE)) {
                            sendMessage(CMD_DEVICE_IDLE);
                        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
                                    WifiManager.EXTRA_NETWORK_INFO);
                        } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
                            int state = intent.getIntExtra(
                                    WifiManager.EXTRA_WIFI_AP_STATE,
                                    WifiManager.WIFI_AP_STATE_FAILED);
                            if(state == WifiManager.WIFI_AP_STATE_FAILED) {
                                loge(TAG + "SoftAP start failed");
                                sendMessage(CMD_AP_START_FAILURE);
                            }
                        }
                    }
                },
                new IntentFilter(filter));

        initializeAndRegisterForSettingsChange(looper);
    }

实例化这两个类mWifiStateMachine ,mSettingsStore 并设置各个state,初始化起始状态为mApStaDisabledState,初始化代码如下。

 synchronized boolean isScanAlwaysAvailable() {
        return !mAirplaneModeOn && mScanAlwaysAvailable;
    }

boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();

if (isScanningAlwaysAvailable) {
            setInitialState(mStaDisabledWithScanState);
        } else {
            setInitialState(mApStaDisabledState);
        }

最终为false所以初始化为mApStaDisabledState,状态机开启函数在
WifiService的checkAndStartWifi()函数中开启。

    public void checkAndStartWifi() {
        /* Check if wi-fi needs to be enabled */
        boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
        Slog.i(TAG, "WifiService starting up with Wi-Fi " +
                (wifiEnabled ? "enabled" : "disabled"));

        registerForScanModeChange();
        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        if (mSettingsStore.handleAirplaneModeToggled()) {
                            mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);
                        }
                        if (mSettingsStore.isAirplaneModeOn()) {
                            Log.d(TAG, "resetting country code because Airplane mode is ON");
                            mWifiStateMachine.resetCountryCode();
                        }
                    }
                },
                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));

        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String state = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
                        if (state.equals(IccCardConstants.INTENT_VALUE_ICC_ABSENT)) {
                            Log.d(TAG, "resetting networks because SIM was removed");
                            mWifiStateMachine.resetSimAuthNetworks();
                            Log.d(TAG, "resetting country code because SIM is removed");
                            mWifiStateMachine.resetCountryCode();
                        }
                    }
                },
                new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED));

        // Adding optimizations of only receiving broadcasts when wifi is enabled
        // can result in race conditions when apps toggle wifi in the background
        // without active user involvement. Always receive broadcasts.
        registerForBroadcasts();
        registerForPackageOrUserRemoval();
        mInIdleMode = mPowerManager.isDeviceIdleMode();

        //开启wificontrol ,启动状态机
        mWifiController.start();

        // If we are already disabled (could be due to airplane mode), avoid changing persist
        // state here
        if (wifiEnabled) setWifiEnabled(wifiEnabled);

        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
               makeWifiWatchdogStateMachine(mContext, mWifiStateMachine.getMessenger());

再来看下StaEnabledState state下的如何开始加载driver和开启wpa_supplicant。代码如下

class StaEnabledState extends State {
        @Override
        public void enter() {
            mWifiStateMachine.setSupplicantRunning(true);
        }
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case CMD_WIFI_TOGGLED:
                    if (! mSettingsStore.isWifiToggleEnabled()) {
                        if (mSettingsStore.isScanAlwaysAvailable()) {
                            transitionTo(mStaDisabledWithScanState);
                        } else {
                            transitionTo(mApStaDisabledState);
                        }
                    }
                    break;
                case CMD_AIRPLANE_TOGGLED:
                    /* When wi-fi is turned off due to airplane,
                    * disable entirely (including scan)
                    */
                    if (! mSettingsStore.isWifiToggleEnabled()) {
                        transitionTo(mApStaDisabledState);
                    }
                    break;
                case CMD_EMERGENCY_CALL_STATE_CHANGED:
                case CMD_EMERGENCY_MODE_CHANGED:
                    if (msg.arg1 == 1) {
                        transitionTo(mEcmState);
                        break;
                    }
                case CMD_SET_AP:
                    if (msg.arg1 == 1) {
                        // remeber that we were enabled
                        Settings.Global.putInt(mContext.getContentResolver(),
                                Settings.Global.WIFI_SAVED_STATE, WIFI_ENABLED);
                        deferMessage(obtainMessage(msg.what, msg.arg1, 1, msg.obj));
                        transitionTo(mApStaDisabledState);
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

其中enter函数调用了mWifiStateMachine.setSupplicantRunning(true);
在看下代码

    public void setSupplicantRunning(boolean enable) {
        if (enable) {
            sendMessage(CMD_START_SUPPLICANT);
        } else {
            sendMessage(CMD_STOP_SUPPLICANT);
        }
    }

跳转到WifiStateMachine发送CMD_START_SUPPLICANT命令。此时再看下wifistatemachine的构造函数,由于代码较长,我只截取一些,读者可自行查看源码。

 public WifiStateMachine(Context context, String wlanInterface,
                            WifiTrafficPoller trafficPoller) {
        super("WifiStateMachine");
        mContext = context;
        mInterfaceName = wlanInterface;
        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
                BatteryStats.SERVICE_NAME));

        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        mNwService = INetworkManagementService.Stub.asInterface(b);

        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_WIFI_DIRECT);

        mWifiNative = new WifiNative(mInterfaceName, mContext);
        mWifiConfigStore = new WifiConfigStore(context,this,  mWifiNative);
        mWifiAutoJoinController = new WifiAutoJoinController(context, this,
                mWifiConfigStore, mWifiConnectionStatistics, mWifiNative);
        mWifiMonitor = new WifiMonitor(this, mWifiNative);

这里实例化了一些类,其中WifiMonitor作为监控读取wpa_supplicant传上来的event,

addState(mDefaultState);
            addState(mInitialState, 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(mConnectedState, mL2ConnectedState);
                            addState(mRoamingState, 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(mUntetheringState, mSoftApStartedState);

        setInitialState(mInitialState);
         setLogRecSize(ActivityManager.isLowRamDeviceStatic() ? 100 : 3000);
        setLogOnlyTransitions(false);
        if (VDBG) setDbg(true);

        //start the state machine
        start();

add许多状态最终初始化为mInitialState(),最后开启状态机,即CMD_START_SUPPLICANT命令会在mInitialState()中读取到,看下代码

  class InitialState extends State {
        @Override
        public void enter() {
       //关闭HAL,在unloader driver,如果已经load的情况下,其余为配置通信handle 函数
            WifiNative.stopHal();
            mWifiNative.unloadDriver();
            if (mWifiP2pChannel == null) {
                mWifiP2pChannel = new AsyncChannel();
                mWifiP2pChannel.connect(mContext, getHandler(),
                    mWifiP2pServiceImpl.getP2pStateMachineMessenger());
            }

            if (mWifiApConfigChannel == null) {
                mWifiApConfigChannel = new AsyncChannel();
                mWifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
                        mContext, getHandler());
                mWifiApConfigStore.loadApConfiguration();
                mWifiApConfigChannel.connectSync(mContext, getHandler(),
                        mWifiApConfigStore.getMessenger());
            }

            if (mWifiConfigStore.enableHalBasedPno.get()) {
                // make sure developer Settings are in sync with the config option
                mHalBasedPnoEnableInDevSettings = true;
            }
        }
        @Override
        public boolean processMessage(Message message) {
            logStateAndMessage(message, this);
            switch (message.what) {
            //接收到命令,先loaddriver
                case CMD_START_SUPPLICANT:
                    if (mWifiNative.loadDriver()) {
                        try {
                            mNwService.wifiFirmwareReload(mInterfaceName, "STA");
                        } catch (Exception e) {
                            loge("Failed to reload STA firmware " + e);
                            // Continue
                        }

                        try {
                            // A runtime crash can leave the interface up and
                            // IP addresses configured, and this affects
                            // connectivity when supplicant starts up.
                            // Ensure interface is down and we have no IP
                            // addresses before a supplicant start.
                            mNwService.setInterfaceDown(mInterfaceName);
                            mNwService.clearInterfaceAddresses(mInterfaceName);

                            // Set privacy extensions
                            mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);

                            // IPv6 is enabled only as long as access point is connected since:
                            // - IPv6 addresses and routes stick around after disconnection
                            // - kernel is unaware when connected and fails to start IPv6 negotiation
                            // - kernel can start autoconfiguration when 802.1x is not complete
                            mNwService.disableIpv6(mInterfaceName);
                        } catch (RemoteException re) {
                            loge("Unable to change interface settings: " + re);
                        } catch (IllegalStateException ie) {
                            loge("Unable to change interface settings: " + ie);
                        }

                       /* Stop a running supplicant after a runtime restart
                        * Avoids issues with drivers that do not handle interface down
                        * on a running supplicant properly.
                        */
                        mWifiMonitor.killSupplicant(mP2pSupported);

                        if (WifiNative.startHal() == false) {
                            /* starting HAL is optional */
                            loge("Failed to start HAL");
                        }

                        if (mWifiNative.startSupplicant(mP2pSupported)) {
                            setWifiState(WIFI_STATE_ENABLING);
                            if (DBG) log("Supplicant start successful");
                            //开启wifi montor
                            mWifiMonitor.startMonitoring();
                            transitionTo(mSupplicantStartingState);
                        } else {
                            loge("Failed to start supplicant!");
                        }
                    } else {
                        loge("Failed to load driver");
                    }
                    break;
                case CMD_START_AP:
                    if (mWifiNative.loadDriver() == false) {
                        loge("Failed to load driver for softap");
                    } else {
                        if (enableSoftAp() == true) {
                            setWifiApState(WIFI_AP_STATE_ENABLING, 0);
                            transitionTo(mSoftApStartingState);
                        } else {
                            setWifiApState(WIFI_AP_STATE_FAILED,
                                    WifiManager.SAP_START_FAILURE_GENERAL);
                            transitionTo(mInitialState);
                        }
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

先load driver 在开启wpa_supplicant,最后开启WIfiMonitor其中loaddriver和startSupplicant都是通过wifinative调用的,最终通过JNI调用,代码如下,在com_android_server_wifi_WifiNative.cpp中定义

/*
 * JNI registration.
 */
static JNINativeMethod gWifiMethods[] = {
    /* name, signature, funcPtr */

    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },
    { "isDriverLoaded", "()Z",  (void *)android_net_wifi_isDriverLoaded },
    { "unloadDriver", "()Z",  (void *)android_net_wifi_unloadDriver },
    { "startSupplicant", "(Z)Z",  (void *)android_net_wifi_startSupplicant },
    { "killSupplicant", "(Z)Z",  (void *)android_net_wifi_killSupplicant },
    { "connectToSupplicantNative", "()Z", (void *)android_net_wifi_connectToSupplicant },
    { "closeSupplicantConnectionNative", "()V",
            (void *)android_net_wifi_closeSupplicantConnection },
    { "waitForEventNative", "()Ljava/lang/String;", (void*)android_net_wifi_waitForEvent },
    { "doBooleanCommandNative", "(Ljava/lang/String;)Z", (void*)android_net_wifi_doBooleanCommand },
    { "doIntCommandNative", "(Ljava/lang/String;)I", (void*)android_net_wifi_doIntCommand },
    { "doStringCommandNative", "(Ljava/lang/String;)Ljava/lang/String;",
            (void*) android_net_wifi_doStringCommand },
    { "startHalNative", "()Z", (void*) android_net_wifi_startHal },
    { "stopHalNative", "()V", (void*) android_net_wifi_stopHal },
    { "waitForHalEventNative", "()V", (void*) android_net_wifi_waitForHalEvents },
    { "getInterfacesNative", "()I", (void*) android_net_wifi_getInterfaces},
    { "getInterfaceNameNative", "(I)Ljava/lang/String;", (void*) android_net_wifi_getInterfaceName},
    { "getScanCapabilitiesNative", "(ILcom/android/server/wifi/WifiNative$ScanCapabilities;)Z",
            (void *) android_net_wifi_getScanCapabilities},
    { "startScanNative", "(IILcom/android/server/wifi/WifiNative$ScanSettings;)Z",
            (void*) android_net_wifi_startScan},
    { "stopScanNative", "(II)Z", (void*) android_net_wifi_stopScan},
    { "getScanResultsNative", "(IZ)[Landroid/net/wifi/WifiScanner$ScanData;",
            (void *) android_net_wifi_getScanResults},
    { "setHotlistNative", "(IILandroid/net/wifi/WifiScanner$HotlistSettings;)Z",
            (void*) android_net_wifi_setHotlist},
    { "resetHotlistNative", "(II)Z", (void*) android_net_wifi_resetHotlist},
    { "trackSignificantWifiChangeNative", "(IILandroid/net/wifi/WifiScanner$WifiChangeSettings;)Z",
            (void*) android_net_wifi_trackSignificantWifiChange},
    { "untrackSignificantWifiChangeNative", "(II)Z",
            (void*) android_net_wifi_untrackSignificantWifiChange},
    { "getWifiLinkLayerStatsNative", "(I)Landroid/net/wifi/WifiLinkLayerStats;",
            (void*) android_net_wifi_getLinkLayerStats},
    { "setWifiLinkLayerStatsNative", "(II)V",
            (void*) android_net_wifi_setLinkLayerStats},
    { "getSupportedFeatureSetNative", "(I)I",
            (void*) android_net_wifi_getSupportedFeatures},
    { "requestRangeNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
            (void*) android_net_wifi_requestRange},
    { "cancelRangeRequestNative", "(II[Landroid/net/wifi/RttManager$RttParams;)Z",
            (void*) android_net_wifi_cancelRange},
    { "setScanningMacOuiNative", "(I[B)Z",  (void*) android_net_wifi_setScanningMacOui},
    { "getChannelsForBandNative", "(II)[I", (void*) android_net_wifi_getValidChannels},
    { "setDfsFlagNative",         "(IZ)Z",  (void*) android_net_wifi_setDfsFlag},
    { "toggleInterfaceNative",    "(I)Z",  (void*) android_net_wifi_toggle_interface},
    { "getRttCapabilitiesNative", "(I)Landroid/net/wifi/RttManager$RttCapabilities;",
            (void*) android_net_wifi_get_rtt_capabilities},
    {"setCountryCodeHalNative", "(ILjava/lang/String;)Z",
            (void*) android_net_wifi_set_Country_Code_Hal},
    { "setPnoListNative", "(II[Lcom/android/server/wifi/WifiNative$WifiPnoNetwork;)Z",
            (void*) android_net_wifi_setPnoListNative},
    {"enableDisableTdlsNative", "(IZLjava/lang/String;)Z",
            (void*) android_net_wifi_enable_disable_tdls},
    {"getTdlsStatusNative", "(ILjava/lang/String;)Lcom/android/server/wifi/WifiNative$TdlsStatus;",
            (void*) android_net_wifi_get_tdls_status},
    {"getTdlsCapabilitiesNative", "(I)Lcom/android/server/wifi/WifiNative$TdlsCapabilities;",
            (void*) android_net_wifi_get_tdls_capabilities},
    {"getSupportedLoggerFeatureSetNative","(I)I",
            (void*) android_net_wifi_get_supported_logger_feature},
    {"getDriverVersionNative", "(I)Ljava/lang/String;",
            (void*) android_net_wifi_get_driver_version},
    {"getFirmwareVersionNative", "(I)Ljava/lang/String;",
            (void*) android_net_wifi_get_firmware_version},
    {"getRingBufferStatusNative", "(I)[Lcom/android/server/wifi/WifiNative$RingBufferStatus;",
            (void*) android_net_wifi_get_ring_buffer_status},
    {"startLoggingRingBufferNative", "(IIIIILjava/lang/String;)Z",
            (void*) android_net_wifi_start_logging_ring_buffer},
    {"getRingBufferDataNative", "(ILjava/lang/String;)Z",
            (void*) android_net_wifi_get_ring_buffer_data},
    {"getFwMemoryDumpNative","(I)Z", (void*) android_net_wifi_get_fw_memory_dump},
    { "setLazyRoamNative", "(IIZLcom/android/server/wifi/WifiNative$WifiLazyRoamParams;)Z",
            (void*) android_net_wifi_setLazyRoam},
    { "setBssidBlacklistNative", "(II[Ljava/lang/String;)Z",
            (void*)android_net_wifi_setBssidBlacklist},
    { "setSsidWhitelistNative", "(II[Ljava/lang/String;)Z",
            (void*)android_net_wifi_setSsidWhitelist},
    {"setLoggingEventHandlerNative", "(II)Z", (void *) android_net_wifi_set_log_handler},
    {"resetLogHandlerNative", "(II)Z", (void *) android_net_wifi_reset_log_handler},
    { "startSendingOffloadedPacketNative", "(II[B[B[BI)I",
             (void*)android_net_wifi_start_sending_offloaded_packet},
    { "stopSendingOffloadedPacketNative", "(II)I",
             (void*)android_net_wifi_stop_sending_offloaded_packet},
    {"startRssiMonitoringNative", "(IIBB)I",
            (void*)android_net_wifi_start_rssi_monitoring_native},
    {"stopRssiMonitoringNative", "(II)I",
            (void*)android_net_wifi_stop_rssi_monitoring_native},
    {"isGetChannelsForBandSupportedNative", "()Z",
            (void*)android_net_wifi_is_get_channels_for_band_supported}
};

int register_android_net_wifi_WifiNative(JNIEnv* env) {
    return AndroidRuntime::registerNativeMethods(env,
            "com/android/server/wifi/WifiNative", gWifiMethods, NELEM(gWifiMethods));
}

则最终调用(void *)android_net_wifi_loadDriver函数,代码如下,在wifi.c中定义

static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
    return (::wifi_load_driver() == 0);
}

最终会调用insmod通过加载.ko驱动的路径加载wifi,本人代码使修改过的,主体并未改变。

int wifi_load_driver()
{
    FILE *fp        = NULL;
    DIR *d;
    struct dirent *de;
#ifdef MULTI_WIFI_SUPPORT
    set_wifi_power(SDIO_POWER_UP);
#else
#ifdef USB_WIFI_SUPPORT
    set_wifi_power(USB_POWER_UP);
#endif
#endif
#ifdef WIFI_DRIVER_MODULE_PATH
    char driver_status[PROPERTY_VALUE_MAX];
    int count = 100; /* wait at most 20 seconds for completion */

    if (is_wifi_driver_loaded()) {
        return 0;
    }

#ifdef MULTI_WIFI_SUPPORT
    if (multi_wifi_load_driver() < 0)
    {
        set_wifi_power(SDIO_POWER_DOWN);
        ALOGE("MULTI wifi load fail\n");
        return -1;
    }
#else
    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
        return -1;

#ifdef BCM_USB_WIFI
   enable_bcmdl(1);
#endif

#endif
#define TIME_COUNT 200
    count = 0;
    ALOGD("check loading wifi driver is ok...");
    do {
        d = opendir("/sys/class/net");
        if (d == 0) {
           ALOGD("fail to open /sys/class/net");
           wifi_unload_driver();
           return -1;
        }
        while ((de = readdir(d))) {
            if (strcmp(de->d_name, "wlan0")== 0) {
                ALOGE("driver loaded");
                property_set(DRIVER_PROP_NAME, "ok");
                closedir(d);
                return 0;
            }
        }
        closedir(d);
        usleep(200000);// 200ms
        ALOGD("driver not ok ,wait\n");
    } while (count++ <= TIME_COUNT);
    property_set(DRIVER_PROP_NAME, "timeout");
    wifi_unload_driver();
    return -1;
#else
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
    if (is_wifi_driver_loaded()) {
        return 0;
    }

    if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0)
        return -1;
#endif
    property_set(DRIVER_PROP_NAME, "ok");
    return 0;
#endif
}

分析这么多简述了Wifimanage如何通过直接调用WIfiServiceImpl开启wifi,WifiManage还有通过message传递command的方式调用WIfiServiceImpl,
主要差别在于调用方式不同,最终都是发送命令给WifiStateMachine来处理,这里以Wifimanage的connect函数为例,

    public void connect(int networkId, ActionListener listener) {
        if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
        validateChannel();
        sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener));
    }

最终会在WIfiServiceImpl的ClientHandler中接收数据,代码如下

                /* Client commands are forwarded to state machine */
                case WifiManager.CONNECT_NETWORK:
                case WifiManager.SAVE_NETWORK: {
                    WifiConfiguration config = (WifiConfiguration) msg.obj;
                    int networkId = msg.arg1;
                    if (msg.what == WifiManager.SAVE_NETWORK) {
                        Slog.e("WiFiServiceImpl ", "SAVE"
                                + " nid=" + Integer.toString(networkId)
                                + " uid=" + msg.sendingUid
                                + " name="
                                + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                    }
                    if (msg.what == WifiManager.CONNECT_NETWORK) {
                        Slog.e("WiFiServiceImpl ", "CONNECT "
                                + " nid=" + Integer.toString(networkId)
                                + " uid=" + msg.sendingUid
                                + " name="
                                + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                    }

                    if (config != null && isValid(config)) {
                        if (DBG) Slog.d(TAG, "Connect with config" + config);
                        mWifiStateMachine.sendMessage(Message.obtain(msg));
                    } else if (config == null
                            && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
                        if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
                        mWifiStateMachine.sendMessage(Message.obtain(msg));
                    } else {
                        Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
                        if (msg.what == WifiManager.CONNECT_NETWORK) {
                            replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED,
                                    WifiManager.INVALID_ARGS);
                        } else {
                            replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED,
                                    WifiManager.INVALID_ARGS);
                        }
                    }
                    break;
                }

最后会在WifistateMachine的ConnectModeState状态下读取connect命令

        case WifiManager.CONNECT_NETWORK:
                    /**
                     *  The connect message can contain a network id passed as arg1 on message or
                     * or a config passed as obj on message.
                     * For a new network, a config is passed to create and connect.
                     * For an existing network, a network id is passed
                     */
                    netId = message.arg1;
                    config = (WifiConfiguration) message.obj;
                    mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
                    boolean updatedExisting = false;

                    /* Save the network config */

代码较长。总之就是根据传入的wifi配置信息连接wifi,成功能reply一个成功的信息,否则回复失败。
到目前wifi整个流程以大致完成,还缺少wifiMonitor接收wpa_supplicant回传过来的信息。上面说到wifiMonitor在发送开启wifi命令时在WifiStateMachine的initstage中调用开启,看下构造函数,

    public WifiMonitor(StateMachine stateMachine, WifiNative wifiNative) {
        if (DBG) Log.d(TAG, "Creating WifiMonitor");
        mWifiNative = wifiNative;
        mInterfaceName = wifiNative.mInterfaceName;
        mStateMachine = stateMachine;
        mStateMachine2 = null;
        mMonitoring = false;

        WifiMonitorSingleton.sInstance.registerInterfaceMonitor(mInterfaceName, this);
    }

,没干什么软事,直接看startMonitoring函数

    public void startMonitoring() {
        WifiMonitorSingleton.sInstance.startMonitoring(mInterfaceName);
    }

再看下WifiMonitorSingleton.sInstance.startMonitoring(mInterfaceName);

 public synchronized void startMonitoring(String iface) {
            WifiMonitor m = mIfaceMap.get(iface);
            if (m == null) {
                Log.e(TAG, "startMonitor called with unknown iface=" + iface);
                return;
            }

            Log.d(TAG, "startMonitoring(" + iface + ") with mConnected = " + mConnected);

            if (mConnected) {
                m.mMonitoring = true;
                m.mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
            } else {
                if (DBG) Log.d(TAG, "connecting to supplicant");
                int connectTries = 0;
                while (true) {
                    if (mWifiNative.connectToSupplicant()) {
                        m.mMonitoring = true;
                        m.mStateMachine.sendMessage(SUP_CONNECTION_EVENT);
                        mConnected = true;
                        new MonitorThread(mWifiNative, this).start();
                        break;
                    }
                    if (connectTries++ < 5) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ignore) {
                        }
                    } else {
                        m.mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT);
                        Log.e(TAG, "startMonitoring(" + iface + ") failed!");
                        break;
                    }
                }
            }
        }

像WifiStateMachine发送了wpa_supplicant连接的event并开启了WifiMonitor线程,看下线程构造函数

private static class MonitorThread extends Thread {
        private final WifiNative mWifiNative;
        private final WifiMonitorSingleton mWifiMonitorSingleton;
        private final LocalLog mLocalLog = WifiNative.getLocalLog();

        public MonitorThread(WifiNative wifiNative, WifiMonitorSingleton wifiMonitorSingleton) {
            super("WifiMonitor");
            mWifiNative = wifiNative;
            mWifiMonitorSingleton = wifiMonitorSingleton;
        }

        public void run() {
            if (DBG) {
                Log.d(TAG, "MonitorThread start with mConnected=" +
                     mWifiMonitorSingleton.mConnected);
            }
            //noinspection InfiniteLoopStatement
            for (;;) {
                if (!mWifiMonitorSingleton.mConnected) {
                    if (DBG) Log.d(TAG, "MonitorThread exit because mConnected is false");
                    break;
                }
                String eventStr = mWifiNative.waitForEvent();

                // Skip logging the common but mostly uninteresting events
                if (eventStr.indexOf(BSS_ADDED_STR) == -1
                        && eventStr.indexOf(BSS_REMOVED_STR) == -1) {
                    if (DBG) Log.d(TAG, "Event [" + eventStr + "]");
                    mLocalLog.log("Event [" + eventStr + "]");
                }

                if (mWifiMonitorSingleton.dispatchEvent(eventStr)) {
                    if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
                    break;
                }
            }
        }
    }

在run里面先调用了 String eventStr = mWifiNative.waitForEvent();的native函数这个函数通过JNI在wifi.c里面,看下这个函数

int wifi_wait_on_socket(char *buf, size_t buflen)
{
    size_t nread = buflen - 1;
    int result;
    char *match, *match2;

    if (monitor_conn == NULL) {
        return snprintf(buf, buflen, "IFNAME=%s %s - connection closed",
                        primary_iface, WPA_EVENT_TERMINATING);
    }

    result = wifi_ctrl_recv(buf, &nread);

    /* Terminate reception on exit socket */
    if (result == -2) {
        return snprintf(buf, buflen, "IFNAME=%s %s - connection closed",
                        primary_iface, WPA_EVENT_TERMINATING);
    }

    if (result < 0) {
        ALOGD("wifi_ctrl_recv failed: %s\n", strerror(errno));
        return snprintf(buf, buflen, "IFNAME=%s %s - recv error",
                        primary_iface, WPA_EVENT_TERMINATING);
    }
    buf[nread] = '\0';
    /* Check for EOF on the socket */
    if (result == 0 && nread == 0) {
        /* Fabricate an event to pass up */
        ALOGD("Received EOF on supplicant socket\n");
        return snprintf(buf, buflen, "IFNAME=%s %s - signal 0 received",
                        primary_iface, WPA_EVENT_TERMINATING);
    }
    /*
     * Events strings are in the format
     *
     *     IFNAME=iface CTRL-EVENT-XXX 
     *        or
     *     CTRL-EVENT-XXX 
     *
     * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
     * etc.) and XXX is the event name. The level information is not useful
     * to us, so strip it off.
     */

    if (strncmp(buf, IFNAME, IFNAMELEN) == 0) {
        match = strchr(buf, ' ');
        if (match != NULL) {
            if (match[1] == '<') {
                match2 = strchr(match + 2, '>');
                if (match2 != NULL) {
                    nread -= (match2 - match);
                    memmove(match + 1, match2 + 1, nread - (match - buf) + 1);
                }
            }
        } else {
            return snprintf(buf, buflen, "%s", WPA_EVENT_IGNORE);
        }
    } else if (buf[0] == '<') {
        match = strchr(buf, '>');
        if (match != NULL) {
            nread -= (match + 1 - buf);
            memmove(buf, match + 1, nread + 1);
            ALOGV("supplicant generated event without interface - %s\n", buf);
        }
    } else {
        /* let the event go as is! */
        ALOGW("supplicant generated event without interface and without message level - %s\n", buf);
    }

    return nread;
}

一个 result = wifi_ctrl_recv(buf, &nread);和wpa_suplicant连接,这个反正具体分析wpa_suplicant后面详细说明。所以在接收到event后先判断是否有无用信息,在调用mWifiMonitorSingleton.dispatchEvent(eventStr)函数,看下这个函数

        private synchronized boolean dispatchEvent(String eventStr) {
            String iface;
            // IFNAME=wlan0 ANQP-QUERY-DONE addr=18:cf:5e:26:a4:88 result=SUCCESS
            if (eventStr.startsWith("IFNAME=")) {
                int space = eventStr.indexOf(' ');
                if (space != -1) {
                    iface = eventStr.substring(7, space);
                    if (!mIfaceMap.containsKey(iface) && iface.startsWith("p2p-")) {
                        // p2p interfaces are created dynamically, but we have
                        // only one P2p state machine monitoring all of them; look
                        // for it explicitly, and send messages there ..
                        iface = "p2p0";
                    }
                    eventStr = eventStr.substring(space + 1);
                } else {
                    // No point dispatching this event to any interface, the dispatched
                    // event string will begin with "IFNAME=" which dispatchEvent can't really
                    // do anything about.
                    Log.e(TAG, "Dropping malformed event (unparsable iface): " + eventStr);
                    return false;
                }
            } else {
                // events without prefix belong to p2p0 monitor
                iface = "p2p0";
            }

            if (VDBG) Log.d(TAG, "Dispatching event to interface: " + iface);

            WifiMonitor m = mIfaceMap.get(iface);
            //确定event接收的接口。在下面接收event
            if (m != null) {
                if (m.mMonitoring) {
                    if (m.dispatchEvent(eventStr, iface)) {
                        mConnected = false;
                        return true;
                    }

                    return false;
                } else {
                    if (DBG) Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
                    return false;
                }
            } else {
                if (DBG) Log.d(TAG, "Sending to all monitors because there's no matching iface");
                boolean done = false;
                boolean isMonitoring = false;
                boolean isTerminating = false;
                if (eventStr.startsWith(EVENT_PREFIX_STR)
                        && eventStr.contains(TERMINATING_STR)) {
                    isTerminating = true;
                }
                for (WifiMonitor monitor : mIfaceMap.values()) {
                    if (monitor.mMonitoring) {
                        isMonitoring = true;
                        if (monitor.dispatchEvent(eventStr, iface)) {
                            done = true;
                        }
                    }
                }

                if (!isMonitoring && isTerminating) {
                    done = true;
                }

                if (done) {
                    mConnected = false;
                }

                return done;
            }
        }
    }

先确定wifi接口后,在调用m.dispatchEvent(eventStr, iface)函数。再看下这个函数做了什么

    /* @return true if the event was supplicant disconnection */
    private boolean dispatchEvent(String eventStr, String iface) {

        if (DBG) {
            // Dont log CTRL-EVENT-BSS-ADDED which are too verbose and not handled
            if (eventStr != null && !eventStr.contains("CTRL-EVENT-BSS-ADDED")) {
                logDbg("WifiMonitor:" + iface + " cnt=" + Integer.toString(eventLogCounter)
                        + " dispatchEvent: " + eventStr);
            }
        }

        if (!eventStr.startsWith(EVENT_PREFIX_STR)) {
            if (eventStr.startsWith(WPA_EVENT_PREFIX_STR) &&
                    0 < eventStr.indexOf(PASSWORD_MAY_BE_INCORRECT_STR)) {
               mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT, eventLogCounter);
            } else if (eventStr.startsWith(WPS_SUCCESS_STR)) {
                mStateMachine.sendMessage(WPS_SUCCESS_EVENT);
            } else if (eventStr.startsWith(WPS_FAIL_STR)) {
                handleWpsFailEvent(eventStr);
            } else if (eventStr.startsWith(WPS_OVERLAP_STR)) {
                mStateMachine.sendMessage(WPS_OVERLAP_EVENT);
            } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) {
                mStateMachine.sendMessage(WPS_TIMEOUT_EVENT);
            } else if (eventStr.startsWith(P2P_EVENT_PREFIX_STR)) {
                handleP2pEvents(eventStr);
            } else if (eventStr.startsWith(HOST_AP_EVENT_PREFIX_STR)) {
                handleHostApEvents(eventStr);
            } else if (eventStr.startsWith(ANQP_DONE_STR)) {
                try {
                    handleAnqpResult(eventStr);
                }
                catch (IllegalArgumentException iae) {
                    Log.e(TAG, "Bad ANQP event string: '" + eventStr + "': " + iae);
                }
            } else if (eventStr.startsWith(GAS_QUERY_PREFIX_STR)) {        // !!! clean >>End
                handleGasQueryEvents(eventStr);
            } else if (eventStr.startsWith(RX_HS20_ANQP_ICON_STR)) {
                if (mStateMachine2 != null)
                    mStateMachine2.sendMessage(RX_HS20_ANQP_ICON_EVENT,
                            eventStr.substring(RX_HS20_ANQP_ICON_STR_LEN + 1));
            } else if (eventStr.startsWith(HS20_PREFIX_STR)) {                  // !!! <
                handleHs20Events(eventStr);
            } else if (eventStr.startsWith(REQUEST_PREFIX_STR)) {
                handleRequests(eventStr);
            } else if (eventStr.startsWith(TARGET_BSSID_STR)) {
                handleTargetBSSIDEvent(eventStr);
            } else if (eventStr.startsWith(ASSOCIATED_WITH_STR)) {
                handleAssociatedBSSIDEvent(eventStr);
            } else if (eventStr.startsWith(AUTH_EVENT_PREFIX_STR) &&
                    eventStr.endsWith(AUTH_TIMEOUT_STR)) {
                mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT);
            } else if (eventStr.startsWith(RSN_PMKID_STR)) {
                mStateMachine.sendMessage(RSN_PMKID_MISMATCH_EVENT);
            } else {
                if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
            }
            eventLogCounter++;
            return false;
        }

        String eventName = eventStr.substring(EVENT_PREFIX_LEN_STR);
        int nameEnd = eventName.indexOf(' ');
        if (nameEnd != -1)
            eventName = eventName.substring(0, nameEnd);
        if (eventName.length() == 0) {
            if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
            eventLogCounter++;
            return false;
        }
        /*
        * Map event name into event enum
        */
        int event;
        if (eventName.equals(CONNECTED_STR))
            event = CONNECTED;
        else if (eventName.equals(DISCONNECTED_STR))
            event = DISCONNECTED;
        else if (eventName.equals(STATE_CHANGE_STR))
            event = STATE_CHANGE;
        else if (eventName.equals(SCAN_RESULTS_STR))
            event = SCAN_RESULTS;
        else if (eventName.equals(SCAN_FAILED_STR))
            event = SCAN_FAILED;
        else if (eventName.equals(LINK_SPEED_STR))
            event = LINK_SPEED;
        else if (eventName.equals(TERMINATING_STR))
            event = TERMINATING;
        else if (eventName.equals(DRIVER_STATE_STR))
            event = DRIVER_STATE;
        else if (eventName.equals(EAP_FAILURE_STR))
            event = EAP_FAILURE;
        else if (eventName.equals(ASSOC_REJECT_STR))
            event = ASSOC_REJECT;
        else if (eventName.equals(TEMP_DISABLED_STR)) {
            event = SSID_TEMP_DISABLE;
        } else if (eventName.equals(REENABLED_STR)) {
            event = SSID_REENABLE;
        } else if (eventName.equals(BSS_ADDED_STR)) {
            event = BSS_ADDED;
        } else if (eventName.equals(BSS_REMOVED_STR)) {
            event = BSS_REMOVED;
        } else
            event = UNKNOWN;

        String eventData = eventStr;
        if (event == DRIVER_STATE || event == LINK_SPEED)
            eventData = eventData.split(" ")[1];
        else if (event == STATE_CHANGE || event == EAP_FAILURE) {
            int ind = eventStr.indexOf(" ");
            if (ind != -1) {
                eventData = eventStr.substring(ind + 1);
            }
        } else {
            int ind = eventStr.indexOf(" - ");
            if (ind != -1) {
                eventData = eventStr.substring(ind + 3);
            }
        }

        if ((event == SSID_TEMP_DISABLE)||(event == SSID_REENABLE)) {
            String substr = null;
            int netId = -1;
            int ind = eventStr.indexOf(" ");
            if (ind != -1) {
                substr = eventStr.substring(ind + 1);
            }
            if (substr != null) {
                String status[] = substr.split(" ");
                for (String key : status) {
                    if (key.regionMatches(0, "id=", 0, 3)) {
                        int idx = 3;
                        netId = 0;
                        while (idx < key.length()) {
                            char c = key.charAt(idx);
                            if ((c >= 0x30) && (c <= 0x39)) {
                                netId *= 10;
                                netId += c - 0x30;
                                idx++;
                            } else {
                                break;
                            }
                        }
                    }
                }
            }
            mStateMachine.sendMessage((event == SSID_TEMP_DISABLE)?
                    SSID_TEMP_DISABLED:SSID_REENABLED, netId, 0, substr);
        } else if (event == STATE_CHANGE) {
            handleSupplicantStateChange(eventData);
        } else if (event == DRIVER_STATE) {
            handleDriverEvent(eventData);
        } else if (event == TERMINATING) {
            /**
             * Close the supplicant connection if we see
             * too many recv errors
             */
            if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
                if (++sRecvErrors > MAX_RECV_ERRORS) {
                    if (DBG) {
                        Log.d(TAG, "too many recv errors, closing connection");
                    }
                } else {
                    eventLogCounter++;
                    return false;
                }
            }

            // Notify and exit
            mStateMachine.sendMessage(SUP_DISCONNECTION_EVENT, eventLogCounter);
            return true;
        } else if (event == EAP_FAILURE) {
            if (eventData.startsWith(EAP_AUTH_FAILURE_STR)) {
                logDbg("WifiMonitor send auth failure (EAP_AUTH_FAILURE) ");
                mStateMachine.sendMessage(AUTHENTICATION_FAILURE_EVENT, eventLogCounter);
            }
        } else if (event == ASSOC_REJECT) {
            Matcher match = mAssocRejectEventPattern.matcher(eventData);
            String BSSID = "";
            int status = -1;
            if (!match.find()) {
                if (DBG) Log.d(TAG, "Assoc Reject: Could not parse assoc reject string");
            } else {
                BSSID = match.group(1);
                try {
                    status = Integer.parseInt(match.group(2));
                } catch (NumberFormatException e) {
                    status = -1;
                }
            }
            mStateMachine.sendMessage(ASSOCIATION_REJECTION_EVENT, eventLogCounter, status, BSSID);
        } else if (event == BSS_ADDED && !VDBG) {
            // Ignore that event - it is not handled, and dont log it as it is too verbose
        } else if (event == BSS_REMOVED && !VDBG) {
            // Ignore that event - it is not handled, and dont log it as it is too verbose
        }  else {
                handleEvent(event, eventData);
        }
        sRecvErrors = 0;
        eventLogCounter++;
        return false;
    }

原来就是处理接收上来不同wifi接口的event而已,先以不同的envet前导过滤一些,由函数!eventStr.startsWith(EVENT_PREFIX_STR),再将去掉前导过滤掉的保存在event中,再判断不同event的状态跳转到相应的handle中去,以handleEvent(event, eventData);为例看下代码

void handleEvent(int event, String remainder) {
        if (DBG) {
            logDbg("handleEvent " + Integer.toString(event) + "  " + remainder);
        }
        switch (event) {
            case DISCONNECTED:
                handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
                break;

            case CONNECTED:
                handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
                break;

            case SCAN_RESULTS:
                mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
                break;

            case SCAN_FAILED:
                mStateMachine.sendMessage(SCAN_FAILED_EVENT);
                break;

            case UNKNOWN:
                if (DBG) {
                    logDbg("handleEvent unknown: " + Integer.toString(event) + "  " + remainder);
                }
                break;
            default:
                break;
        }
    }

在以SCAN_RESULTS为例看下WifiStateMachine如何处理event,在此函数中mStateMachine.sendMessage(SCAN_RESULTS_EVENT),发送信息
在SupplicantStartedState中

case WifiMonitor.SCAN_RESULTS_EVENT:
                case WifiMonitor.SCAN_FAILED_EVENT:
                    maybeRegisterNetworkFactory(); // Make sure our NetworkFactory is registered
                    noteScanEnd();
                    setScanResults();
                    if (mIsFullScanOngoing || mSendScanResultsBroadcast) {
                        /* Just updated results from full scan, let apps know about this */
                        boolean scanSucceeded = message.what == WifiMonitor.SCAN_RESULTS_EVENT;
                        sendScanResultsAvailableBroadcast(scanSucceeded);
                    }
                    mSendScanResultsBroadcast = false;
                    mIsScanOngoing = false;
                    mIsFullScanOngoing = false;
                    if (mBufferedScanMsg.size() > 0)
                        sendMessage(mBufferedScanMsg.remove());
                    break;

其中 sendScanResultsAvailableBroadcast(scanSucceeded);通过广播发送接收结果

    void sendScanResultsAvailableBroadcast(boolean scanSucceeded) {
        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        intent.putExtra(WifiManager.EXTRA_RESULTS_UPDATED, scanSucceeded);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
    }

到此告一段落,下次分析wpa_suplicant源码,在结合此文章会有更清晰的思路

你可能感兴趣的:(linux)