(九十四) Android O 连接WiFi AP流程梳理续——连接网络

版权声明:本文为博主原创文章,未经授权禁止转载,O(∩_∩)O谢谢 https://blog.csdn.net/sinat_20059415/article/details/82718937

前言: 之前在(五十五)Android O 连接WiFi AP流程梳理 梳理连接流程梳理到SupplicantStaNetworkHal 然后没梳理的下去,现在继续梳理下。

相关梳理:

1)(九十三) Android O 连接WiFi AP流程梳理续——保存网络

2) (九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程

1. 前期准备

1.小米 mix2 Android O抓取连接WiFi期间的log:

09-01 21:09:27.991  1561  2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:27.993  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.listNetworks succeeded
09-01 21:09:27.993  2379  2379 D wpa_supplicant: Deregistering network from hidl control: 0
09-01 21:09:27.994  1561  1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkRemoved received
09-01 21:09:27.995  1561  2460 D WifiHandler.WifiScanningService: Received message=159773d sendingUid=1000
09-01 21:09:27.995  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.removeNetwork succeeded
09-01 21:09:27.995  1561  2457 I SupplicantStaIfaceHal: addSupplicantStaNetwork via HIDL
09-01 21:09:27.995  1561  2460 D WifiScanningService: replySucceeded recvdMessage=159773
09-01 21:09:27.995  2379  2379 D wpa_supplicant: Registering network to hidl control: 0
09-01 21:09:27.995  1561  1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkAdded received
09-01 21:09:27.996  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.addNetwork succeeded
09-01 21:09:27.996  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setSsid succeeded
09-01 21:09:27.996  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.002  1561 14441 D WifiService: getConfiguredNetworks uid=1000
09-01 21:09:28.002  1561 14441 D WifiAsyncChannel.WifiService: sendMessageSynchronously.send message=131131
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPskPassphrase succeeded
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setScanSsid succeeded
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setRequirePmf succeeded
09-01 21:09:28.017  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setKeyMgmt succeeded
09-01 21:09:28.017  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setProto succeeded
09-01 21:09:28.018  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setAuthAlg succeeded
09-01 21:09:28.018  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setGroupCipher succeeded
09-01 21:09:28.019  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPairwiseCipher succeeded
09-01 21:09:28.019  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setIdStr succeeded
09-01 21:09:28.020  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.registerCallback succeeded
09-01 21:09:28.020  2379  2379 E wpa_supplicant: eap_proxy: eap_proxy_notify_config
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: Scan results matching the currently selected network
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x511
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wpa_supplicant_ssid_bss_match : wapi is null
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: 0: 20:6b:e7:93:84:f9 freq=5765 level=-45 snr=47 est_throughput=390001
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 1: e4:ea:83:03:94:dc ssid='CMCC-RDNL-5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x11
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 2: d8:c8:e9:1d:5e:b0 ssid='@PHICOMM_A0_5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 3: 20:6b:e7:93:84:f7 ssid='jiatai 2.4G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 4: 30:fc:68:6e:89:c0 ssid='TP-LINK_89C0' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 5: d8:c8:e9:1d:5e:a8 ssid='703' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0xc11
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 6: e4:72:e2:82:12:a0 ssid='ChinaNet-xYjr' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 7: 8c:be:be:44:46:3c ssid='Xiaomi-Wan' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0xc11
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 8: e4:ea:83:03:94:d0 ssid='CMCC-RDNL' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 9: 62:01:0f:b8:2b:f2 ssid='iTV-R3rH' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 10: 08:01:0f:b8:2b:f1 ssid='ChinaNet-R3rH' wpa_ie_len=26 rsn_ie_len=0 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 11: 44:6e:e5:88:c0:bc ssid='HUAWEI-Apple' wpa_ie_len=0 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 12: ac:54:74:1f:a0:e0 ssid='CMCC-3pc7' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 13: 48:7d:2e:b1:b7:e9 ssid='TP-LINK804' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x1c11
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 14: 8c:be:be:44:46:3d ssid='Xiaomi-Wan_5G' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 15: 1c:60:de:3d:c6:70 ssid='modenggongyu' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x31
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 16: 88:25:93:45:2c:3f ssid='303' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x431
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 17: 5c:09:79:25:f1:58 ssid='ChinaNet-YPpp' wpa_ie_len=26 rsn_ie_len=24 wapi_ie_len=0 caps=0x411
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: Selecting BSS from priority group 0
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 caps=0x511 level=-45 freq=5765 
09-01 21:09:28.020  2379  2379 D wpa_supplicant: 0: 20:6b:e7:93:84:f9 ssid='jiatai 5G' wpa_ie_len=22 rsn_ie_len=20 wapi_ie_len=0 caps=0x511
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wpa_supplicant_ssid_bss_match : wapi is null
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0:    selected based on RSN IE
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0:    selected BSS 20:6b:e7:93:84:f9 ssid='jiatai 5G'
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: Considering connect request: reassociate: 1  selected: 20:6b:e7:93:84:f9  bssid: 00:00:00:00:00:00  pending: 00:00:00:00:00:00  wpa_state: DISCONNECTED  ssid=0x76a18b5c00  current_ssid=0x76a18b5c00
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: Request association with 20:6b:e7:93:84:f9
09-01 21:09:28.020  2379  2379 D wpa_supplicant: TDLS: TDLS is allowed in the target BSS
09-01 21:09:28.020  2379  2379 D wpa_supplicant: TDLS: TDLS channel switch allowed in the target BSS
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: No ongoing scan/p2p-scan found to abort
09-01 21:09:28.020  2379  2379 D wpa_supplicant: wlan0: Add radio work 'connect'@0x76a1830540
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: First radio work item in the queue - schedule start immediately
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: Starting radio work 'connect'@0x76a1830540 after 0.000085 second wait
09-01 21:09:28.021  2379  2379 I wpa_supplicant: wlan0: Trying to associate with SSID 'jiatai 5G'
09-01 21:09:28.021  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.select succeeded
09-01 21:09:28.021  2379  2379 I wpa_supplicant: wlan0: Trying to associate with SSID 'jiatai 5G'
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: Cancelling scan request
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: clearing own WPA/RSN IE
09-01 21:09:28.021  2379  2379 D wpa_supplicant: RSN: PMKSA cache search - network_ctx=0x76a18b5c00 try_opportunistic=0
09-01 21:09:28.021  2379  2379 D wpa_supplicant: RSN: Search for BSSID 20:6b:e7:93:84:f9
09-01 21:09:28.021  2379  2379 D wpa_supplicant: RSN: No PMKSA cache entry found
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: RSN: using IEEE 802.11i/D9.0
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: Selected cipher suites: group 16 pairwise 16 key_mgmt 2 proto 2
09-01 21:09:28.021  2379  2379 D wpa_supplicant: WPA: set AP WPA IE - hexdump(len=24): dd 16 00 50 f2 01 01 00 00 50 f2 04 01 00 00 50 f2 04 01 00 00 50 f2 02
09-01 21:09:28.021  1561  2457 D SupplicantStateTracker: DefaultState{ when=-32ms what=151553 arg1=16 target=com.android.internal.util.StateMachine$SmHandler }
09-01 21:09:28.021  2379  2379 D wpa_supplicant: WPA: set AP RSN IE - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 00 00
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: using GTK CCMP
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: using PTK CCMP
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: using KEY_MGMT WPA-PSK
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: WPA: not using MGMT group cipher
09-01 21:09:28.021  2379  2379 D wpa_supplicant: WPA: Set own WPA IE default - hexdump(len=22): 30 14 01 00 00 0f ac 04 01 00 00 0f ac 04 01 00 00 0f ac 02 00 00
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: Automatic auth_alg selection: 0x1
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: Overriding auth_alg selection: 0x1
09-01 21:09:28.021  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021  2379  2379 D wpa_supplicant: Added supported operating classes IE - hexdump(len=18): 3b 10 7c 51 53 54 73 74 75 76 77 78 7c 7d 7e 7f 80 82
09-01 21:09:28.021  2379  2379 D wpa_supplicant: wlan0: State: DISCONNECTED -> ASSOCIATING

2.(五十五)Android O 连接WiFi AP流程梳理 之前梳理的WiFi连接的时序图

2.流程梳理

2.1 WifiSettings

    /* package */ void submit(WifiConfigController configController) {

        final WifiConfiguration config = configController.getConfig();

        if (config == null) {
            if (mSelectedAccessPoint != null
                    && mSelectedAccessPoint.isSaved()) {
                connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */);
            }
        } else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) {
            mWifiManager.save(config, mSaveListener);
        } else {
            mWifiManager.save(config, mSaveListener);
            if (mSelectedAccessPoint != null) { // Not an "Add network"
                connect(config, false /* isSavedNetwork */);
            }
        }

        mWifiTracker.resumeScanning();
    }

    protected void connect(final WifiConfiguration config, boolean isSavedNetwork) {
        // Log subtype if configuration is a saved network.
        mMetricsFeatureProvider.action(getActivity(), MetricsEvent.ACTION_WIFI_CONNECT,
                isSavedNetwork);
        mWifiManager.connect(config, mConnectListener);
        mClickedConnect = true;
    }

