Wifi模块—源码分析连接AP(Android P)

一 前言

        在前面一篇简单地说明了用户在WifiSettings界面选择一个AP显示配置AP参数的对话框的过程,当用户在对话框中选择好加密方式和输入密码之后,点击确定按钮,Android就会去连接这个AP,这一篇将主要分析连接AP的过程(AP参数没有保存的这种情况)。

                                                Wifi模块—源码分析配置AP(Android P)

二 图示调用流程

       为了调用流程图更简洁明了,整个调用流程图示将以一条主线走下去,对于其它的一些方法调用将不在流程图显示,更详细更细节地可以看下面的代码具体流程。

三 代码具体流程

1 应用层

1.1 packages/apps/settings/WifiSettings.java

当填写完配置相关参数后,点击确定按钮会监听到操作。

@Override
public void onSubmit(WifiDialog dialog) {
    if (mDialog != null) {
        submit(mDialog.getController());
    }
}

看submit。

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

看mWifiManager.save。

扫描二维码关注公众号,回复: 3700348 查看本文章

2 框架层

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

/**
* Save the given network to the list of configured networks for the
* foreground user. If the network already exists, the configuration
* is updated. Any new network is enabled by default.
*
* For a new network, this function is used instead of a
* sequence of addNetwork() and enableNetwork().
*
* For an existing network, it accomplishes the task of updateNetwork()
*
* This API will cause reconnect if the crecdentials of the current active
* connection has been changed.
*
* @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
*/
public void save(WifiConfiguration config, ActionListener listener) {
    if (config == null) throw new IllegalArgumentException("config cannot be null");
    getChannel().sendMessage(SAVE_NETWORK, 0, putListener(listener), config);

通过异步通道AsyncChannel来调用WifiServiceImpl的ClientHandler来处理SAVE_NETWORK消息。

2.2 frameworks/base/wifi/java/android/net/wifi/WifiServiceImpl.java

/**
* Handles client connections
*/
private class ClientHandler extends WifiHandler {

    ClientHandler(String tag, Looper looper) {
        super(tag, looper);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            ...
            case WifiManager.SAVE_NETWORK: {
                if (checkChangePermissionAndReplyIfNotAuthorized(
                        msg, WifiManager.SAVE_NETWORK_FAILED)) {
                    WifiConfiguration config = (WifiConfiguration) msg.obj;
                    int networkId = msg.arg1;
                    Slog.d(TAG, "SAVE"
                            + " nid=" + Integer.toString(networkId)
                            + " config=" + config
                            + " uid=" + msg.sendingUid
                            + " name="
                            + mContext.getPackageManager().getNameForUid(msg.sendingUid));
                    if (config != null) {
                        /* Command is forwarded to state machine */
                        mWifiStateMachine.sendMessage(Message.obtain(msg));
                    } else {
                        Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid msg=" + msg);
                        replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED,
                                WifiManager.INVALID_ARGS);
                    }
                }
                break;
            }
            ...
        }
    }
    ...
}

mWifiStateMachine.sendMessage发送消息直接让WifiStateMachine状态机来处理。

2.3 frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper,
                        UserManager userManager, WifiInjector wifiInjector,
                        BackupManagerProxy backupManagerProxy, WifiCountryCode countryCode,
                        WifiNative wifiNative,
                        WrongPasswordNotifier wrongPasswordNotifier,
                        SarManager sarManager) {
    ...
    // CHECKSTYLE:OFF IndentationCheck
    addState(mDefaultState);
        addState(mConnectModeState, mDefaultState);
            addState(mL2ConnectedState, mConnectModeState);
                addState(mObtainingIpState, mL2ConnectedState);
                addState(mConnectedState, mL2ConnectedState);
                addState(mRoamingState, mL2ConnectedState);
            addState(mDisconnectingState, mConnectModeState);
            addState(mDisconnectedState, mConnectModeState);
    // CHECKSTYLE:ON IndentationCheck

    setInitialState(mDefaultState);

    setLogRecSize(NUM_LOG_RECS_NORMAL);
    setLogOnlyTransitions(false);

    //start the state machine
    start();

    // Learn the initial state of whether the screen is on.
    // We update this field when we receive broadcasts from the system.
    handleScreenStateChanged(powerManager.isInteractive());
}

WifiStateMachine的状态图为

WifiStateMachine此时处于DisconnectedState状态,但这个状态里没有做什么,接着ConnectModeState会进行处理。

class ConnectModeState extends State {
    ...
    @Override
    public boolean processMessage(Message message) {
        WifiConfiguration config;
        int netId;
        boolean ok;
        boolean didDisconnect;
        String bssid;
        String ssid;
        NetworkUpdateResult result;
        Set<Integer> removedNetworkIds;
        int reasonCode;
        boolean timedOut;
        logStateAndMessage(message, this);

        switch (message.what) {
            ...
            case WifiManager.SAVE_NETWORK:
                result = saveNetworkConfigAndSendReply(message);
                netId = result.getNetworkId();
                if (result.isSuccess() && mWifiInfo.getNetworkId() == netId) {
                    if (result.hasCredentialChanged()) {
                        config = (WifiConfiguration) message.obj;
                        // The network credentials changed and we're connected to this network,
                        // start a new connection with the updated credentials.
                        logi("SAVE_NETWORK credential changed for config=" + config.configKey()
                                + ", Reconnecting.");
                        startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
                    } else {
                        if (result.hasProxyChanged()) {
                            log("Reconfiguring proxy on connection");
                            mIpClient.setHttpProxy(
                                    getCurrentWifiConfiguration().getHttpProxy());
                        }
                        if (result.hasIpChanged()) {
                            // The current connection configuration was changed
                            // We switched from DHCP to static or from static to DHCP, or the
                            // static IP address has changed.
                            log("Reconfiguring IP on connection");
                            // TODO(b/36576642): clear addresses and disable IPv6
                            // to simplify obtainingIpState.
                            transitionTo(mObtainingIpState);
                        }
                    }
                }
                break;
            ...
            }
            return HANDLED;
        }
    }
}

