Android 12 WiFi连接过程

我们从setting 入口开始分析该过程;

1.setting界面 

packages\apps\Settings\src\com\android\settings\wifi\WifiSettings.java 创建Dialog2

@Override
    public Dialog onCreateDialog(int dialogId) {
        switch (dialogId) {
            case WIFI_DIALOG_ID:
                // modify network
                mDialog = WifiDialog2
                        .createModal(getActivity(), this, mDialogWifiEntry, mDialogMode);
                return mDialog;
            default:
                return super.onCreateDialog(dialogId);
        }
    }

 2.packages\apps\Settings\src\com\android\settings\wifi\WifiDialog2.java

点击事件

private static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE;
    private static final int BUTTON_FORGET = DialogInterface.BUTTON_NEUTRAL;
@Override
    public void onClick(DialogInterface dialogInterface, int id) {
        if (mListener != null) {
            switch (id) {
                case BUTTON_SUBMIT:
                    mListener.onSubmit(this);
                    break;
                case BUTTON_FORGET:
                    if (WifiUtils.isNetworkLockedDown(getContext(),
                            mWifiEntry.getWifiConfiguration())) {
                        RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
                                RestrictedLockUtilsInternal.getDeviceOwner(getContext()));
                        return;
                    }
                    mListener.onForget(this);
                    break;
            }
        }
    }
private final WifiDialog2Listener mListener;
WifiDialog2Listener 在WifiSettings里实现
  @Override
    public void onSubmit(WifiDialog2 dialog) {
        final int dialogMode = dialog.getMode();
        final WifiConfiguration config = dialog.getController().getConfig();
        final WifiEntry wifiEntry = dialog.getWifiEntry();

        if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) {
            if (config == null) {
                Toast.makeText(getContext(), R.string.wifi_failed_save_message,
                        Toast.LENGTH_SHORT).show();
            } else {
                mWifiManager.save(config, mSaveListener);
            }
        } else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT
                || (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) {
            if (config == null) {
                connect(wifiEntry, false /* editIfNoConfig */,
                        false /* fullScreenEdit*/);
            } else {
                mWifiManager.connect(config, new WifiConnectActionListener());
            }
        }
    }

调用 WifiManager.connect方法进行连接

packages\modules\Wifi\framework\java\android\net\wifi\WifiManager.java

public void connect(int networkId, @Nullable ActionListener listener) {
        if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative");
        connectInternal(null, networkId, listener);
    }
 private void connectInternal(@Nullable WifiConfiguration config, int networkId,
            @Nullable ActionListener listener) {
        ActionListenerProxy listenerProxy = null;
        if (listener != null) {
            listenerProxy = new ActionListenerProxy("connect", mLooper, listener);
        }
        try {
            mService.connect(config, networkId, listenerProxy);
        } catch (RemoteException e) {
            if (listenerProxy != null) listenerProxy.onFailure(ERROR);
        } catch (SecurityException e) {
            if (listenerProxy != null) listenerProxy.onFailure(NOT_AUTHORIZED);
        }
    }

mService是IWifiManager 类型的变量,由BaseWifiService实现

packages\modules\Wifi\service\java\com\android\server\wifi\BaseWifiService.java

public class BaseWifiService extends IWifiManager.Stub {

BaseWifiService是抽象类 具体实现逻辑在WifiServiceImpl

packages\modules\Wifi\service\java\com\android\server\wifi\WifiServiceImpl.java

 

