Android WiFi 连接
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()
当前连接的WiFimWifiPickerTracker.getWifiEntries()
搜索的WiFimAddWifiNetworkPreference
添加WiFi项WifiManager.java#connect
和StandardWifiEntry.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 changedif (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 changedremovePreference(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 animationgetView().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() {@Overridepublic 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);}}};@Overridepublic 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);}@Overridepublic 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();}@Overridepublic 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 connectionmLastScanRssi = 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 netlinkcase 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:
相关文章:

Android WiFi 连接
Android WiFi 连接 1、设置中WiFi显示2、WiFi 连接流程2.1 获取PrimaryClientModeManager2.2 ClientModeImpl状态机ConnectableState2.3 ISupplicantStaNetworkCallback 回调监听 3、 简要时序图4、原生低层驱动5、关键日志 1、设置中WiFi显示 Android WiFi基础概览 packages/a…...

PLC与上位机PN通讯时,如何防止连接失败?
连接西门子PLC时失败,或者连接不上PLC,你可能需要做以下几点设置才可以。 一般来说每个PLC都有自己的IP地址,如果你的地址与PLC的地址冲突也就是地址重复是连接不上PLC的,如果地址没有冲突,但是不是在一个网段上也会导…...
LDD学习笔记 -- Linux错误码
LDD学习笔记 -- Linux错误码 EACCES(Permission Denied) 13EEXIST(File Exits) 17EINVAL(Invalid Argument) 22ENOENT(No Such File or Directory)ENOMEM(Out of Memory)EIO(Input/Output Error) 5ENOSPC(No space Left on Device)ENOTTY(Not a Typewrite)EPIPE(Broken Pipe)EI…...

华为交换机入门(六):VLAN的配置
VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。VLAN内的主机间可以直接通信,而VLAN间不能直接互通,从而将广播报文限制在一个VLAN内。 VLAN 主要用来解决如何…...

登录验证
目录 会话技术 Cookie Session JWT JWT生成 JWT校验 会话技术 会话 打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求与响应 会话跟踪 一种维护浏览器的方法 服务器需要…...
利用Podman构建基于Fission env/builder的镜像
镜像准备 构建Dockerfile fission的基础环境包括两种:env 以及 builder。如果仅基于code构建function(i.e., 只创建deployachive),仅构建env即可;但如果需要构建sourcearchive,则需要同时创建env和builde…...
php加减乘除函数
目录 第一部分:简单示例 1、加法 2、减法 3、乘法 4、除法 第二部分:官方文档 1、加法 2、减法 3、乘法 4、除法 第一部分:简单示例 1、加法 $result bcadd(1.2, 1.4, 2); echo $result;//2.60 2、减法 $result bcsub(1.6, 1.…...
Go语言学习记录——用正则表达式(regexp包)来校验参数
前言 最近坐毕设ing,简单的一个管理系统。 其中对于用户注册、登录功能,需要进行一些参数校验。 因为之前使用过,因此这里计划使用正则表达式进行校验。但是之前的使用也仅限于使用,因此这次专门进行一次学习,并做此记…...

公司办公电脑文件防泄密系统
电脑文件防泄密系统是一种用于保护企业机密文件的软件系统,它采用一系列的安全技术手段,如数据加密、访问控制、审计跟踪等,来确保企业机密文件不被非法获取、窃取或泄漏。这种系统通常适用于企业、政府机构等需要对重要文件进行保密的机构。…...
手把手带你死磕ORBSLAM3源代码(三十四)Tracking.cc MonocularInitialization编辑
目录 一.前言 二.代码 2.1完整代码 2.2 单目视觉跟踪初始化 一.前言 这段代码是一个名为MonocularInitialization的函数,它属于Tracking类。从函数名称和代码内容来看,这个函数主要用于单目视觉跟踪的初始化过程。以下是代码的详细解读: 首先,函数检查一个名为m...

STL标准库与泛型编程(侯捷)笔记3
STL标准库与泛型编程(侯捷) 本文是学习笔记,仅供个人学习使用。如有侵权,请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCo…...
Iceberg: 列式读取Parquet数据
通过Spark读取Parquet文件的基本流程 SQL > Spark解析SQL生成逻辑计划树 LogicalPlan > Spark创建扫描表/读取数据的逻辑计划结点 DataSourceV2ScanRelation > Spark优化逻辑计划树,生成物理计划树 SparkPlan > Spark根据不同的属性,将逻辑…...

Ansible、Saltstack、Puppet自动化运维工具介绍
本文主要是分享介绍三款主流批量操控工具Ansible、Saltstack、Puppet主要对比区别,以及Ansible和saltstack的基础安装和使用示例,如果觉得本文对你有帮助,欢迎点赞、收藏、评论! There are many things that can not be broken&am…...
python线程池提交任务
1. 线程池参数设置 CPU数量:N线程池的核心线程数量 IO密集型的话,一般设置为 2 * N 1; CPU密集型的话,一般设置为 N 1 或者 使用进程池。线程池的最大任务队列长度 (线程池的核心线程数 / 单个任务的执行时间&#…...

跨境电商企业客户服务优化指南:关键步骤与实用建议
随着全球经济一体化的加强,跨境电子商务产业在过去几年蓬勃发展。但是,为应对激烈竞争,提供全方面的客户服务成为了跨境电子商务卖家在市场中获得优势的关键因素之一。本文将介绍跨境电商企业优化客户服务有哪些步骤?以助力企业提…...
Visual Studio Code 常用快捷键
Visual Studio Code 常用快捷键 文章目录 Visual Studio Code 常用快捷键1. 主命令框2. 常用快捷键2.1 编辑器与窗口管理2.2 代码编辑格式调整光标相关重构代码查找替换显示相关其他 1. 主命令框 F1 或 CtrlShiftP : 打开命令面板。在打开的输入框内,可以输入任何命…...

ubuntu创建pytorch-gpu的docker环境
文章目录 安装docker创建镜像创建容器 合作推广,分享一个人工智能学习网站。计划系统性学习的同学可以了解下,点击助力博主脱贫( •̀ ω •́ )✧ 使用docker的好处就是可以将你的环境和别人的分开,特别是共用的情况下。本文介绍了ubuntu环境…...
数据库原理与应用期末复习试卷2
数据库原理技术与应用 一.单项选择题 设有属性A,B,C,D,以下表示中不是关系的是( C) A、R(A) B、R(A, B, C, D) C、R(AxBxCxD) D、R(A,B) 在SQL语言中的视图VIEW是数据库的(A)…...
操作系统丨单元测试
文章目录 单元测试选择题填空题单元测试 选择题 【单选题】可以实现虚拟存储器的方案是(D)。 A. 固定分区方式 B. 可变分区方式 C. 纯分页方式 D. 请求页式 【单选题】文件系统中文件存储空间的分配是以(D)为基本单位进行的。 A. 字 B. 字节 C. 文件 D. 块 【单选题】哪种…...

tcp/ip协议2实现的插图,数据结构6 (24 - 章)
(142) 142 二四1 TCP传输控制协议 tcpstat统计量与tcp 函数调用链 (143) 143 二四2 TCP传输控制协议 宏定义与常量值–上 (144) 144 二四3 TCP传输控制协议 宏定义与常量值–下 (145) 145 二四4 TCP传输控制协议 结构tcphdr,tcpiphdr (146) 146 二四5 TCP传输控制协议 结构 tcp…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...