summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/net/DhcpStateMachine.java353
-rw-r--r--core/java/android/net/NetworkUtils.java10
-rw-r--r--core/jni/android_net_NetUtils.cpp35
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java281
4 files changed, 134 insertions, 545 deletions
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
deleted file mode 100644
index eaf087f..0000000
--- a/core/java/android/net/DhcpStateMachine.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.DhcpInfoInternal;
-import android.net.NetworkUtils;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.Log;
-
-/**
- * StateMachine that interacts with the native DHCP client and can talk to
- * a controller that also needs to be a StateMachine
- *
- * The Dhcp state machine provides the following features:
- * - Wakeup and renewal using the native DHCP client (which will not renew
- * on its own when the device is in suspend state and this can lead to device
- * holding IP address beyond expiry)
- * - A notification right before DHCP request or renewal is started. This
- * can be used for any additional setup before DHCP. For example, wifi sets
- * BT-Wifi coex settings right before DHCP is initiated
- *
- * @hide
- */
-public class DhcpStateMachine extends StateMachine {
-
- private static final String TAG = "DhcpStateMachine";
- private static final boolean DBG = false;
-
-
- /* A StateMachine that controls the DhcpStateMachine */
- private StateMachine mController;
-
- private Context mContext;
- private BroadcastReceiver mBroadcastReceiver;
- private AlarmManager mAlarmManager;
- private PendingIntent mDhcpRenewalIntent;
- private PowerManager.WakeLock mDhcpRenewWakeLock;
- private static final String WAKELOCK_TAG = "DHCP";
-
- private static final int DHCP_RENEW = 0;
- private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
-
- private enum DhcpAction {
- START,
- RENEW
- };
-
- private String mInterfaceName;
- private boolean mRegisteredForPreDhcpNotification = false;
-
- private static final int BASE = Protocol.BASE_DHCP;
-
- /* Commands from controller to start/stop DHCP */
- public static final int CMD_START_DHCP = BASE + 1;
- public static final int CMD_STOP_DHCP = BASE + 2;
- public static final int CMD_RENEW_DHCP = BASE + 3;
-
- /* Notification from DHCP state machine prior to DHCP discovery/renewal */
- public static final int CMD_PRE_DHCP_ACTION = BASE + 4;
- /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
- * success/failure */
- public static final int CMD_POST_DHCP_ACTION = BASE + 5;
-
- /* Command from controller to indicate DHCP discovery/renewal can continue
- * after pre DHCP action is complete */
- public static final int CMD_PRE_DHCP_ACTION_COMPLETE = BASE + 6;
-
- /* Message.arg1 arguments to CMD_POST_DHCP notification */
- public static final int DHCP_SUCCESS = 1;
- public static final int DHCP_FAILURE = 2;
-
- private State mDefaultState = new DefaultState();
- private State mStoppedState = new StoppedState();
- private State mWaitBeforeStartState = new WaitBeforeStartState();
- private State mRunningState = new RunningState();
- private State mWaitBeforeRenewalState = new WaitBeforeRenewalState();
-
- private DhcpStateMachine(Context context, StateMachine controller, String intf) {
- super(TAG);
-
- mContext = context;
- mController = controller;
- mInterfaceName = intf;
-
- mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- Intent dhcpRenewalIntent = new Intent(ACTION_DHCP_RENEW, null);
- mDhcpRenewalIntent = PendingIntent.getBroadcast(mContext, DHCP_RENEW, dhcpRenewalIntent, 0);
-
- PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mDhcpRenewWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
- mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- //DHCP renew
- if (DBG) Log.d(TAG, "Sending a DHCP renewal " + this);
- //acquire a 40s wakelock to finish DHCP renewal
- mDhcpRenewWakeLock.acquire(40000);
- sendMessage(CMD_RENEW_DHCP);
- }
- };
- mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_DHCP_RENEW));
-
- addState(mDefaultState);
- addState(mStoppedState, mDefaultState);
- addState(mWaitBeforeStartState, mDefaultState);
- addState(mRunningState, mDefaultState);
- addState(mWaitBeforeRenewalState, mDefaultState);
-
- setInitialState(mStoppedState);
- }
-
- public static DhcpStateMachine makeDhcpStateMachine(Context context, StateMachine controller,
- String intf) {
- DhcpStateMachine dsm = new DhcpStateMachine(context, controller, intf);
- dsm.start();
- return dsm;
- }
-
- /**
- * This sends a notification right before DHCP request/renewal so that the
- * controller can do certain actions before DHCP packets are sent out.
- * When the controller is ready, it sends a CMD_PRE_DHCP_ACTION_COMPLETE message
- * to indicate DHCP can continue
- *
- * This is used by Wifi at this time for the purpose of doing BT-Wifi coex
- * handling during Dhcp
- */
- public void registerForPreDhcpNotification() {
- mRegisteredForPreDhcpNotification = true;
- }
-
- class DefaultState extends State {
- @Override
- public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_RENEW_DHCP:
- Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
- break;
- case SM_QUIT_CMD:
- mContext.unregisterReceiver(mBroadcastReceiver);
- //let parent kill the state machine
- return NOT_HANDLED;
- default:
- Log.e(TAG, "Error! unhandled message " + message);
- break;
- }
- return HANDLED;
- }
- }
-
-
- class StoppedState extends State {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
-
- @Override
- public boolean processMessage(Message message) {
- boolean retValue = HANDLED;
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_START_DHCP:
- if (mRegisteredForPreDhcpNotification) {
- /* Notify controller before starting DHCP */
- mController.sendMessage(CMD_PRE_DHCP_ACTION);
- transitionTo(mWaitBeforeStartState);
- } else {
- if (runDhcp(DhcpAction.START)) {
- transitionTo(mRunningState);
- }
- }
- break;
- case CMD_STOP_DHCP:
- //ignore
- break;
- default:
- retValue = NOT_HANDLED;
- break;
- }
- return retValue;
- }
- }
-
- class WaitBeforeStartState extends State {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
-
- @Override
- public boolean processMessage(Message message) {
- boolean retValue = HANDLED;
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_PRE_DHCP_ACTION_COMPLETE:
- if (runDhcp(DhcpAction.START)) {
- transitionTo(mRunningState);
- } else {
- transitionTo(mStoppedState);
- }
- break;
- case CMD_STOP_DHCP:
- transitionTo(mStoppedState);
- break;
- case CMD_START_DHCP:
- //ignore
- break;
- default:
- retValue = NOT_HANDLED;
- break;
- }
- return retValue;
- }
- }
-
- class RunningState extends State {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
-
- @Override
- public boolean processMessage(Message message) {
- boolean retValue = HANDLED;
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_STOP_DHCP:
- mAlarmManager.cancel(mDhcpRenewalIntent);
- if (!NetworkUtils.stopDhcp(mInterfaceName)) {
- Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
- }
- transitionTo(mStoppedState);
- break;
- case CMD_RENEW_DHCP:
- if (mRegisteredForPreDhcpNotification) {
- /* Notify controller before starting DHCP */
- mController.sendMessage(CMD_PRE_DHCP_ACTION);
- transitionTo(mWaitBeforeRenewalState);
- } else {
- if (!runDhcp(DhcpAction.RENEW)) {
- transitionTo(mStoppedState);
- }
- }
- break;
- case CMD_START_DHCP:
- //ignore
- break;
- default:
- retValue = NOT_HANDLED;
- }
- return retValue;
- }
- }
-
- class WaitBeforeRenewalState extends State {
- @Override
- public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
- }
-
- @Override
- public boolean processMessage(Message message) {
- boolean retValue = HANDLED;
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- switch (message.what) {
- case CMD_STOP_DHCP:
- mAlarmManager.cancel(mDhcpRenewalIntent);
- if (!NetworkUtils.stopDhcp(mInterfaceName)) {
- Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
- }
- transitionTo(mStoppedState);
- break;
- case CMD_PRE_DHCP_ACTION_COMPLETE:
- if (runDhcp(DhcpAction.RENEW)) {
- transitionTo(mRunningState);
- } else {
- transitionTo(mStoppedState);
- }
- break;
- case CMD_START_DHCP:
- //ignore
- break;
- default:
- retValue = NOT_HANDLED;
- break;
- }
- return retValue;
- }
- }
-
- private boolean runDhcp(DhcpAction dhcpAction) {
- boolean success = false;
- DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
-
- if (dhcpAction == DhcpAction.START) {
- Log.d(TAG, "DHCP request on " + mInterfaceName);
- success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
- } else if (dhcpAction == DhcpAction.RENEW) {
- Log.d(TAG, "DHCP renewal on " + mInterfaceName);
- success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
- }
-
- if (success) {
- Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
- //Do it a bit earlier than half the lease duration time
- //to beat the native DHCP client and avoid extra packets
- //48% for one hour lease time = 29 minutes
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() +
- dhcpInfoInternal.leaseDuration * 480, //in milliseconds
- mDhcpRenewalIntent);
-
- mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
- .sendToTarget();
- } else {
- Log.d(TAG, "DHCP failed on " + mInterfaceName + ": " +
- NetworkUtils.getDhcpError());
- NetworkUtils.stopDhcp(mInterfaceName);
- mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
- .sendToTarget();
- }
- return success;
- }
-}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 8a678d6..cb9caf8 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -54,16 +54,6 @@ public class NetworkUtils {
public native static boolean runDhcp(String interfaceName, DhcpInfoInternal ipInfo);
/**
- * Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
- * a result (either success or failure) from the daemon.
- * @param interfaceName the name of the interface to configure
- * @param ipInfo if the request succeeds, this object is filled in with
- * the IP address information.
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean runDhcpRenew(String interfaceName, DhcpInfoInternal ipInfo);
-
- /**
* Shut down the DHCP client daemon.
* @param interfaceName the name of the interface for which the daemon
* should be stopped
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 68d1b3a..f11c81d 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -36,16 +36,6 @@ int dhcp_do_request(const char *ifname,
const char *dns2,
const char *server,
uint32_t *lease);
-
-int dhcp_do_request_renew(const char *ifname,
- const char *ipaddr,
- const char *gateway,
- uint32_t *prefixLength,
- const char *dns1,
- const char *dns2,
- const char *server,
- uint32_t *lease);
-
int dhcp_stop(const char *ifname);
int dhcp_release_lease(const char *ifname);
char *dhcp_get_errmsg();
@@ -101,8 +91,7 @@ static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstri
return (jint)result;
}
-static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
- jobject info, bool renew)
+static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
{
int result;
char ipaddr[PROPERTY_VALUE_MAX];
@@ -116,14 +105,8 @@ static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstr
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
if (nameStr == NULL) return (jboolean)false;
- if (renew) {
- result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
- dns1, dns2, server, &lease);
- } else {
- result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
- dns1, dns2, server, &lease);
- }
-
+ result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
+ dns1, dns2, server, &lease);
env->ReleaseStringUTFChars(ifname, nameStr);
if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
@@ -161,17 +144,6 @@ static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstr
return (jboolean)(result == 0);
}
-static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
-{
- return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
-}
-
-static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
-{
- return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
-}
-
-
static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
@@ -209,7 +181,6 @@ static JNINativeMethod gNetworkUtilMethods[] = {
{ "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
{ "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcp },
- { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcpRenew },
{ "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
{ "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index d10a5d8..ce441aa 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -48,7 +48,6 @@ import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.DhcpInfoInternal;
-import android.net.DhcpStateMachine;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -153,7 +152,6 @@ public class WifiStateMachine extends StateMachine {
private NetworkInfo mNetworkInfo;
private SupplicantStateTracker mSupplicantStateTracker;
private WpsStateMachine mWpsStateMachine;
- private DhcpStateMachine mDhcpStateMachine;
private AlarmManager mAlarmManager;
private PendingIntent mScanIntent;
@@ -191,10 +189,10 @@ public class WifiStateMachine extends StateMachine {
static final int CMD_START_DRIVER = BASE + 13;
/* Start the driver */
static final int CMD_STOP_DRIVER = BASE + 14;
- /* Indicates Static IP succeded */
- static final int CMD_STATIC_IP_SUCCESS = BASE + 15;
- /* Indicates Static IP failed */
- static final int CMD_STATIC_IP_FAILURE = BASE + 16;
+ /* Indicates DHCP succeded */
+ static final int CMD_IP_CONFIG_SUCCESS = BASE + 15;
+ /* Indicates DHCP failed */
+ static final int CMD_IP_CONFIG_FAILURE = BASE + 16;
/* Start the soft access point */
static final int CMD_START_AP = BASE + 21;
@@ -344,11 +342,8 @@ public class WifiStateMachine extends StateMachine {
*/
private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
- static final int POWER_MODE_ACTIVE = 1;
- static final int POWER_MODE_AUTO = 0;
-
- /* Tracks the power mode for restoration after a DHCP request/renewal goes through */
- private int mPowerMode = POWER_MODE_AUTO;
+ private static final int POWER_MODE_ACTIVE = 1;
+ private static final int POWER_MODE_AUTO = 0;
/**
* See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
@@ -1415,10 +1410,10 @@ public class WifiStateMachine extends StateMachine {
/*
* stop DHCP
*/
- if (mDhcpStateMachine != null) {
- mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
- mDhcpStateMachine.quit();
- mDhcpStateMachine = null;
+ NetworkUtils.resetConnections(mInterfaceName);
+
+ if (!NetworkUtils.stopDhcp(mInterfaceName)) {
+ Log.e(TAG, "Could not stop DHCP");
}
/* Disable interface */
@@ -1447,99 +1442,7 @@ public class WifiStateMachine extends StateMachine {
mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
}
- void handlePreDhcpSetup() {
- if (!mBluetoothConnectionActive) {
- /*
- * There are problems setting the Wi-Fi driver's power
- * mode to active when bluetooth coexistence mode is
- * enabled or sense.
- * <p>
- * We set Wi-Fi to active mode when
- * obtaining an IP address because we've found
- * compatibility issues with some routers with low power
- * mode.
- * <p>
- * In order for this active power mode to properly be set,
- * we disable coexistence mode until we're done with
- * obtaining an IP address. One exception is if we
- * are currently connected to a headset, since disabling
- * coexistence would interrupt that connection.
- */
- // Disable the coexistence mode
- WifiNative.setBluetoothCoexistenceModeCommand(
- WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
- }
-
- mPowerMode = WifiNative.getPowerModeCommand();
- if (mPowerMode < 0) {
- // Handle the case where supplicant driver does not support
- // getPowerModeCommand.
- mPowerMode = WifiStateMachine.POWER_MODE_AUTO;
- }
- if (mPowerMode != WifiStateMachine.POWER_MODE_ACTIVE) {
- WifiNative.setPowerModeCommand(WifiStateMachine.POWER_MODE_ACTIVE);
- }
- }
-
-
- void handlePostDhcpSetup() {
- /* restore power mode */
- WifiNative.setPowerModeCommand(mPowerMode);
-
- // Set the coexistence mode back to its default value
- WifiNative.setBluetoothCoexistenceModeCommand(
- WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
- }
-
- private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
- synchronized (mDhcpInfoInternal) {
- mDhcpInfoInternal = dhcpInfoInternal;
- }
- mLastSignalLevel = -1; // force update of signal strength
- WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
- InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
- mWifiInfo.setInetAddress(addr);
- if (getNetworkDetailedState() == DetailedState.CONNECTED) {
- //DHCP renewal in connected state
- LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
- linkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
- linkProperties.setInterfaceName(mInterfaceName);
- if (!linkProperties.equals(mLinkProperties)) {
- Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
- + " old: " + mLinkProperties + "new: " + linkProperties);
- mLinkProperties = linkProperties;
- sendLinkConfigurationChangedBroadcast();
- }
- } else {
- configureLinkProperties();
- setNetworkDetailedState(DetailedState.CONNECTED);
- sendNetworkStateChangeBroadcast(mLastBssid);
- }
- }
-
- private void handleFailedIpConfiguration() {
- Log.e(TAG, "IP configuration failed");
-
- mWifiInfo.setInetAddress(null);
- /**
- * If we've exceeded the maximum number of retries for DHCP
- * to a given network, disable the network
- */
- if (++mReconnectCount > getMaxDhcpRetries()) {
- Log.e(TAG, "Failed " +
- mReconnectCount + " times, Disabling " + mLastNetworkId);
- WifiConfigStore.disableNetwork(mLastNetworkId);
- mReconnectCount = 0;
- }
-
- /* DHCP times out after about 30 seconds, we do a
- * disconnect and an immediate reconnect to try again
- */
- WifiNative.disconnectCommand();
- WifiNative.reconnectCommand();
- }
-
- private boolean startSoftApWithConfig(WifiConfiguration config, int currentStatus) {
+ private boolean startSoftApWithConfig(WifiConfiguration config, int currentStatus) {
if (config == null) {
config = WifiApConfigStore.getApConfiguration();
} else {
@@ -1564,7 +1467,6 @@ public class WifiStateMachine extends StateMachine {
return true;
}
-
/*********************************************************
* Notifications from WifiMonitor
********************************************************/
@@ -1742,8 +1644,6 @@ public class WifiStateMachine extends StateMachine {
case CMD_FORGET_NETWORK:
case CMD_RSSI_POLL:
case CMD_ENABLE_ALL_NETWORKS:
- case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
- case DhcpStateMachine.CMD_POST_DHCP_ACTION:
break;
case CMD_START_WPS:
/* Return failure when the state machine cannot handle WPS initiation*/
@@ -2609,18 +2509,74 @@ public class WifiStateMachine extends StateMachine {
}
class ConnectingState extends State {
+ boolean mModifiedBluetoothCoexistenceMode;
+ int mPowerMode;
+ boolean mUseStaticIp;
+ Thread mDhcpThread;
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
+ if (!mUseStaticIp) {
+ mDhcpThread = null;
+ mModifiedBluetoothCoexistenceMode = false;
+ mPowerMode = POWER_MODE_AUTO;
+
+ 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.
+ */
+ mModifiedBluetoothCoexistenceMode = true;
+
+ // Disable the coexistence mode
+ WifiNative.setBluetoothCoexistenceModeCommand(
+ WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
+ }
- if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
- //start DHCP
- mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
- mContext, WifiStateMachine.this, mInterfaceName);
- mDhcpStateMachine.registerForPreDhcpNotification();
- mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
+ mPowerMode = WifiNative.getPowerModeCommand();
+ if (mPowerMode < 0) {
+ // Handle the case where supplicant driver does not support
+ // getPowerModeCommand.
+ mPowerMode = POWER_MODE_AUTO;
+ }
+ if (mPowerMode != POWER_MODE_ACTIVE) {
+ WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
+ }
+
+ Log.d(TAG, "DHCP request started");
+ mDhcpThread = new Thread(new Runnable() {
+ public void run() {
+ DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
+ if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal)) {
+ Log.d(TAG, "DHCP request succeeded");
+ synchronized (mDhcpInfoInternal) {
+ mDhcpInfoInternal = dhcpInfoInternal;
+ }
+ WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
+ sendMessage(CMD_IP_CONFIG_SUCCESS);
+ } else {
+ Log.d(TAG, "DHCP request failed: " +
+ NetworkUtils.getDhcpError());
+ sendMessage(CMD_IP_CONFIG_FAILURE);
+ }
+ }
+ });
+ mDhcpThread.start();
} else {
DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
mLastNetworkId);
@@ -2632,13 +2588,16 @@ public class WifiStateMachine extends StateMachine {
try {
netd.setInterfaceConfig(mInterfaceName, ifcg);
Log.v(TAG, "Static IP configuration succeeded");
- sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
+ synchronized (mDhcpInfoInternal) {
+ mDhcpInfoInternal = dhcpInfoInternal;
+ }
+ sendMessage(CMD_IP_CONFIG_SUCCESS);
} catch (RemoteException re) {
Log.v(TAG, "Static IP configuration failed: " + re);
- sendMessage(CMD_STATIC_IP_FAILURE);
+ sendMessage(CMD_IP_CONFIG_FAILURE);
} catch (IllegalStateException e) {
Log.v(TAG, "Static IP configuration failed: " + e);
- sendMessage(CMD_STATIC_IP_FAILURE);
+ sendMessage(CMD_IP_CONFIG_FAILURE);
}
}
}
@@ -2647,26 +2606,44 @@ public class WifiStateMachine extends StateMachine {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch(message.what) {
- case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
- handlePreDhcpSetup();
- mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
- break;
- case DhcpStateMachine.CMD_POST_DHCP_ACTION:
- handlePostDhcpSetup();
- if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
- handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
- transitionTo(mConnectedState);
- } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
- handleFailedIpConfiguration();
- transitionTo(mDisconnectingState);
+ case CMD_IP_CONFIG_SUCCESS:
+ mLastSignalLevel = -1; // force update of signal strength
+ InetAddress addr;
+ synchronized (mDhcpInfoInternal) {
+ addr = NetworkUtils.numericToInetAddress(mDhcpInfoInternal.ipAddress);
}
- break;
- case CMD_STATIC_IP_SUCCESS:
- handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
+ mWifiInfo.setInetAddress(addr);
+ configureLinkProperties();
+ if (getNetworkDetailedState() == DetailedState.CONNECTED) {
+ sendLinkConfigurationChangedBroadcast();
+ } else {
+ setNetworkDetailedState(DetailedState.CONNECTED);
+ sendNetworkStateChangeBroadcast(mLastBssid);
+ }
+ //TODO: The framework is not detecting a DHCP renewal and a possible
+ //IP change. we should detect this and send out a config change broadcast
transitionTo(mConnectedState);
break;
- case CMD_STATIC_IP_FAILURE:
- handleFailedIpConfiguration();
+ case CMD_IP_CONFIG_FAILURE:
+ mWifiInfo.setInetAddress(null);
+
+ Log.e(TAG, "IP configuration failed");
+ /**
+ * If we've exceeded the maximum number of retries for DHCP
+ * to a given network, disable the network
+ */
+ if (++mReconnectCount > getMaxDhcpRetries()) {
+ Log.e(TAG, "Failed " +
+ mReconnectCount + " times, Disabling " + mLastNetworkId);
+ WifiConfigStore.disableNetwork(mLastNetworkId);
+ mReconnectCount = 0;
+ }
+
+ /* DHCP times out after about 30 seconds, we do a
+ * disconnect and an immediate reconnect to try again
+ */
+ WifiNative.disconnectCommand();
+ WifiNative.reconnectCommand();
transitionTo(mDisconnectingState);
break;
case CMD_DISCONNECT:
@@ -2710,6 +2687,23 @@ public class WifiStateMachine extends StateMachine {
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
return HANDLED;
}
+
+ @Override
+ public void exit() {
+ /* reset power state & bluetooth coexistence if on DHCP */
+ if (!mUseStaticIp) {
+ if (mPowerMode != POWER_MODE_ACTIVE) {
+ WifiNative.setPowerModeCommand(mPowerMode);
+ }
+
+ if (mModifiedBluetoothCoexistenceMode) {
+ // Set the coexistence mode back to its default value
+ WifiNative.setBluetoothCoexistenceModeCommand(
+ WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+ }
+ }
+
+ }
}
class ConnectedState extends State {
@@ -2727,19 +2721,6 @@ public class WifiStateMachine extends StateMachine {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
boolean eventLoggingEnabled = true;
switch (message.what) {
- case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
- handlePreDhcpSetup();
- mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
- break;
- case DhcpStateMachine.CMD_POST_DHCP_ACTION:
- handlePostDhcpSetup();
- if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
- handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
- } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
- handleFailedIpConfiguration();
- transitionTo(mDisconnectingState);
- }
- break;
case CMD_DISCONNECT:
WifiNative.disconnectCommand();
transitionTo(mDisconnectingState);