2.2 WifiManager

    /**
     * Connect to a network with the given configuration. The network also
     * gets added to the list of configured networks for the foreground user.
     *
     * For a new network, this function is used instead of a
     * sequence of addNetwork(), enableNetwork(), saveConfiguration() and
     * reconnect()
     *
     * @param config the set of variables that describe the configuration,
     *            contained in a {@link WifiConfiguration} object.
     * @param listener for callbacks on success or failure. Can be null.
     * @throws IllegalStateException if the WifiManager instance needs to be
     * initialized again
     *
     * @hide
     */
    @SystemApi
    public void connect(WifiConfiguration config, ActionListener listener) {
        if (config == null) throw new IllegalArgumentException("config cannot be null");
        // Use INVALID_NETWORK_ID for arg1 when passing a config object
        // arg1 is used to pass network id when the network already exists
        getChannel().sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID,
                putListener(listener), config);
    }

2.3 WifiServiceImpl

                case WifiManager.CONNECT_NETWORK: {
                    if (checkChangePermissionAndReplyIfNotAuthorized(
                            msg, WifiManager.CONNECT_NETWORK_FAILED)) {
                        WifiConfiguration config = (WifiConfiguration) msg.obj;
                        int networkId = msg.arg1;
                        Slog.d(TAG, "CONNECT "
                                + " nid=" + Integer.toString(networkId)
                                + " uid=" + msg.sendingUid
                                + " name="
                                + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                        if (config != null) {
                            if (DBG) Slog.d(TAG, "Connect with config " + config);
                            /* Command is forwarded to state machine */
                            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);
                            replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED,
                                    WifiManager.INVALID_ARGS);
                        }
                    }
                    break;
                }

2.4 WifiStateMachine

                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 hasCredentialChanged = false;
                    // New network addition.
                    if (config != null) {
                        result = mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
                        if (!result.isSuccess()) {
                            loge("CONNECT_NETWORK adding/updating config=" + config + " failed");
                            messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
                            replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
                                    WifiManager.ERROR);
                            break;
                        }
                        netId = result.getNetworkId();
                        hasCredentialChanged = result.hasCredentialChanged();
                    }
                    if (!connectToUserSelectNetwork(
                            netId, message.sendingUid, hasCredentialChanged)) {
                        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
                                WifiManager.NOT_AUTHORIZED);
                        break;
                    }
                    mWifiMetrics.logStaEvent(StaEvent.TYPE_CONNECT_NETWORK, config);
                    broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
                    replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
                    break;

这边分为两步:

  1. 更新网络并获取netId和验证credential是否改变
  2. 连接网络

对于新添加网络hasCredentialChanged肯定是false的,刚更新config为最新的。

    /**
     * Initiates connection to a network specified by the user/app. This method checks if the
     * requesting app holds the NETWORK_SETTINGS permission.
     *
     * @param netId Id network to initiate connection.
     * @param uid UID of the app requesting the connection.
     * @param forceReconnect Whether to force a connection even if we're connected to the same
     *                       network currently.
     */
    private boolean connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
        logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid
                + ", forceReconnect = " + forceReconnect);
        if (mWifiConfigManager.getConfiguredNetwork(netId) == null) {
            loge("connectToUserSelectNetwork Invalid network Id=" + netId);
            return false;
        }
        if (!mWifiConfigManager.enableNetwork(netId, true, uid)
                || !mWifiConfigManager.checkAndUpdateLastConnectUid(netId, uid)) {
            logi("connectToUserSelectNetwork Allowing uid " + uid
                    + " with insufficient permissions to connect=" + netId);
        } else {
            // Note user connect choice here, so that it will be considered in the next network
            // selection.
            mWifiConnectivityManager.setUserConnectChoice(netId);
        }
        if (!forceReconnect && mWifiInfo.getNetworkId() == netId) {
            // We're already connected to the user specified network, don't trigger a
            // reconnection unless it was forced.
            logi("connectToUserSelectNetwork already connecting/connected=" + netId);
        } else {
            mWifiConnectivityManager.prepareForForcedConnection(netId);
            startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY);
        }
        return true;
    }


    /**
     * Value to set in wpa_supplicant "bssid" field when we don't want to restrict connection to
     * a specific AP.
     */
    public static final String SUPPLICANT_BSSID_ANY = "any";

