(九十) Android O 结合WifiStateMachine梳理WIFI DHCP流程
发布日期:2021-06-30 15:25:17 浏览次数:2 分类:技术文章

本文共 57464 字,大约阅读时间需要 191 分钟。

前言:之前在 梳理了DHCP流程,现在结合WiFiStateMachine梳理下流程。

 

准备工作:抓取了小米 mix2 8.0 WifiStateMachine进入ObtainingIpState状态开始,到进入ConnectedState结束的log。

09-01 21:09:28.135  1561  2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK  roam=false static=false09-01 21:09:28.135  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false09-01 21:09:28.136  1561  2457 D WifiStateMachine: ObtainingIpAddress clearTargetBssid any key="jiatai 5G"-WPA_PSK09-01 21:09:28.137  1561  2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - stopIpManager - -wrap4809-01 21:09:28.142  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.142  1561  2457 D WifiStateMachine:  DefaultState !CMD_GET_CONFIGURED_NETWORKS uid=1000 rt=411753411/1208576024 1000 0 num=1309-01 21:09:28.143  1561  2457 D WifiStateMachine:  ObtainingIpState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143  1561  2457 D WifiStateMachine:  L2ConnectedState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143  1561  2457 D WifiStateMachine:  ConnectModeState !SUPPLICANT_STATE_CHANGE_EVENT rt=411753412/1208576025 0 0 SSID: jiatai 5G BSSID: 20:6b:e7:93:84:f9 nid: 16 state: COMPLETED09-01 21:09:28.143  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_RSSI_POLL rt=411753412/1208576025 1332 0 "jiatai 5G" 20:6b:e7:93:84:f9 rssi=-127 f=-1 sc=0 link=-1 tx=795242.0, 0.0, 0.0  rx=1663737.8 bcn=2413 [on:0 tx:0 rx:0 period:4689] from screen [on:0 period:1033485890]09-01 21:09:28.143  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_RSSI_POLL rt=411753412/1208576025 1332 0 "jiatai 5G" 20:6b:e7:93:84:f9 rssi=-127 f=-1 sc=0 link=-1 tx=795242.0, 0.0, 0.0  rx=1663737.8 bcn=2413 [on:0 tx:0 rx:0 period:0] from screen [on:0 period:1033485890]09-01 21:09:28.143  1561  2457 D WifiStateMachine:  get link layer stats 009-01 21:09:28.145  1561  2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.146  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 009-01 21:09:28.146  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_CONFIG_ND_OFFLOAD rt=411753415/1208576029 1 009-01 21:09:28.146  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 009-01 21:09:28.146  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_CONFIG_ND_OFFLOAD rt=411753416/1208576029 1 009-01 21:09:28.147  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.147  1561  2457 D WifiStateMachine:  DefaultState !CMD_SET_FALLBACK_PACKET_FILTERING rt=411753416/1208576029 enabled=true09-01 21:09:28.149  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {LinkAddresses: []  Routes: [] DnsAddresses: [] Domains: null MTU: 0} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,]  Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.150  1561  2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR 09-01 21:09:28.151  1561  4875 D DhcpClient: Receive thread started09-01 21:09:28.151  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151  1561  2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg09-01 21:09:28.153  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153  1561  4872 D DhcpClient: Broadcasting DHCPDISCOVER09-01 21:09:28.157  1561  4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 OFFER, ip /192.168.0.105, mask /255.255.255.0, DNS servers: /192.168.0.1 , gateways [/192.168.0.1] lease time 7200, domain null09-01 21:09:28.158  1561  4872 D DhcpClient: Got pending lease: IP address 192.168.0.105/24 Gateway 192.168.0.1  DNS servers: [ 192.168.0.1 ] Domains  DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.158  1561  4872 D DhcpClient: Broadcasting DHCPREQUEST ciaddr=0.0.0.0 request=192.168.0.105 serverid=192.168.0.109-01 21:09:28.162  1561  4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 ACK: your new IP /192.168.0.105, netmask /255.255.255.0, gateways [/192.168.0.1] DNS servers: /192.168.0.1 , lease time 720009-01 21:09:28.162  1561  4872 D DhcpClient: Confirmed lease: IP address 192.168.0.105/24 Gateway 192.168.0.1  DNS servers: [ 192.168.0.1 ] Domains  DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.163  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163  1561  2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 true -want true stack:setSuspendOptimizationsNative - handlePostDhcpSetup - processMessage - processMsg09-01 21:09:28.164  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165  1561  2457 D WifiStateMachine: handleIPv4Success 
09-01 21:09:28.165 1561 2457 D WifiStateMachine: link address 192.168.0.105/2409-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576047 0 0 09-01 21:09:28.165 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.165 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165 1561 2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,192.168.0.105/24,] Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [192.168.0.1,] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.166 1561 2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR v4 v4r v4dns09-01 21:09:28.166 1561 2457 D WifiStateMachine: ObtainingIpState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166 1561 2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK09-01 21:09:28.166 1561 2457 D WifiStateMachine: Network selected by UID 1000 prompt=true09-01 21:09:28.166 1561 2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false09-01 21:09:28.166 1561 2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false09-01 21:09:28.168 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling renewal in 3599s09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling rebind in 6299s09-01 21:09:28.173 1561 4872 D DhcpClient: Scheduling expiry in 7199s09-01 21:09:28.173 1561 2457 D WifiStateMachine: fetchRssiLinkSpeedAndFrequencyNative rssi=-42 linkspeed=866 freq=576509-01 21:09:28.174 1561 2457 D WifiStateMachine: updateDefaultRouteMacAddress found Ipv4 default :192.168.0.109-01 21:09:28.174 1561 2457 E WifiStateMachine: Did not find remoteAddress {192.168.0.1} in /proc/net/arp09-01 21:09:28.178 1561 2457 D WifiStateMachine: Enter ConnectedState mScreenOn=true

 