    /**
     * Connects to a network.
     *
     * If the supplied config is not null, then the netId argument will be ignored and the config
     * will be saved (or updated if its networkId or profile key already exist) and connected to.
     *
     * If the supplied config is null, then the netId argument will be matched to a saved config to
     * be connected to.
     *
     * @param config New or existing config to add/update and connect to
     * @param netId Network ID of existing config to connect to if the supplied config is null
     * @param callback Listener to notify action result
     *
     * see: {@link WifiManager#connect(WifiConfiguration, WifiManager.ActionListener)}
     *      {@link WifiManager#connect(int, WifiManager.ActionListener)}
     */
    @Override
    public void connect(WifiConfiguration config, int netId, @Nullable IActionListener callback) {
        int uid = Binder.getCallingUid();
        if (!isPrivileged(Binder.getCallingPid(), uid)) {
            throw new SecurityException(TAG + ": Permission denied");
        }
        if (config != null) {
            config.networkId = removeSecurityTypeFromNetworkId(config.networkId);
        }
        final int netIdArg = removeSecurityTypeFromNetworkId(netId);
        mLog.info("connect uid=%").c(uid).flush();
        mWifiThreadRunner.post(() -> {
            ActionListenerWrapper wrapper = new ActionListenerWrapper(callback);
            final NetworkUpdateResult result;
            // if connecting using WifiConfiguration, save the network first
            if (config != null) {
                if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
                    mWifiMetrics.logUserActionEvent(
                            UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK, config.networkId);
                }
                result = mWifiConfigManager.addOrUpdateNetwork(config, uid);
                if (!result.isSuccess()) {
                    Log.e(TAG, "connect adding/updating config=" + config + " failed");
                    wrapper.sendFailure(WifiManager.ERROR);
                    return;
                }
                broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
            } else {
                if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
                    mWifiMetrics.logUserActionEvent(
                            UserActionEvent.EVENT_MANUAL_CONNECT, netIdArg);
                }
                result = new NetworkUpdateResult(netIdArg);
            }
            WifiConfiguration configuration = mWifiConfigManager
                    .getConfiguredNetwork(result.getNetworkId());
            if (configuration == null) {
                Log.e(TAG, "connect to Invalid network Id=" + netIdArg);
                wrapper.sendFailure(WifiManager.ERROR);
                return;
            }
            if (configuration.enterpriseConfig != null
                    && configuration.enterpriseConfig.isAuthenticationSimBased()) {
                int subId = mWifiCarrierInfoManager.getBestMatchSubscriptionId(configuration);
                if (!mWifiCarrierInfoManager.isSimReady(subId)) {
                    Log.e(TAG, "connect to SIM-based config=" + configuration
                            + "while SIM is absent");
                    wrapper.sendFailure(WifiManager.ERROR);
                    return;
                }
                if (mWifiCarrierInfoManager.requiresImsiEncryption(subId)
                        && !mWifiCarrierInfoManager.isImsiEncryptionInfoAvailable(subId)) {
                    Log.e(TAG, "Imsi protection required but not available for Network="
                            + configuration);
                    wrapper.sendFailure(WifiManager.ERROR);
                    return;
                }
            }
            mMakeBeforeBreakManager.stopAllSecondaryTransientClientModeManagers(() ->
                    mConnectHelper.connectToNetwork(result, wrapper, uid));
        });
    }

调用ConnectHelper的connectToNetwork方法  packages\modules\Wifi\service\java\com\android\server\wifi\ConnectHelper.java

    /**
     * Trigger connection to an existing network and provide status via the provided callback.
     * This uses the primary client mode manager for making the connection.
     */
    public void connectToNetwork(
            @NonNull NetworkUpdateResult result,
            @NonNull ActionListenerWrapper wrapper,
            int callingUid) {
        connectToNetwork(
                mActiveModeWarden.getPrimaryClientModeManager(), result, wrapper, callingUid);
    }

    /**
     * Trigger connection to an existing network and provide status via the provided callback.
     * This uses the provided client mode manager for making the connection.
     */
    public void connectToNetwork(
            @NonNull ClientModeManager clientModeManager,
            @NonNull NetworkUpdateResult result,
            @NonNull ActionListenerWrapper wrapper,
            int callingUid) {
        int netId = result.getNetworkId();
        if (mWifiConfigManager.getConfiguredNetwork(netId) == null) {
            Log.e(TAG, "connectToNetwork Invalid network Id=" + netId);
            wrapper.sendFailure(WifiManager.ERROR);
            return;
        }
        mWifiConfigManager.updateBeforeConnect(netId, callingUid);
        clientModeManager.connectNetwork(result, wrapper, callingUid);
    }

掉用 clientModeManager.connectNetwork(result, wrapper, callingUid);

clientModeManager   packages\modules\Wifi\service\java\com\android\server\wifi\ClientModeManager.java 是接口类 具体实现是在 

connectToNetwork(
                mActiveModeWarden.getPrimaryClientModeManager(), result, wrapper, callingUid);

packages\modules\Wifi\service\java\com\android\server\wifi\ActiveModeWarden.java

 @NonNull
    public ClientModeManager getPrimaryClientModeManager() {
        ClientModeManager cm = getPrimaryClientModeManagerNullable();
        if (cm != null) return cm;
        // If there is no primary client manager, return the default one.
        return mDefaultClientModeManager;
    }
@Nullable
    public ConcreteClientModeManager getPrimaryClientModeManagerNullable() {
        return getClientModeManagerInRole(ROLE_CLIENT_PRIMARY);
    }
/** Get any client mode manager in the given role, or null if none was found. */
    @Nullable
    public ConcreteClientModeManager getClientModeManagerInRole(ClientRole role) {
        for (ConcreteClientModeManager manager : mClientModeManagers) {
            if (manager.getRole() == role) return manager;
        }
        return null;
    }

所以最后调用的是ConcreteClientModeManager 的connectNetwork方法

