WifiSsid.java revision b6deeed3ceff9e0f754697987b7c724901996082
1b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff/* 2b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * Copyright (C) 2012 The Android Open Source Project 3b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * 4b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 5b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * you may not use this file except in compliance with the License. 6b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * You may obtain a copy of the License at 7b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * 8b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 9b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * 10b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * Unless required by applicable law or agreed to in writing, software 11b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 12b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * See the License for the specific language governing permissions and 14b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * limitations under the License. 15b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff */ 16b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 17b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffpackage android.net.wifi; 18b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 19b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport android.os.Parcelable; 20b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport android.os.Parcel; 21b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport android.util.Log; 22b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 23b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.io.ByteArrayOutputStream; 24b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.ByteBuffer; 25b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.CharBuffer; 26b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.charset.Charset; 27b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.charset.CharsetDecoder; 28b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.charset.CoderResult; 29b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffimport java.nio.charset.CodingErrorAction; 30b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 31b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff/** 32b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * Stores SSID octets and handles conversion. 33b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * 34b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * For Ascii encoded string, any octet < 32 or > 127 is encoded as 35b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * a "\x" followed by the hex representation of the octet. 36b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * Exception chars are ", \, \e, \n, \r, \t which are escaped by a \ 37b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * See src/utils/common.c for the implementation in the supplicant. 38b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * 39b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * @hide 40b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff */ 41b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriffpublic class WifiSsid implements Parcelable { 42b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff private static final String TAG = "WifiSsid"; 43b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 44b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public ByteArrayOutputStream octets = new ByteArrayOutputStream(32); 45b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 46b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff private static final int HEX_RADIX = 16; 47b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public static final String NONE = "<unknown ssid>"; 48b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 49b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff private WifiSsid() { 50b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 51b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 52b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public static WifiSsid createFromAsciiEncoded(String asciiEncoded) { 53b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff WifiSsid a = new WifiSsid(); 54b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff a.convertToBytes(asciiEncoded); 55b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return a; 56b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 57b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 58b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public static WifiSsid createFromHex(String hexStr) { 59b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff WifiSsid a = new WifiSsid(); 60b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff int length = 0; 61b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (hexStr == null) return a; 62b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 63b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) { 64b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff hexStr = hexStr.substring(2); 65b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 66b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 67b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff for (int i = 0; i < hexStr.length()-1; i += 2) { 68b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff int val; 69b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff try { 70b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = Integer.parseInt(hexStr.substring(i, i + 2), HEX_RADIX); 71b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } catch(NumberFormatException e) { 72b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = 0; 73b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 74b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff a.octets.write(val); 75b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 76b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return a; 77b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 78b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 79b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /* This function is equivalent to printf_decode() at src/utils/common.c in 80b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff * the supplicant */ 81b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff private void convertToBytes(String asciiEncoded) { 82b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff int i = 0; 83b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff int val = 0; 84b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff while (i< asciiEncoded.length()) { 85b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff char c = asciiEncoded.charAt(i); 86b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff switch (c) { 87b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '\\': 88b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 89b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff switch(asciiEncoded.charAt(i)) { 90b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '\\': 91b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write('\\'); 92b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 93b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '"': 94b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write('"'); 95b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 96b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case 'n': 97b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write('\n'); 98b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 99b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case 'r': 100b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write('\r'); 101b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 102b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case 't': 103b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write('\t'); 104b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 105b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case 'e': 106b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write(27); //escape char 107b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 108b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case 'x': 109b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 110b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff try { 111b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = Integer.parseInt(asciiEncoded.substring(i, i + 2), HEX_RADIX); 112b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } catch (NumberFormatException e) { 113b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = -1; 114b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 115b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (val < 0) { 116b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = Character.digit(asciiEncoded.charAt(i), HEX_RADIX); 117b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (val < 0) break; 118b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write(val); 119b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 120b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } else { 121b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write(val); 122b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i += 2; 123b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 124b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 125b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '0': 126b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '1': 127b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '2': 128b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '3': 129b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '4': 130b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '5': 131b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '6': 132b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff case '7': 133b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = asciiEncoded.charAt(i) - '0'; 134b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 135b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') { 136b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = val * 8 + asciiEncoded.charAt(i) - '0'; 137b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 138b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 139b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (asciiEncoded.charAt(i) >= '0' && asciiEncoded.charAt(i) <= '7') { 140b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff val = val * 8 + asciiEncoded.charAt(i) - '0'; 141b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 142b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 143b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write(val); 144b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 145b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff default: 146b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 147b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 148b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 149b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff default: 150b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff octets.write(c); 151b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff i++; 152b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff break; 153b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 154b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 155b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 156b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 157b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff @Override 158b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public String toString() { 159b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (octets.size() <= 0) return ""; 160b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff // TODO: Handle conversion to other charsets upon failure 161b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff Charset charset = Charset.forName("UTF-8"); 162b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff CharsetDecoder decoder = charset.newDecoder() 163b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff .onMalformedInput(CodingErrorAction.REPLACE) 164b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff .onUnmappableCharacter(CodingErrorAction.REPLACE); 165b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff CharBuffer out = CharBuffer.allocate(32); 166b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 167b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff CoderResult result = decoder.decode(ByteBuffer.wrap(octets.toByteArray()), out, true); 168b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff out.flip(); 169b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff if (result.isError()) { 170b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return NONE; 171b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 172b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return out.toString(); 173b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 174b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 175b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /** @hide */ 176b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public byte[] getOctets() { 177b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return octets.toByteArray(); 178b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 179b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 180b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /** @hide */ 181b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public String getHexString() { 182b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff String out = "0x"; 183b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff byte[] ssidbytes = getOctets(); 184b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff for (int i = 0; i < octets.size(); i++) { 185b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff out += String.format("%02x", ssidbytes[i]); 186b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 187b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return out; 188b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 189b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 190b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 191b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public int describeContents() { 192b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return 0; 193b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 194b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 195b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 196b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public void writeToParcel(Parcel dest, int flags) { 197b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff dest.writeInt(octets.size()); 198b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff dest.writeByteArray(octets.toByteArray()); 199b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 200b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 201b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff /** Implement the Parcelable interface {@hide} */ 202b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public static final Creator<WifiSsid> CREATOR = 203b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff new Creator<WifiSsid>() { 204b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public WifiSsid createFromParcel(Parcel in) { 205b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff WifiSsid ssid = new WifiSsid(); 206b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff int length = in.readInt(); 207b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff byte b[] = new byte[length]; 208b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff in.readByteArray(b); 209b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff ssid.octets.write(b, 0, length); 210b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return ssid; 211b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 212b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff 213b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff public WifiSsid[] newArray(int size) { 214b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff return new WifiSsid[size]; 215b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff } 216b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff }; 217b6deeed3ceff9e0f754697987b7c724901996082Irfan Sheriff} 218