1.WiFi 连接过程状态切换

09-01 21:09:28.023  1561  2457 D WifiStateMachine: setDetailed state, old =DISCONNECTED and new state=CONNECTING hidden=false09-01 21:09:28.023  1561  2457 D WifiStateMachine: setDetailed state send new extra info"jiatai 5G"09-01 21:09:28.083  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=CONNECTING hidden=false09-01 21:09:28.085  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=AUTHENTICATING hidden=false09-01 21:09:28.095  1561  2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=AUTHENTICATING hidden=false09-01 21:09:28.105  1561  2457 D WifiStateMachine: setDetailed state, old =AUTHENTICATING and new state=CONNECTING hidden=false09-01 21:09:28.135  1561  2457 D WifiStateMachine: enter ObtainingIpState netId=16 "jiatai 5G"-WPA_PSK  roam=false static=false09-01 21:09:28.135  1561  2457 D WifiStateMachine: setDetailed state, old =CONNECTING and new state=OBTAINING_IPADDR hidden=false09-01 21:09:28.166  1561  2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false09-01 21:09:28.178  1561  2457 D WifiStateMachine: Enter ConnectedState  mScreenOn=true

可以观察到WiFi连接过程中有如下几个状态

  • DISCONNECTED
  • CONNECTING
  • AUTHENTICATING
  • OBTAINING_IPADDR
  • CONNECTED

这次主要梳理下OBTAINING_IPADDR状态切换到CONNECTED的流程。

NetworkInfo.java    /**     * The fine-grained state of a network connection. This level of detail     * is probably of interest to few applications. Most should use     * {@link android.net.NetworkInfo.State State} instead.     */    public enum DetailedState {        /** Ready to start data connection setup. */        IDLE,        /** Searching for an available access point. */        SCANNING,        /** Currently setting up data connection. */        CONNECTING,        /** Network link established, performing authentication. */        AUTHENTICATING,        /** Awaiting response from DHCP server in order to assign IP address information. */        OBTAINING_IPADDR,        /** IP traffic should be available. */        CONNECTED,        /** IP traffic is suspended */        SUSPENDED,        /** Currently tearing down data connection. */        DISCONNECTING,        /** IP traffic not available. */        DISCONNECTED,        /** Attempt to connect failed. */        FAILED,        /** Access to this network is blocked. */        BLOCKED,        /** Link has poor connectivity. */        VERIFYING_POOR_LINK,        /** Checking if network is a captive portal */        CAPTIVE_PORTAL_CHECK    }

2.流程梳理

class ObtainingIpState extends State {        @Override        public void enter() {            final WifiConfiguration currentConfig = getCurrentWifiConfiguration();            final boolean isUsingStaticIp =                    (currentConfig.getIpAssignment() == IpConfiguration.IpAssignment.STATIC);            if (mVerboseLoggingEnabled) {                final String key = currentConfig.configKey();                log("enter ObtainingIpState netId=" + Integer.toString(mLastNetworkId)                        + " " + key + " "                        + " roam=" + mIsAutoRoaming                        + " static=" + isUsingStaticIp);            }            // Reset link Debouncing, indicating we have successfully re-connected to the AP            // We might still be roaming            mIsLinkDebouncing = false;            // Send event to CM & network change broadcast            setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);            // We must clear the config BSSID, as the wifi chipset may decide to roam            // from this point on and having the BSSID specified in the network block would            // cause the roam to fail and the device to disconnect.            clearTargetBssid("ObtainingIpAddress");            // Stop IpClient in case we're switching from DHCP to static            // configuration or vice versa.            //            // TODO: Only ever enter this state the first time we connect to a            // network, never on switching between static configuration and            // DHCP. When we transition from static configuration to DHCP in            // particular, we must tell ConnectivityService that we're            // disconnected, because DHCP might take a long time during which            // connectivity APIs such as getActiveNetworkInfo should not return            // CONNECTED.            stopIpClient();            mIpClient.setHttpProxy(currentConfig.getHttpProxy());            if (!TextUtils.isEmpty(mTcpBufferSizes)) {                mIpClient.setTcpBufferSizes(mTcpBufferSizes);            }            final IpClient.ProvisioningConfiguration prov;            if (!isUsingStaticIp) {                prov = IpClient.buildProvisioningConfiguration()                            .withPreDhcpAction()                            .withApfCapabilities(mWifiNative.getApfCapabilities())                            .withNetwork(getCurrentNetwork())                            .withDisplayName(currentConfig.SSID)                            .build();            } else {                StaticIpConfiguration staticIpConfig = currentConfig.getStaticIpConfiguration();                prov = IpClient.buildProvisioningConfiguration()                            .withStaticConfiguration(staticIpConfig)                            .withApfCapabilities(mWifiNative.getApfCapabilities())                            .withNetwork(getCurrentNetwork())                            .withDisplayName(currentConfig.SSID)                            .build();            }            mIpClient.startProvisioning(prov);            // Get Link layer stats so as we get fresh tx packet counters            getWifiLinkLayerStats();        }

将状态设为DetailedState.OBTAINING_IPADDR,初始化好配置后会调用IpClient的startProvisioning

public void startProvisioning(ProvisioningConfiguration req) {        if (!req.isValid()) {            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);            return;        }        mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName);        if (mInterfaceParams == null) {            logError("Failed to find InterfaceParams for " + mInterfaceName);            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND);            return;        }        mCallback.setNeighborDiscoveryOffload(true);        sendMessage(CMD_START, new ProvisioningConfiguration(req));    }