这边有个注释比较有意思,这边会记住用户的选择,在下次网络选择的时候会考虑其中,也就是说打开WiFi时的自动连接会将用户最近一次的连接行为考虑其中,这也很合理。

    /**
     * Automatically connect to the network specified
     *
     * @param networkId ID of the network to connect to
     * @param uid UID of the app triggering the connection.
     * @param bssid BSSID of the network
     */
    public void startConnectToNetwork(int networkId, int uid, String bssid) {
        sendMessage(CMD_START_CONNECT, networkId, uid, bssid);
    }

ConnectModeState会处理CMD_START_CONNECT 消息

                case CMD_START_CONNECT:
                    /* connect command coming from auto-join */
                    netId = message.arg1;
                    int uid = message.arg2;
                    bssid = (String) message.obj;

                    synchronized (mWifiReqCountLock) {
                        if (!hasConnectionRequests()) {
                            if (mNetworkAgent == null) {
                                loge("CMD_START_CONNECT but no requests and not connected,"
                                        + " bailing");
                                break;
                            } else if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
                                loge("CMD_START_CONNECT but no requests and connected, but app "
                                        + "does not have sufficient permissions, bailing");
                                break;
                            }
                        }
                    }

                    config = mWifiConfigManager.getConfiguredNetworkWithPassword(netId);
                    logd("CMD_START_CONNECT sup state "
                            + mSupplicantStateTracker.getSupplicantStateName()
                            + " my state " + getCurrentState().getName()
                            + " nid=" + Integer.toString(netId)
                            + " roam=" + Boolean.toString(mIsAutoRoaming));
                    if (config == null) {
                        loge("CMD_START_CONNECT and no config, bail out...");
                        break;
                    }
                    mTargetNetworkId = netId;
                    setTargetBssid(config, bssid);

                    reportConnectionAttemptStart(config, mTargetRoamBSSID,
                            WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);
                    if (mWifiNative.connectToNetwork(config)) {
                        mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT, config);
                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                        targetWificonfiguration = config;
                        mIsAutoRoaming = false;
                        if (isLinkDebouncing()) {
                            transitionTo(mRoamingState);
                        } else if (getCurrentState() != mDisconnectedState) {
                            transitionTo(mDisconnectingState);
                        }
                    } else {
                        loge("CMD_START_CONNECT Failed to start connection to network " + config);
                        reportConnectionAttemptEnd(
                                WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED,
                                WifiMetricsProto.ConnectionEvent.HLF_NONE);
                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
                                WifiManager.ERROR);
                        break;
                    }
                    break;

2.5 WifiNative

    /**
     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
     * This method does the following:
     * 1. Abort any ongoing scan to unblock the connection request.
     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
     * 3. Add a new network to wpa_supplicant.
     * 4. Save the provided configuration to wpa_supplicant.
     * 5. Select the new network in wpa_supplicant.
     * 6. Triggers reconnect command to wpa_supplicant.
     *
     * @param configuration WifiConfiguration parameters for the provided network.
     * @return {@code true} if it succeeds, {@code false} otherwise
     */
    public boolean connectToNetwork(WifiConfiguration configuration) {
        // Abort ongoing scan before connect() to unblock connection request.
        mWificondControl.abortScan();
        return mSupplicantStaIfaceHal.connectToNetwork(configuration);
    }

如注释所示,这个方法做了6件事:

1. 中止任何正在进行的扫描来不阻塞连接请求

2.删除wpa_supplicant中的任何现有网络(这会隐式触发断开连接)

3.在wpa_supplicant中添加一个新的网络

4.在wpa_supplicant中保存提供的configuration

5.在wpa_supplicant中选择新的网络

6.触发wpa_supplicant 的重新连接命令

2.6 SupplicantStaIfaceHal

    /**
     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
     * This method does the following:
     * 1. If |config| is different to the current supplicant network, removes all supplicant
     * networks and saves |config|.
     * 2. Select the new network in wpa_supplicant.
     *
     * @param config WifiConfiguration parameters for the provided network.
     * @return {@code true} if it succeeds, {@code false} otherwise
     */
    public boolean connectToNetwork(@NonNull WifiConfiguration config) {
        synchronized (mLock) {
            logd("connectToNetwork " + config.configKey());
            if (WifiConfigurationUtil.isSameNetwork(config, mCurrentNetworkLocalConfig)) {
                logd("Network is already saved, will not trigger remove and add operation.");
            } else {
                mCurrentNetworkRemoteHandle = null;
                mCurrentNetworkLocalConfig = null;
                if (!removeAllNetworks()) {
                    loge("Failed to remove existing networks");
                    return false;
                }
                Pair<SupplicantStaNetworkHal, WifiConfiguration> pair =
                        addNetworkAndSaveConfig(config);
                if (pair == null) {
                    loge("Failed to add/save network configuration: " + config.configKey());
                    return false;
                }
                mCurrentNetworkRemoteHandle = pair.first;
                mCurrentNetworkLocalConfig = pair.second;
            }

            if (!mCurrentNetworkRemoteHandle.select()) {
                loge("Failed to select network configuration: " + config.configKey());
                return false;
            }
            return true;
        }
    }

这边连接网络涉及两步:添加网络并保存配置以及选择网络

相关log

09-01 21:09:27.991   936   936 W wificond: Scan is not started. Ignore abort request
09-01 21:09:27.991  1561  2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:27.993  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.listNetworks succeeded
09-01 21:09:27.993  2379  2379 D wpa_supplicant: Deregistering network from hidl control: 0
09-01 21:09:27.994  1561  1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkRemoved received
09-01 21:09:27.995  1561  2460 D WifiHandler.WifiScanningService: Received message=159773d sendingUid=1000
09-01 21:09:27.995  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.removeNetwork succeeded
09-01 21:09:27.995  1561  2457 I SupplicantStaIfaceHal: addSupplicantStaNetwork via HIDL
09-01 21:09:27.995  1561  2460 D WifiScanningService: replySucceeded recvdMessage=159773
09-01 21:09:27.995  2379  2379 D wpa_supplicant: Registering network to hidl control: 0
09-01 21:09:27.995  1561  1999 D SupplicantStaIfaceHal: ISupplicantStaIfaceCallback.onNetworkAdded received
09-01 21:09:27.996  1561  2457 D SupplicantStaIfaceHal: ISupplicantStaIface.addNetwork succeeded
09-01 21:09:27.996  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setSsid succeeded
09-01 21:09:27.996  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.002  1561 14441 D WifiService: getConfiguredNetworks uid=1000
09-01 21:09:28.002  1561 14441 D WifiAsyncChannel.WifiService: sendMessageSynchronously.send message=131131
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPskPassphrase succeeded
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setScanSsid succeeded
09-01 21:09:28.016  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setRequirePmf succeeded
09-01 21:09:28.017  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setKeyMgmt succeeded
09-01 21:09:28.017  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setProto succeeded
09-01 21:09:28.018  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setAuthAlg succeeded
09-01 21:09:28.018  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setGroupCipher succeeded
09-01 21:09:28.019  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setPairwiseCipher succeeded
09-01 21:09:28.019  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setIdStr succeeded
09-01 21:09:28.020  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.registerCallback succeeded