首先会调用saveNetworkConfigAndSendReply来保存连接配置参数并发送广播。

/**
* Private method to handle calling WifiConfigManager to add & enable network configs and reply
* to the message from the sender of the outcome.
*
* @return NetworkUpdateResult with networkId of the added/updated configuration. Will return
* {@link WifiConfiguration#INVALID_NETWORK_ID} in case of error.
*/
private NetworkUpdateResult saveNetworkConfigAndSendReply(Message message) {
    WifiConfiguration config = (WifiConfiguration) message.obj;
    if (config == null) {
        loge("SAVE_NETWORK with null configuration "
                + mSupplicantStateTracker.getSupplicantStateName()
                + " my state " + getCurrentState().getName());
        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
        return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
    }
    NetworkUpdateResult result =
            mWifiConfigManager.addOrUpdateNetwork(config, message.sendingUid);
    if (!result.isSuccess()) {
        loge("SAVE_NETWORK adding/updating config=" + config + " failed");
        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
        return result;
    }
    if (!mWifiConfigManager.enableNetwork(
            result.getNetworkId(), false, message.sendingUid)) {
        loge("SAVE_NETWORK enabling config=" + config + " failed");
        messageHandlingStatus = MESSAGE_HANDLING_STATUS_FAIL;
        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED, WifiManager.ERROR);
        return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
    }
    broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
    replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
    return result;
}

调用mWifiConfigManager.addOrUpdateNetwork进行配置参数的保存,调用 broadcastWifiCredentialChanged发送广播。

 /**
* Notify interested parties if a wifi config has been changed.
*
* @param wifiCredentialEventType WIFI_CREDENTIAL_SAVED or WIFI_CREDENTIAL_FORGOT
* @param config Must have a WifiConfiguration object to succeed
* TODO: b/35258354 investigate if this can be removed.  Is the broadcast sent by
* WifiConfigManager sufficient?
*/
private void broadcastWifiCredentialChanged(int wifiCredentialEventType,
        WifiConfiguration config) {
    if (config != null && config.preSharedKey != null) {
        Intent intent = new Intent(WifiManager.WIFI_CREDENTIAL_CHANGED_ACTION);
        intent.putExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_SSID, config.SSID);
        intent.putExtra(WifiManager.EXTRA_WIFI_CREDENTIAL_EVENT_TYPE,
                wifiCredentialEventType);
        mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
                android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE);
    }
}

除了对配置AP参数的保存之外,回过头来再看startConnectToNetwork。

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

发送CMD_START_CONNECT消息,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.getConfiguredNetworkWithoutMasking(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);

    if (mEnableConnectedMacRandomization.get()) {
        configureRandomizedMacAddress(config);
    }

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

    reportConnectionAttemptStart(config, mTargetRoamBSSID,
                    WifiMetricsProto.ConnectionEvent.ROAM_UNRELATED);
    if (mWifiNative.connectToNetwork(mInterfaceName, config)) {
        mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT, config);
        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
        targetWificonfiguration = config;
        mIsAutoRoaming = false;
        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;

看mWifiNative.connectToNetwork。

2.4 frameworks/base/wifi/java/android/net/wifi/WifiNative.java

/**
* 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 ifaceName Name of the interface.
* @param configuration WifiConfiguration parameters for the provided network.
* @return {@code true} if it succeeds, {@code false} otherwise
*/
public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
    // Abort ongoing scan before connect() to unblock connection request.
    mWificondControl.abortScan(ifaceName);
    return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
}

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

(1) 中止任何正在进行的扫描以免阻塞连接请求

(2)移除wpa_supplicant里的所有现有网络(这会隐式触发断开连接)

(3)在wpa_supplicant里添加一个新的网络

(4)在wpa_supplicant中保存提供的configuration

(5)在wpa_supplicant中选择新的网络

(6)触发wpa_supplicant 的重新连接命令

看mSupplicantStaIfaceHal.connectToNetwork。

2.5 frameworks/base/wifi/java/android/net/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.configKey());
        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);
            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.configKey());
                return false;
            }
            mCurrentNetworkRemoteHandles.put(ifaceName, pair.first);
            mCurrentNetworkLocalConfigs.put(ifaceName, pair.second);
        }
        SupplicantStaNetworkHal networkHandle =
                checkSupplicantStaNetworkAndLogFailure(ifaceName, "connectToNetwork");
        if (networkHandle == null || !networkHandle.select()) {
            loge("Failed to select network configuration: " + config.configKey());
            return false;
        }
        return true;
    }
}

首先添加网络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(@NonNull String ifaceName, WifiConfiguration config) {
    synchronized (mLock) {
        logi("addSupplicantStaNetwork via HIDL");
        if (config == null) {
            loge("Cannot add NULL network!");
            return null;
        }
        SupplicantStaNetworkHal network = addNetwork(ifaceName);
        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(ifaceName)) {
                loge("Failed to remove all networks on failure.");
            }
            return null;
        }
        return new Pair(network, new WifiConfiguration(config));
    }
}

看 addNetwork。

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

添加网络就暂时只跟到Java框架层,回头再看保存配置network.saveWifiConfiguration。

2.6  frameworks/base/wifi/java/android/net/wifi/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;
    }
}

整个AP连接过程暂时就跟到Java框架层。

猜你喜欢

转载自blog.csdn.net/weixin_42093428/article/details/83066508