| /* |
| * Copyright (C) 2008 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.net.NetworkInfo.DetailedState; |
| import android.net.NetworkUtils; |
| import android.text.TextUtils; |
| |
| import java.net.InetAddress; |
| import java.net.Inet4Address; |
| import java.net.UnknownHostException; |
| import java.util.EnumMap; |
| import java.util.Locale; |
| |
| /** |
| * Describes the state of any Wifi connection that is active or |
| * 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 |
| * of <code>DetailedState</code>. |
| */ |
| private static final EnumMap<SupplicantState, DetailedState> stateMap = |
| new EnumMap<SupplicantState, DetailedState>(SupplicantState.class); |
| |
| static { |
| stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED); |
| stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED); |
| stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE); |
| stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING); |
| stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING); |
| stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING); |
| stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING); |
| stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING); |
| stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING); |
| stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR); |
| stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED); |
| stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE); |
| stateMap.put(SupplicantState.INVALID, DetailedState.FAILED); |
| } |
| |
| private SupplicantState mSupplicantState; |
| private String mBSSID; |
| private WifiSsid mWifiSsid; |
| private int mNetworkId; |
| /** Received Signal Strength Indicator */ |
| private int mRssi; |
| |
| /** Link speed in Mbps */ |
| public static final String LINK_SPEED_UNITS = "Mbps"; |
| private int mLinkSpeed; |
| |
| private InetAddress mIpAddress; |
| private String mMacAddress; |
| |
| /** |
| * Flag indicating that AP has hinted that upstream connection is metered, |
| * and sensitive to heavy data transfers. |
| */ |
| private boolean mMeteredHint; |
| |
| /** @hide */ |
| public WifiInfo() { |
| mWifiSsid = null; |
| mBSSID = null; |
| mNetworkId = -1; |
| mSupplicantState = SupplicantState.UNINITIALIZED; |
| mRssi = -9999; |
| mLinkSpeed = -1; |
| } |
| |
| /** |
| * Copy constructor |
| * @hide |
| */ |
| public WifiInfo(WifiInfo source) { |
| if (source != null) { |
| mSupplicantState = source.mSupplicantState; |
| mBSSID = source.mBSSID; |
| mWifiSsid = source.mWifiSsid; |
| mNetworkId = source.mNetworkId; |
| mRssi = source.mRssi; |
| mLinkSpeed = source.mLinkSpeed; |
| mIpAddress = source.mIpAddress; |
| mMacAddress = source.mMacAddress; |
| mMeteredHint = source.mMeteredHint; |
| } |
| } |
| |
| /** @hide */ |
| public void setSSID(WifiSsid wifiSsid) { |
| mWifiSsid = wifiSsid; |
| } |
| |
| /** |
| * Returns the service set identifier (SSID) of the current 802.11 network. |
| * 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() { |
| 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; |
| } |
| |
| /** @hide */ |
| public void setBSSID(String BSSID) { |
| mBSSID = BSSID; |
| } |
| |
| /** |
| * Return the basic service set identifier (BSSID) of the current access point. |
| * The BSSID may be {@code null} if there is no network currently connected. |
| * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX} |
| */ |
| public String getBSSID() { |
| return mBSSID; |
| } |
| |
| /** |
| * Returns the received signal strength indicator of the current 802.11 |
| * network. |
| * <p><strong>This is not normalized, but should be!</strong></p> |
| * @return the RSSI, in the range ??? to ??? |
| */ |
| public int getRssi() { |
| return mRssi; |
| } |
| |
| /** @hide */ |
| public void setRssi(int rssi) { |
| mRssi = rssi; |
| } |
| |
| /** |
| * Returns the current link speed in {@link #LINK_SPEED_UNITS}. |
| * @return the link speed. |
| * @see #LINK_SPEED_UNITS |
| */ |
| public int getLinkSpeed() { |
| return mLinkSpeed; |
| } |
| |
| /** @hide */ |
| public void setLinkSpeed(int linkSpeed) { |
| this.mLinkSpeed = linkSpeed; |
| } |
| |
| /** |
| * Record the MAC address of the WLAN interface |
| * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form |
| * @hide |
| */ |
| public void setMacAddress(String macAddress) { |
| this.mMacAddress = macAddress; |
| } |
| |
| public String getMacAddress() { |
| return mMacAddress; |
| } |
| |
| /** {@hide} */ |
| public void setMeteredHint(boolean meteredHint) { |
| mMeteredHint = meteredHint; |
| } |
| |
| /** {@hide} */ |
| public boolean getMeteredHint() { |
| return mMeteredHint; |
| } |
| |
| /** @hide */ |
| public void setNetworkId(int id) { |
| mNetworkId = id; |
| } |
| |
| /** |
| * Each configured network has a unique small integer ID, used to identify |
| * the network when performing operations on the supplicant. This method |
| * returns the ID for the currently connected network. |
| * @return the network ID, or -1 if there is no currently connected network |
| */ |
| public int getNetworkId() { |
| return mNetworkId; |
| } |
| |
| /** |
| * Return the detailed state of the supplicant's negotiation with an |
| * access point, in the form of a {@link SupplicantState SupplicantState} object. |
| * @return the current {@link SupplicantState SupplicantState} |
| */ |
| public SupplicantState getSupplicantState() { |
| return mSupplicantState; |
| } |
| |
| /** @hide */ |
| public void setSupplicantState(SupplicantState state) { |
| mSupplicantState = state; |
| } |
| |
| /** @hide */ |
| public void setInetAddress(InetAddress address) { |
| mIpAddress = address; |
| } |
| |
| public int getIpAddress() { |
| int result = 0; |
| if (mIpAddress instanceof Inet4Address) { |
| result = NetworkUtils.inetAddressToInt((Inet4Address)mIpAddress); |
| } |
| return result; |
| } |
| |
| /** |
| * @return {@code true} if this network does not broadcast its SSID, so an |
| * SSID-specific probe request must be used for scans. |
| */ |
| public boolean getHiddenSSID() { |
| return mWifiSsid.isHidden(); |
| } |
| |
| /** |
| * Map a supplicant state into a fine-grained network connectivity state. |
| * @param suppState the supplicant state |
| * @return the corresponding {@link DetailedState} |
| */ |
| public static DetailedState getDetailedStateOf(SupplicantState suppState) { |
| return stateMap.get(suppState); |
| } |
| |
| /** |
| * Set the <code>SupplicantState</code> from the string name |
| * of the state. |
| * @param stateName the name of the state, as a <code>String</code> returned |
| * in an event sent by {@code wpa_supplicant}. |
| */ |
| void setSupplicantState(String stateName) { |
| mSupplicantState = valueOf(stateName); |
| } |
| |
| static SupplicantState valueOf(String stateName) { |
| if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName)) |
| return SupplicantState.FOUR_WAY_HANDSHAKE; |
| else { |
| try { |
| return SupplicantState.valueOf(stateName.toUpperCase(Locale.ROOT)); |
| } catch (IllegalArgumentException e) { |
| return SupplicantState.INVALID; |
| } |
| } |
| } |
| |
| /** {@hide} */ |
| public static String removeDoubleQuotes(String string) { |
| if (string == null) return null; |
| final int length = string.length(); |
| if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) { |
| return string.substring(1, length - 1); |
| } |
| return string; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuffer sb = new StringBuffer(); |
| String none = "<none>"; |
| |
| 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: "). |
| append(mSupplicantState == null ? none : mSupplicantState). |
| append(", RSSI: ").append(mRssi). |
| append(", Link speed: ").append(mLinkSpeed). |
| append(", Net ID: ").append(mNetworkId). |
| append(", Metered hint: ").append(mMeteredHint); |
| |
| return sb.toString(); |
| } |
| |
| /** Implement the Parcelable interface {@hide} */ |
| public int describeContents() { |
| return 0; |
| } |
| |
| /** Implement the Parcelable interface {@hide} */ |
| public void writeToParcel(Parcel dest, int flags) { |
| dest.writeInt(mNetworkId); |
| dest.writeInt(mRssi); |
| dest.writeInt(mLinkSpeed); |
| if (mIpAddress != null) { |
| dest.writeByte((byte)1); |
| dest.writeByteArray(mIpAddress.getAddress()); |
| } else { |
| dest.writeByte((byte)0); |
| } |
| 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); |
| mSupplicantState.writeToParcel(dest, flags); |
| } |
| |
| /** Implement the Parcelable interface {@hide} */ |
| public static final Creator<WifiInfo> CREATOR = |
| new Creator<WifiInfo>() { |
| public WifiInfo createFromParcel(Parcel in) { |
| WifiInfo info = new WifiInfo(); |
| info.setNetworkId(in.readInt()); |
| info.setRssi(in.readInt()); |
| info.setLinkSpeed(in.readInt()); |
| if (in.readByte() == 1) { |
| try { |
| info.setInetAddress(InetAddress.getByAddress(in.createByteArray())); |
| } catch (UnknownHostException e) {} |
| } |
| if (in.readInt() == 1) { |
| info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in); |
| } |
| info.mBSSID = in.readString(); |
| info.mMacAddress = in.readString(); |
| info.mMeteredHint = in.readInt() != 0; |
| info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in); |
| return info; |
| } |
| |
| public WifiInfo[] newArray(int size) { |
| return new WifiInfo[size]; |
| } |
| }; |
| } |