本文共 57464 字,大约阅读时间需要 191 分钟。
前言:之前在 梳理了DHCP流程,现在结合WiFiStateMachine梳理下流程。
准备工作:抓取了小米 mix2 8.0 WifiStateMachine进入ObtainingIpState状态开始,到进入ConnectedState结束的log。
09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false09-01 21:09:28.136 1561 2457 D WifiStateMachine: ObtainingIpAddress clearTargetBssid any key="jiatai 5G"-WPA_PSK09-01 21:09:28.137 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - stopIpManager - -wrap4809-01 21:09:28.142 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.143 1561 2457 D WifiStateMachine: ObtainingIpState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143 1561 2457 D WifiStateMachine: L2ConnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143 1561 2457 D WifiStateMachine: ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_RSSI_POLL rt=411753412/1208576025 1332 0 "jiatai 5G" 20:6b:e7:93:84:f9 rssi=-127 f=-1 sc=0 link=-1 tx=795242.0, 0.0, 0.0 rx=1663737.8 bcn=2413 [on:0 tx:0 rx:0 period:4689] from screen [on:0 period:1033485890]09-01 21:09:28.143 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_RSSI_POLL rt=411753412/1208576025 1332 0 "jiatai 5G" 20:6b:e7:93:84:f9 rssi=-127 f=-1 sc=0 link=-1 tx=795242.0, 0.0, 0.0 rx=1663737.8 bcn=2413 [on:0 tx:0 rx:0 period:0] from screen [on:0 period:1033485890]09-01 21:09:28.143 1561 2457 D WifiStateMachine: get link layer stats 009-01 21:09:28.145 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.146 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 009-01 21:09:28.146 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 009-01 21:09:28.146 1561 2457 D WifiStateMachine: ConnectModeState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 009-01 21:09:28.146 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 009-01 21:09:28.147 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147 1561 2457 D WifiStateMachine: ConnectModeState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147 1561 2457 D WifiStateMachine: DefaultState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.149 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {LinkAddresses: [] Routes: [] DnsAddresses: [] Domains: null MTU: 0} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.150 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR 09-01 21:09:28.151 1561 4875 D DhcpClient: Receive thread started09-01 21:09:28.151 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153 1561 4872 D DhcpClient: Broadcasting DHCPDISCOVER09-01 21:09:28.157 1561 4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 OFFER, ip /192.168.0.105, mask /255.255.255.0, DNS servers: /192.168.0.1 , gateways [/192.168.0.1] lease time 7200, domain null09-01 21:09:28.158 1561 4872 D DhcpClient: Got pending lease: IP address 192.168.0.105/24 Gateway 192.168.0.1 DNS servers: [ 192.168.0.1 ] Domains DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.158 1561 4872 D DhcpClient: Broadcasting DHCPREQUEST ciaddr=0.0.0.0 request=192.168.0.105 serverid=192.168.0.109-01 21:09:28.162 1561 4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 ACK: your new IP /192.168.0.105, netmask /255.255.255.0, gateways [/192.168.0.1] DNS servers: /192.168.0.1 , lease time 720009-01 21:09:28.162 1561 4872 D DhcpClient: Confirmed lease: IP address 192.168.0.105/24 Gateway 192.168.0.1 DNS servers: [ 192.168.0.1 ] Domains DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.163 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - processMessage - processMsg09-01 21:09:28.164 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165 1561 2457 D WifiStateMachine: handleIPv4Success09-01 21:09:28.165 1561 2457 D WifiStateMachine: link address 192.168.0.105/2409-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.165 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,192.168.0.105/24,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [192.168.0.1,] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.166 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR v4 v4r v4dns09-01 21:09:28.166 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK09-01 21:09:28.166 1561 2457 D WifiStateMachine: Network selected by UID 1000 prompt=true09-01 21:09:28.166 1561 2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false09-01 21:09:28.168 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling renewal in 3599s09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling rebind in 6299s09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling expiry in 7199s09-01 21:09:28.173 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.174 1561 2457 D WifiStateMachine: updateDefaultRouteMacAddress found Ipv4 default :192.168.0.109-01 21:09:28.174 1561 2457 E WifiStateMachine: Did not find remoteAddress {192.168.0.1} in /proc/net/arp09-01 21:09:28.178 1561 2457 D WifiStateMachine: Enter ConnectedState mScreenOn=true
1.WiFi 连接过程状态切换
09-01 21:09:28.023 1561 2457 D WifiStateMachine: setDetailed state, old =DISCONNECTED and new state=CONNECTING hidden=false09-01 21:09:28.023 1561 2457 D WifiStateMachine: setDetailed state send new extra info"jiatai 5G"09-01 21:09:28.083 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=CONNECTING hidden=false09-01 21:09:28.085 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=AUTHENTICATING hidden=false09-01 21:09:28.095 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=AUTHENTICATING hidden=false09-01 21:09:28.105 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false09-01 21:09:28.178 1561 2457 D WifiStateMachine: Enter ConnectedState mScreenOn=true
可以观察到WiFi连接过程中有如下几个状态
- DISCONNECTED
- CONNECTING
- AUTHENTICATING
- OBTAINING_IPADDR
- CONNECTED
这次主要梳理下OBTAINING_IPADDR状态切换到CONNECTED的流程。
NetworkInfo.java /** * The fine-grained state of a network connection. This level of detail * is probably of interest to few applications. Most should use * {@link android.net.NetworkInfo.State State} instead. */ public enum DetailedState { /** Ready to start data connection setup. */ IDLE, /** Searching for an available access point. */ SCANNING, /** Currently setting up data connection. */ CONNECTING, /** Network link established, performing authentication. */ AUTHENTICATING, /** Awaiting response from DHCP server in order to assign IP address information. */ OBTAINING_IPADDR, /** IP traffic should be available. */ CONNECTED, /** IP traffic is suspended */ SUSPENDED, /** Currently tearing down data connection. */ DISCONNECTING, /** IP traffic not available. */ DISCONNECTED, /** Attempt to connect failed. */ FAILED, /** Access to this network is blocked. */ BLOCKED, /** Link has poor connectivity. */ VERIFYING_POOR_LINK, /** Checking if network is a captive portal */ CAPTIVE_PORTAL_CHECK }
2.流程梳理
class ObtainingIpState extends State { @Override public void enter() { final WifiConfiguration currentConfig = getCurrentWifiConfiguration(); final boolean isUsingStaticIp = (currentConfig.getIpAssignment() == IpConfiguration.IpAssignment.STATIC); if (mVerboseLoggingEnabled) { final String key = currentConfig.configKey(); log("enter ObtainingIpState netId=" + Integer.toString(mLastNetworkId) + " " + key + " " + " roam=" + mIsAutoRoaming + " static=" + isUsingStaticIp); } // Reset link Debouncing, indicating we have successfully re-connected to the AP // We might still be roaming mIsLinkDebouncing = false; // Send event to CM & network change broadcast setNetworkDetailedState(DetailedState.OBTAINING_IPADDR); // We must clear the config BSSID, as the wifi chipset may decide to roam // from this point on and having the BSSID specified in the network block would // cause the roam to fail and the device to disconnect. clearTargetBssid("ObtainingIpAddress"); // Stop IpClient in case we're switching from DHCP to static // configuration or vice versa. // // TODO: Only ever enter this state the first time we connect to a // network, never on switching between static configuration and // DHCP. When we transition from static configuration to DHCP in // particular, we must tell ConnectivityService that we're // disconnected, because DHCP might take a long time during which // connectivity APIs such as getActiveNetworkInfo should not return // CONNECTED. stopIpClient(); mIpClient.setHttpProxy(currentConfig.getHttpProxy()); if (!TextUtils.isEmpty(mTcpBufferSizes)) { mIpClient.setTcpBufferSizes(mTcpBufferSizes); } final IpClient.ProvisioningConfiguration prov; if (!isUsingStaticIp) { prov = IpClient.buildProvisioningConfiguration() .withPreDhcpAction() .withApfCapabilities(mWifiNative.getApfCapabilities()) .withNetwork(getCurrentNetwork()) .withDisplayName(currentConfig.SSID) .build(); } else { StaticIpConfiguration staticIpConfig = currentConfig.getStaticIpConfiguration(); prov = IpClient.buildProvisioningConfiguration() .withStaticConfiguration(staticIpConfig) .withApfCapabilities(mWifiNative.getApfCapabilities()) .withNetwork(getCurrentNetwork()) .withDisplayName(currentConfig.SSID) .build(); } mIpClient.startProvisioning(prov); // Get Link layer stats so as we get fresh tx packet counters getWifiLinkLayerStats(); }
将状态设为DetailedState.OBTAINING_IPADDR,初始化好配置后会调用IpClient的startProvisioning
public void startProvisioning(ProvisioningConfiguration req) { if (!req.isValid()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); return; } mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName); if (mInterfaceParams == null) { logError("Failed to find InterfaceParams for " + mInterfaceName); doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND); return; } mCallback.setNeighborDiscoveryOffload(true); sendMessage(CMD_START, new ProvisioningConfiguration(req)); }
先看下IpClient的初始化
mIpClient = mFacade.makeIpClient(mContext, mInterfaceName, new IpClientCallback());
mInterfaceName默认是wlan0
mWifiNative = new WifiNative(SystemProperties.get("wifi.interface", "wlan0"), mWifiVendorHal, mSupplicantStaIfaceHal, mWificondControl); mInterfaceName = mWifiNative.getInterfaceName();
IPClient的准备工作是随配置发出CMD_START的消息
IPClient也包含了一个状态机
private void configureAndStartStateMachine() { addState(mStoppedState); addState(mStartedState); addState(mRunningState, mStartedState); addState(mStoppingState); setInitialState(mStoppedState); super.start(); }
其中StoppedState会处理CMD_START消息,切换到StartedState状态。
case CMD_START: mConfiguration = (ProvisioningConfiguration) msg.obj; transitionTo(mStartedState); break;
class StartedState extends State { @Override public void enter() { mStartTimeMillis = SystemClock.elapsedRealtime(); if (mConfiguration.mProvisioningTimeoutMs > 0) { final long alarmTime = SystemClock.elapsedRealtime() + mConfiguration.mProvisioningTimeoutMs; mProvisioningTimeoutAlarm.schedule(alarmTime); } if (readyToProceed()) { deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING)); } else { // Clear all IPv4 and IPv6 before proceeding to RunningState. // Clean up any leftover state from an abnormal exit from // tethering or during an IpClient restart. stopAllIP(); } } @Override public void exit() { mProvisioningTimeoutAlarm.cancel(); } @Override public boolean processMessage(Message msg) { switch (msg.what) { case CMD_JUMP_STARTED_TO_RUNNING: transitionTo(mRunningState); break; case CMD_STOP: transitionTo(mStoppingState); break; case EVENT_NETLINK_LINKPROPERTIES_CHANGED: handleLinkPropertiesUpdate(NO_CALLBACKS); if (readyToProceed()) { transitionTo(mRunningState); } break; case EVENT_PROVISIONING_TIMEOUT: handleProvisioningFailure(); break; default: // It's safe to process messages out of order because the // only message that can both // a) be received at this time and // b) affect provisioning state // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above). deferMessage(msg); } mMsgStateLogger.handled(this, getCurrentState()); return HANDLED; } private boolean readyToProceed() { return (!mLinkProperties.hasIPv4Address() && !mLinkProperties.hasGlobalIPv6Address()); } }
StartedState在enter方法里deferMessage CMD_JUMP_STARTED_TO_RUNNING,enter方法执行完就会处理。因此状态切换到RunningState状态。
class RunningState extends State { private ConnectivityPacketTracker mPacketTracker; private boolean mDhcpActionInFlight; @Override public void enter() { ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration(); apfConfig.apfCapabilities = mConfiguration.mApfCapabilities; apfConfig.multicastFilter = mMulticastFiltering; // Get the Configuration for ApfFilter from Context apfConfig.ieee802_3Filter = mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames); apfConfig.ethTypeBlackList = mContext.getResources().getIntArray(R.array.config_apfEthTypeBlackList); mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback); // TODO: investigate the effects of any multicast filtering racing/interfering with the // rest of this IP configuration startup. if (mApfFilter == null) { mCallback.setFallbackMulticastFilter(mMulticastFiltering); } mPacketTracker = createPacketTracker(); if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName); if (mConfiguration.mEnableIPv6 && !startIPv6()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6); enqueueJumpToStoppingState(); return; } if (mConfiguration.mEnableIPv4 && !startIPv4()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4); enqueueJumpToStoppingState(); return; } final InitialConfiguration config = mConfiguration.mInitialConfig; if ((config != null) && !applyInitialConfig(config)) { // TODO introduce a new IpManagerEvent constant to distinguish this error case. doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); enqueueJumpToStoppingState(); return; } if (mConfiguration.mUsingMultinetworkPolicyTracker) { mMultinetworkPolicyTracker = new MultinetworkPolicyTracker( mContext, getHandler(), () -> { mLog.log("OBSERVED AvoidBadWifi changed"); }); mMultinetworkPolicyTracker.start(); } if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) { doImmediateProvisioningFailure( IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR); enqueueJumpToStoppingState(); return; } }
enter方法区别是配置了ipv6还是ipv4走不同的流程,现在默认一般是ipv4。
看下startIPv4逻辑
private boolean startIPv4() { // If we have a StaticIpConfiguration attempt to apply it and // handle the result accordingly. if (mConfiguration.mStaticIpConfig != null) { if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) { handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig)); } else { return false; } } else { // Start DHCPv4. mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams); mDhcpClient.registerForPreDhcpNotification(); mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP); } return true; }
由于不是静态ip,所以走下面DhcpClient流程,这边就和之前的 流程对上了。
但当时没梳理清楚WaitBeforeStartState状态的含义。
DhcpClient切换到mWaitBeforeStartState,这是由于之前有调用mDhcpClient.registerForPreDhcpNotification();所以这边状态等待其他状态完成,其实是dhcp有些准备工作需要在WifiStateMachine中完成,所以这边流程需要等一下,流程完了自然会切换到DhcpInitState。
class StoppedState extends State { @Override public boolean processMessage(Message message) { switch (message.what) { case CMD_START_DHCP: if (mRegisteredForPreDhcpNotification) { transitionTo(mWaitBeforeStartState); } else { transitionTo(mDhcpInitState); } return HANDLED; default: return NOT_HANDLED; } } }private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
这个消息还没搞清楚:CMD_UPDATE_LINKPROPERTIES
09-01 21:09:28.149 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {LinkAddresses: [] Routes: [] DnsAddresses: [] Domains: null MTU: 0} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.150 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR
接着看
09-01 21:09:28.151 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0
class WaitBeforeStartState extends WaitBeforeOtherState { public WaitBeforeStartState(State otherState) { super(); mOtherState = otherState; } } // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState. abstract class WaitBeforeOtherState extends LoggingState { protected State mOtherState; @Override public void enter() { super.enter(); mController.sendMessage(CMD_PRE_DHCP_ACTION); } @Override public boolean processMessage(Message message) { super.processMessage(message); switch (message.what) { case CMD_PRE_DHCP_ACTION_COMPLETE: transitionTo(mOtherState); return HANDLED; default: return NOT_HANDLED; } } }
进入到这个等待状态时会发送CMD_PRE_DHCP_ACTION给IpClient,RunningState会对该消息进行对应处理
case DhcpClient.CMD_PRE_DHCP_ACTION: if (mConfiguration.mRequestedPreDhcpActionMs > 0) { ensureDhcpAction(); } else { sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE); } break;
这边从log来看是走了ensureDhcpAction(),没有直接发出完成消息。
private void ensureDhcpAction() { if (!mDhcpActionInFlight) { mCallback.onPreDhcpAction(); mDhcpActionInFlight = true; final long alarmTime = SystemClock.elapsedRealtime() + mConfiguration.mRequestedPreDhcpActionMs; mDhcpActionTimeoutAlarm.schedule(alarmTime); } }
回调WifiStateMachine
class IpClientCallback extends IpClient.Callback { @Override public void onPreDhcpAction() { sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION); }
L2ConnectedState处理
@Override public boolean processMessage(Message message) { logStateAndMessage(message, this); switch (message.what) { case DhcpClient.CMD_PRE_DHCP_ACTION: handlePreDhcpSetup(); break; void handlePreDhcpSetup() { if (!mBluetoothConnectionActive) { /* * There are problems setting the Wi-Fi driver's power * mode to active when bluetooth coexistence mode is * enabled or sense. ** We set Wi-Fi to active mode when * obtaining an IP address because we've found * compatibility issues with some routers with low power * mode. *
* In order for this active power mode to properly be set, * we disable coexistence mode until we're done with * obtaining an IP address. One exception is if we * are currently connected to a headset, since disabling * coexistence would interrupt that connection. */ // Disable the coexistence mode mWifiNative.setBluetoothCoexistenceMode( WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); } // Disable power save and suspend optimizations during DHCP // Note: The order here is important for now. Brcm driver changes // power settings when we control suspend mode optimizations. // TODO: Remove this comment when the driver is fixed. setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false); mWifiNative.setPowerSave(false); // Update link layer stats getWifiLinkLayerStats(); if (mWifiP2pChannel != null) { /* P2p discovery breaks dhcp, shut it down in order to get through this */ Message msg = new Message(); msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY; msg.arg1 = WifiP2pServiceImpl.ENABLED; msg.arg2 = DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE; msg.obj = WifiStateMachine.this; mWifiP2pChannel.sendMessage(msg); } else { // If the p2p service is not running, we can proceed directly. sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE); } }
之前梳理过支持p2p的话开机启动的时候wifip2pChannel就会被初始化,所以这边需要先禁用p2p discovery,让dhcp流程继续往下走。
WifiP2pServiceImpl P2pEnabledState
case BLOCK_DISCOVERY: boolean blocked = (message.arg1 == ENABLED ? true : false); if (mDiscoveryBlocked == blocked) break; mDiscoveryBlocked = blocked; if (blocked && mDiscoveryStarted) { mWifiNative.p2pStopFind(); mDiscoveryPostponed = true; } if (!blocked && mDiscoveryPostponed) { mDiscoveryPostponed = false; mWifiNative.p2pFind(DISCOVER_TIMEOUT_S); } if (blocked) { if (message.obj == null) { Log.e(TAG, "Illegal argument(s)"); break; } StateMachine m = (StateMachine) message.obj; try { m.sendMessage(message.arg2); } catch (Exception e) { loge("unable to send BLOCK_DISCOVERY response: " + e); } } break;
调用完p2pStopFind后会发DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE给WifiStateMachine,L2ConnectedState继续处理
09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0
case DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE: mIpClient.completedPreDhcpAction(); break;
IpClient
public void completedPreDhcpAction() { sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE); }RunningState case EVENT_PRE_DHCP_ACTION_COMPLETE: // It's possible to reach here if, for example, someone // calls completedPreDhcpAction() after provisioning with // a static IP configuration. if (mDhcpClient != null) { mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE); } break;
DhcpClient接收到chcp准备完成消息将状态切换到mDhcpInitState
class WaitBeforeStartState extends WaitBeforeOtherState { public WaitBeforeStartState(State otherState) { super(); mOtherState = otherState; } } // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState. abstract class WaitBeforeOtherState extends LoggingState { protected State mOtherState; @Override public void enter() { super.enter(); mController.sendMessage(CMD_PRE_DHCP_ACTION); } @Override public boolean processMessage(Message message) { super.processMessage(message); switch (message.what) { case CMD_PRE_DHCP_ACTION_COMPLETE: transitionTo(mOtherState); return HANDLED; default: return NOT_HANDLED; } } }
class DhcpInitState extends PacketRetransmittingState { public DhcpInitState() { super(); } @Override public void enter() { super.enter(); startNewTransaction(); mLastInitEnterTime = SystemClock.elapsedRealtime(); } protected boolean sendPacket() { return sendDiscoverPacket(); } protected void receivePacket(DhcpPacket packet) { if (!isValidPacket(packet)) return; if (!(packet instanceof DhcpOfferPacket)) return; mOffer = packet.toDhcpResults(); if (mOffer != null) { Log.d(TAG, "Got pending lease: " + mOffer); transitionTo(mDhcpRequestingState); } } }
dhcp开始干活,之前梳理过了,流程略。
09-01 21:09:28.153 1561 4872 D DhcpClient: Broadcasting DHCPDISCOVER09-01 21:09:28.157 1561 4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 OFFER, ip /192.168.0.105, mask /255.255.255.0, DNS servers: /192.168.0.1 , gateways [/192.168.0.1] lease time 7200, domain null09-01 21:09:28.158 1561 4872 D DhcpClient: Got pending lease: IP address 192.168.0.105/24 Gateway 192.168.0.1 DNS servers: [ 192.168.0.1 ] Domains DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.158 1561 4872 D DhcpClient: Broadcasting DHCPREQUEST ciaddr=0.0.0.0 request=192.168.0.105 serverid=192.168.0.109-01 21:09:28.159 1561 12753 D WifiService: getWifiEnabledState uid=100009-01 21:09:28.161 1561 12753 D WifiService: getConnectionInfo uid=100009-01 21:09:28.161 1561 12753 D WifiService: getWifiEnabledState uid=100009-01 21:09:28.162 1561 4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 ACK: your new IP /192.168.0.105, netmask /255.255.255.0, gateways [/192.168.0.1] DNS servers: /192.168.0.1 , lease time 720009-01 21:09:28.162 1561 4872 D DhcpClient: Confirmed lease: IP address 192.168.0.105/24 Gateway 192.168.0.1 DNS servers: [ 192.168.0.1 ] Domains DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.163 1561 12753 D WifiService: getConnectionInfo uid=1000
DhcpClient
DHCPREQUEST收到回应,向IpClient发出CMD_POST_DHCP_ACTION消息。
private void notifySuccess() { mController.sendMessage( CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease)); } private void acceptDhcpResults(DhcpResults results, String msg) { mDhcpLease = results; mOffer = null; Log.d(TAG, msg + " lease: " + mDhcpLease); notifySuccess(); } class DhcpRequestingState extends PacketRetransmittingState { public DhcpRequestingState() { mTimeout = DHCP_TIMEOUT_MS / 2; } protected boolean sendPacket() { return sendRequestPacket( INADDR_ANY, // ciaddr (Inet4Address) mOffer.ipAddress.getAddress(), // DHCP_REQUESTED_IP (Inet4Address) mOffer.serverAddress, // DHCP_SERVER_IDENTIFIER INADDR_BROADCAST); // packet destination address } protected void receivePacket(DhcpPacket packet) { if (!isValidPacket(packet)) return; if ((packet instanceof DhcpAckPacket)) { DhcpResults results = packet.toDhcpResults(); if (results != null) { setDhcpLeaseExpiry(packet); acceptDhcpResults(results, "Confirmed"); transitionTo(mConfiguringInterfaceState); } } else if (packet instanceof DhcpNakPacket) { // TODO: Wait a while before returning into INIT state. Log.d(TAG, "Received NAK, returning to INIT"); mOffer = null; transitionTo(mDhcpInitState); } }
IpClient进行处理
09-01 21:09:28.163 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0
case DhcpClient.CMD_POST_DHCP_ACTION: stopDhcpAction(); switch (msg.arg1) { case DhcpClient.DHCP_SUCCESS: handleIPv4Success((DhcpResults) msg.obj); break; case DhcpClient.DHCP_FAILURE: handleIPv4Failure(); break; default: logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1); } break;
private void stopDhcpAction() { mDhcpActionTimeoutAlarm.cancel(); if (mDhcpActionInFlight) { mCallback.onPostDhcpAction(); mDhcpActionInFlight = false; } }取消timeout倒计时,回调WifiStateMachine @Override public void onPostDhcpAction() { sendMessage(DhcpClient.CMD_POST_DHCP_ACTION); } case DhcpClient.CMD_POST_DHCP_ACTION: handlePostDhcpSetup(); // We advance to mConnectedState because IpClient will also send a // CMD_IPV4_PROVISIONING_SUCCESS message, which calls handleIPv4Success(), // which calls updateLinkProperties, which then sends // CMD_IP_CONFIGURATION_SUCCESSFUL. // // In the event of failure, we transition to mDisconnectingState // similarly--via messages sent back from IpClient. break;放开之前对p2p find的控制。 void handlePostDhcpSetup() { /* Restore power save and suspend optimizations */ setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true); mWifiNative.setPowerSave(true); p2pSendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED); // Set the coexistence mode back to its default value mWifiNative.setBluetoothCoexistenceMode( WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE); }
09-01 21:09:28.164 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165 1561 2457 D WifiStateMachine: handleIPv4Success09-01 21:09:28.165 1561 2457 D WifiStateMachine: link address 192.168.0.105/24
private void handleIPv4Success(DhcpResults dhcpResults) { mDhcpResults = new DhcpResults(dhcpResults); final LinkProperties newLp = assembleLinkProperties(); final ProvisioningChange delta = setLinkProperties(newLp); if (DBG) { Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")"); } mCallback.onNewDhcpResults(dhcpResults); dispatchCallback(delta, newLp); }回调WifiStateMachine的callback @Override public void onNewDhcpResults(DhcpResults dhcpResults) { if (dhcpResults != null) { sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults); } else { sendMessage(CMD_IPV4_PROVISIONING_FAILURE); mWifiInjector.getWifiLastResortWatchdog().noteConnectionFailureAndTriggerIfNeeded( getTargetSsid(), mTargetRoamBSSID, WifiLastResortWatchdog.FAILURE_CODE_DHCP); } } case CMD_IPV4_PROVISIONING_SUCCESS: { handleIPv4Success((DhcpResults) message.obj); sendNetworkStateChangeBroadcast(mLastBssid); break; } private void handleIPv4Success(DhcpResults dhcpResults) { if (mVerboseLoggingEnabled) { logd("handleIPv4Success <" + dhcpResults.toString() + ">"); logd("link address " + dhcpResults.ipAddress); } Inet4Address addr; synchronized (mDhcpResultsLock) { mDhcpResults = dhcpResults; addr = (Inet4Address) dhcpResults.ipAddress.getAddress(); } if (mIsAutoRoaming) { int previousAddress = mWifiInfo.getIpAddress(); int newAddress = NetworkUtils.inetAddressToInt(addr); if (previousAddress != newAddress) { logd("handleIPv4Success, roaming and address changed" + mWifiInfo + " got: " + addr); } } mWifiInfo.setInetAddress(addr); final WifiConfiguration config = getCurrentWifiConfiguration(); if (config != null) { mWifiInfo.setEphemeral(config.ephemeral); } // Set meteredHint if DHCP result says network is metered if (dhcpResults.hasMeteredHint()) { mWifiInfo.setMeteredHint(true); } updateCapabilities(config); } private void sendNetworkStateChangeBroadcast(String bssid) { Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo)); intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties)); if (bssid != null) intent.putExtra(WifiManager.EXTRA_BSSID, bssid); if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK || mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) { // We no longer report MAC address to third-parties and our code does // not rely on this broadcast, so just send the default MAC address. fetchRssiLinkSpeedAndFrequencyNative(); WifiInfo sentWifiInfo = new WifiInfo(mWifiInfo); sentWifiInfo.setMacAddress(WifiInfo.DEFAULT_MAC_ADDRESS); intent.putExtra(WifiManager.EXTRA_WIFI_INFO, sentWifiInfo); } mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); }
继续
09-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,192.168.0.105/24,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [192.168.0.1,] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.166 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK09-01 21:09:28.166 2552 2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE09-01 21:09:28.166 1561 2457 D WifiStateMachine: Network selected by UID 1000 prompt=true09-01 21:09:28.166 1561 2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false
IpClient
private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) { switch (delta) { case GAINED_PROVISIONING: if (DBG) { Log.d(mTag, "onProvisioningSuccess()"); } recordMetric(IpManagerEvent.PROVISIONING_OK); mCallback.onProvisioningSuccess(newLp); break; case LOST_PROVISIONING: if (DBG) { Log.d(mTag, "onProvisioningFailure()"); } recordMetric(IpManagerEvent.PROVISIONING_FAIL); mCallback.onProvisioningFailure(newLp); break; default: if (DBG) { Log.d(mTag, "onLinkPropertiesChange()"); } mCallback.onLinkPropertiesChange(newLp); break; } }
回调WifiStateMachine的callback
@Override public void onProvisioningSuccess(LinkProperties newLp) { mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL); sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp); sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL); }
/* Link configuration (IP address, DNS, ...) changes notified via netlink */ case CMD_UPDATE_LINKPROPERTIES: updateLinkProperties((LinkProperties) message.obj); break; private void updateLinkProperties(LinkProperties newLp) { if (mVerboseLoggingEnabled) { log("Link configuration changed for netId: " + mLastNetworkId + " old: " + mLinkProperties + " new: " + newLp); } // We own this instance of LinkProperties because IpClient passes us a copy. mLinkProperties = newLp; if (mNetworkAgent != null) { mNetworkAgent.sendLinkProperties(mLinkProperties); } if (getNetworkDetailedState() == DetailedState.CONNECTED) { // If anything has changed and we're already connected, send out a notification. // TODO: Update all callers to use NetworkCallbacks and delete this. sendLinkConfigurationChangedBroadcast(); } if (mVerboseLoggingEnabled) { StringBuilder sb = new StringBuilder(); sb.append("updateLinkProperties nid: " + mLastNetworkId); sb.append(" state: " + getNetworkDetailedState()); if (mLinkProperties != null) { sb.append(" "); sb.append(getLinkPropertiesSummary(mLinkProperties)); } logd(sb.toString()); } }
case CMD_IP_CONFIGURATION_SUCCESSFUL: handleSuccessfulIpConfiguration(); reportConnectionAttemptEnd( WifiMetrics.ConnectionEvent.FAILURE_NONE, WifiMetricsProto.ConnectionEvent.HLF_NONE); if (getCurrentWifiConfiguration() == null) { // The current config may have been removed while we were connecting, // trigger a disconnect to clear up state. mWifiNative.disconnect(); transitionTo(mDisconnectingState); } else { sendConnectedState(); transitionTo(mConnectedState); } break; private void handleSuccessfulIpConfiguration() { mLastSignalLevel = -1; // Force update of signal strength WifiConfiguration c = getCurrentWifiConfiguration(); if (c != null) { // Reset IP failure tracking c.getNetworkSelectionStatus().clearDisableReasonCounter( WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE); // Tell the framework whether the newly connected network is trusted or untrusted. updateCapabilities(c); } if (c != null) { ScanResult result = getCurrentScanResult(); if (result == null) { logd("WifiStateMachine: handleSuccessfulIpConfiguration and no scan results" + c.configKey()); } else { // Clear the per BSSID failure count result.numIpConfigFailures = 0; private void sendConnectedState() { // If this network was explicitly selected by the user, evaluate whether to call // explicitlySelected() so the system can treat it appropriately. WifiConfiguration config = getCurrentWifiConfiguration(); if (shouldEvaluateWhetherToSendExplicitlySelected(config)) { boolean prompt = mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid); if (mVerboseLoggingEnabled) { log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt); } if (prompt) { // Selected by the user via Settings or QuickSettings. If this network has Internet // access, switch to it. Otherwise, switch to it only if the user confirms that they // really want to switch, or has already confirmed and selected "Don't ask again". if (mVerboseLoggingEnabled) { log("explictlySelected acceptUnvalidated=" + config.noInternetAccessExpected); } if (mNetworkAgent != null) { mNetworkAgent.explicitlySelected(config.noInternetAccessExpected); } } } setNetworkDetailedState(DetailedState.CONNECTED); mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId); sendNetworkStateChangeBroadcast(mLastBssid); }
ip配置成功后设置网络状态变为connected并发送广播通知,最后状态切到ConnectedState。
class ConnectedState extends State { @Override public void enter() { // TODO: b/64349637 Investigate getting default router IP/MAC address info from // IpManager //updateDefaultRouteMacAddress(1000); if (mVerboseLoggingEnabled) { log("Enter ConnectedState " + " mScreenOn=" + mScreenOn); } mWifiConnectivityManager.handleConnectionStateChanged( WifiConnectivityManager.WIFI_STATE_CONNECTED); registerConnected(); lastConnectAttemptTimestamp = 0; targetWificonfiguration = null; // Paranoia mIsLinkDebouncing = false; // Not roaming anymore mIsAutoRoaming = false; if (testNetworkDisconnect) { testNetworkDisconnectCounter++; logd("ConnectedState Enter start disconnect test " + testNetworkDisconnectCounter); sendMessageDelayed(obtainMessage(CMD_TEST_NETWORK_DISCONNECT, testNetworkDisconnectCounter, 0), 15000); } mLastDriverRoamAttempt = 0; mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID; mWifiInjector.getWifiLastResortWatchdog().connectedStateTransition(true); mWifiStateTracker.updateState(WifiStateTracker.CONNECTED); }
看下连接上了以后的逻辑处理,这边是对应连接上了以后的扫描逻辑,singleScan/pnoScan/periodicScan,扫描逻辑梳理待续。
这边可以看到的startConnectivityScan逻辑是亮屏并且连接ap那就进行定时扫描,否则如果未连接ap并且pno扫描未开始,则进行pno扫描,pno扫描是只针对已保存网络的扫描。
WifiConnectivityManager
/** * Handler for WiFi state (connected/disconnected) changes */ public void handleConnectionStateChanged(int state) { localLog("handleConnectionStateChanged: state=" + stateToString(state)); mWifiState = state; if (mWifiState == WIFI_STATE_CONNECTED) { mOpenNetworkNotifier.handleWifiConnected(); } // Reset BSSID of last connection attempt and kick off // the watchdog timer if entering disconnected state. if (mWifiState == WIFI_STATE_DISCONNECTED) { mLastConnectionAttemptBssid = null; scheduleWatchdogTimer(); startConnectivityScan(SCAN_IMMEDIATELY); } else { startConnectivityScan(SCAN_ON_SCHEDULE); } } // Start a connectivity scan. The scan method is chosen according to // the current screen state and WiFi state. private void startConnectivityScan(boolean scanImmediately) { localLog("startConnectivityScan: screenOn=" + mScreenOn + " wifiState=" + stateToString(mWifiState) + " scanImmediately=" + scanImmediately + " wifiEnabled=" + mWifiEnabled + " wifiConnectivityManagerEnabled=" + mWifiConnectivityManagerEnabled); if (!mWifiEnabled || !mWifiConnectivityManagerEnabled) { return; } // Always stop outstanding connecivity scan if there is any stopConnectivityScan(); // Don't start a connectivity scan while Wifi is in the transition // between connected and disconnected states. if (mWifiState != WIFI_STATE_CONNECTED && mWifiState != WIFI_STATE_DISCONNECTED) { return; } if (mScreenOn) { startPeriodicScan(scanImmediately); } else { if (mWifiState == WIFI_STATE_DISCONNECTED && !mPnoScanStarted) { startDisconnectedPnoScan(); } } } // Start a periodic scan when screen is on private void startPeriodicScan(boolean scanImmediately) { mPnoScanListener.resetLowRssiNetworkRetryDelay(); // No connectivity scan if auto roaming is disabled. if (mWifiState == WIFI_STATE_CONNECTED && !mEnableAutoJoinWhenAssociated) { return; } // Due to b/28020168, timer based single scan will be scheduled // to provide periodic scan in an exponential backoff fashion. if (scanImmediately) { resetLastPeriodicSingleScanTimeStamp(); } mPeriodicSingleScanInterval = PERIODIC_SCAN_INTERVAL_MS; startPeriodicSingleScan(); }
先到这吧。
3. 总结
转载地址:https://jiatai.blog.csdn.net/article/details/82527796 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!