Android WiFi 连接

news2024/9/24 11:31:20

Android WiFi 连接

  • 1、设置中WiFi显示
  • 2、WiFi 连接流程
    • 2.1 获取PrimaryClientModeManager
    • 2.2 ClientModeImpl状态机ConnectableState
    • 2.3 ISupplicantStaNetworkCallback 回调监听
  • 3、 简要时序图
  • 4、原生低层驱动
  • 5、关键日志

1、设置中WiFi显示

Android WiFi基础概览
packages/apps/Settings/src/com/android/settings/network/NetworkProviderSettings.java
packages/apps/Settings/src/com/android/settings/wifi/WifiPickerTrackerHelper.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java
frameworks/opt/net/wifi/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java

  • mWifiPickerTracker.getConnectedWifiEntry() 当前连接的WiFi
  • mWifiPickerTracker.getWifiEntries() 搜索的WiFi
  • mAddWifiNetworkPreference 添加WiFi项
  • WifiManager.java#connectStandardWifiEntry.java#connect->WifiManager.java#connect 连接WiFi
    protected void updateWifiEntryPreferences() {
        // bypass the update if the activity and the view are not ready, or it's restricted UI.
        if (getActivity() == null || getView() == null || mIsRestricted) {
            return;
        }
        // in case state has changed
        if (mWifiPickerTracker == null
                || mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
            return;
        }

        boolean hasAvailableWifiEntries = false;
        mWifiEntryPreferenceCategory.setVisible(true);

        final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry();
        PreferenceCategory connectedWifiPreferenceCategory = getConnectedWifiPreferenceCategory();
        connectedWifiPreferenceCategory.setVisible(connectedEntry != null);
        if (connectedEntry != null) {
            final LongPressWifiEntryPreference connectedPref =
                    connectedWifiPreferenceCategory.findPreference(connectedEntry.getKey());
            if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) {
                connectedWifiPreferenceCategory.removeAll();
                final ConnectedWifiEntryPreference pref =
                        createConnectedWifiEntryPreference(connectedEntry);
                pref.setKey(connectedEntry.getKey());
                pref.refresh();
                connectedWifiPreferenceCategory.addPreference(pref);
                pref.setOnPreferenceClickListener(preference -> {
                    if (connectedEntry.canSignIn()) {
                        connectedEntry.signIn(null /* callback */);
                    } else {
                        launchNetworkDetailsFragment(pref);
                    }
                    return true;
                });
                pref.setOnGearClickListener(preference -> {
                    launchNetworkDetailsFragment(pref);
                });

                if (mClickedConnect) {
                    mClickedConnect = false;
                    scrollToPreference(connectedWifiPreferenceCategory);
                }
            }
        } else {
            connectedWifiPreferenceCategory.removeAll();
        }

        int index = 0;
        cacheRemoveAllPrefs(mWifiEntryPreferenceCategory);
        List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();
        for (WifiEntry wifiEntry : wifiEntries) {
            hasAvailableWifiEntries = true;

            String key = wifiEntry.getKey();
            LongPressWifiEntryPreference pref =
                    (LongPressWifiEntryPreference) getCachedPreference(key);
            if (pref != null) {
                if (pref.getWifiEntry() == wifiEntry) {
                    pref.setOrder(index++);
                    continue;
                } else {
                    // Create a new preference if the underlying WifiEntry object has changed
                    removePreference(key);
                }
            }

            pref = createLongPressWifiEntryPreference(wifiEntry);
            pref.setKey(wifiEntry.getKey());
            pref.setOrder(index++);
            pref.refresh();

            if (wifiEntry.getHelpUriString() != null) {
                pref.setOnButtonClickListener(preference -> {
                    openSubscriptionHelpPage(wifiEntry);
                });
            }
            mWifiEntryPreferenceCategory.addPreference(pref);
        }
        removeCachedPrefs(mWifiEntryPreferenceCategory);

        if (!hasAvailableWifiEntries) {
            setProgressBarVisible(true);
            Preference pref = new Preference(getPrefContext());
            pref.setSelectable(false);
            pref.setSummary(R.string.wifi_empty_list_wifi_on);
            pref.setOrder(index++);
            pref.setKey(PREF_KEY_EMPTY_WIFI_LIST);
            mWifiEntryPreferenceCategory.addPreference(pref);
        } else {
            // Continuing showing progress bar for an additional delay to overlap with animation
            getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */);
        }

        mAddWifiNetworkPreference.setOrder(index++);
        mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference);
        setAdditionalSettingsSummaries();
    }

