summaryrefslogtreecommitdiffstats
path: root/wifi/java/android/net
diff options
context:
space:
mode:
Diffstat (limited to 'wifi/java/android/net')
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java35
-rw-r--r--wifi/java/android/net/wifi/StateChangeResult.java7
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java8
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java21
-rw-r--r--wifi/java/android/net/wifi/WifiInfo.java44
-rw-r--r--wifi/java/android/net/wifi/WifiMonitor.java16
-rw-r--r--wifi/java/android/net/wifi/WifiSsid.java217
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java18
8 files changed, 326 insertions, 40 deletions
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 3e20756..9977419 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -28,6 +28,10 @@ import android.os.Parcel;
public class ScanResult implements Parcelable {
/** The network name. */
public String SSID;
+
+ /** Ascii encoded SSID. This will replace SSID when we deprecate it. @hide */
+ public WifiSsid wifiSsid;
+
/** The address of the access point. */
public String BSSID;
/**
@@ -52,15 +56,11 @@ public class ScanResult implements Parcelable {
*/
public long timestamp;
- /**
- * We'd like to obtain the following attributes,
- * but they are not reported via the socket
- * interface, even though they are known
- * internally by wpa_supplicant.
- * {@hide}
- */
- public ScanResult(String SSID, String BSSID, String caps, int level, int frequency, long tsf) {
- this.SSID = SSID;
+ /** {@hide} */
+ public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
+ long tsf) {
+ this.wifiSsid = wifiSsid;
+ this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
this.BSSID = BSSID;
this.capabilities = caps;
this.level = level;
@@ -68,9 +68,11 @@ public class ScanResult implements Parcelable {
this.timestamp = tsf;
}
+
/** copy constructor {@hide} */
public ScanResult(ScanResult source) {
if (source != null) {
+ wifiSsid = source.wifiSsid;
SSID = source.SSID;
BSSID = source.BSSID;
capabilities = source.capabilities;
@@ -86,7 +88,7 @@ public class ScanResult implements Parcelable {
String none = "<none>";
sb.append("SSID: ").
- append(SSID == null ? none : SSID).
+ append(wifiSsid == null ? WifiSsid.NONE : wifiSsid).
append(", BSSID: ").
append(BSSID == null ? none : BSSID).
append(", capabilities: ").
@@ -108,7 +110,12 @@ public class ScanResult implements Parcelable {
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(SSID);
+ if (wifiSsid != null) {
+ dest.writeInt(1);
+ wifiSsid.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
dest.writeString(BSSID);
dest.writeString(capabilities);
dest.writeInt(level);
@@ -120,8 +127,12 @@ public class ScanResult implements Parcelable {
public static final Creator<ScanResult> CREATOR =
new Creator<ScanResult>() {
public ScanResult createFromParcel(Parcel in) {
+ WifiSsid wifiSsid = null;
+ if (in.readInt() == 1) {
+ wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
+ }
return new ScanResult(
- in.readString(),
+ wifiSsid,
in.readString(),
in.readString(),
in.readInt(),
diff --git a/wifi/java/android/net/wifi/StateChangeResult.java b/wifi/java/android/net/wifi/StateChangeResult.java
index b15c4a6..c334b91 100644
--- a/wifi/java/android/net/wifi/StateChangeResult.java
+++ b/wifi/java/android/net/wifi/StateChangeResult.java
@@ -23,15 +23,16 @@
* @hide
*/
public class StateChangeResult {
- StateChangeResult(int networkId, String SSID, String BSSID, SupplicantState state) {
+ StateChangeResult(int networkId, WifiSsid wifiSsid, String BSSID,
+ SupplicantState state) {
this.state = state;
- this.SSID = SSID;
+ this.wifiSsid= wifiSsid;
this.BSSID = BSSID;
this.networkId = networkId;
}
int networkId;
- String SSID;
+ WifiSsid wifiSsid;
String BSSID;
SupplicantState state;
}
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index a2332e3..84506b6 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -1318,7 +1318,13 @@ class WifiConfigStore {
value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
if (!TextUtils.isEmpty(value)) {
- config.SSID = value;
+ if (value.charAt(0) != '"') {
+ config.SSID = "\"" + WifiSsid.createFromHex(value).toString() + "\"";
+ //TODO: convert a hex string that is not UTF-8 decodable to a P-formatted
+ //supplicant string
+ } else {
+ config.SSID = value;
+ }
} else {
config.SSID = null;
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 0a846fd..c4fe1b4 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -524,6 +524,27 @@ public class WifiConfiguration implements Parcelable {
}
*/
+ /** {@hide} */
+ public String getPrintableSsid() {
+ if (SSID == null) return "";
+ final int length = SSID.length();
+ if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
+ return SSID.substring(1, length - 1);
+ }
+
+ /** The ascii-encoded string format is P"<ascii-encoded-string>"
+ * The decoding is implemented in the supplicant for a newly configured
+ * network.
+ */
+ if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
+ (SSID.charAt(length-1) == '"')) {
+ WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
+ SSID.substring(2, length - 1));
+ return wifiSsid.toString();
+ }
+ return SSID;
+ }
+
private static BitSet readBitSet(Parcel src) {
int cardinality = src.readInt();
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 1f1cfdd..05db571 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -20,6 +20,7 @@ import android.os.Parcelable;
import android.os.Parcel;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkUtils;
+import android.text.TextUtils;
import java.net.InetAddress;
import java.net.Inet6Address;
@@ -31,6 +32,7 @@ import java.util.EnumMap;
* is in the process of being set up.
*/
public class WifiInfo implements Parcelable {
+ private static final String TAG = "WifiInfo";
/**
* This is the map described in the Javadoc comment above. The positions
* of the elements of the array must correspond to the ordinal values
@@ -57,7 +59,7 @@ public class WifiInfo implements Parcelable {
private SupplicantState mSupplicantState;
private String mBSSID;
- private String mSSID;
+ private WifiSsid mWifiSsid;
private int mNetworkId;
private boolean mHiddenSSID;
/** Received Signal Strength Indicator */
@@ -77,7 +79,7 @@ public class WifiInfo implements Parcelable {
private boolean mMeteredHint;
WifiInfo() {
- mSSID = null;
+ mWifiSsid = null;
mBSSID = null;
mNetworkId = -1;
mSupplicantState = SupplicantState.UNINITIALIZED;
@@ -94,7 +96,7 @@ public class WifiInfo implements Parcelable {
if (source != null) {
mSupplicantState = source.mSupplicantState;
mBSSID = source.mBSSID;
- mSSID = source.mSSID;
+ mWifiSsid = source.mWifiSsid;
mNetworkId = source.mNetworkId;
mHiddenSSID = source.mHiddenSSID;
mRssi = source.mRssi;
@@ -105,21 +107,34 @@ public class WifiInfo implements Parcelable {
}
}
- void setSSID(String SSID) {
- mSSID = SSID;
+ void setSSID(WifiSsid wifiSsid) {
+ mWifiSsid = wifiSsid;
// network is considered not hidden by default
mHiddenSSID = false;
}
/**
* Returns the service set identifier (SSID) of the current 802.11 network.
- * If the SSID is an ASCII string, it will be returned surrounded by double
- * quotation marks.Otherwise, it is returned as a string of hex digits. The
+ * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
+ * quotation marks. Otherwise, it is returned as a string of hex digits. The
* SSID may be {@code null} if there is no network currently connected.
* @return the SSID
*/
public String getSSID() {
- return mSSID;
+ if (mWifiSsid != null) {
+ String unicode = mWifiSsid.toString();
+ if (!TextUtils.isEmpty(unicode)) {
+ return "\"" + unicode + "\"";
+ } else {
+ return mWifiSsid.getHexString();
+ }
+ }
+ return WifiSsid.NONE;
+ }
+
+ /** @hide */
+ public WifiSsid getWifiSsid() {
+ return mWifiSsid;
}
void setBSSID(String BSSID) {
@@ -279,7 +294,7 @@ public class WifiInfo implements Parcelable {
StringBuffer sb = new StringBuffer();
String none = "<none>";
- sb.append("SSID: ").append(mSSID == null ? none : mSSID).
+ sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid).
append(", BSSID: ").append(mBSSID == null ? none : mBSSID).
append(", MAC: ").append(mMacAddress == null ? none : mMacAddress).
append(", Supplicant state: ").
@@ -308,7 +323,12 @@ public class WifiInfo implements Parcelable {
} else {
dest.writeByte((byte)0);
}
- dest.writeString(getSSID());
+ if (mWifiSsid != null) {
+ dest.writeInt(1);
+ mWifiSsid.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
dest.writeString(mBSSID);
dest.writeString(mMacAddress);
dest.writeInt(mMeteredHint ? 1 : 0);
@@ -328,7 +348,9 @@ public class WifiInfo implements Parcelable {
info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
} catch (UnknownHostException e) {}
}
- info.setSSID(in.readString());
+ if (in.readInt() == 1) {
+ info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
+ }
info.mBSSID = in.readString();
info.mMacAddress = in.readString();
info.mMeteredHint = in.readInt() != 0;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 17c930b..ab54a15 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -645,9 +645,12 @@ public class WifiMonitor {
* id=network-id state=new-state
*/
private void handleSupplicantStateChange(String dataString) {
- String SSID = null;
+ WifiSsid wifiSsid = null;
int index = dataString.lastIndexOf("SSID=");
- if (index != -1) SSID = dataString.substring(index + 5);
+ if (index != -1) {
+ wifiSsid = WifiSsid.createFromAsciiEncoded(
+ dataString.substring(index + 5));
+ }
String[] dataTokens = dataString.split(" ");
String BSSID = null;
@@ -690,7 +693,7 @@ public class WifiMonitor {
if (newSupplicantState == SupplicantState.INVALID) {
Log.w(TAG, "Invalid supplicant state: " + newState);
}
- notifySupplicantStateChange(networkId, SSID, BSSID, newSupplicantState);
+ notifySupplicantStateChange(networkId, wifiSsid, BSSID, newSupplicantState);
}
}
@@ -739,13 +742,14 @@ public class WifiMonitor {
* Send the state machine a notification that the state of the supplicant
* has changed.
* @param networkId the configured network on which the state change occurred
- * @param SSID network name
+ * @param wifiSsid network name
* @param BSSID network address
* @param newState the new {@code SupplicantState}
*/
- void notifySupplicantStateChange(int networkId, String SSID, String BSSID, SupplicantState newState) {
+ void notifySupplicantStateChange(int networkId, WifiSsid wifiSsid, String BSSID,
+ SupplicantState newState) {
mStateMachine.sendMessage(mStateMachine.obtainMessage(SUPPLICANT_STATE_CHANGE_EVENT,
- new StateChangeResult(networkId, SSID, BSSID, newState)));
+ new StateChangeResult(networkId, wifiSsid, BSSID, newState)));
}
/**
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
new file mode 100644
index 0000000..6f36111
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2012 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.wifi;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * Stores SSID octets and handles conversion.
+ *
+ * For Ascii encoded string, any octet < 32 or > 127 is encoded as
+ * a "\x" followed by the hex representation of the octet.
+ * Exception chars are ", \, \e, \n, \r, \t which are escaped by a \
+ * See src/utils/common.c for the implementation in the supplicant.
+ *
+ * @hide
+ */
+public class WifiSsid implements Parcelable {
+ private static final String TAG = "WifiSsid";
+
+ public ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
+
+ private static final int HEX_RADIX = 16;
+ public static final String NONE = "<unknown ssid>";
+
+ private WifiSsid() {
+ }
+
+ public static WifiSsid createFromAsciiEncoded(String asciiEncoded) {
+ WifiSsid a = new WifiSsid();
+ a.convertToBytes(asciiEncoded);
+ return a;
+ }
+
+ public static WifiSsid createFromHex(String hexStr) {
+ WifiSsid a = new WifiSsid();
+ int length = 0;
+ if (hexStr == null) return a;
+
+ if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
+ hexStr = hexStr.substring(2);
+ }
+
+ for (int i = 0; i < hexStr.length()-1; i += 2) {
+ int val;
+ try {
+ val = Integer.parseInt(hexStr.substring(i, i + 2), HEX_RADIX);
+ } catch(NumberFormatException e) {
+ val = 0;
+ }
+ a.octets.write(val);
+ }
+ return a;
+ }
+
+ /* This function is equivalent to printf_decode() at src/utils/common.c in
+ * the supplicant */
+ private void convertToBytes(String asciiEncoded) {
+ int i = 0;
+ int val = 0;
+ while (i< asciiEncoded.length()) {
+ char c = asciiEncoded.charAt(i);
+ switch (c) {
+ case '\\':
+ i++;
+ switch(asciiEncoded.charAt(i)) {
+ case '\\':
+ octets.write('\\');
+ break;
+ case '"':
+ octets.write('"');
+ break;
+ case 'n':
+ octets.write('\n');
+ break;
+ case 'r':
+ octets.write('\r');
+ break;
+ case 't':
+ octets.write('\t');
+ break;
+ case 'e':
+ octets.write(27); //escape char
+ break;
+ case 'x':
+ i++;
+ try {
+ val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX);
+ } catch (NumberFormatException e) {
+ val = -1;
+ }
+ if (val < 0) {
+ val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX);
+ if (val < 0) break;
+ octets.write(val);
+ i++;
+ } else {
+ octets.write(val);
+ i += 2;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ val = asciiEncoded.charAt(i) - '0';
+ i++;
+ if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
+ val = val * 8 + asciiEncoded.charAt(i) - '0';
+ i++;
+ }
+ if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') {
+ val = val * 8 + asciiEncoded.charAt(i) - '0';
+ i++;
+ }
+ octets.write(val);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ octets.write(c);
+ i++;
+ break;
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (octets.size() <= 0) return "";
+ // TODO: Handle conversion to other charsets upon failure
+ Charset charset = Charset.forName("UTF-8");
+ CharsetDecoder decoder = charset.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ CharBuffer out = CharBuffer.allocate(32);
+
+ CoderResult result = decoder.decode(ByteBuffer.wrap(octets.toByteArray()), out, true);
+ out.flip();
+ if (result.isError()) {
+ return NONE;
+ }
+ return out.toString();
+ }
+
+ /** @hide */
+ public byte[] getOctets() {
+ return octets.toByteArray();
+ }
+
+ /** @hide */
+ public String getHexString() {
+ String out = "0x";
+ byte[] ssidbytes = getOctets();
+ for (int i = 0; i < octets.size(); i++) {
+ out += String.format("%02x", ssidbytes[i]);
+ }
+ return out;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(octets.size());
+ dest.writeByteArray(octets.toByteArray());
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WifiSsid> CREATOR =
+ new Creator<WifiSsid>() {
+ public WifiSsid createFromParcel(Parcel in) {
+ WifiSsid ssid = new WifiSsid();
+ int length = in.readInt();
+ byte b[] = new byte[length];
+ in.readByteArray(b);
+ ssid.octets.write(b, 0, length);
+ return ssid;
+ }
+
+ public WifiSsid[] newArray(int size) {
+ return new WifiSsid[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 40111fa..2e50b08 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1403,7 +1403,7 @@ public class WifiStateMachine extends StateMachine {
int freq = 0;
long tsf = 0;
String flags = "";
- String ssid = "";
+ WifiSsid wifiSsid = null;
if (scanResults == null) {
return;
@@ -1441,22 +1441,26 @@ public class WifiStateMachine extends StateMachine {
} else if (line.startsWith(FLAGS_STR)) {
flags = line.substring(FLAGS_STR.length());
} else if (line.startsWith(SSID_STR)) {
- ssid = line.substring(SSID_STR.length());
- if (ssid == null) ssid = "";
+ wifiSsid = WifiSsid.createFromAsciiEncoded(
+ line.substring(SSID_STR.length()));
} else if (line.startsWith(DELIMITER_STR)) {
if (bssid != null) {
+ String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
String key = bssid + ssid;
ScanResult scanResult = mScanResultCache.get(key);
if (scanResult != null) {
scanResult.level = level;
- scanResult.SSID = ssid;
+ scanResult.wifiSsid = wifiSsid;
+ // Keep existing API
+ scanResult.SSID = (wifiSsid != null) ? wifiSsid.toString() :
+ WifiSsid.NONE;
scanResult.capabilities = flags;
scanResult.frequency = freq;
scanResult.timestamp = tsf;
} else {
scanResult =
new ScanResult(
- ssid, bssid, flags, level, freq, tsf);
+ wifiSsid, bssid, flags, level, freq, tsf);
mScanResultCache.put(key, scanResult);
}
mScanResults.add(scanResult);
@@ -1466,7 +1470,7 @@ public class WifiStateMachine extends StateMachine {
freq = 0;
tsf = 0;
flags = "";
- ssid = "";
+ wifiSsid = null;
}
}
}
@@ -1652,7 +1656,7 @@ public class WifiStateMachine extends StateMachine {
}
mWifiInfo.setBSSID(stateChangeResult.BSSID);
- mWifiInfo.setSSID(stateChangeResult.SSID);
+ mWifiInfo.setSSID(stateChangeResult.wifiSsid);
mSupplicantStateTracker.sendMessage(Message.obtain(message));