Add per network static IP settings
Remove the existing global static IP settings and add support
for per network configuration
Change-Id: I5a6d8b877471b8c8ad07951c96d273893754607f
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 1178bec..9c81c19 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -37,6 +37,19 @@
super();
}
+ /** copy constructor {@hide} */
+ public DhcpInfo(DhcpInfo source) {
+ if (source != null) {
+ ipAddress = source.ipAddress;
+ gateway = source.gateway;
+ netmask = source.netmask;
+ dns1 = source.dns1;
+ dns2 = source.dns2;
+ serverAddress = source.serverAddress;
+ leaseDuration = source.leaseDuration;
+ }
+ }
+
public String toString() {
StringBuffer str = new StringBuffer();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index e1c84ef..5b4aedb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1128,6 +1128,7 @@
*/
public static final int WIFI_SLEEP_POLICY_NEVER = 2;
+ //TODO: deprecate static IP constants
/**
* Whether to use static IP and other static network attributes.
* <p>
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 78d5b7e..dfa9f75 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -19,12 +19,22 @@
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
+import android.net.DhcpInfo;
+import android.net.wifi.WifiConfiguration.IpAssignment;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.Status;
+import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.BitSet;
+import java.util.HashMap;
import java.util.List;
/**
@@ -34,9 +44,23 @@
*
* It deals with the following
* - Add/update/remove a WifiConfiguration
+ * The configuration contains two types of information.
+ * = IP configuration that is handled by WifiConfigStore and
+ * is saved to disk on any change.
+ * = SSID & security details that is pushed to the supplicant.
+ * supplicant saves these details to the disk on calling
+ * saveConfigCommand().
+ *
+ * We have two kinds of APIs exposed:
+ * > public API calls that provide fine grained control
+ * - enableNetwork, disableNetwork, addOrUpdateNetwork(),
+ * removeNetwork(). For these calls, the config is not persisted
+ * to the disk. (TODO: deprecate these calls in WifiManager)
+ * > The new API calls - selectNetwork(), saveNetwork() & forgetNetwork().
+ * These calls persist the supplicant config to disk.
* - Maintain a list of configured networks for quick access
+ *
* TODO:
- * - handle static IP per configuration
* - handle proxy per configuration
*/
class WifiConfigStore {
@@ -44,10 +68,28 @@
private static Context sContext;
private static final String TAG = "WifiConfigStore";
- private static List<WifiConfiguration> sConfiguredNetworks = new ArrayList<WifiConfiguration>();
+ /* configured networks with network id as the key */
+ private static HashMap<Integer, WifiConfiguration> sConfiguredNetworks =
+ new HashMap<Integer, WifiConfiguration>();
+
+ /* A network id is a unique identifier for a network configured in the
+ * supplicant. Network ids are generated when the supplicant reads
+ * the configuration file at start and can thus change for networks.
+ * We store the IP configuration for networks along with a unique id
+ * that is generated from SSID and security type of the network. A mapping
+ * from the generated unique id to network id of the network is needed to
+ * map supplicant config to IP configuration. */
+ private static HashMap<Integer, Integer> sNetworkIds =
+ new HashMap<Integer, Integer>();
+
/* Tracks the highest priority of configured networks */
private static int sLastPriority = -1;
+ private static final String ipConfigFile = Environment.getDataDirectory() +
+ "/misc/wifi/ipconfig.txt";
+
+ private static final int IPCONFIG_FILE_VERSION = 1;
+
/**
* Initialize context, fetch the list of configured networks
* and enable all stored networks in supplicant.
@@ -66,7 +108,7 @@
static List<WifiConfiguration> getConfiguredNetworks() {
List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
synchronized (sConfiguredNetworks) {
- for (WifiConfiguration config : sConfiguredNetworks) {
+ for(WifiConfiguration config : sConfiguredNetworks.values()) {
networks.add(config.clone());
}
}
@@ -78,14 +120,20 @@
* of configured networks indicates all networks as being enabled
*/
static void enableAllNetworks() {
- for (WifiConfiguration config : sConfiguredNetworks) {
- if(config != null && config.status == Status.DISABLED) {
- WifiNative.enableNetworkCommand(config.networkId, false);
+ synchronized (sConfiguredNetworks) {
+ for(WifiConfiguration config : sConfiguredNetworks.values()) {
+ if(config != null && config.status == Status.DISABLED) {
+ if(WifiNative.enableNetworkCommand(config.networkId, false)) {
+ config.status = Status.ENABLED;
+ } else {
+ Log.e(TAG, "Enable network failed on " + config.networkId);
+ }
+ }
}
}
WifiNative.saveConfigCommand();
- updateConfigAndSendChangeBroadcast();
+ sendConfigChangeBroadcast();
}
/**
@@ -102,7 +150,11 @@
static void selectNetwork(WifiConfiguration config) {
if (config != null) {
int netId = addOrUpdateNetworkNative(config);
- selectNetwork(netId);
+ if (netId != -1) {
+ selectNetwork(netId);
+ } else {
+ Log.e(TAG, "Failed to update network " + config);
+ }
}
}
@@ -120,10 +172,12 @@
static void selectNetwork(int netId) {
// Reset the priority of each network at start or if it goes too high.
if (sLastPriority == -1 || sLastPriority > 1000000) {
- for (WifiConfiguration conf : sConfiguredNetworks) {
- if (conf.networkId != -1) {
- conf.priority = 0;
- addOrUpdateNetworkNative(conf);
+ synchronized (sConfiguredNetworks) {
+ for(WifiConfiguration config : sConfiguredNetworks.values()) {
+ if (config.networkId != -1) {
+ config.priority = 0;
+ addOrUpdateNetworkNative(config);
+ }
}
}
sLastPriority = 0;
@@ -138,13 +192,10 @@
WifiNative.saveConfigCommand();
/* Enable the given network while disabling all other networks */
- WifiNative.enableNetworkCommand(netId, true);
+ enableNetworkWithoutBroadcast(netId, true);
- /* update the configured networks list but not send a
- * broadcast to avoid a fetch from settings
- * during this temporary disabling of networks
- */
- updateConfiguredNetworks();
+ /* Avoid saving the config & sending a broadcast to prevent settings
+ * from displaying a disabled list of networks */
}
/**
@@ -153,13 +204,17 @@
* @param config WifiConfiguration to be saved
*/
static void saveNetwork(WifiConfiguration config) {
+ boolean newNetwork = (config.networkId == -1);
int netId = addOrUpdateNetworkNative(config);
/* enable a new network */
- if (config.networkId < 0) {
+ if (newNetwork && netId >= 0) {
WifiNative.enableNetworkCommand(netId, false);
+ synchronized (sConfiguredNetworks) {
+ sConfiguredNetworks.get(netId).status = Status.ENABLED;
+ }
}
WifiNative.saveConfigCommand();
- updateConfigAndSendChangeBroadcast();
+ sendConfigChangeBroadcast();
}
/**
@@ -168,9 +223,15 @@
* @param netId network to forget
*/
static void forgetNetwork(int netId) {
- WifiNative.removeNetworkCommand(netId);
- WifiNative.saveConfigCommand();
- updateConfigAndSendChangeBroadcast();
+ if (WifiNative.removeNetworkCommand(netId)) {
+ WifiNative.saveConfigCommand();
+ synchronized (sConfiguredNetworks) {
+ sConfiguredNetworks.remove(netId);
+ }
+ sendConfigChangeBroadcast();
+ } else {
+ Log.e(TAG, "Failed to remove network " + netId);
+ }
}
/**
@@ -183,7 +244,7 @@
*/
static int addOrUpdateNetwork(WifiConfiguration config) {
int ret = addOrUpdateNetworkNative(config);
- updateConfigAndSendChangeBroadcast();
+ sendConfigChangeBroadcast();
return ret;
}
@@ -197,7 +258,10 @@
*/
static boolean removeNetwork(int netId) {
boolean ret = WifiNative.removeNetworkCommand(netId);
- updateConfigAndSendChangeBroadcast();
+ synchronized (sConfiguredNetworks) {
+ if (ret) sConfiguredNetworks.remove(netId);
+ }
+ sendConfigChangeBroadcast();
return ret;
}
@@ -210,8 +274,28 @@
* @param netId network to be removed
*/
static boolean enableNetwork(int netId, boolean disableOthers) {
+ boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
+ sendConfigChangeBroadcast();
+ return ret;
+ }
+
+ static boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
boolean ret = WifiNative.enableNetworkCommand(netId, disableOthers);
- updateConfigAndSendChangeBroadcast();
+
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(netId);
+ if (config != null) config.status = Status.ENABLED;
+ }
+
+ if (disableOthers) {
+ synchronized (sConfiguredNetworks) {
+ for(WifiConfiguration config : sConfiguredNetworks.values()) {
+ if(config != null && config.networkId != netId) {
+ config.status = Status.DISABLED;
+ }
+ }
+ }
+ }
return ret;
}
@@ -221,7 +305,11 @@
*/
static boolean disableNetwork(int netId) {
boolean ret = WifiNative.disableNetworkCommand(netId);
- updateConfigAndSendChangeBroadcast();
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(netId);
+ if (config != null) config.status = Status.DISABLED;
+ }
+ sendConfigChangeBroadcast();
return ret;
}
@@ -232,8 +320,31 @@
return WifiNative.saveConfigCommand();
}
- private static void updateConfigAndSendChangeBroadcast() {
- updateConfiguredNetworks();
+ /**
+ * Fetch the IP configuration for a given network id
+ */
+ static DhcpInfo getIpConfiguration(int netId) {
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(netId);
+ if (config != null) return new DhcpInfo(config.ipConfig);
+ }
+ return null;
+ }
+
+ /**
+ * Return if the specified network is using static IP
+ */
+ static boolean isUsingStaticIp(int netId) {
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(netId);
+ if (config != null && config.ipAssignment == IpAssignment.STATIC) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static void sendConfigChangeBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
sContext.sendBroadcast(intent);
@@ -245,6 +356,7 @@
synchronized (sConfiguredNetworks) {
sConfiguredNetworks.clear();
+ sNetworkIds.clear();
if (listStr == null)
return;
@@ -274,9 +386,129 @@
if (config.priority > sLastPriority) {
sLastPriority = config.priority;
}
- sConfiguredNetworks.add(config);
+ sConfiguredNetworks.put(config.networkId, config);
+ sNetworkIds.put(configKey(config), config.networkId);
}
}
+ readIpConfigurations();
+ }
+
+ private static void writeIpConfigurations() {
+ StringBuilder builder = new StringBuilder();
+ BufferedWriter out = null;
+
+ builder.append(IPCONFIG_FILE_VERSION);
+ builder.append("\n");
+
+ synchronized (sConfiguredNetworks) {
+ for(WifiConfiguration config : sConfiguredNetworks.values()) {
+ if (config.ipAssignment == WifiConfiguration.IpAssignment.STATIC) {
+ builder.append("id=" + configKey(config));
+ builder.append(":");
+ builder.append("ip=" + config.ipConfig.ipAddress);
+ builder.append(":");
+ builder.append("gateway=" + config.ipConfig.gateway);
+ builder.append(":");
+ builder.append("netmask=" + config.ipConfig.netmask);
+ builder.append(":");
+ builder.append("dns1=" + config.ipConfig.dns1);
+ builder.append(":");
+ builder.append("dns2=" + config.ipConfig.dns2);
+ builder.append("\n");
+ }
+ }
+ }
+
+ try {
+ out = new BufferedWriter(new FileWriter(ipConfigFile), builder.length());
+ out.write(builder.toString());
+ } catch (IOException e) {
+ Log.e(TAG, "Error writing data file");
+ return;
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (Exception e) {}
+ }
+ }
+ }
+
+ private static void readIpConfigurations() {
+ File f = new File(ipConfigFile);
+ byte[] buffer;
+ FileInputStream s = null;
+ try {
+ buffer = new byte[(int)f.length()];
+ s = new FileInputStream(f);
+ s.read(buffer);
+ } catch (IOException e) {
+ Log.e(TAG, "Error reading data file");
+ return;
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (Exception e) {}
+ }
+ }
+
+ String data = new String(buffer);
+ if (data == null || data.length() == 0) {
+ Log.d(TAG, "IP configuration file empty");
+ return;
+ }
+
+ String[] parsed = data.split("\n");
+ try {
+ if (Integer.parseInt(parsed[0]) != IPCONFIG_FILE_VERSION) {
+ Log.e(TAG, "Bad version on IP configuration file, ignore read");
+ return;
+ }
+
+ for (String line : parsed) {
+ int hashKey = -1;
+ DhcpInfo ipConfig = new DhcpInfo();
+ String[] keyVals = line.split(":");
+
+ for (String keyVal : keyVals) {
+ String[] keyValPair = keyVal.split("=");
+ if (keyValPair[0].equals("id")) {
+ hashKey = Integer.parseInt(keyValPair[1]);
+ } else if (keyValPair[0].equals("ip")) {
+ ipConfig.ipAddress = Integer.parseInt(keyValPair[1]);
+ } else if (keyValPair[0].equals("gateway")) {
+ ipConfig.gateway = Integer.parseInt(keyValPair[1]);
+ } else if (keyValPair[0].equals("netmask")) {
+ ipConfig.netmask = Integer.parseInt(keyValPair[1]);
+ } else if (keyValPair[0].equals("dns1")) {
+ ipConfig.dns1 = Integer.parseInt(keyValPair[1]);
+ } else if (keyValPair[0].equals("dns2")) {
+ ipConfig.dns2 = Integer.parseInt(keyValPair[1]);
+ } else {
+ Log.w(TAG, "Ignoring " + keyVal);
+ }
+ }
+
+ if (hashKey != -1) {
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(
+ sNetworkIds.get(hashKey));
+
+ if (config == null) {
+ Log.e(TAG, "IP configuration found for missing network, ignored");
+ } else {
+ config.ipAssignment = WifiConfiguration.IpAssignment.STATIC;
+ config.ipConfig = ipConfig;
+ }
+ }
+ } else {
+ Log.e(TAG,"Missing id while parsing configuration" + line);
+ }
+ }
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Error parsing configuration");
+ }
}
private static int addOrUpdateNetworkNative(WifiConfiguration config) {
@@ -286,6 +518,7 @@
* refer to an existing configuration.
*/
int netId = config.networkId;
+ boolean updateFailed = true;
boolean newNetwork = netId == -1;
// networkId of -1 means we want to create a new network
@@ -457,17 +690,53 @@
}
}
}
- return netId;
+ updateFailed = false;
}
- if (newNetwork) {
- WifiNative.removeNetworkCommand(netId);
- Log.d(TAG,
- "Failed to set a network variable, removed network: "
- + netId);
+ if (updateFailed) {
+ if (newNetwork) {
+ WifiNative.removeNetworkCommand(netId);
+ Log.d(TAG,
+ "Failed to set a network variable, removed network: "
+ + netId);
+ }
+ return -1;
}
- return -1;
+ /* An update of the network variables requires reading them
+ * back from the supplicant to update sConfiguredNetworks.
+ * This is because some of the variables (SSID, wep keys &
+ * passphrases) reflect different values when read back than
+ * when written. For example, wep key is stored as * irrespective
+ * of the value sent to the supplicant
+ */
+ WifiConfiguration sConfig;
+ synchronized (sConfiguredNetworks) {
+ sConfig = sConfiguredNetworks.get(netId);
+ }
+ if (sConfig == null) {
+ sConfig = new WifiConfiguration();
+ sConfig.networkId = netId;
+ synchronized (sConfiguredNetworks) {
+ sConfiguredNetworks.put(netId, sConfig);
+ }
+ }
+ readNetworkVariables(sConfig);
+
+ if (config.ipAssignment != IpAssignment.UNASSIGNED) {
+ if (newNetwork ||
+ (sConfig.ipAssignment != config.ipAssignment) ||
+ (sConfig.ipConfig.ipAddress != config.ipConfig.ipAddress) ||
+ (sConfig.ipConfig.gateway != config.ipConfig.gateway) ||
+ (sConfig.ipConfig.netmask != config.ipConfig.netmask) ||
+ (sConfig.ipConfig.dns1 != config.ipConfig.dns1) ||
+ (sConfig.ipConfig.dns2 != config.ipConfig.dns2)) {
+ sConfig.ipAssignment = config.ipAssignment;
+ sConfig.ipConfig = config.ipConfig;
+ writeIpConfigurations();
+ }
+ }
+ return netId;
}
/**
@@ -669,6 +938,24 @@
return -1;
}
+ /* Returns a unique for a given configuration */
+ private static int configKey(WifiConfiguration config) {
+ String key;
+
+ if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
+ key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
+ } else if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
+ config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+ key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
+ } else if (config.wepKeys[0] != null) {
+ key = config.SSID + "WEP";
+ } else {
+ key = config.SSID + KeyMgmt.strings[KeyMgmt.NONE];
+ }
+
+ return key.hashCode();
+ }
+
static String dump() {
StringBuffer sb = new StringBuffer();
String LS = System.getProperty("line.separator");
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index ca4f29f..8971bdd 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -16,6 +16,7 @@
package android.net.wifi;
+import android.net.DhcpInfo;
import android.os.Parcelable;
import android.os.Parcel;
@@ -294,6 +295,22 @@
*/
public BitSet allowedGroupCiphers;
+ /**
+ * @hide
+ */
+ public enum IpAssignment {
+ STATIC,
+ DHCP,
+ UNASSIGNED
+ }
+ /**
+ * @hide
+ */
+ public IpAssignment ipAssignment;
+ /**
+ * @hide
+ */
+ public DhcpInfo ipConfig;
public WifiConfiguration() {
networkId = -1;
@@ -312,6 +329,8 @@
for (EnterpriseField field : enterpriseFields) {
field.setValue(null);
}
+ ipAssignment = IpAssignment.UNASSIGNED;
+ ipConfig = new DhcpInfo();
}
public String toString() {
@@ -393,6 +412,11 @@
if (value != null) sbuf.append(value);
}
sbuf.append('\n');
+ if (ipAssignment == IpAssignment.STATIC) {
+ sbuf.append(" ").append("Static IP configuration:").append('\n');
+ sbuf.append(" ").append(ipConfig);
+ }
+ sbuf.append('\n');
return sbuf.toString();
}
@@ -461,6 +485,8 @@
for (int i = 0; i < enterpriseFields.length; i++) {
config.enterpriseFields[i].setValue(enterpriseFields[i].value());
}
+ config.ipAssignment = ipAssignment;
+ config.ipConfig = new DhcpInfo(ipConfig);
return config;
}
@@ -486,6 +512,14 @@
for (EnterpriseField field : enterpriseFields) {
dest.writeString(field.value());
}
+ dest.writeString(ipAssignment.name());
+ dest.writeInt(ipConfig.ipAddress);
+ dest.writeInt(ipConfig.netmask);
+ dest.writeInt(ipConfig.gateway);
+ dest.writeInt(ipConfig.dns1);
+ dest.writeInt(ipConfig.dns2);
+ dest.writeInt(ipConfig.serverAddress);
+ dest.writeInt(ipConfig.leaseDuration);
}
/** Implement the Parcelable interface {@hide} */
@@ -512,6 +546,15 @@
for (EnterpriseField field : config.enterpriseFields) {
field.setValue(in.readString());
}
+
+ config.ipAssignment = IpAssignment.valueOf(in.readString());
+ config.ipConfig.ipAddress = in.readInt();
+ config.ipConfig.netmask = in.readInt();
+ config.ipConfig.gateway = in.readInt();
+ config.ipConfig.dns1 = in.readInt();
+ config.ipConfig.dns2 = in.readInt();
+ config.ipConfig.serverAddress = in.readInt();
+ config.ipConfig.leaseDuration = in.readInt();
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e1cbf5b..075cca4 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -123,10 +123,8 @@
private int mLastNetworkId;
private boolean mEnableRssiPolling = false;
private boolean mPasswordKeyMayBeIncorrect = false;
- private boolean mUseStaticIp = false;
private int mReconnectCount = 0;
private boolean mIsScanMode = false;
- private boolean mConfigChanged = false;
/**
* Instance of the bluetooth headset helper. This needs to be created
@@ -138,10 +136,6 @@
private BluetoothA2dp mBluetoothA2dp;
- /**
- * Observes the static IP address settings.
- */
- private SettingsObserver mSettingsObserver;
private LinkProperties mLinkProperties;
// Held during driver load and unload
@@ -447,8 +441,6 @@
}
};
- mSettingsObserver = new SettingsObserver(new Handler());
-
PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
sWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
@@ -596,7 +588,9 @@
}
public DhcpInfo syncGetDhcpInfo() {
- return mDhcpInfo;
+ synchronized (mDhcpInfo) {
+ return new DhcpInfo(mDhcpInfo);
+ }
}
/**
@@ -909,10 +903,8 @@
sb.append("mEnableAllNetworks ").append(mEnableAllNetworks).append(LS);
sb.append("mEnableRssiPolling ").append(mEnableRssiPolling).append(LS);
sb.append("mPasswordKeyMayBeIncorrect ").append(mPasswordKeyMayBeIncorrect).append(LS);
- sb.append("mUseStaticIp ").append(mUseStaticIp).append(LS);
sb.append("mReconnectCount ").append(mReconnectCount).append(LS);
sb.append("mIsScanMode ").append(mIsScanMode).append(LS);
- sb.append("mConfigChanged ").append(mConfigChanged).append(LS).append(LS);
sb.append("Supplicant status").append(LS)
.append(WifiNative.statusCommand()).append(LS).append(LS);
@@ -1196,140 +1188,21 @@
return;
}
// TODO - fix this for v6
- mLinkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
- mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
- mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
- mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
+ synchronized (mDhcpInfo) {
+ mLinkProperties.addAddress(NetworkUtils.intToInetAddress(mDhcpInfo.ipAddress));
+ mLinkProperties.setGateway(NetworkUtils.intToInetAddress(mDhcpInfo.gateway));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns1));
+ mLinkProperties.addDns(NetworkUtils.intToInetAddress(mDhcpInfo.dns2));
+ }
// TODO - add proxy info
}
-
- private void checkUseStaticIp() {
- mUseStaticIp = false;
- final ContentResolver cr = mContext.getContentResolver();
- try {
- if (Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP) == 0) {
- return;
- }
- } catch (Settings.SettingNotFoundException e) {
- return;
- }
-
- try {
- String addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_IP);
- if (addr != null) {
- mDhcpInfo.ipAddress = stringToIpAddr(addr);
- } else {
- return;
- }
- addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_GATEWAY);
- if (addr != null) {
- mDhcpInfo.gateway = stringToIpAddr(addr);
- } else {
- return;
- }
- addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_NETMASK);
- if (addr != null) {
- mDhcpInfo.netmask = stringToIpAddr(addr);
- } else {
- return;
- }
- addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_DNS1);
- if (addr != null) {
- mDhcpInfo.dns1 = stringToIpAddr(addr);
- } else {
- return;
- }
- addr = Settings.System.getString(cr, Settings.System.WIFI_STATIC_DNS2);
- if (addr != null) {
- mDhcpInfo.dns2 = stringToIpAddr(addr);
- } else {
- mDhcpInfo.dns2 = 0;
- }
- } catch (UnknownHostException e) {
- return;
- }
- mUseStaticIp = true;
- }
-
- private static int stringToIpAddr(String addrString) throws UnknownHostException {
- try {
- String[] parts = addrString.split("\\.");
- if (parts.length != 4) {
- throw new UnknownHostException(addrString);
- }
-
- int a = Integer.parseInt(parts[0]) ;
- int b = Integer.parseInt(parts[1]) << 8;
- int c = Integer.parseInt(parts[2]) << 16;
- int d = Integer.parseInt(parts[3]) << 24;
-
- return a | b | c | d;
- } catch (NumberFormatException ex) {
- throw new UnknownHostException(addrString);
- }
- }
-
private int getMaxDhcpRetries() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
DEFAULT_MAX_DHCP_RETRIES);
}
- private class SettingsObserver extends ContentObserver {
- public SettingsObserver(Handler handler) {
- super(handler);
- ContentResolver cr = mContext.getContentResolver();
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_USE_STATIC_IP), false, this);
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_STATIC_IP), false, this);
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_STATIC_GATEWAY), false, this);
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_STATIC_NETMASK), false, this);
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_STATIC_DNS1), false, this);
- cr.registerContentObserver(Settings.System.getUriFor(
- Settings.System.WIFI_STATIC_DNS2), false, this);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- super.onChange(selfChange);
-
- boolean wasStaticIp = mUseStaticIp;
- int oIp, oGw, oMsk, oDns1, oDns2;
- oIp = oGw = oMsk = oDns1 = oDns2 = 0;
- if (wasStaticIp) {
- oIp = mDhcpInfo.ipAddress;
- oGw = mDhcpInfo.gateway;
- oMsk = mDhcpInfo.netmask;
- oDns1 = mDhcpInfo.dns1;
- oDns2 = mDhcpInfo.dns2;
- }
- checkUseStaticIp();
-
- if (mWifiInfo.getSupplicantState() == SupplicantState.UNINITIALIZED) {
- return;
- }
-
- boolean changed =
- (wasStaticIp != mUseStaticIp) ||
- (wasStaticIp && (
- oIp != mDhcpInfo.ipAddress ||
- oGw != mDhcpInfo.gateway ||
- oMsk != mDhcpInfo.netmask ||
- oDns1 != mDhcpInfo.dns1 ||
- oDns2 != mDhcpInfo.dns2));
-
- if (changed) {
- sendMessage(CMD_RECONFIGURE_IP);
- mConfigChanged = true;
- }
- }
- }
-
/**
* Whether to disable coexistence mode while obtaining IP address. This
* logic will return true only if the current bluetooth
@@ -1382,6 +1255,7 @@
mContext.sendStickyBroadcast(intent);
}
+ /* TODO: Unused for now, will be used when ip change on connected network is handled */
private void sendConfigChangeBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.CONFIG_CHANGED_ACTION);
@@ -1969,7 +1843,6 @@
}
checkIsBluetoothPlaying();
- checkUseStaticIp();
sendSupplicantConnectionChangedBroadcast(true);
transitionTo(mDriverSupReadyState);
break;
@@ -2477,8 +2350,9 @@
}
class ConnectingState extends HierarchicalState {
- boolean modifiedBluetoothCoexistenceMode;
- int powerMode;
+ boolean mModifiedBluetoothCoexistenceMode;
+ int mPowerMode;
+ boolean mUseStaticIp;
Thread mDhcpThread;
@Override
@@ -2486,11 +2360,11 @@
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
if (!mUseStaticIp) {
-
mDhcpThread = null;
- modifiedBluetoothCoexistenceMode = false;
- powerMode = DRIVER_POWER_MODE_AUTO;
+ mModifiedBluetoothCoexistenceMode = false;
+ mPowerMode = DRIVER_POWER_MODE_AUTO;
if (shouldDisableCoexistenceMode()) {
/*
@@ -2509,28 +2383,32 @@
* are currently connected to a headset, since disabling
* coexistence would interrupt that connection.
*/
- modifiedBluetoothCoexistenceMode = true;
+ mModifiedBluetoothCoexistenceMode = true;
// Disable the coexistence mode
WifiNative.setBluetoothCoexistenceModeCommand(
WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
}
- powerMode = WifiNative.getPowerModeCommand();
- if (powerMode < 0) {
+ mPowerMode = WifiNative.getPowerModeCommand();
+ if (mPowerMode < 0) {
// Handle the case where supplicant driver does not support
// getPowerModeCommand.
- powerMode = DRIVER_POWER_MODE_AUTO;
+ mPowerMode = DRIVER_POWER_MODE_AUTO;
}
- if (powerMode != DRIVER_POWER_MODE_ACTIVE) {
+ if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
WifiNative.setPowerModeCommand(DRIVER_POWER_MODE_ACTIVE);
}
Log.d(TAG, "DHCP request started");
mDhcpThread = new Thread(new Runnable() {
public void run() {
- if (NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
+ DhcpInfo dhcpInfo = new DhcpInfo();
+ if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfo)) {
Log.d(TAG, "DHCP request succeeded");
+ synchronized (mDhcpInfo) {
+ mDhcpInfo = dhcpInfo;
+ }
sendMessage(CMD_IP_CONFIG_SUCCESS);
} else {
Log.d(TAG, "DHCP request failed: " +
@@ -2541,8 +2419,12 @@
});
mDhcpThread.start();
} else {
- if (NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) {
+ DhcpInfo dhcpInfo = WifiConfigStore.getIpConfiguration(mLastNetworkId);
+ if (NetworkUtils.configureInterface(mInterfaceName, dhcpInfo)) {
Log.v(TAG, "Static IP configuration succeeded");
+ synchronized (mDhcpInfo) {
+ mDhcpInfo = dhcpInfo;
+ }
sendMessage(CMD_IP_CONFIG_SUCCESS);
} else {
Log.v(TAG, "Static IP configuration failed");
@@ -2558,18 +2440,15 @@
case CMD_IP_CONFIG_SUCCESS:
mReconnectCount = 0;
mLastSignalLevel = -1; // force update of signal strength
- mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
- Log.d(TAG, "IP configuration: " + mDhcpInfo);
+ synchronized (mDhcpInfo) {
+ mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
+ Log.d(TAG, "IP configuration: " + mDhcpInfo);
+ }
configureLinkProperties();
setDetailedState(DetailedState.CONNECTED);
sendNetworkStateChangeBroadcast(mLastBssid);
- //TODO: we could also detect an IP config change
- // from a DHCP renewal and send out a config change
- // broadcast
- if (mConfigChanged) {
- sendConfigChangeBroadcast();
- mConfigChanged = false;
- }
+ //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_IP_CONFIG_FAILURE:
@@ -2631,11 +2510,11 @@
public void exit() {
/* reset power state & bluetooth coexistence if on DHCP */
if (!mUseStaticIp) {
- if (powerMode != DRIVER_POWER_MODE_ACTIVE) {
- WifiNative.setPowerModeCommand(powerMode);
+ if (mPowerMode != DRIVER_POWER_MODE_ACTIVE) {
+ WifiNative.setPowerModeCommand(mPowerMode);
}
- if (modifiedBluetoothCoexistenceMode) {
+ if (mModifiedBluetoothCoexistenceMode) {
// Set the coexistence mode back to its default value
WifiNative.setBluetoothCoexistenceModeCommand(
WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);