1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.wifi; 18 19 import android.os.Parcelable; 20 import android.os.Parcel; 21 import android.net.NetworkInfo.DetailedState; 22 import android.net.NetworkUtils; 23 24 import java.net.InetAddress; 25 import java.net.Inet6Address; 26 import java.net.UnknownHostException; 27 import java.util.EnumMap; 28 29 /** 30 * Describes the state of any Wifi connection that is active or 31 * is in the process of being set up. 32 */ 33 public class WifiInfo implements Parcelable { 34 /** 35 * This is the map described in the Javadoc comment above. The positions 36 * of the elements of the array must correspond to the ordinal values 37 * of <code>DetailedState</code>. 38 */ 39 private static final EnumMap<SupplicantState, DetailedState> stateMap = 40 new EnumMap<SupplicantState, DetailedState>(SupplicantState.class); 41 42 static { 43 stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); 44 stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); 45 stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); 46 stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); 47 stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); 48 stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); 49 stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); 50 stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); 51 stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING); 52 stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR); 53 stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED); 54 stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE); 55 stateMap.put(SupplicantState.INVALID, DetailedState.FAILED); 56 } 57 58 private SupplicantState mSupplicantState; 59 private String mBSSID; 60 private String mSSID; 61 private int mNetworkId; 62 private boolean mHiddenSSID; 63 /** Received Signal Strength Indicator */ 64 private int mRssi; 65 66 /** Link speed in Mbps */ 67 public static final String LINK_SPEED_UNITS = "Mbps"; 68 private int mLinkSpeed; 69 70 private InetAddress mIpAddress; 71 72 private String mMacAddress; 73 private boolean mExplicitConnect; 74 75 WifiInfo() { 76 mSSID = null; 77 mBSSID = null; 78 mNetworkId = -1; 79 mSupplicantState = SupplicantState.UNINITIALIZED; 80 mRssi = -9999; 81 mLinkSpeed = -1; 82 mHiddenSSID = false; 83 mExplicitConnect = false; 84 } 85 86 /** 87 * Copy constructor 88 * @hide 89 */ 90 public WifiInfo(WifiInfo source) { 91 if (source != null) { 92 mSupplicantState = source.mSupplicantState; 93 mBSSID = source.mBSSID; 94 mSSID = source.mSSID; 95 mNetworkId = source.mNetworkId; 96 mHiddenSSID = source.mHiddenSSID; 97 mRssi = source.mRssi; 98 mLinkSpeed = source.mLinkSpeed; 99 mIpAddress = source.mIpAddress; 100 mMacAddress = source.mMacAddress; 101 mExplicitConnect = source.mExplicitConnect; 102 } 103 } 104 105 void setSSID(String SSID) { 106 mSSID = SSID; 107 // network is considered not hidden by default 108 mHiddenSSID = false; 109 } 110 111 /** 112 * Returns the service set identifier (SSID) of the current 802.11 network. 113 * If the SSID is an ASCII string, it will be returned surrounded by double 114 * quotation marks.Otherwise, it is returned as a string of hex digits. The 115 * SSID may be {@code null} if there is no network currently connected. 116 * @return the SSID 117 */ 118 public String getSSID() { 119 return mSSID; 120 } 121 122 void setBSSID(String BSSID) { 123 mBSSID = BSSID; 124 } 125 126 /** 127 * Return the basic service set identifier (BSSID) of the current access point. 128 * The BSSID may be {@code null} if there is no network currently connected. 129 * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} 130 */ 131 public String getBSSID() { 132 return mBSSID; 133 } 134 135 /** 136 * Returns the received signal strength indicator of the current 802.11 137 * network. 138 * <p><strong>This is not normalized, but should be!</strong></p> 139 * @return the RSSI, in the range ??? to ??? 140 */ 141 public int getRssi() { 142 return mRssi; 143 } 144 145 void setRssi(int rssi) { 146 mRssi = rssi; 147 } 148 149 /** 150 * Returns the current link speed in {@link #LINK_SPEED_UNITS}. 151 * @return the link speed. 152 * @see #LINK_SPEED_UNITS 153 */ 154 public int getLinkSpeed() { 155 return mLinkSpeed; 156 } 157 158 void setLinkSpeed(int linkSpeed) { 159 this.mLinkSpeed = linkSpeed; 160 } 161 162 /** 163 * Record the MAC address of the WLAN interface 164 * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form 165 */ 166 void setMacAddress(String macAddress) { 167 this.mMacAddress = macAddress; 168 } 169 170 public String getMacAddress() { 171 return mMacAddress; 172 } 173 174 void setNetworkId(int id) { 175 mNetworkId = id; 176 } 177 178 179 /** 180 * @hide 181 */ 182 public boolean isExplicitConnect() { 183 return mExplicitConnect; 184 } 185 186 /** 187 * @hide 188 */ 189 public void setExplicitConnect(boolean explicitConnect) { 190 this.mExplicitConnect = explicitConnect; 191 } 192 193 194 /** 195 * Each configured network has a unique small integer ID, used to identify 196 * the network when performing operations on the supplicant. This method 197 * returns the ID for the currently connected network. 198 * @return the network ID, or -1 if there is no currently connected network 199 */ 200 public int getNetworkId() { 201 return mNetworkId; 202 } 203 204 /** 205 * Return the detailed state of the supplicant's negotiation with an 206 * access point, in the form of a {@link SupplicantState SupplicantState} object. 207 * @return the current {@link SupplicantState SupplicantState} 208 */ 209 public SupplicantState getSupplicantState() { 210 return mSupplicantState; 211 } 212 213 void setSupplicantState(SupplicantState state) { 214 mSupplicantState = state; 215 } 216 217 void setInetAddress(InetAddress address) { 218 mIpAddress = address; 219 } 220 221 public int getIpAddress() { 222 if (mIpAddress == null || mIpAddress instanceof Inet6Address) return 0; 223 return NetworkUtils.inetAddressToInt(mIpAddress); 224 } 225 226 /** 227 * @return {@code true} if this network does not broadcast its SSID, so an 228 * SSID-specific probe request must be used for scans. 229 */ 230 public boolean getHiddenSSID() { 231 return mHiddenSSID; 232 } 233 234 /** {@hide} */ 235 public void setHiddenSSID(boolean hiddenSSID) { 236 mHiddenSSID = hiddenSSID; 237 } 238 239 /** 240 * Map a supplicant state into a fine-grained network connectivity state. 241 * @param suppState the supplicant state 242 * @return the corresponding {@link DetailedState} 243 */ 244 public static DetailedState getDetailedStateOf(SupplicantState suppState) { 245 return stateMap.get(suppState); 246 } 247 248 /** 249 * Set the <code>SupplicantState</code> from the string name 250 * of the state. 251 * @param stateName the name of the state, as a <code>String</code> returned 252 * in an event sent by {@code wpa_supplicant}. 253 */ 254 void setSupplicantState(String stateName) { 255 mSupplicantState = valueOf(stateName); 256 } 257 258 static SupplicantState valueOf(String stateName) { 259 if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName)) 260 return SupplicantState.FOUR_WAY_HANDSHAKE; 261 else { 262 try { 263 return SupplicantState.valueOf(stateName.toUpperCase()); 264 } catch (IllegalArgumentException e) { 265 return SupplicantState.INVALID; 266 } 267 } 268 } 269 270 @Override 271 public String toString() { 272 StringBuffer sb = new StringBuffer(); 273 String none = "<none>"; 274 275 sb.append("SSID: ").append(mSSID == null ? none : mSSID). 276 append(", BSSID: ").append(mBSSID == null ? none : mBSSID). 277 append(", MAC: ").append(mMacAddress == null ? none : mMacAddress). 278 append(", Supplicant state: "). 279 append(mSupplicantState == null ? none : mSupplicantState). 280 append(", RSSI: ").append(mRssi). 281 append(", Link speed: ").append(mLinkSpeed). 282 append(", Net ID: ").append(mNetworkId). 283 append(", Explicit connect: ").append(mExplicitConnect); 284 285 return sb.toString(); 286 } 287 288 /** Implement the Parcelable interface {@hide} */ 289 public int describeContents() { 290 return 0; 291 } 292 293 /** Implement the Parcelable interface {@hide} */ 294 public void writeToParcel(Parcel dest, int flags) { 295 dest.writeInt(mNetworkId); 296 dest.writeInt(mRssi); 297 dest.writeInt(mLinkSpeed); 298 if (mIpAddress != null) { 299 dest.writeByte((byte)1); 300 dest.writeByteArray(mIpAddress.getAddress()); 301 } else { 302 dest.writeByte((byte)0); 303 } 304 dest.writeString(getSSID()); 305 dest.writeString(mBSSID); 306 dest.writeString(mMacAddress); 307 dest.writeByte(mExplicitConnect ? (byte)1 : (byte)0); 308 mSupplicantState.writeToParcel(dest, flags); 309 } 310 311 /** Implement the Parcelable interface {@hide} */ 312 public static final Creator<WifiInfo> CREATOR = 313 new Creator<WifiInfo>() { 314 public WifiInfo createFromParcel(Parcel in) { 315 WifiInfo info = new WifiInfo(); 316 info.setNetworkId(in.readInt()); 317 info.setRssi(in.readInt()); 318 info.setLinkSpeed(in.readInt()); 319 if (in.readByte() == 1) { 320 try { 321 info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); 322 } catch (UnknownHostException e) {} 323 } 324 info.setSSID(in.readString()); 325 info.mBSSID = in.readString(); 326 info.mMacAddress = in.readString(); 327 info.mExplicitConnect = in.readByte() == 1 ? true : false; 328 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); 329 return info; 330 } 331 332 public WifiInfo[] newArray(int size) { 333 return new WifiInfo[size]; 334 } 335 }; 336 } 337