2.6.1 addNetworkAndSaveConfig

    /**
     * Add a network configuration to wpa_supplicant.
     *
     * @param config Config corresponding to the network.
     * @return a Pair object including SupplicantStaNetworkHal and WifiConfiguration objects
     * for the current network.
     */
    private Pair<SupplicantStaNetworkHal, WifiConfiguration>
            addNetworkAndSaveConfig(WifiConfiguration config) {
        synchronized (mLock) {
            logi("addSupplicantStaNetwork via HIDL");
            if (config == null) {
                loge("Cannot add NULL network!");
                return null;
            }
            SupplicantStaNetworkHal network = addNetwork();
            if (network == null) {
                loge("Failed to add a network!");
                return null;
            }
            boolean saveSuccess = false;
            try {
                saveSuccess = network.saveWifiConfiguration(config);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Exception while saving config params: " + config, e);
            }
            if (!saveSuccess) {
                loge("Failed to save variables for: " + config.configKey());
                if (!removeAllNetworks()) {
                    loge("Failed to remove all networks on failure.");
                }
                return null;
            }
            return new Pair(network, new WifiConfiguration(config));
        }
    }

    /**
     * Adds a new network.
     *
     * @return The ISupplicantNetwork object for the new network, or null if the call fails
     */
    private SupplicantStaNetworkHal addNetwork() {
        synchronized (mLock) {
            final String methodStr = "addNetwork";
            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
            try {
                mISupplicantStaIface.addNetwork((SupplicantStatus status,
                        ISupplicantNetwork network) -> {
                    if (checkStatusAndLogFailure(status, methodStr)) {
                        newNetwork.value = network;
                    }
                });
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
            }
            if (newNetwork.value != null) {
                return getStaNetworkMockable(
                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
            } else {
                return null;
            }
        }
    }

mISupplicantStaIface 在 八十八)Android O WiFi启动流程梳理续——connectToSupplicant 梳理过,是连接supplicant成功后framework保留下来的服务器对象即ISupplicantStaIface应该是对应sta_iface.cpp的引用

external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/sta_iface.cpp

Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
{
	return validateAndCall(
	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
	    &StaIface::addNetworkInternal, _hidl_cb);
}

std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
StaIface::addNetworkInternal()
{
	android::sp<ISupplicantStaNetwork> network;
	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
	if (!ssid) {
		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
	}
	HidlManager *hidl_manager = HidlManager::getInstance();
	if (!hidl_manager ||
	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
		wpa_s->ifname, ssid->id, &network)) {
		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
	}
	return {{SupplicantStatusCode::SUCCESS, ""}, network};
}

/**
 * Retrieve the underlying |wpa_supplicant| struct
 * pointer for this iface.
 * If the underlying iface is removed, then all RPC method calls on this object
 * will return failure.
 */
wpa_supplicant *StaIface::retrieveIfacePtr()
{
	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}

wpa_supplicant.c

/**
 * wpa_supplicant_add_network - Add a new network
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: The new network configuration or %NULL if operation failed
 *
 * This function performs the following operations:
 * 1. Adds a new network.
 * 2. Send network addition notification.
 * 3. Marks the network disabled.
 * 4. Set network default parameters.
 */
struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
{
	struct wpa_ssid *ssid;

	ssid = wpa_config_add_network(wpa_s->conf);
	if (!ssid)
		return NULL;
	wpas_notify_network_added(wpa_s, ssid);
	ssid->disabled = 1;
	wpa_config_set_network_defaults(ssid);

	return ssid;
}

config.c

/**
 * wpa_config_add_network - Add a new network with empty configuration
 * @config: Configuration data from wpa_config_read()
 * Returns: The new network configuration or %NULL if operation failed
 */
struct wpa_ssid * wpa_config_add_network(struct wpa_config *config)
{
	int id;
	struct wpa_ssid *ssid, *last = NULL;

	id = -1;
	ssid = config->ssid;
	while (ssid) {
		if (ssid->id > id)
			id = ssid->id;
		last = ssid;
		ssid = ssid->next;
	}
	id++;

	ssid = os_zalloc(sizeof(*ssid));
	if (ssid == NULL)
		return NULL;
	ssid->id = id;
	dl_list_init(&ssid->psk_list);
	if (last)
		last->next = ssid;
	else
		config->ssid = ssid;

	wpa_config_update_prio_list(config);

	return ssid;
}

遍历ssid,找到最大的id,然后加1作为新添加网络的id。说到底就是在结构体数组后面加一个新的,没有就自己当第一个。

另外这个方法也很关键

wpas_notify_network_added(wpa_s, ssid);

notify.c

void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
			       struct wpa_ssid *ssid)
{
	if (wpa_s->p2p_mgmt)
		return;

	/*
	 * Networks objects created during any P2P activities should not be
	 * exposed out. They might/will confuse certain non-P2P aware
	 * applications since these network objects won't behave like
	 * regular ones.
	 */
	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
		wpas_dbus_register_network(wpa_s, ssid);
		wpas_hidl_register_network(wpa_s, ssid);
	}
}

hidl.cpp

int wpas_hidl_register_network(
    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
	if (!wpa_s || !wpa_s->global->hidl || !ssid)
		return 1;

	wpa_printf(
	    MSG_DEBUG, "Registering network to hidl control: %d", ssid->id);

	HidlManager *hidl_manager = HidlManager::getInstance();
	if (!hidl_manager)
		return 1;

	return hidl_manager->registerNetwork(wpa_s, ssid);
}

hidl_manager.cpp

/**
 * Register a network to hidl manager.
 *
 * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
 * the network is added.
 * @param ssid |wpa_ssid| struct corresponding to the network being added.
 *
 * @return 0 on success, 1 on failure.
 */
int HidlManager::registerNetwork(
    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
	if (!wpa_s || !ssid)
		return 1;

	// Generate the key to be used to lookup the network.
	const std::string network_key =
	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);

	if (isP2pIface(wpa_s)) {
		if (addHidlObjectToMap<P2pNetwork>(
			network_key,
			new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
			p2p_network_object_map_)) {
			wpa_printf(
			    MSG_ERROR,
			    "Failed to register P2P network with HIDL "
			    "control: %d",
			    ssid->id);
			return 1;
		}
		p2p_network_callbacks_map_[network_key] =
		    std::vector<android::sp<ISupplicantP2pNetworkCallback>>();
		// Invoke the |onNetworkAdded| method on all registered
		// callbacks.
		callWithEachP2pIfaceCallback(
		    wpa_s->ifname,
		    std::bind(
			&ISupplicantP2pIfaceCallback::onNetworkAdded,
			std::placeholders::_1, ssid->id));
	} else {
		if (addHidlObjectToMap<StaNetwork>(
			network_key,
			new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
			sta_network_object_map_)) {
			wpa_printf(
			    MSG_ERROR,
			    "Failed to register STA network with HIDL "
			    "control: %d",
			    ssid->id);
			return 1;
		}
		sta_network_callbacks_map_[network_key] =
		    std::vector<android::sp<ISupplicantStaNetworkCallback>>();
		// Invoke the |onNetworkAdded| method on all registered
		// callbacks.
		callWithEachStaIfaceCallback(
		    wpa_s->ifname,
		    std::bind(
			&ISupplicantStaIfaceCallback::onNetworkAdded,
			std::placeholders::_1, ssid->id));
	}
	return 0;
}

