Preface: before (87) WiFi & DHCP Combing the DHCP process, now combing the next process with WiFi state machine.
Preparatory work: grab the log from Xiaomi mix2 8.0 WiFi state machine to the beginning of ObtainingIpState and the end of ConnectedState.
09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false 09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false 09-01 21:09:28.136 1561 2457 D WifiStateMachine: ObtainingIpAddress clearTargetBssid any key="jiatai 5G"-WPA_PSK 09-01 21:09:28.137 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - stopIpManager - -wrap48 09-01 21:09:28.142 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=13 09-01 21:09:28.142 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=13 09-01 21:09:28.142 1561 2457 D WifiStateMachine: ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=13 09-01 21:09:28.142 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=13 09-01 21:09:28.142 1561 2457 D WifiStateMachine: DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=13 09-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: COMPLETED 09-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: COMPLETED 09-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: COMPLETED 09-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 0 09-01 21:09:28.145 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=5765 09-01 21:09:28.146 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 0 09-01 21:09:28.146 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 0 09-01 21:09:28.146 1561 2457 D WifiStateMachine: ConnectModeState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 0 09-01 21:09:28.146 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 0 09-01 21:09:28.147 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true 09-01 21:09:28.147 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true 09-01 21:09:28.147 1561 2457 D WifiStateMachine: ConnectModeState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true 09-01 21:09:28.147 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true 09-01 21:09:28.147 1561 2457 D WifiStateMachine: DefaultState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true 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 4875 D DhcpClient: Receive thread started 09-01 21:09:28.151 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,0 09-01 21:09:28.151 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,0 09-01 21:09:28.151 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg 09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0 09-01 21:09:28.153 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0 09-01 21:09:28.153 1561 4872 D DhcpClient: Broadcasting DHCPDISCOVER 09-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 null 09-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 seconds 09-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.1 09-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 7200 09-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 seconds 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 09-01 21:09:28.163 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - processMessage - processMsg 09-01 21:09:28.164 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: handleIPv4Success <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 seconds> 09-01 21:09:28.165 1561 2457 D WifiStateMachine: link address 192.168.0.105/24 09-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 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 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,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 v4dns 09-01 21:09:28.166 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 0 09-01 21:09:28.166 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 0 09-01 21:09:28.166 1561 2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK 09-01 21:09:28.166 1561 2457 D WifiStateMachine: Network selected by UID 1000 prompt=true 09-01 21:09:28.166 1561 2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false 09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false 09-01 21:09:28.168 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=5765 09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling renewal in 3599s 09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling rebind in 6299s 09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling expiry in 7199s 09-01 21:09:28.173 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=5765 09-01 21:09:28.174 1561 2457 D WifiStateMachine: updateDefaultRouteMacAddress found Ipv4 default :192.168.0.1 09-01 21:09:28.174 1561 2457 E WifiStateMachine: Did not find remoteAddress {192.168.0.1} in /proc/net/arp 09-01 21:09:28.178 1561 2457 D WifiStateMachine: Enter ConnectedState mScreenOn=true
1.WiFi connection process state switching
09-01 21:09:28.023 1561 2457 D WifiStateMachine: setDetailed state, old =DISCONNECTED and new state=CONNECTING hidden=false 09-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=false 09-01 21:09:28.085 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=AUTHENTICATING hidden=false 09-01 21:09:28.095 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=AUTHENTICATING hidden=false 09-01 21:09:28.105 1561 2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false 09-01 21:09:28.135 1561 2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK roam=false static=false 09-01 21:09:28.135 1561 2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false 09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false 09-01 21:09:28.178 1561 2457 D WifiStateMachine: Enter ConnectedState mScreenOn=true
You can observe the following states during WiFi connection
- DISCONNECTED
- CONNECTING
- AUTHENTICATING
- OBTAINING_IPADDR
- CONNECTED
This time, it mainly sorts out the process of switching the obtaining ABCD IPADDR state to 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. Process sorting
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(); }
Set the state to detailedstate.obtainingipaddr. After the configuration is initialized, the startProvisioning of IpClient will be called
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)); }
Let's first look at the initialization of IpClient
mIpClient = mFacade.makeIpClient(mContext, mInterfaceName, new IpClientCallback());
Mminterfacename defaults to WLAN 0
mWifiNative = new WifiNative(SystemProperties.get("wifi.interface", "wlan0"), mWifiVendorHal, mSupplicantStaIfaceHal, mWificondControl); mInterfaceName = mWifiNative.getInterfaceName();
The preparation of the IPClient is to send the message "CMD start" along with the configuration
IPClient also includes a state machine
private void configureAndStartStateMachine() { addState(mStoppedState); addState(mStartedState); addState(mRunningState, mStartedState); addState(mStoppingState); setInitialState(mStoppedState); super.start(); }
Where StoppedState will process the CMD "start message and switch to the StartedState state state.
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 defirmessage CMD? Jump? Started? To? Running in the enter method, which will be processed after the execution of the enter method. So the state switches to the running state state state.
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; } }
The difference of the enter method is whether ipv6 is configured or ipv4 goes through different processes. Now the default is generally ipv4.
Look at the startIPv4 logic
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; }
Since it is not a static ip, follow the DhcpClient process, which is the same as the previous one (87) WiFi & DHCP The process is right.
But the meaning of WaitBeforeStartState was not clear at that time.
Dhcclient switches to mWaitBeforeStartState. This is because mDhcpClient.registerForPreDhcpNotification() was called before. So the state here is waiting for other states to complete. In fact, some preparatory work of dhcp needs to be completed in WiFi state machine, so the process here needs to wait. After the process is completed, it will naturally switch to 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);
This message is not clear: 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
Then look
09-01 21:09:28.151 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,0 09-01 21:09:28.151 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,0 09-01 21:09:28.151 1561 2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg 09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0 09-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; } } }
When entering this waiting state, it will send CMD ﹣ pre ﹣ DHCP ﹣ action to IpClient, and RunningState will process the message accordingly
case DhcpClient.CMD_PRE_DHCP_ACTION: if (mConfiguration.mRequestedPreDhcpActionMs > 0) { ensureDhcpAction(); } else { sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE); } break;
From the log view, we went to ensureDhcpAction() and didn't send the completion message directly.
private void ensureDhcpAction() { if (!mDhcpActionInFlight) { mCallback.onPreDhcpAction(); mDhcpActionInFlight = true; final long alarmTime = SystemClock.elapsedRealtime() + mConfiguration.mRequestedPreDhcpActionMs; mDhcpActionTimeoutAlarm.schedule(alarmTime); } }
Call back to WiFi state machine
class IpClientCallback extends IpClient.Callback { @Override public void onPreDhcpAction() { sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION); }
L2ConnectedState processing
@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. * <p> * 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. * <p> * 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); } }
The WiFi 2p channel will be initialized when starting up after combing the support for p2p, so you need to disable p2p discovery to let the dhcp process continue.
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;
After calling p2pstoppfind, it will send dhcpclient.cmd? Pre? DHCP? Action? Complete to WiFi state machine, L2ConnectedState to continue processing
09-01 21:09:28.153 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0 09-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;
DHCP client receives chcp preparation message to switch state to 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 starts to work. I've combed it before, but the process is a little bit.
09-01 21:09:28.153 1561 4872 D DhcpClient: Broadcasting DHCPDISCOVER 09-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 null 09-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 seconds 09-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.1 09-01 21:09:28.159 1561 12753 D WifiService: getWifiEnabledState uid=1000 09-01 21:09:28.161 1561 12753 D WifiService: getConnectionInfo uid=1000 09-01 21:09:28.161 1561 12753 D WifiService: getWifiEnabledState uid=1000 09-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 7200 09-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 seconds 09-01 21:09:28.163 1561 12753 D WifiService: getConnectionInfo uid=1000
DhcpClient
DHCPREQUEST receives a response and sends a CMD? Post? DHCP? Action message to IpClient.
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 for processing
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; } } //Cancel timeout countdown and call back to WiFi state machine @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; //Let go of the previous control over 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 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: handleIPv4Success <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 seconds> 09-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); } //callback of WiFi state machine @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); }
Continue
09-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r 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,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 0 09-01 21:09:28.166 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 0 09-01 21:09:28.166 1561 2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK 09-01 21:09:28.166 2552 2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE 09-01 21:09:28.166 1561 2457 D WifiStateMachine: Network selected by UID 1000 prompt=true 09-01 21:09:28.166 1561 2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false 09-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; } }
callback of WiFi state machine
@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); }
After ip configuration is successful, set the network state to connected and send broadcast notification. Finally, switch the state to connected state.
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); }
Look at the logic processing after the connection. Here is the scanning logic after the connection. singleScan/pnoScan/periodicScan. The scanning logic will be sorted out and continued.
The startConnectivityScan logic shown here is to light up the screen and connect the ap. If the ap is not connected and the pno scan is not started, the pno scan will be performed. The pno scan is only for the saved network.
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(); }
Come here first.
3. summary