packages\modules\Wifi\service\java\com\android\server\wifi\ConcreteClientModeManager.java

@Override
    public void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper,
            int callingUid) {
        getClientMode().connectNetwork(result, wrapper, callingUid);
    }
 @NonNull
    private ClientMode getClientMode() {
        if (mClientModeImpl != null) {
            return mClientModeImpl;
        }
        if (mScanOnlyModeImpl != null) {
            return mScanOnlyModeImpl;
        }
        return mDefaultClientModeManager;
    }

packages\modules\Wifi\service\java\com\android\server\wifi\ClientModeImpl.java

   /** Trigger network connection and provide status via the provided callback. */
    public void connectNetwork(NetworkUpdateResult result, ActionListenerWrapper wrapper,
            int callingUid) {
        Message message =
                obtainMessage(CMD_CONNECT_NETWORK, new ConnectNetworkMessage(result, wrapper));
        message.sendingUid = callingUid;
        sendMessage(message);
    }

发送CMD_CONNECT_NETWORK消息

   case CMD_CONNECT_NETWORK: {
                    ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
                    if (mIpClient == null) {
                        logd("IpClient is not ready, CONNECT_NETWORK dropped");
                        cnm.listener.sendFailure(WifiManager.ERROR);
                        break;
                    }
                    NetworkUpdateResult result = cnm.result;
                    int netId = result.getNetworkId();
                    connectToUserSelectNetwork(
                            netId, message.sendingUid, result.hasCredentialChanged());
                    mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CONNECT_NETWORK,
                            mWifiConfigManager.getConfiguredNetwork(netId));
                    cnm.listener.sendSuccess();
                    break;
                }
private void connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) {
        logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid
                + ", forceReconnect = " + forceReconnect);
        if (!forceReconnect && (mLastNetworkId == netId || mTargetNetworkId == netId)) {
            // We're already connecting/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);
            if (uid == Process.SYSTEM_UID) {
                mWifiMetrics.setNominatorForNetwork(netId,
                        WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
            }
            startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY);
        }
    }
/**
     * 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);
    }
case CMD_START_CONNECT: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, START_CONNECT dropped");

                        break;
                    }
                    /* connect command coming from auto-join */
                    int netId = message.arg1;
                    int uid = message.arg2;
                    String bssid = (String) message.obj;
                    mSentHLPs = false;
                    // Stop lingering (if it was lingering before) if we start a new connection.
                    // This means that the ClientModeManager was reused for another purpose, so it
                    // should no longer be in lingering mode.
                    mClientModeManager.setShouldReduceNetworkScore(false);

                    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;
                        }
                    }
                    WifiConfiguration config =
                            mWifiConfigManager.getConfiguredNetworkWithoutMasking(netId);
                    logd("CMD_START_CONNECT "
                            + " my state " + getCurrentState().getName()
                            + " nid=" + netId
                            + " roam=" + mIsAutoRoaming);
                    if (config == null) {
                        loge("CMD_START_CONNECT and no config, bail out...");
                        break;
                    }
                    mTargetNetworkId = netId;
                    // Update scorecard while there is still state from existing connection
                    mLastScanRssi = mWifiConfigManager.findScanRssi(netId,
                            mWifiHealthMonitor.getScanRssiValidTimeMs());
                    mWifiScoreCard.noteConnectionAttempt(mWifiInfo, mLastScanRssi, config.SSID);
                    mWifiBlocklistMonitor.setAllowlistSsids(config.SSID, Collections.emptyList());
                    mWifiBlocklistMonitor.updateFirmwareRoamingConfiguration(Set.of(config.SSID));

                    updateWifiConfigOnStartConnection(config, bssid);
                    reportConnectionAttemptStart(config, mTargetBssid,
                            WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);

                    String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName);
                    mWifiInfo.setMacAddress(currentMacAddress);
                    Log.i(getTag(), "Connecting with " + currentMacAddress + " as the mac address");

                    mTargetWifiConfiguration = config;
                    mNetworkNotFoundEventCount = 0;
                    /* Check for FILS configuration again after updating the config */
                    if (config.isFilsSha256Enabled() || config.isFilsSha384Enabled()) {
                        boolean isIpClientStarted = startIpClient(config, true);
                        if (isIpClientStarted) {
                            mIpClientWithPreConnection = true;
                            break;
                        }
                    }
                    connectToNetwork(config);
                    break;
                }
  private void connectToNetwork(WifiConfiguration config) {
        if ((config != null) && mWifiNative.connectToNetwork(mInterfaceName, config)) {
            mWifiLastResortWatchdog.noteStartConnectTime(config.networkId);
            mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CMD_START_CONNECT, config);
            mIsAutoRoaming = false;
            transitionTo(mL2ConnectingState);
        } else {
            loge("CMD_START_CONNECT Failed to start connection to network " + config);
            mTargetWifiConfiguration = null;
            stopIpClient();
            reportConnectionAttemptEnd(
                    WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED,
                    WifiMetricsProto.ConnectionEvent.HLF_NONE,
                    WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN);
        }
    }