2、WiFi 连接流程

2.1 获取PrimaryClientModeManager

packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ActiveModeWarden.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/ISupplicantStaIfaceHal.java

WifiManager.java#connect > WifiServiceImpl.java#connect > ConnectHelper.java#connectToNetwork > ActiveModeWarden.java#getPrimaryClientModeManager/getPrimaryClientModeManagerNullable/getClientModeManagerInRole(ROLE_CLIENT_PRIMARY)

在这里插入图片描述

2.2 ClientModeImpl状态机ConnectableState

packages/modules/Wifi/service/java/com/android/server/wifi/ConnectHelper.java
packages/modules/Wifi/service/java/com/android/server/wifi/ConcreteClientModeManager.java
packages/modules/Wifi/service/java/com/android/server/wifi/ClientModeImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/WifiNative.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java

ConnectHelper.java#connectToNetwork > ConcreteClientModeManager.java#connectToNetwork > ClientModeImpl.java#connectNetwork > ConnectableState#CMD_CONNECT_NETWORK > ClientModeImpl.java#connectToUserSelectNetwork > ClientModeImpl.java#connectToUserSelectNetwork > ConnectableState#CMD_START_CONNECT > ClientModeImpl.java#connectToNetwork > WifiNative.java#connectToNetwork > SupplicantStaIfaceHal.java#connectToNetwork > SupplicantStaIfaceHalAidlImpl.java#connectToNetwork

    class ConnectableState extends State {
        private boolean mIsScreenStateChangeReceiverRegistered = false;
        BroadcastReceiver mScreenStateChangeReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)) {
                    sendMessage(CMD_SCREEN_STATE_CHANGED, 1);
                } else if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
                    sendMessage(CMD_SCREEN_STATE_CHANGED, 0);
                }
            }
        };

        @Override
        public void enter() {
            Log.d(getTag(), "entering ConnectableState: ifaceName = " + mInterfaceName);

            setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, true);

            mWifiStateTracker.updateState(mInterfaceName, WifiStateTracker.INVALID);
            mIpClientCallbacks = new IpClientCallbacksImpl();
            Log.d(getTag(), "Start makeIpClient ifaceName = " + mInterfaceName);
            mFacade.makeIpClient(mContext, mInterfaceName, mIpClientCallbacks);
            mIpClientCallbacks.awaitCreation();
        }

        private void continueEnterSetup(IpClientManager ipClientManager) {
            mIpClient = ipClientManager;
            setupClientMode();

            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_ON);
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            if (!mIsScreenStateChangeReceiverRegistered) {
                mContext.registerReceiver(mScreenStateChangeReceiver, filter);
                mIsScreenStateChangeReceiverRegistered = true;
            }
            // Learn the initial state of whether the screen is on.
            // We update this field when we receive broadcasts from the system.
            handleScreenStateChanged(mContext.getSystemService(PowerManager.class).isInteractive());

            if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
                loge("Failed to remove networks on entering connect mode");
            }
            mWifiInfo.reset();
            mWifiInfo.setSupplicantState(SupplicantState.DISCONNECTED);

            sendNetworkChangeBroadcast(DetailedState.DISCONNECTED);

            // Inform metrics that Wifi is Enabled (but not yet connected)
            mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
            mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_ENABLED);
            mWifiScoreCard.noteSupplicantStateChanged(mWifiInfo);
        }

        @Override
        public void exit() {
            // Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc)
            mWifiMetrics.setWifiState(mInterfaceName, WifiMetricsProto.WifiLog.WIFI_DISABLED);
            mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_WIFI_DISABLED);

            if (!mWifiNative.removeAllNetworks(mInterfaceName)) {
                loge("Failed to remove networks on exiting connect mode");
            }
            if (mIsScreenStateChangeReceiverRegistered) {
                mContext.unregisterReceiver(mScreenStateChangeReceiver);
                mIsScreenStateChangeReceiverRegistered = false;
            }

            stopClientMode();
            mWifiScoreCard.doWrites();
        }

        @Override
        public boolean processMessage(Message message) {
            switch (message.what) {
                case CMD_CONNECTABLE_STATE_SETUP:
                    if (mIpClient != null) {
                        loge("Setup connectable state again when IpClient is ready?");
                    } else {
                        IpClientManager ipClientManager = (IpClientManager) message.obj;
                        continueEnterSetup(ipClientManager);
                    }
                    break;
                case CMD_ENABLE_RSSI_POLL: {
                    mEnableRssiPolling = (message.arg1 == 1);
                    break;
                }
                case CMD_SCREEN_STATE_CHANGED: {
                    handleScreenStateChanged(message.arg1 != 0);
                    break;
                }
                case WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, "
                                + "WifiP2pServiceImpl.DISCONNECT_WIFI_REQUEST dropped");
                        break;
                    }
                    if (mWifiP2pConnection.shouldTemporarilyDisconnectWifi()) {
                        mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_FRAMEWORK_DISCONNECT,
                                StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST);
                        mWifiNative.disconnect(mInterfaceName);
                    } else {
                        mWifiNative.reconnect(mInterfaceName);
                    }
                    break;
                }
                case CMD_RECONNECT: {
                    WorkSource workSource = (WorkSource) message.obj;
                    mWifiConnectivityManager.forceConnectivityScan(workSource);
                    break;
                }
                case CMD_REASSOCIATE: {
                    if (mIpClient != null) {
                        logd("IpClient is not ready, REASSOCIATE dropped");

                        mWifiNative.reassociate(mInterfaceName);
                    }
                    break;
                }
                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;
                    }
                    mCurrentConnectionDetectedCaptivePortal = false;
                    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;
                            transitionTo(mL2ConnectingState);
                            break;
                        }
                    }
                    mInsecureEapNetworkHandler.prepareConnection(mTargetWifiConfiguration);
                    setSelectedRcoiForPasspoint(config);
                    connectToNetwork(config);
                    break;
                }
                case CMD_START_FILS_CONNECTION: {
                    if (mIpClient == null) {
                        logd("IpClient is not ready, START_FILS_CONNECTION dropped");
                        break;
                    }
                    mWifiMetrics.incrementConnectRequestWithFilsAkmCount();
                    List<Layer2PacketParcelable> packets;
                    packets = (List<Layer2PacketParcelable>) message.obj;
                    if (mVerboseLoggingEnabled) {
                        Log.d(getTag(), "Send HLP IEs to supplicant");
                    }
                    addLayer2PacketsToHlpReq(packets);
                    WifiConfiguration config = mTargetWifiConfiguration;
                    connectToNetwork(config);
                    break;
                }
                case CMD_CONNECT_NETWORK: {
                    ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
                    if (mIpClient == null) {
                        logd("IpClient is not ready, CONNECT_NETWORK dropped");
                        cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
                        break;
                    }
                    NetworkUpdateResult result = cnm.result;
                    int netId = result.getNetworkId();
                    connectToUserSelectNetwork(
                            netId, message.sendingUid, result.hasCredentialChanged(),
                            cnm.packageName);
                    mWifiMetrics.logStaEvent(mInterfaceName, StaEvent.TYPE_CONNECT_NETWORK,
                            mWifiConfigManager.getConfiguredNetwork(netId));
                    cnm.listener.sendSuccess();
                    break;
                }
                case CMD_SAVE_NETWORK: {
                    ConnectNetworkMessage cnm = (ConnectNetworkMessage) message.obj;
                    if (mIpClient == null) {
                        logd("IpClient is not ready, SAVE_NETWORK dropped");
                        cnm.listener.sendFailure(WifiManager.ActionListener.FAILURE_INTERNAL_ERROR);
                        break;
                    }
                    NetworkUpdateResult result = cnm.result;
                    int netId = result.getNetworkId();
                    if (mWifiInfo.getNetworkId() == netId) {
                        if (result.hasCredentialChanged()) {
                            // The network credentials changed and we're connected to this network,
                            // start a new connection with the updated credentials.
                            logi("CMD_SAVE_NETWORK credential changed for nid="
                                    + netId + ". Reconnecting.");
                            startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
                        } else {
                            if (result.hasProxyChanged()) {
                                if (mIpClient != null) {
                                    log("Reconfiguring proxy on connection");
                                    WifiConfiguration currentConfig =
                                            getConnectedWifiConfigurationInternal();
                                    if (currentConfig != null) {
                                        mIpClient.setHttpProxy(currentConfig.getHttpProxy());
                                    } else {
                                        Log.w(getTag(),
                                                "CMD_SAVE_NETWORK proxy change - but no current "
                                                        + "Wi-Fi config");
                                    }
                                }
                            }
                            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");
                                WifiConfiguration currentConfig =
                                        getConnectedWifiConfigurationInternal();
                                if (currentConfig != null) {
                                    transitionTo(mL3ProvisioningState);
                                } else {
                                    Log.w(getTag(), "CMD_SAVE_NETWORK Ip change - but no current "
                                            + "Wi-Fi config");
                                }
                            }
                        }
                    } else if (mWifiInfo.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID
                            && result.hasCredentialChanged()) {
                        logi("CMD_SAVE_NETWORK credential changed for nid="
                                + netId + " while disconnected. Connecting.");
                        WifiConfiguration config =
                                mWifiConfigManager.getConfiguredNetwork(netId);
                        if (!mWifiPermissionsUtil.isAdminRestrictedNetwork(config)) {
                            startConnectToNetwork(netId, message.sendingUid, SUPPLICANT_BSSID_ANY);
                        }
                    } else if (result.hasCredentialChanged()) {
                        WifiConfiguration currentConfig =
                                getConnectedWifiConfigurationInternal();
                        WifiConfiguration updatedConfig =
                                mWifiConfigManager.getConfiguredNetwork(netId);
                        if (currentConfig != null && currentConfig.isLinked(updatedConfig)) {
                            logi("current network linked config saved, update linked networks");
                            updateLinkedNetworks(currentConfig);
                        }
                    }
                    cnm.listener.sendSuccess();
                    break;
                }
                case CMD_BLUETOOTH_CONNECTION_STATE_CHANGE: {
                    mWifiNative.setBluetoothCoexistenceScanMode(
                            mInterfaceName, mWifiGlobals.isBluetoothConnected());
                    break;
                }
                case CMD_SET_SUSPEND_OPT_ENABLED: {
                    if (message.arg1 == 1) {
                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
                        if (message.arg2 == 1) {
                            mSuspendWakeLock.release();
                        }
                    } else {
                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
                    }
                    break;
                }
                case WifiMonitor.ANQP_DONE_EVENT: {
                    mPasspointManager.notifyANQPDone((AnqpEvent) message.obj);
                    break;
                }
                case CMD_STOP_IP_PACKET_OFFLOAD: {
                    int slot = message.arg1;
                    int ret = stopWifiIPPacketOffload(slot);
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendSocketKeepaliveEvent(slot, ret);
                    }
                    break;
                }
                case WifiMonitor.RX_HS20_ANQP_ICON_EVENT: {
                    mPasspointManager.notifyIconDone((IconEvent) message.obj);
                    break;
                }
                case WifiMonitor.HS20_DEAUTH_IMMINENT_EVENT:
                    mPasspointManager.handleDeauthImminentEvent((WnmData) message.obj,
                            getConnectedWifiConfigurationInternal());
                    break;
                case WifiMonitor.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT:
                    mWifiMetrics
                            .incrementTotalNumberOfPasspointConnectionsWithTermsAndConditionsUrl();
                    mTermsAndConditionsUrl = mPasspointManager
                            .handleTermsAndConditionsEvent((WnmData) message.obj,
                            getConnectedWifiConfigurationInternal());
                    if (mTermsAndConditionsUrl == null) {
                        loge("Disconnecting from Passpoint network due to an issue with the "
                                + "Terms and Conditions URL");
                        sendMessage(CMD_DISCONNECT, StaEvent.DISCONNECT_PASSPOINT_TAC);
                    }
                    break;
                case WifiMonitor.HS20_REMEDIATION_EVENT:
                    mPasspointManager.receivedWnmFrame((WnmData) message.obj);
                    break;
                case WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE: {
                    handleBssTransitionRequest((BtmFrameData) message.obj);
                    break;
                }
                case CMD_CONFIG_ND_OFFLOAD: {
                    final boolean enabled = (message.arg1 > 0);
                    mWifiNative.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
                    break;
                }
                // Link configuration (IP address, DNS, ...) changes notified via netlink
                case CMD_UPDATE_LINKPROPERTIES: {
                    updateLinkProperties((LinkProperties) message.obj);
                    break;
                }
                case CMD_START_IP_PACKET_OFFLOAD:
                case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF:
                case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
                    if (mNetworkAgent != null) {
                        mNetworkAgent.sendSocketKeepaliveEvent(message.arg1,
                                SocketKeepalive.ERROR_INVALID_NETWORK);
                    }
                    break;
                }
                case CMD_INSTALL_PACKET_FILTER: {
                    mCachedPacketFilter = (byte[]) message.obj;
                    if (mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableApfOnNonPrimarySta)
                            || isPrimary()) {
                        mWifiNative.installPacketFilter(mInterfaceName, mCachedPacketFilter);
                    } else {
                        Log.v(TAG, "Not applying packet filter on non primary CMM");
                    }
                    break;
                }
                case CMD_READ_PACKET_FILTER: {
                    final byte[] packetFilter;
                    if (mContext.getResources().getBoolean(
                            R.bool.config_wifiEnableApfOnNonPrimarySta)
                            || isPrimary()) {
                        packetFilter = mWifiNative.readPacketFilter(mInterfaceName);
                    } else {
                        Log.v(TAG, "Retrieving cached packet filter on non primary CMM");
                        packetFilter = mCachedPacketFilter;
                    }
                    if (mIpClient != null) {
                        mIpClient.readPacketFilterComplete(packetFilter);
                    }
                    break;
                }
                case CMD_SET_FALLBACK_PACKET_FILTERING: {
                    if ((boolean) message.obj) {
                        mWifiNative.startFilteringMulticastV4Packets(mInterfaceName);
                    } else {
                        mWifiNative.stopFilteringMulticastV4Packets(mInterfaceName);
                    }
                    break;
                }
                case CMD_DIAGS_CONNECT_TIMEOUT: {
                    mWifiDiagnostics.reportConnectionEvent(
                            WifiDiagnostics.CONNECTION_EVENT_TIMEOUT, mClientModeManager);
                    break;
                }
                case WifiP2pServiceImpl.P2P_CONNECTION_CHANGED:
                case CMD_RESET_SIM_NETWORKS:
                case WifiMonitor.NETWORK_CONNECTION_EVENT:
                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
                case CMD_RSSI_POLL:
                case CMD_ONESHOT_RSSI_POLL:
                case CMD_PRE_DHCP_ACTION:
                case CMD_PRE_DHCP_ACTION_COMPLETE:
                case CMD_POST_DHCP_ACTION:
                case WifiMonitor.SUP_REQUEST_IDENTITY:
                case WifiMonitor.SUP_REQUEST_SIM_AUTH:
                case WifiMonitor.TARGET_BSSID_EVENT:
                case WifiMonitor.ASSOCIATED_BSSID_EVENT:
                case WifiMonitor.TRANSITION_DISABLE_INDICATION:
                case CMD_UNWANTED_NETWORK:
                case CMD_CONNECTING_WATCHDOG_TIMER:
                case WifiMonitor.NETWORK_NOT_FOUND_EVENT:
                case CMD_ROAM_WATCHDOG_TIMER: {
                    // no-op: all messages must be handled in the base state in case it was missed
                    // in one of the child states.
                    break;
                }
                case CMD_ACCEPT_EAP_SERVER_CERTIFICATE:
                case CMD_REJECT_EAP_SERVER_CERTIFICATE:
                case CMD_START_ROAM:
                case CMD_START_RSSI_MONITORING_OFFLOAD:
                case CMD_STOP_RSSI_MONITORING_OFFLOAD:
                case CMD_IP_CONFIGURATION_SUCCESSFUL:
                case CMD_IP_CONFIGURATION_LOST:
                case CMD_IP_REACHABILITY_LOST:
                case CMD_IP_REACHABILITY_FAILURE: {
                    mMessageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
                    break;
                }
                case 0: {
                    // We want to notice any empty messages (with what == 0) that might crop up.
                    // For example, we may have recycled a message sent to multiple handlers.
                    Log.wtf(getTag(), "Error! empty message encountered");
                    break;
                }
                default: {
                    loge("Error! unhandled message" + message);
                    break;
                }
            }

            logStateAndMessage(message, this);
            return HANDLED;
        }
    }

