(九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程

编程入门 行业动态 更新时间:2024-10-19 23:43:03

(九十) Android O 结合WifiStateMachine梳理WIFI DHCP<a href=https://www.elefans.com/category/jswz/34/1770115.html style=流程"/>

(九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程

前言:之前在(八十七) WiFi & DHCP 梳理了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=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 连接过程状态切换

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

可以观察到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.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 {@Overridepublic 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 roamingmIsLinkDebouncing = false;// Send event to CM & network change broadcastsetNetworkDetailedState(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 countersgetWifiLinkLayerStats();}

将状态设为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 {@Overridepublic 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();}}@Overridepublic void exit() {mProvisioningTimeoutAlarm.cancel();}@Overridepublic 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;@Overridepublic void enter() {ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;apfConfig.multicastFilter = mMulticastFiltering;// Get the Configuration for ApfFilter from ContextapfConfig.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流程,这边就和之前的(八十七) WiFi & DHCP  流程对上了。

但当时没梳理清楚WaitBeforeStartState状态的含义。

DhcpClient切换到mWaitBeforeStartState,这是由于之前有调用mDhcpClient.registerForPreDhcpNotification();所以这边状态等待其他状态完成,其实是dhcp有些准备工作需要在WifiStateMachine中完成,所以这边流程需要等一下,流程完了自然会切换到DhcpInitState。

    class StoppedState extends State {@Overridepublic 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,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;@Overridepublic void enter() {super.enter();mController.sendMessage(CMD_PRE_DHCP_ACTION);}@Overridepublic 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 {@Overridepublic void onPreDhcpAction() {sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION);}

L2ConnectedState处理

        @Overridepublic 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 modemWifiNative.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 statsgetWifiLinkLayerStats();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 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:mIpClientpletedPreDhcpAction();break;

IpClient

    public void completedPreDhcpAction() {sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);}
RunningStatecase 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;@Overridepublic void enter() {super.enter();mController.sendMessage(CMD_PRE_DHCP_ACTION);}@Overridepublic 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();}@Overridepublic 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 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收到回应,向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_IDENTIFIERINADDR_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@Overridepublic 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 valuemWifiNative.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);}回调WifiStateMachine的callback@Overridepublic 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 meteredif (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 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.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;}}

回调WifiStateMachine的callback

        @Overridepublic 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 strengthWifiConfiguration c = getCurrentWifiConfiguration();if (c != null) {// Reset IP failure trackingc.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 countresult.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 {@Overridepublic 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;// ParanoiamIsLinkDebouncing = false;// Not roaming anymoremIsAutoRoaming = 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 anystopConnectivityScan();// 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 onprivate 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();}
贴一下systemui wifi状态栏图标时序图

先到这吧。

 

3. 总结

 

更多推荐

(九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程

本文发布于:2024-03-05 04:22:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1711299.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:流程   WifiStateMachine   Android   DHCP   WIFI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!