先看下IpClient的初始化

mIpClient = mFacade.makeIpClient(mContext, mInterfaceName, new IpClientCallback());

mInterfaceName默认是wlan0

mWifiNative = new WifiNative(SystemProperties.get("wifi.interface", "wlan0"),                mWifiVendorHal, mSupplicantStaIfaceHal, mWificondControl);        mInterfaceName = mWifiNative.getInterfaceName();

IPClient的准备工作是随配置发出CMD_START的消息

IPClient也包含了一个状态机

private void configureAndStartStateMachine() {        addState(mStoppedState);        addState(mStartedState);            addState(mRunningState, mStartedState);        addState(mStoppingState);        setInitialState(mStoppedState);        super.start();    }

其中StoppedState会处理CMD_START消息,切换到StartedState状态。

case CMD_START:                    mConfiguration = (ProvisioningConfiguration) msg.obj;                    transitionTo(mStartedState);                    break;

 

class StartedState extends State {        @Override        public void enter() {            mStartTimeMillis = SystemClock.elapsedRealtime();            if (mConfiguration.mProvisioningTimeoutMs > 0) {                final long alarmTime = SystemClock.elapsedRealtime() +                        mConfiguration.mProvisioningTimeoutMs;                mProvisioningTimeoutAlarm.schedule(alarmTime);            }            if (readyToProceed()) {                deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));            } else {                // Clear all IPv4 and IPv6 before proceeding to RunningState.                // Clean up any leftover state from an abnormal exit from                // tethering or during an IpClient restart.                stopAllIP();            }        }        @Override        public void exit() {            mProvisioningTimeoutAlarm.cancel();        }        @Override        public boolean processMessage(Message msg) {            switch (msg.what) {                case CMD_JUMP_STARTED_TO_RUNNING:                    transitionTo(mRunningState);                    break;                case CMD_STOP:                    transitionTo(mStoppingState);                    break;                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:                    handleLinkPropertiesUpdate(NO_CALLBACKS);                    if (readyToProceed()) {                        transitionTo(mRunningState);                    }                    break;                case EVENT_PROVISIONING_TIMEOUT:                    handleProvisioningFailure();                    break;                default:                    // It's safe to process messages out of order because the                    // only message that can both                    //     a) be received at this time and                    //     b) affect provisioning state                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).                    deferMessage(msg);            }            mMsgStateLogger.handled(this, getCurrentState());            return HANDLED;        }        private boolean readyToProceed() {            return (!mLinkProperties.hasIPv4Address() &&                    !mLinkProperties.hasGlobalIPv6Address());        }    }

StartedState在enter方法里deferMessage CMD_JUMP_STARTED_TO_RUNNING,enter方法执行完就会处理。因此状态切换到RunningState状态。

class RunningState extends State {        private ConnectivityPacketTracker mPacketTracker;        private boolean mDhcpActionInFlight;        @Override        public void enter() {            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;            apfConfig.multicastFilter = mMulticastFiltering;            // Get the Configuration for ApfFilter from Context            apfConfig.ieee802_3Filter =                    mContext.getResources().getBoolean(R.bool.config_apfDrop802_3Frames);            apfConfig.ethTypeBlackList =                    mContext.getResources().getIntArray(R.array.config_apfEthTypeBlackList);            mApfFilter = ApfFilter.maybeCreate(mContext, apfConfig, mInterfaceParams, mCallback);            // TODO: investigate the effects of any multicast filtering racing/interfering with the            // rest of this IP configuration startup.            if (mApfFilter == null) {                mCallback.setFallbackMulticastFilter(mMulticastFiltering);            }            mPacketTracker = createPacketTracker();            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);            if (mConfiguration.mEnableIPv6 && !startIPv6()) {                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);                enqueueJumpToStoppingState();                return;            }            if (mConfiguration.mEnableIPv4 && !startIPv4()) {                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);                enqueueJumpToStoppingState();                return;            }            final InitialConfiguration config = mConfiguration.mInitialConfig;            if ((config != null) && !applyInitialConfig(config)) {                // TODO introduce a new IpManagerEvent constant to distinguish this error case.                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);                enqueueJumpToStoppingState();                return;            }            if (mConfiguration.mUsingMultinetworkPolicyTracker) {                mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(                        mContext, getHandler(),                        () -> { mLog.log("OBSERVED AvoidBadWifi changed"); });                mMultinetworkPolicyTracker.start();            }            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {                doImmediateProvisioningFailure(                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);                enqueueJumpToStoppingState();                return;            }        }

enter方法区别是配置了ipv6还是ipv4走不同的流程,现在默认一般是ipv4。

看下startIPv4逻辑

private boolean startIPv4() {        // If we have a StaticIpConfiguration attempt to apply it and        // handle the result accordingly.        if (mConfiguration.mStaticIpConfig != null) {            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.ipAddress)) {                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));            } else {                return false;            }        } else {            // Start DHCPv4.            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams);            mDhcpClient.registerForPreDhcpNotification();            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);        }        return true;    }

由于不是静态ip,所以走下面DhcpClient流程,这边就和之前的  流程对上了。

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

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

class StoppedState extends State {        @Override        public boolean processMessage(Message message) {            switch (message.what) {                case CMD_START_DHCP:                    if (mRegisteredForPreDhcpNotification) {                        transitionTo(mWaitBeforeStartState);                    } else {                        transitionTo(mDhcpInitState);                    }                    return HANDLED;                default:                    return NOT_HANDLED;            }        }    }private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);

 

 

这个消息还没搞清楚:CMD_UPDATE_LINKPROPERTIES

09-01 21:09:28.149  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine:  DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753418/1208576032 0 0 09-01 21:09:28.149  1561  2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {LinkAddresses: []  Routes: [] DnsAddresses: [] Domains: null MTU: 0} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,]  Routes: [fe80::/64 -> :: wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.150  1561  2457 D WifiStateMachine: updateLinkProperties nid: 16 state: OBTAINING_IPADDR

 

接着看

09-01 21:09:28.151  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_PRE_DHCP_ACTION rt=411753420/1208576033 0 0 txpkts=3180968,0,009-01 21:09:28.151  1561  2457 D WifiStateMachine: setSuspendOptimizationsNative: 1 false -want true stack:setSuspendOptimizationsNative - handlePreDhcpSetup - processMessage - processMsg09-01 21:09:28.153  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0
class WaitBeforeStartState extends WaitBeforeOtherState {        public WaitBeforeStartState(State otherState) {            super();            mOtherState = otherState;        }    }    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.    abstract class WaitBeforeOtherState extends LoggingState {        protected State mOtherState;        @Override        public void enter() {            super.enter();            mController.sendMessage(CMD_PRE_DHCP_ACTION);        }        @Override        public boolean processMessage(Message message) {            super.processMessage(message);            switch (message.what) {                case CMD_PRE_DHCP_ACTION_COMPLETE:                    transitionTo(mOtherState);                    return HANDLED;                default:                    return NOT_HANDLED;            }        }    }

进入到这个等待状态时会发送CMD_PRE_DHCP_ACTION给IpClient,RunningState会对该消息进行对应处理

case DhcpClient.CMD_PRE_DHCP_ACTION:                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {                        ensureDhcpAction();                    } else {                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);                    }                    break;

这边从log来看是走了ensureDhcpAction(),没有直接发出完成消息。

private void ensureDhcpAction() {            if (!mDhcpActionInFlight) {                mCallback.onPreDhcpAction();                mDhcpActionInFlight = true;                final long alarmTime = SystemClock.elapsedRealtime() +                        mConfiguration.mRequestedPreDhcpActionMs;                mDhcpActionTimeoutAlarm.schedule(alarmTime);            }        }

回调WifiStateMachine

class IpClientCallback extends IpClient.Callback {        @Override        public void onPreDhcpAction() {            sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION);        }

L2ConnectedState处理

@Override        public boolean processMessage(Message message) {            logStateAndMessage(message, this);            switch (message.what) {                case DhcpClient.CMD_PRE_DHCP_ACTION:                    handlePreDhcpSetup();                    break;    void handlePreDhcpSetup() {        if (!mBluetoothConnectionActive) {            /*             * There are problems setting the Wi-Fi driver's power             * mode to active when bluetooth coexistence mode is             * enabled or sense.             * 

* We set Wi-Fi to active mode when * obtaining an IP address because we've found * compatibility issues with some routers with low power * mode. *

* In order for this active power mode to properly be set, * we disable coexistence mode until we're done with * obtaining an IP address. One exception is if we * are currently connected to a headset, since disabling * coexistence would interrupt that connection. */ // Disable the coexistence mode mWifiNative.setBluetoothCoexistenceMode( WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); } // Disable power save and suspend optimizations during DHCP // Note: The order here is important for now. Brcm driver changes // power settings when we control suspend mode optimizations. // TODO: Remove this comment when the driver is fixed. setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false); mWifiNative.setPowerSave(false); // Update link layer stats getWifiLinkLayerStats(); if (mWifiP2pChannel != null) { /* P2p discovery breaks dhcp, shut it down in order to get through this */ Message msg = new Message(); msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY; msg.arg1 = WifiP2pServiceImpl.ENABLED; msg.arg2 = DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE; msg.obj = WifiStateMachine.this; mWifiP2pChannel.sendMessage(msg); } else { // If the p2p service is not running, we can proceed directly. sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE); } }

之前梳理过支持p2p的话开机启动的时候wifip2pChannel就会被初始化,所以这边需要先禁用p2p discovery,让dhcp流程继续往下走。

WifiP2pServiceImpl P2pEnabledState

case BLOCK_DISCOVERY:                        boolean blocked = (message.arg1 == ENABLED ? true : false);                        if (mDiscoveryBlocked == blocked) break;                        mDiscoveryBlocked = blocked;                        if (blocked && mDiscoveryStarted) {                            mWifiNative.p2pStopFind();                            mDiscoveryPostponed = true;                        }                        if (!blocked && mDiscoveryPostponed) {                            mDiscoveryPostponed = false;                            mWifiNative.p2pFind(DISCOVER_TIMEOUT_S);                        }                        if (blocked) {                            if (message.obj == null) {                                Log.e(TAG, "Illegal argument(s)");                                break;                            }                            StateMachine m = (StateMachine) message.obj;                            try {                                m.sendMessage(message.arg2);                            } catch (Exception e) {                                loge("unable to send BLOCK_DISCOVERY response: " + e);                            }                        }                        break;

调用完p2pStopFind后会发DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE给WifiStateMachine,L2ConnectedState继续处理

09-01 21:09:28.153  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 009-01 21:09:28.153  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_PRE_DHCP_ACTION_COMPLETE rt=411753422/1208576035 0 0
case DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE:                    mIpClient.completedPreDhcpAction();                    break;

IpClient

public void completedPreDhcpAction() {        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);    }RunningState                case EVENT_PRE_DHCP_ACTION_COMPLETE:                    // It's possible to reach here if, for example, someone                    // calls completedPreDhcpAction() after provisioning with                    // a static IP configuration.                    if (mDhcpClient != null) {                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);                    }                    break;

DhcpClient接收到chcp准备完成消息将状态切换到mDhcpInitState

class WaitBeforeStartState extends WaitBeforeOtherState {        public WaitBeforeStartState(State otherState) {            super();            mOtherState = otherState;        }    }    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.    abstract class WaitBeforeOtherState extends LoggingState {        protected State mOtherState;        @Override        public void enter() {            super.enter();            mController.sendMessage(CMD_PRE_DHCP_ACTION);        }        @Override        public boolean processMessage(Message message) {            super.processMessage(message);            switch (message.what) {                case CMD_PRE_DHCP_ACTION_COMPLETE:                    transitionTo(mOtherState);                    return HANDLED;                default:                    return NOT_HANDLED;            }        }    }
class DhcpInitState extends PacketRetransmittingState {        public DhcpInitState() {            super();        }        @Override        public void enter() {            super.enter();            startNewTransaction();            mLastInitEnterTime = SystemClock.elapsedRealtime();        }        protected boolean sendPacket() {            return sendDiscoverPacket();        }        protected void receivePacket(DhcpPacket packet) {            if (!isValidPacket(packet)) return;            if (!(packet instanceof DhcpOfferPacket)) return;            mOffer = packet.toDhcpResults();            if (mOffer != null) {                Log.d(TAG, "Got pending lease: " + mOffer);                transitionTo(mDhcpRequestingState);            }        }    }

dhcp开始干活,之前梳理过了,流程略。

09-01 21:09:28.153  1561  4872 D DhcpClient: Broadcasting DHCPDISCOVER09-01 21:09:28.157  1561  4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 OFFER, ip /192.168.0.105, mask /255.255.255.0, DNS servers: /192.168.0.1 , gateways [/192.168.0.1] lease time 7200, domain null09-01 21:09:28.158  1561  4872 D DhcpClient: Got pending lease: IP address 192.168.0.105/24 Gateway 192.168.0.1  DNS servers: [ 192.168.0.1 ] Domains  DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.158  1561  4872 D DhcpClient: Broadcasting DHCPREQUEST ciaddr=0.0.0.0 request=192.168.0.105 serverid=192.168.0.109-01 21:09:28.159  1561 12753 D WifiService: getWifiEnabledState uid=100009-01 21:09:28.161  1561 12753 D WifiService: getConnectionInfo uid=100009-01 21:09:28.161  1561 12753 D WifiService: getWifiEnabledState uid=100009-01 21:09:28.162  1561  4875 D DhcpClient: Received packet: e4:46:da:6b:f5:50 ACK: your new IP /192.168.0.105, netmask /255.255.255.0, gateways [/192.168.0.1] DNS servers: /192.168.0.1 , lease time 720009-01 21:09:28.162  1561  4872 D DhcpClient: Confirmed lease: IP address 192.168.0.105/24 Gateway 192.168.0.1  DNS servers: [ 192.168.0.1 ] Domains  DHCP server /192.168.0.1 Vendor info null lease 7200 seconds09-01 21:09:28.163  1561 12753 D WifiService: getConnectionInfo uid=1000

 

DhcpClient

DHCPREQUEST收到回应,向IpClient发出CMD_POST_DHCP_ACTION消息。

private void notifySuccess() {        mController.sendMessage(                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));    }    private void acceptDhcpResults(DhcpResults results, String msg) {        mDhcpLease = results;        mOffer = null;        Log.d(TAG, msg + " lease: " + mDhcpLease);        notifySuccess();    }    class DhcpRequestingState extends PacketRetransmittingState {        public DhcpRequestingState() {            mTimeout = DHCP_TIMEOUT_MS / 2;        }        protected boolean sendPacket() {            return sendRequestPacket(                    INADDR_ANY,                                    // ciaddr                    (Inet4Address) mOffer.ipAddress.getAddress(),  // DHCP_REQUESTED_IP                    (Inet4Address) mOffer.serverAddress,           // DHCP_SERVER_IDENTIFIER                    INADDR_BROADCAST);                             // packet destination address        }        protected void receivePacket(DhcpPacket packet) {            if (!isValidPacket(packet)) return;            if ((packet instanceof DhcpAckPacket)) {                DhcpResults results = packet.toDhcpResults();                if (results != null) {                    setDhcpLeaseExpiry(packet);                    acceptDhcpResults(results, "Confirmed");                    transitionTo(mConfiguringInterfaceState);                }            } else if (packet instanceof DhcpNakPacket) {                // TODO: Wait a while before returning into INIT state.                Log.d(TAG, "Received NAK, returning to INIT");                mOffer = null;                transitionTo(mDhcpInitState);            }        }

IpClient进行处理

09-01 21:09:28.163  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0 09-01 21:09:28.163  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_POST_DHCP_ACTION rt=411753432/1208576045 0 0
case DhcpClient.CMD_POST_DHCP_ACTION:                    stopDhcpAction();                    switch (msg.arg1) {                        case DhcpClient.DHCP_SUCCESS:                            handleIPv4Success((DhcpResults) msg.obj);                            break;                        case DhcpClient.DHCP_FAILURE:                            handleIPv4Failure();                            break;                        default:                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);                    }                    break;
private void stopDhcpAction() {            mDhcpActionTimeoutAlarm.cancel();            if (mDhcpActionInFlight) {                mCallback.onPostDhcpAction();                mDhcpActionInFlight = false;            }        }取消timeout倒计时,回调WifiStateMachine        @Override        public void onPostDhcpAction() {            sendMessage(DhcpClient.CMD_POST_DHCP_ACTION);        }                case DhcpClient.CMD_POST_DHCP_ACTION:                    handlePostDhcpSetup();                    // We advance to mConnectedState because IpClient will also send a                    // CMD_IPV4_PROVISIONING_SUCCESS message, which calls handleIPv4Success(),                    // which calls updateLinkProperties, which then sends                    // CMD_IP_CONFIGURATION_SUCCESSFUL.                    //                    // In the event of failure, we transition to mDisconnectingState                    // similarly--via messages sent back from IpClient.                    break;放开之前对p2p find的控制。    void handlePostDhcpSetup() {        /* Restore power save and suspend optimizations */        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);        mWifiNative.setPowerSave(true);        p2pSendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED);        // Set the coexistence mode back to its default value        mWifiNative.setBluetoothCoexistenceMode(                WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);    }

 

09-01 21:09:28.164  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_IPV4_PROVISIONING_SUCCESS rt=411753434/1208576047 009-01 21:09:28.165  1561  2457 D WifiStateMachine: handleIPv4Success 
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        @Override        public void onNewDhcpResults(DhcpResults dhcpResults) {            if (dhcpResults != null) {                sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults);            } else {                sendMessage(CMD_IPV4_PROVISIONING_FAILURE);                mWifiInjector.getWifiLastResortWatchdog().noteConnectionFailureAndTriggerIfNeeded(                        getTargetSsid(), mTargetRoamBSSID,                        WifiLastResortWatchdog.FAILURE_CODE_DHCP);            }        }                case CMD_IPV4_PROVISIONING_SUCCESS: {                    handleIPv4Success((DhcpResults) message.obj);                    sendNetworkStateChangeBroadcast(mLastBssid);                    break;                }    private void handleIPv4Success(DhcpResults dhcpResults) {        if (mVerboseLoggingEnabled) {            logd("handleIPv4Success <" + dhcpResults.toString() + ">");            logd("link address " + dhcpResults.ipAddress);        }        Inet4Address addr;        synchronized (mDhcpResultsLock) {            mDhcpResults = dhcpResults;            addr = (Inet4Address) dhcpResults.ipAddress.getAddress();        }        if (mIsAutoRoaming) {            int previousAddress = mWifiInfo.getIpAddress();            int newAddress = NetworkUtils.inetAddressToInt(addr);            if (previousAddress != newAddress) {                logd("handleIPv4Success, roaming and address changed" +                        mWifiInfo + " got: " + addr);            }        }        mWifiInfo.setInetAddress(addr);        final WifiConfiguration config = getCurrentWifiConfiguration();        if (config != null) {            mWifiInfo.setEphemeral(config.ephemeral);        }        // Set meteredHint if DHCP result says network is metered        if (dhcpResults.hasMeteredHint()) {            mWifiInfo.setMeteredHint(true);        }        updateCapabilities(config);    }    private void sendNetworkStateChangeBroadcast(String bssid) {        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));        if (bssid != null)            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);        if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK ||                mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) {            // We no longer report MAC address to third-parties and our code does            // not rely on this broadcast, so just send the default MAC address.            fetchRssiLinkSpeedAndFrequencyNative();            WifiInfo sentWifiInfo = new WifiInfo(mWifiInfo);            sentWifiInfo.setMacAddress(WifiInfo.DEFAULT_MAC_ADDRESS);            intent.putExtra(WifiManager.EXTRA_WIFI_INFO, sentWifiInfo);        }        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);    }

 

继续

09-01 21:09:28.165  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165  1561  2457 D WifiStateMachine:  ConnectModeState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165  1561  2457 D WifiStateMachine:  SupplicantStartedState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165  1561  2457 D WifiStateMachine:  DefaultState !CMD_UPDATE_LINKPROPERTIES rt=411753434/1208576048 0 0 v4r09-01 21:09:28.165  1561  2457 D WifiStateMachine: Link configuration changed for netId: 16 old: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,]  Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024} new: {InterfaceName: wlan0 LinkAddresses: [fe80::e646:daff:fe6b:f550/64,192.168.0.105/24,]  Routes: [fe80::/64 -> :: wlan0,192.168.0.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.0.1 wlan0,] DnsAddresses: [192.168.0.1,] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,5505024,262144,524288,5505024}09-01 21:09:28.166  1561  2457 D WifiStateMachine:  ObtainingIpState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166  1561  2457 D WifiStateMachine:  L2ConnectedState !CMD_IP_CONFIGURATION_SUCCESSFUL rt=411753435/1208576048 0 009-01 21:09:28.166  1561  2457 D WifiStateMachine: WifiStateMachine: handleSuccessfulIpConfiguration and no scan results"jiatai 5G"-WPA_PSK09-01 21:09:28.166  2552  2552 D ToggleManager: updateWifiToggle wifiState=-1 mWifiConnected=false action=android.net.wifi.STATE_CHANGE09-01 21:09:28.166  1561  2457 D WifiStateMachine: Network selected by UID 1000 prompt=true09-01 21:09:28.166  1561  2457 D WifiStateMachine: explictlySelected acceptUnvalidated=false09-01 21:09:28.166  1561  2457 D WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR and new state=CONNECTED hidden=false

IpClient

private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {        switch (delta) {            case GAINED_PROVISIONING:                if (DBG) { Log.d(mTag, "onProvisioningSuccess()"); }                recordMetric(IpManagerEvent.PROVISIONING_OK);                mCallback.onProvisioningSuccess(newLp);                break;            case LOST_PROVISIONING:                if (DBG) { Log.d(mTag, "onProvisioningFailure()"); }                recordMetric(IpManagerEvent.PROVISIONING_FAIL);                mCallback.onProvisioningFailure(newLp);                break;            default:                if (DBG) { Log.d(mTag, "onLinkPropertiesChange()"); }                mCallback.onLinkPropertiesChange(newLp);                break;        }    }

回调WifiStateMachine的callback

@Override        public void onProvisioningSuccess(LinkProperties newLp) {            mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL);            sendMessage(CMD_UPDATE_LINKPROPERTIES, newLp);            sendMessage(CMD_IP_CONFIGURATION_SUCCESSFUL);        }

 

/* Link configuration (IP address, DNS, ...) changes notified via netlink */                case CMD_UPDATE_LINKPROPERTIES:                    updateLinkProperties((LinkProperties) message.obj);                    break;    private void updateLinkProperties(LinkProperties newLp) {        if (mVerboseLoggingEnabled) {            log("Link configuration changed for netId: " + mLastNetworkId                    + " old: " + mLinkProperties + " new: " + newLp);        }        // We own this instance of LinkProperties because IpClient passes us a copy.        mLinkProperties = newLp;        if (mNetworkAgent != null) {            mNetworkAgent.sendLinkProperties(mLinkProperties);        }        if (getNetworkDetailedState() == DetailedState.CONNECTED) {            // If anything has changed and we're already connected, send out a notification.            // TODO: Update all callers to use NetworkCallbacks and delete this.            sendLinkConfigurationChangedBroadcast();        }        if (mVerboseLoggingEnabled) {            StringBuilder sb = new StringBuilder();            sb.append("updateLinkProperties nid: " + mLastNetworkId);            sb.append(" state: " + getNetworkDetailedState());            if (mLinkProperties != null) {                sb.append(" ");                sb.append(getLinkPropertiesSummary(mLinkProperties));            }            logd(sb.toString());        }    }

 

case CMD_IP_CONFIGURATION_SUCCESSFUL:                    handleSuccessfulIpConfiguration();                    reportConnectionAttemptEnd(                            WifiMetrics.ConnectionEvent.FAILURE_NONE,                            WifiMetricsProto.ConnectionEvent.HLF_NONE);                    if (getCurrentWifiConfiguration() == null) {                        // The current config may have been removed while we were connecting,                        // trigger a disconnect to clear up state.                        mWifiNative.disconnect();                        transitionTo(mDisconnectingState);                    } else {                        sendConnectedState();                        transitionTo(mConnectedState);                    }                    break;    private void handleSuccessfulIpConfiguration() {        mLastSignalLevel = -1; // Force update of signal strength        WifiConfiguration c = getCurrentWifiConfiguration();        if (c != null) {            // Reset IP failure tracking            c.getNetworkSelectionStatus().clearDisableReasonCounter(                    WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE);            // Tell the framework whether the newly connected network is trusted or untrusted.            updateCapabilities(c);        }        if (c != null) {            ScanResult result = getCurrentScanResult();            if (result == null) {                logd("WifiStateMachine: handleSuccessfulIpConfiguration and no scan results" +                        c.configKey());            } else {                // Clear the per BSSID failure count                result.numIpConfigFailures = 0;            private void sendConnectedState() {        // If this network was explicitly selected by the user, evaluate whether to call        // explicitlySelected() so the system can treat it appropriately.        WifiConfiguration config = getCurrentWifiConfiguration();        if (shouldEvaluateWhetherToSendExplicitlySelected(config)) {            boolean prompt =                    mWifiPermissionsUtil.checkNetworkSettingsPermission(config.lastConnectUid);            if (mVerboseLoggingEnabled) {                log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt);            }            if (prompt) {                // Selected by the user via Settings or QuickSettings. If this network has Internet                // access, switch to it. Otherwise, switch to it only if the user confirms that they                // really want to switch, or has already confirmed and selected "Don't ask again".                if (mVerboseLoggingEnabled) {                    log("explictlySelected acceptUnvalidated=" + config.noInternetAccessExpected);                }                if (mNetworkAgent != null) {                    mNetworkAgent.explicitlySelected(config.noInternetAccessExpected);                }            }        }        setNetworkDetailedState(DetailedState.CONNECTED);        mWifiConfigManager.updateNetworkAfterConnect(mLastNetworkId);        sendNetworkStateChangeBroadcast(mLastBssid);    }

ip配置成功后设置网络状态变为connected并发送广播通知,最后状态切到ConnectedState。

class ConnectedState extends State {        @Override        public void enter() {            // TODO: b/64349637 Investigate getting default router IP/MAC address info from            // IpManager            //updateDefaultRouteMacAddress(1000);            if (mVerboseLoggingEnabled) {                log("Enter ConnectedState "                       + " mScreenOn=" + mScreenOn);            }            mWifiConnectivityManager.handleConnectionStateChanged(                    WifiConnectivityManager.WIFI_STATE_CONNECTED);            registerConnected();            lastConnectAttemptTimestamp = 0;            targetWificonfiguration = null;            // Paranoia            mIsLinkDebouncing = false;            // Not roaming anymore            mIsAutoRoaming = false;            if (testNetworkDisconnect) {                testNetworkDisconnectCounter++;                logd("ConnectedState Enter start disconnect test " +                        testNetworkDisconnectCounter);                sendMessageDelayed(obtainMessage(CMD_TEST_NETWORK_DISCONNECT,                        testNetworkDisconnectCounter, 0), 15000);            }            mLastDriverRoamAttempt = 0;            mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID;            mWifiInjector.getWifiLastResortWatchdog().connectedStateTransition(true);            mWifiStateTracker.updateState(WifiStateTracker.CONNECTED);        }

看下连接上了以后的逻辑处理,这边是对应连接上了以后的扫描逻辑,singleScan/pnoScan/periodicScan,扫描逻辑梳理待续。

这边可以看到的startConnectivityScan逻辑是亮屏并且连接ap那就进行定时扫描,否则如果未连接ap并且pno扫描未开始,则进行pno扫描,pno扫描是只针对已保存网络的扫描。

WifiConnectivityManager

/**     * Handler for WiFi state (connected/disconnected) changes     */    public void handleConnectionStateChanged(int state) {        localLog("handleConnectionStateChanged: state=" + stateToString(state));        mWifiState = state;        if (mWifiState == WIFI_STATE_CONNECTED) {            mOpenNetworkNotifier.handleWifiConnected();        }        // Reset BSSID of last connection attempt and kick off        // the watchdog timer if entering disconnected state.        if (mWifiState == WIFI_STATE_DISCONNECTED) {            mLastConnectionAttemptBssid = null;            scheduleWatchdogTimer();            startConnectivityScan(SCAN_IMMEDIATELY);        } else {            startConnectivityScan(SCAN_ON_SCHEDULE);        }    }    // Start a connectivity scan. The scan method is chosen according to    // the current screen state and WiFi state.    private void startConnectivityScan(boolean scanImmediately) {        localLog("startConnectivityScan: screenOn=" + mScreenOn                + " wifiState=" + stateToString(mWifiState)                + " scanImmediately=" + scanImmediately                + " wifiEnabled=" + mWifiEnabled                + " wifiConnectivityManagerEnabled="                + mWifiConnectivityManagerEnabled);        if (!mWifiEnabled || !mWifiConnectivityManagerEnabled) {            return;        }        // Always stop outstanding connecivity scan if there is any        stopConnectivityScan();        // Don't start a connectivity scan while Wifi is in the transition        // between connected and disconnected states.        if (mWifiState != WIFI_STATE_CONNECTED && mWifiState != WIFI_STATE_DISCONNECTED) {            return;        }        if (mScreenOn) {            startPeriodicScan(scanImmediately);        } else {            if (mWifiState == WIFI_STATE_DISCONNECTED && !mPnoScanStarted) {                startDisconnectedPnoScan();            }        }    }    // Start a periodic scan when screen is on    private void startPeriodicScan(boolean scanImmediately) {        mPnoScanListener.resetLowRssiNetworkRetryDelay();        // No connectivity scan if auto roaming is disabled.        if (mWifiState == WIFI_STATE_CONNECTED && !mEnableAutoJoinWhenAssociated) {            return;        }        // Due to b/28020168, timer based single scan will be scheduled        // to provide periodic scan in an exponential backoff fashion.        if (scanImmediately) {            resetLastPeriodicSingleScanTimeStamp();        }        mPeriodicSingleScanInterval = PERIODIC_SCAN_INTERVAL_MS;        startPeriodicSingleScan();    }
贴一下system wifi状态栏图标时序图
贴一下systemui wifi状态栏图标时序图

先到这吧。

 

3. 总结

 

转载地址:https://jiatai.blog.csdn.net/article/details/82527796 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:(九十一) Ubuntu 16.04 安装wireshark
下一篇:(八十九) Android O 探索WiFi直连默认名称由来

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月14日 13时29分02秒