2.3 ISupplicantStaNetworkCallback 回调监听

packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkHalAidlImpl.java
packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaNetworkCallbackAidlImpl.java

SupplicantStaIfaceHalAidlImpl.java#connectToNetwork / addNetworkAndSaveConfig > SupplicantStaNetworkHalAidlImpl.java#saveWifiConfiguration / registerNewCallback / registerCallback > mISupplicantStaNetwork.registerCallback(callback)

3、 简要时序图

在这里插入图片描述

4、原生低层驱动

external/wpa_supplicant_8

在这里插入图片描述

5、关键日志

WifiService: connect uid=|WifiConfigManager: Adding/Updating network|WifiConfigManager: Enable disabled network:|WifiConfigManager: Enabling network|WifiConfigManager: Update network last connect|WifiPickerTracker: Received broadcast:|WifiClientModeImpl.*entering.*State|WifiClientModeImpl.*entering|WifiClientModeImpl.*connectToUserSelectNetwork netId|WifiClientModeImpl.*CMD_START_CONNECT|WifiClientModeImpl.*Select candidate security params for|WifiClientModeImpl.*Connecting with|SupplicantStaIfaceHalAidlImpl: connectToNetwork|SupplicantStaNetworkHalAidlImpl: Successfully set SSID|SupplicantStaNetworkHalAidlImpl: The target security params|SupplicantStaIfaceHalAidlImpl: ISupplicantStaIfaceCallback|wpa_supplicant:.* State:|wpa_supplicant: Notifying state change event|wpa_supplicant: wlan