packages\modules\Wifi\service\java\com\android\server\wifi\WifiNative.java

  public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
        // Abort ongoing scan before connect() to unblock connection request.
        mWifiCondManager.abortScan(ifaceName);
        return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
    }

packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaIfaceHal.java

    /**
     * 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 ifaceName Name of the interface.
     * @param config WifiConfiguration parameters for the provided network.
     * @return {@code true} if it succeeds, {@code false} otherwise
     */
    public boolean connectToNetwork(@NonNull String ifaceName, @NonNull WifiConfiguration config) {
        synchronized (mLock) {
            logd("connectToNetwork " + config.getProfileKey());
            WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName);
            if (WifiConfigurationUtil.isSameNetwork(config, currentConfig)) {
                String networkSelectionBSSID = config.getNetworkSelectionStatus()
                        .getNetworkSelectionBSSID();
                String networkSelectionBSSIDCurrent =
                        currentConfig.getNetworkSelectionStatus().getNetworkSelectionBSSID();
                if (Objects.equals(networkSelectionBSSID, networkSelectionBSSIDCurrent)) {
                    logd("Network is already saved, will not trigger remove and add operation.");
                } else {
                    logd("Network is already saved, but need to update BSSID.");
                    if (!setCurrentNetworkBssid(
                            ifaceName,
                            config.getNetworkSelectionStatus().getNetworkSelectionBSSID())) {
                        loge("Failed to set current network BSSID.");
                        return false;
                    }
                    mCurrentNetworkLocalConfigs.put(ifaceName, new WifiConfiguration(config));
                }
            } else {
                mCurrentNetworkRemoteHandles.remove(ifaceName);
                mCurrentNetworkLocalConfigs.remove(ifaceName);
                mLinkedNetworkLocalAndRemoteConfigs.remove(ifaceName);
                if (!removeAllNetworks(ifaceName)) {
                    loge("Failed to remove existing networks");
                    return false;
                }
                Pair<SupplicantStaNetworkHal, WifiConfiguration> pair =
                        addNetworkAndSaveConfig(ifaceName, config);
                if (pair == null) {
                    loge("Failed to add/save network configuration: " + config
                            .getProfileKey());
                    return false;
                }
                mCurrentNetworkRemoteHandles.put(ifaceName, pair.first);
                mCurrentNetworkLocalConfigs.put(ifaceName, pair.second);
            }
            SupplicantStaNetworkHal networkHandle =
                    checkSupplicantStaNetworkAndLogFailure(ifaceName, "connectToNetwork");
            if (networkHandle == null) {
                loge("No valid remote network handle for network configuration: "
                        + config.getProfileKey());
                return false;
            }

            PmkCacheStoreData pmkData = mPmkCacheEntries.get(config.networkId);
            if (pmkData != null
                    && !WifiConfigurationUtil.isConfigForPskNetwork(config)
                    && pmkData.expirationTimeInSec > mClock.getElapsedSinceBootMillis() / 1000) {
                logi("Set PMK cache for config id " + config.networkId);
                if (networkHandle.setPmkCache(pmkData.data)) {
                    mWifiMetrics.setConnectionPmkCache(ifaceName, true);
                }
            }

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

packages\modules\Wifi\service\java\com\android\server\wifi\SupplicantStaNetworkHal.java

 /**
     * 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;
            }
        }
    }

 调用到hal层

hardware\interfaces\wifi\supplicant\1.0\ISupplicantStaNetwork.hal

/**
   * Initiate connection to this network.
   *
   * @return status Status of the operation.
   *         Possible status codes:
   *         |SupplicantStatusCode.SUCCESS|,
   *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
   *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
   */
  select() generates (SupplicantStatus status);

接下来会进入到 external\wpa_supplicant_8\wpa_supplicant\hidl\1.4\sta_iface.cpp

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, ""};
}

external\wpa_supplicant_8\wpa_supplicant\wpa_supplicant.c

/**
 * 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;
    wpa_s_clear_sae_rejected(wpa_s);
    wpa_s->last_owe_group = 0;
    if (ssid) {
        ssid->owe_transition_bss_select_count = 0;
        wpa_s_setup_sae_pt(wpa_s->conf, ssid);
    }

    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);
}

 

posted @ 2023-09-14 17:50  xiaowang_lj  阅读(798)  评论(0编辑  收藏  举报