/**
 * Creates a unique key for the network using the provided |ifname| and
 * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
 * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
 *
 * @param ifname Name of the corresponding interface.
 * @param network_id ID of the corresponding network.
 */
const std::string getNetworkObjectMapKey(
    const std::string &ifname, int network_id)
{
	return ifname + "_" + std::to_string(network_id);
}

	// Map of all the STA network specific hidl objects controlled by
	// wpa_supplicant. This map is keyed in by the corresponding
	// |ifname| & |network_id|.
	std::map<const std::string, android::sp<StaNetwork>>
	    sta_network_object_map_;

这边new出一个StaNetwork对应,以network_key为key放入了sta_network_object_map_这个map中。

sta_network.h

/**
 * Implementation of StaNetwork hidl object. Each unique hidl
 * object is used for control operations on a specific network
 * controlled by wpa_supplicant.
 */
class StaNetwork : public ISupplicantStaNetwork
{
public:
	StaNetwork(
	    struct wpa_global* wpa_global, const char ifname[], int network_id);
	~StaNetwork() override = default;
	// Refer to |StaIface::invalidate()|.

一系列网络添加流程完了以后返回一个network对象给上层,这个network对象就是刚才在HidlManager中注册的StaNetwork对象。

	HidlManager *hidl_manager = HidlManager::getInstance();
	if (!hidl_manager ||
	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
		wpa_s->ifname, ssid->id, &network)) {
		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
	}

hidl_manager.cpp

/**
 * Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided
 * ifname and network_id.
 *
 * @param ifname Name of the corresponding interface.
 * @param network_id ID of the corresponding network.
 * @param network_object Hidl reference corresponding to the network.
 *
 * @return 0 on success, 1 on failure.
 */
int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId(
    const std::string &ifname, int network_id,
    android::sp<ISupplicantStaNetwork> *network_object)
{
	if (ifname.empty() || network_id < 0 || !network_object)
		return 1;

	// Generate the key to be used to lookup the network.
	const std::string network_key =
	    getNetworkObjectMapKey(ifname, network_id);

	auto network_object_iter = sta_network_object_map_.find(network_key);
	if (network_object_iter == sta_network_object_map_.end())
		return 1;

	*network_object = network_object_iter->second;
	return 0;
}

之后会saveWifiConfiguration

SupplicantStaNetworkHal.java

    /**
     * Save an entire WifiConfiguration to wpa_supplicant via HIDL.
     *
     * @param config WifiConfiguration object to be saved.
     * @return true if succeeds, false otherwise.
     * @throws IllegalArgumentException on malformed configuration params.
     */
    public boolean saveWifiConfiguration(WifiConfiguration config) {
        synchronized (mLock) {
            if (config == null) return false;
            /** SSID */
            if (config.SSID != null) {
                if (!setSsid(NativeUtil.decodeSsid(config.SSID))) {
                    Log.e(TAG, "failed to set SSID: " + config.SSID);
                    return false;
                }
            }
            /** BSSID */
            String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
            if (bssidStr != null) {
                byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
                if (!setBssid(bssid)) {
                    Log.e(TAG, "failed to set BSSID: " + bssidStr);
                    return false;
                }
            }
            /** Pre Shared Key */
            // This can either be quoted ASCII passphrase or hex string for raw psk.
            if (config.preSharedKey != null) {
                if (config.preSharedKey.startsWith("\"")) {
                    if (!setPskPassphrase(NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
                        Log.e(TAG, "failed to set psk passphrase");
                        return false;
                    }
                } else {
                    if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
                        Log.e(TAG, "failed to set psk");
                        return false;
                    }
                }
            }

            /** Wep Keys */
            boolean hasSetKey = false;
            if (config.wepKeys != null) {
                for (int i = 0; i < config.wepKeys.length; i++) {
                    if (config.wepKeys[i] != null) {
                        if (!setWepKey(
                                i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) {
                            Log.e(TAG, "failed to set wep_key " + i);
                            return false;
                        }
                        hasSetKey = true;
                    }
                }
            }
            /** Wep Tx Key Idx */
            if (hasSetKey) {
                if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
                    Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
                    return false;
                }
            }
            /** HiddenSSID */
            if (!setScanSsid(config.hiddenSSID)) {
                Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
                return false;
            }
            /** RequirePMF */
            if (!setRequirePmf(config.requirePMF)) {
                Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePMF);
                return false;
            }
            /** Key Management Scheme */
            if (config.allowedKeyManagement.cardinality() != 0) {
                // Add FT flags if supported.
                BitSet keyMgmtMask = addFastTransitionFlags(config.allowedKeyManagement);
                if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) {
                    Log.e(TAG, "failed to set Key Management");
                    return false;
                }
            }
            /** Security Protocol */
            if (config.allowedProtocols.cardinality() != 0
                    && !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
                Log.e(TAG, "failed to set Security Protocol");
                return false;
            }
            /** Auth Algorithm */
            if (config.allowedAuthAlgorithms.cardinality() != 0
                    && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
                    config.allowedAuthAlgorithms))) {
                Log.e(TAG, "failed to set AuthAlgorithm");
                return false;
            }
            /** Group Cipher */
            if (config.allowedGroupCiphers.cardinality() != 0
                    && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
                    config.allowedGroupCiphers))) {
                Log.e(TAG, "failed to set Group Cipher");
                return false;
            }
            /** Pairwise Cipher*/
            if (config.allowedPairwiseCiphers.cardinality() != 0
                    && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
                    config.allowedPairwiseCiphers))) {
                Log.e(TAG, "failed to set PairwiseCipher");
                return false;
            }
            /** metadata: FQDN + ConfigKey + CreatorUid */
            final Map<String, String> metadata = new HashMap<String, String>();
            if (config.isPasspoint()) {
                metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
            }
            metadata.put(ID_STRING_KEY_CONFIG_KEY, config.configKey());
            metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
            if (!setIdStr(createNetworkExtra(metadata))) {
                Log.e(TAG, "failed to set id string");
                return false;
            }
            /** UpdateIdentifier */
            if (config.updateIdentifier != null
                    && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
                Log.e(TAG, "failed to set update identifier");
                return false;
            }
            // Finish here if no EAP config to set
            if (config.enterpriseConfig != null
                    && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
                if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
                    return false;
                }
            }

            // Now that the network is configured fully, start listening for callback events.
            mISupplicantStaNetworkCallback =
                    new SupplicantStaNetworkHalCallback(config.networkId, config.SSID);
            if (!registerCallback(mISupplicantStaNetworkCallback)) {
                Log.e(TAG, "Failed to register callback");
                return false;
            }
            return true;
        }
    }