wpa_supplicant: wlan|wpa_supplicant:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ(九)死信队列

目录 一、简介1.1 定义1.2 何时进入死信队列&#xff1f;1.3 死信消息的变化1.4 死信队列的应用场景1.5 死信消息的生命周期 二、代码实现2.1 死信队列的配置步骤2.2 配置类2.3 配置文件2.4 生产者2.5 业务消费者2.6 死信消费者2.7 测试结果 三、总结 RabbitMQ 是流行的开源消息…

MYSQL InnoDB引擎

逻辑存储结构 架构 内存架构 磁盘结构 后台线程 事务原理 redolog undo log MVCC 基本概念 实现原理 隐藏字段 undo log readview

学习使用layPage, 多功能JS分页组件/插件的方法

学习使用layPage, 多功能JS分页组件/插件的方法 效果图分页代码 效果图 点击查看链接 分页代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>Layui</title><meta name"renderer" content"we…

用队列实现栈oj题——225

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;LeetCode刷题|数据结构|Linux 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 题目要求&#xff1a;实现 MyStack 类&#xff1a;注意&#xff1a;示例&#xff1a;解释&#xff1a;提示&#xff1a; 解题核心数据结构的定义…

通信触发流程

该示例方案主要介绍如何通过建立的Modbus或TCP通信来实现触发方案、协议解析、发送事件和以及响应配置等功能。 需求&#xff1a;使用Modbus通信触发指定流程运行。 搭建思路&#xff1a;在接收事件中使用协议组装&#xff0c;比较规则选择上升沿&#xff0c;当接收到的值从其…

如何成为一名高级UI设计师,UI设计与交互动效进阶教学

一、教程描述 本套教程从基础学习到案例实践教学&#xff0c;涵盖了设计师所需的全部知识和实战技术&#xff0c;比如&#xff0c;品牌形象设计&#xff0c;企业视觉识别系统VIS&#xff0c;标志logo提案设计&#xff0c;banner运营视觉设计&#xff0c;字体搭配使用&#xff…

学习笔记 | Kafka

一、概述 定义 1、Kafka传统定义&#xff1a;Kafka 是一个分布式的基于 发布/订阅模式 的消息队列&#xff08;Message Queue&#xff09; &#xff0c;主要应用与大数据实时处理领域。 2、发布/订阅&#xff1a;消息的发送者不会将消息直接发送给特定的订阅者&#xff0c;而…

企业网盘全方位解读:热门云存储工具的优势与适用场景

企业网盘无疑是当下最热门的企业协同工具。什么是企业网盘&#xff1f;企业网盘与个人网盘又有什么不同呢&#xff1f;一文全方位解读企业网盘这一热门云存储工具。 什么是企业网盘 企业网盘为企业级文件存储、管理与共享平台&#xff0c;企业团队可以在企业网盘中存储企业文…

【python】连上钉钉机器人每日推送