这边将WifiConfiguration中的各个属性复制到wpa_supplicant中去,比如ssid

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setSsid(java.util.ArrayList<Byte> ssid) {
        synchronized (mLock) {
            final String methodStr = "setSsid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status =  mISupplicantStaNetwork.setSsid(ssid);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

sta_network.cpp

Return<void> StaNetwork::setSsid(
    const hidl_vec<uint8_t> &ssid, setSsid_cb _hidl_cb)
{
	return validateAndCall(
	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
	    &StaNetwork::setSsidInternal, _hidl_cb, ssid);
}

SupplicantStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
{
	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
	if (ssid.size() == 0 ||
	    ssid.size() >
		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
					  SSID_MAX_LEN_IN_BYTES)) {
		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
	}
	if (setByteArrayFieldAndResetState(
		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
		&(wpa_ssid->ssid_len), "ssid")) {
		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
	}
	if (wpa_ssid->passphrase) {
		wpa_config_update_psk(wpa_ssid);
	}
	return {SupplicantStatusCode::SUCCESS, ""};
}



/**
 * Helper function to set value in a string field with a corresponding length
 * field in |wpa_ssid| structue instance for this network.
 * This function frees any existing data in these fields.
 */
int StaNetwork::setByteArrayFieldAndResetState(
    const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
    size_t *to_update_field_len, const char *hexdump_prefix)
{
	if (*to_update_field) {
		os_free(*to_update_field);
	}
	*to_update_field = (uint8_t *)os_malloc(value_len);
	if (!(*to_update_field)) {
		return 1;
	}
	os_memcpy(*to_update_field, value, value_len);
	*to_update_field_len = value_len;

	wpa_hexdump_ascii(
	    MSG_MSGDUMP, hexdump_prefix, *to_update_field,
	    *to_update_field_len);
	resetInternalStateAfterParamsUpdate();
	return 0;
}

2.6.2 select

    /**
     * Trigger a connection to this network.
     *
     * @return true if it succeeds, false otherwise.
     */
    public boolean select() {
        synchronized (mLock) {
            final String methodStr = "select";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status =  mISupplicantStaNetwork.select();
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

sta_network.cpp

Return<void> StaNetwork::select(select_cb _hidl_cb)
{
	return validateAndCall(
	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
	    &StaNetwork::selectInternal, _hidl_cb);
}

SupplicantStatus StaNetwork::selectInternal()
{
	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
	if (wpa_ssid->disabled == 2) {
		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
	}
	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
	wpa_s->scan_min_time.sec = 0;
	wpa_s->scan_min_time.usec = 0;
	wpa_supplicant_select_network(wpa_s, wpa_ssid);
	return {SupplicantStatusCode::SUCCESS, ""};
}

/**
 * wpa_supplicant_select_network - Attempt association with a network
 * @wpa_s: wpa_supplicant structure for a network interface
 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
 */
void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
				   struct wpa_ssid *ssid)
{

	struct wpa_ssid *other_ssid;
	int disconnected = 0;

	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
		if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
			wpa_s->own_disconnect_req = 1;
		wpa_supplicant_deauthenticate(
			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
		disconnected = 1;
	}

	if (ssid)
		wpas_clear_temp_disabled(wpa_s, ssid, 1);

	/*
	 * Mark all other networks disabled or mark all networks enabled if no
	 * network specified.
	 */
	for (other_ssid = wpa_s->conf->ssid; other_ssid;
	     other_ssid = other_ssid->next) {
		int was_disabled = other_ssid->disabled;
		if (was_disabled == 2)
			continue; /* do not change persistent P2P group data */

		other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
		if (was_disabled && !other_ssid->disabled)
			wpas_clear_temp_disabled(wpa_s, other_ssid, 0);

		if (was_disabled != other_ssid->disabled)
			wpas_notify_network_enabled_changed(wpa_s, other_ssid);
	}

	if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
	    wpa_s->wpa_state >= WPA_AUTHENTICATING) {
		/* We are already associated with the selected network */
		wpa_printf(MSG_DEBUG, "Already associated with the "
			   "selected network - do nothing");
		return;
	}

	if (ssid) {
		wpa_s->current_ssid = ssid;
		eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
		wpa_s->connect_without_scan =
			(ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;

		/*
		 * Don't optimize next scan freqs since a new ESS has been
		 * selected.
		 */
		os_free(wpa_s->next_scan_freqs);
		wpa_s->next_scan_freqs = NULL;
	} else {
		wpa_s->connect_without_scan = NULL;
	}

	wpa_s->disconnected = 0;
	wpa_s->reassociate = 1;

	if (wpa_s->connect_without_scan ||
	    wpa_supplicant_fast_associate(wpa_s) != 1) {
		wpa_s->scan_req = NORMAL_SCAN_REQ;
		wpas_scan_reset_sched_scan(wpa_s);
		wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
	}

	if (ssid)
		wpas_notify_network_selected(wpa_s, ssid);
}

supplicant流程先到这里吧,不大看得懂,后续再梳理。待续

3. WifiStateMachine的状态变化

下面结合log看下连接过程中WifiStateMachine的状态变化

09-01 21:09:27.991  1561  2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:28.021  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575903 1000 0 num=13
09-01 21:09:28.021  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753290/1208575904 1000 0 num=13
09-01 21:09:28.022  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753291/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.022  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATING -> state= CONNECTING debouncing=false
09-01 21:09:28.023  1561  2457 D WifiStateMachine: setDetailed state, old =DISCONNECTED and new state=CONNECTING hidden=false
09-01 21:09:28.023  1561  2457 D WifiStateMachine: setDetailed state send new extra info"jiatai 5G"
09-01 21:09:28.023  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753292/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.036  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.036  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753305/1208575918 1000 0 num=13
09-01 21:09:28.042  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753310/1208575924 1000 0 num=13
09-01 21:09:28.042  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.042  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.042  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753311/1208575924 1000 0 num=13
09-01 21:09:28.047  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575929 1000 0 num=13
09-01 21:09:28.047  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753316/1208575930 1000 0 num=13
09-01 21:09:28.053  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.053  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.053  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753322/1208575935 1000 0 num=13
09-01 21:09:28.054  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753323/1208575936 1000 0 num=13
09-01 21:09:28.059  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753328/1208575941 1000 0 num=13
09-01 21:09:28.060  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.060  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.060  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753329/1208575942 1000 0 num=13
09-01 21:09:28.065  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.065  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.065  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753334/1208575947 1000 0 num=13
09-01 21:09:28.066  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753335/1208575948 1000 0 num=13
09-01 21:09:28.071  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.071  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753340/1208575953 1000 0 num=13
09-01 21:09:28.074  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753343/1208575956 1000 0 num=13
09-01 21:09:28.075  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.075  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.075  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753344/1208575957 1000 0 num=13
09-01 21:09:28.081  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575963 1000 0 num=13
09-01 21:09:28.081  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753350/1208575964 1000 0 num=13
09-01 21:09:28.083  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753352/1208575965 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.083  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATED -> state= CONNECTING debouncing=false
09-01 21:09:28.083  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=CONNECTING hidden=false
09-01 21:09:28.083  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753353/1208575966 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.084  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.084  1561  2457 D WifiStateMachine:  DefaultState !CMD_ASSOCIATED_BSSID rt=411753353/1208575966 0 0 BSSID=20:6b:e7:93:84:f9 Target=any roam=false
09-01 21:09:28.085  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753354/1208575967 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.085  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=FOUR_WAY_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.085  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=AUTHENTICATING hidden=false
09-01 21:09:28.086  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753355/1208575968 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.091  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753360/1208575973 1000 0 num=13
09-01 21:09:28.091  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753360/1208575974 1000 0 num=13
09-01 21:09:28.091  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753361/1208575974 1000 0 num=13
09-01 21:09:28.092  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753361/1208575974 1000 0 num=13
09-01 21:09:28.095  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.095  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=GROUP_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.095  1561  2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=AUTHENTICATING hidden=false
09-01 21:09:28.095  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.098  1561  2457 D WifiStateMachine:  DisconnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.098  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753367/1208575980 1000 0 num=13
09-01 21:09:28.104  1561  2457 D WifiStateMachine:  DisconnectedState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104  1561  2457 D WifiStateMachine:  ConnectModeState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104  1561  2457 D WifiStateMachine: Network connection established
09-01 21:09:28.105  1561  2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false
09-01 21:09:28.134  1561  2457 D WifiStateMachine: L2ConnectedState clearTargetBssid any key="jiatai 5G"-WPA_PSK
09-01 21:09:28.135  1561  2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK  roam=false static=false
09-01 21:09:28.135  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false

先抽取如下SUPPLICANT_STATE_CHANGE_EVENT log看下

09-01 21:09:27.991  1561  2457 D SupplicantStaIfaceHal: connectToNetwork "jiatai 5G"-WPA_PSK
09-01 21:09:28.022  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753291/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.022  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATING -> state= CONNECTING debouncing=false
09-01 21:09:28.023  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753292/1208575905 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATING
09-01 21:09:28.083  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753352/1208575965 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.083  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=ASSOCIATED -> state= CONNECTING debouncing=false
09-01 21:09:28.083  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753353/1208575966 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: ASSOCIATED
09-01 21:09:28.085  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753354/1208575967 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.085  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=FOUR_WAY_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.086  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753355/1208575968 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: FOUR_WAY_HANDSHAKE
09-01 21:09:28.095  1561  2457 D WifiStateMachine:  DisconnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.095  1561  2457 D WifiStateMachine: SUPPLICANT_STATE_CHANGE_EVENT state=GROUP_HANDSHAKE -> state= AUTHENTICATING debouncing=false
09-01 21:09:28.095  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753364/1208575977 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: GROUP_HANDSHAKE
09-01 21:09:28.143  1561  2457 D WifiStateMachine:  ObtainingIpState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED
09-01 21:09:28.143  1561  2457 D WifiStateMachine:  L2ConnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED
09-01 21:09:28.143  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED

状态机在连接过程中时是处于DisconnectedState状态,后续会一直收到SUPPLICANT_STATE_CHANGE_EVENT消息进行状态变更。

DisconnectedState的父状态ConnectModeState会做如下处理:

                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                    SupplicantState state = handleSupplicantStateChange(message);
                    // A driver/firmware hang can now put the interface in a down state.
                    // We detect the interface going down and recover from it
                    if (!SupplicantState.isDriverActive(state)) {
                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
                            handleNetworkDisconnect();
                        }
                        log("Detected an interface down, restart driver");
                        // Rely on the fact that this will force us into killing supplicant and then
                        // restart supplicant from a clean state.
                        transitionTo(mSupplicantStoppingState);
                        sendMessage(CMD_START_SUPPLICANT);
                        break;
                    }

                    // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
                    // when authentication times out after a successful connection,
                    // we can figure this from the supplicant state. If supplicant
                    // state is DISCONNECTED, but the mNetworkInfo says we are not
                    // disconnected, we need to handle a disconnection
                    if (!isLinkDebouncing() && state == SupplicantState.DISCONNECTED &&
                            mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
                        if (mVerboseLoggingEnabled) {
                            log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
                        }
                        handleNetworkDisconnect();
                        transitionTo(mDisconnectedState);
                    }

                    // If we have COMPLETED a connection to a BSSID, start doing
                    // DNAv4/DNAv6 -style probing for on-link neighbors of
                    // interest (e.g. routers); harmless if none are configured.
                    if (state == SupplicantState.COMPLETED) {
                        mIpClient.confirmConfiguration();
                    }
                    break;

然后一直等放到状态变为SupplicantState.COMPLETED的时候,调用IpClient

    public void confirmConfiguration() {
        sendMessage(CMD_CONFIRM);
    }


                case CMD_CONFIRM:
                    // TODO: Possibly introduce a second type of confirmation
                    // that both probes (a) on-link neighbors and (b) does
                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
                    // roams.
                    if (mIpReachabilityMonitor != null) {
                        mIpReachabilityMonitor.probeAll();
                    }
                    break;

接着在看下如下NETWORK_CONNECTION_EVENT log

09-01 21:09:28.104  1561  2457 D WifiStateMachine:  DisconnectedState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104  1561  2457 D WifiStateMachine:  ConnectModeState !NETWORK_CONNECTION_EVENT rt=411753373/1208575986 16 0 null nid=-1 last="jiatai 5G"-WPA_PSK
09-01 21:09:28.104  1561  2457 D WifiStateMachine: Network connection established
09-01 21:09:28.104  1038  2499 I LOWI-8.5.0.3.a: [LOWI-Scan] get_intf_mode: WLAN interface type 2, err 0
09-01 21:09:28.104  2379  2379 D wpa_supplicant: EAPOL: SUPP_BE entering state IDLE
09-01 21:09:28.104  2379  2379 D wpa_supplicant: EAPOL authentication completed - result=SUCCESS
09-01 21:09:28.104  2379  2379 D wpa_supplicant: nl80211: Set rekey offload
09-01 21:09:28.104  2379  2379 D wpa_supplicant: RTM_NEWLINK: ifi_index=23 ifname=wlan0 operstate=6 linkmode=1 ifi_family=0 ifi_flags=0x11043 ([UP][RUNNING][LOWER_UP])
09-01 21:09:28.105  1561  2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false
09-01 21:09:28.122  1561  2455 I MiuiNetworkPolicy: wasConnected = false mWifiConnected = false mNetworkPriorityMode =255
09-01 21:09:28.122  2552  2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.122  4722  4722 D TrafficManageService: wifi2mobile:android.net.wifi.STATE_CHANGE
09-01 21:09:28.122  2552  2552 D StatusBar.NetworkController: slot=-10;action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.122  2650  2767 I QCNEJ/CndHalConnector: -> SND notifyRatConnectionStatusChanged(rat = 1, CONNECTING)
09-01 21:09:28.122  2552  2552 D StatusBar.NetworkController: updateNetworkName slotId=1 chosenNetType=13 mNetworkName=中国移动 mNetworkTypeName=4G
09-01 21:09:28.123  1561  2455 I MiuiNetworkPolicy: wasConnected = false mWifiConnected = false mNetworkPriorityMode =255
09-01 21:09:28.123  1561  4183 D WifiService: getWifiApEnabledState uid=1000
09-01 21:09:28.123  1561  4100 D WifiService: getConnectionInfo uid=1000
09-01 21:09:28.124  1088  1088 E Parcel  : Reading a NULL string not supported here.
09-01 21:09:28.124  1088  1088 E Parcel  : Reading a NULL string not supported here.
09-01 21:09:28.125  1561 14441 D WifiService: getWifiApEnabledState uid=1000
09-01 21:09:28.125  1088  1088 E Parcel  : Reading a NULL string not supported here.
09-01 21:09:28.125  1088  1088 E Parcel  : Reading a NULL string not supported here.
09-01 21:09:28.124  1561  4183 D WifiService: getConnectionInfo uid=1000
09-01 21:09:28.126  2552  2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.126  2552  2552 D StatusBar.NetworkController: slot=-10;action=android.net.wifi.STATE_CHANGE
09-01 21:09:28.126  2552  2552 D StatusBar.NetworkController: updateNetworkName slotId=1 chosenNetType=13 mNetworkName=中国移动 mNetworkTypeName=4G
09-01 21:09:28.127  1561  4100 D WifiService: getWifiEnabledState uid=1000
09-01 21:09:28.127  2650  2767 I QCNEJ/CndHalConnector: -> SND notifyRatConnectionStatusChanged(rat = 1, CONNECTING)
09-01 21:09:28.127  4722  4722 D TrafficManageService: wifi2mobile:android.net.wifi.STATE_CHANGE
09-01 21:09:28.128  1561  4183 D WifiService: getWifiEnabledState uid=1000
09-01 21:09:28.134  1561  2457 D WifiStateMachine: L2ConnectedState clearTargetBssid any key="jiatai 5G"-WPA_PSK
09-01 21:09:28.135  1561  2457 D SupplicantStaNetworkHal: ISupplicantStaNetwork.setBssid succeeded
09-01 21:09:28.135  1561  2457 D WifiCountryCode: Set ready: false
09-01 21:09:28.135  1561  2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK  roam=false static=false
09-01 21:09:28.135  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false
09-01 21:09:28.136  1561  2457 D WifiStateMachine: ObtainingIpAddress clearTargetBssid any key="jiatai 5G"-WPA_PSK
                case WifiMonitor.NETWORK_CONNECTION_EVENT:
                    if (mVerboseLoggingEnabled) log("Network connection established");
                    mLastNetworkId = lookupFrameworkNetworkId(message.arg1);
                    mWifiConfigManager.clearRecentFailureReason(mLastNetworkId);
                    mLastBssid = (String) message.obj;
                    reasonCode = message.arg2;
                    // TODO: This check should not be needed after WifiStateMachinePrime refactor.
                    // Currently, the last connected network configuration is left in
                    // wpa_supplicant, this may result in wpa_supplicant initiating connection
                    // to it after a config store reload. Hence the old network Id lookups may not
                    // work, so disconnect the network and let network selector reselect a new
                    // network.
                    config = getCurrentWifiConfiguration();
                    if (config != null) {
                        mWifiInfo.setBSSID(mLastBssid);
                        mWifiInfo.setNetworkId(mLastNetworkId);

                        ScanDetailCache scanDetailCache =
                                mWifiConfigManager.getScanDetailCacheForNetwork(config.networkId);
                        if (scanDetailCache != null && mLastBssid != null) {
                            ScanResult scanResult = scanDetailCache.getScanResult(mLastBssid);
                            if (scanResult != null) {
                                mWifiInfo.setFrequency(scanResult.frequency);
                            }
                        }
                        mWifiConnectivityManager.trackBssid(mLastBssid, true, reasonCode);
                        // We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA'
                        if (config.enterpriseConfig != null
                                && TelephonyUtil.isSimEapMethod(
                                        config.enterpriseConfig.getEapMethod())) {
                            String anonymousIdentity = mWifiNative.getEapAnonymousIdentity();
                            if (anonymousIdentity != null) {
                                config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
                            } else {
                                Log.d(TAG, "Failed to get updated anonymous identity"
                                        + " from supplicant, reset it in WifiConfiguration.");
                                config.enterpriseConfig.setAnonymousIdentity(null);
                            }
                            mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
                        }
                        sendNetworkStateChangeBroadcast(mLastBssid);
                        transitionTo(mObtainingIpState);
                    } else {
                        logw("Connected to unknown networkId " + mLastNetworkId
                                + ", disconnecting...");
                        sendMessage(CMD_DISCONNECT);
                    }
                    break;

收到该消息后进入到ObtainingIpState状态,与 (九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程 梳理的流程对接。

这两个消息都是SupplicantStaIfaceHal的SupplicantStaIfaceHalCallback上报上来的。

    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
        private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i
        private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
        @Override
        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
                                   ArrayList<Byte> ssid) {
            synchronized (mLock) {
                logCallback("onStateChanged");
                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
                WifiSsid wifiSsid =
                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
                mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
                if (newSupplicantState == SupplicantState.COMPLETED) {
                    mWifiMonitor.broadcastNetworkConnectionEvent(
                            mIfaceName, getCurrentNetworkId(), bssidStr);
                }
                mWifiMonitor.broadcastSupplicantStateChangeEvent(
                        mIfaceName, getCurrentNetworkId(), wifiSsid, bssidStr, newSupplicantState);
            }
        }

4. 总结

猜你喜欢

转载自blog.csdn.net/sinat_20059415/article/details/82718937