使用Python向钉钉机器人发送消息 导入必要的库 导入json库用于处理JSON数据&#xff0c;time库用于获取当前时间&#xff0c;requests库用于发送HTTP请求。 定义send_ding_message函数 该函数接收一个消息作为参数&#xff0c;并通过POST请求发送给钉钉机器人。请求的URL和头部…

阿里云服务器可用区是什么?

阿里云服务器地域和可用区怎么选择&#xff1f;地域是指云服务器所在物理数据中心的位置&#xff0c;地域选择就近选择&#xff0c;访客距离地域所在城市越近网络延迟越低&#xff0c;速度就越快&#xff1b;可用区是指同一个地域下&#xff0c;网络和电力相互独立的区域&#…

JS加密/解密之常见的JS代码加密

在软件开发领域&#xff0c;混淆&#xff08;JS&#xff09;是一种常见的技术&#xff0c;通过改变代码结构、命名和逻辑&#xff0c;增加代码的复杂性&#xff0c;使其对于逆向工程者变得更加困难。然而&#xff0c;有时候开发者可能需要解开混淆&#xff0c;以便理解、维护或…

jupyter如何更改默认保存路径

jupyter更改默认路径 jupyter默认路径在‘c\用户\Administrator’下&#xff0c;很不方便。 接下来看如何更改默认路径: 1、找到Anaconda Prompt,打开 2、 输入conda activate env1&#xff0c;其中env1为自己创建的环境&#xff0c;如果不知道怎么创建&#xff0c;按照下面…

技术学习周刊第 1 期

2018 年参与过 1 年的 ARTS 打卡&#xff0c;也因为打卡有幸加入了 MegaEase 能与皓哥&#xff08;左耳朵耗子&#xff09;共事。时过境迁&#xff0c;皓哥已经不在了&#xff0c;自己的学习梳理习惯也荒废了一段时间。 2024 年没给自己定具体的目标&#xff0c;只要求自己好好…

大模型迎来“AppStore时刻”,OpenAI给2024的新想象

一夜之间&#xff0c;OpenAI公布了多个重磅消息&#xff0c;引发市场关注。 钛媒体App 1月5日消息&#xff0c;今晨&#xff0c;OpenAI公司向所有GPT开发者们发布一封邮件称&#xff0c;下周将上线自定义的“GPT Store”商店&#xff0c;这有望推动ChatGPT开发者生态不断完善。…

java基础-给个一键三联呗^_^哈哈

文章目录 1.注释修改注释字体三种注释方式 2.标识符和关键字3.数据类型4.类型转换5. 变量、常量、作用域6.基本运算符7.自增自减运算符、初识Math类8.逻辑运算符、位运算符9.三元运算符及小结10.包机制11.JavaDoc生成文档 1.注释 修改注释字体 打开设置Settings 三种注释方…

IDEA 每次新建工程都要重新配置 Maven的解决方案

文章目录 IDEA 每次新建工程都要重新配置 Maven 解决方案一、选择 File -> New Projects Setup -> Settingsfor New Projects…二、选择 Build,Execution,Deployment -> Build Tools -> Maven IDEA 每次新建工程都要重新配置 Maven 解决方案 DEA 每次新建工程都要…

lv14 ioctl、printk及多个此设备支持 6

1 ioctl操作实现 对相应设备做指定的控制操作&#xff08;各种属性的设置获取等等&#xff09; long xxx_ioctl (struct file *filp, unsigned int cmd, unsigned long arg); 功能&#xff1a;对相应设备做指定的控制操作&#xff08;各种属性的设置获取等等&#xff09; 参数…

关于vite的glob坑

我先展示一段代码&#xff1a; /*** function 根据pages路径动态生成路由* param {Array} 基础路由*/ export default function (routes) {const modules import.meta.glob("../pages/**/page.js", { eager: true, import: "default" });const comps im…

CSS3渐变属性详解

渐变属性 线性渐变 概念&#xff1a;线性渐变&#xff0c;指的是在一条直线上进行的渐变。在线性渐变过程中&#xff0c;起始颜色会沿着一条直线按顺序过渡到结束颜色 语法&#xff1a; background:linear-gradient(渐变角度&#xff0c;开始颜色&#xff0c;结束颜色);渐变…

循环队列的队空队满情况

有题目&#xff1a; 循环队列放在一维数组A[0....M-1]中&#xff0c;end1指向队头元素&#xff0c;end2指向队尾元素的后一个位置。假设队列两端均可进行入队和出队操作&#xff0c;队列中最多能容纳M-1个元素。初始时为空。下列判断队空和队满的条件中&#xff0c;正确的是 …