Home | History | Annotate | Download | only in wifi
      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 import android.text.TextUtils;
     24 
     25 import java.net.InetAddress;
     26 import java.net.Inet4Address;
     27 import java.net.UnknownHostException;
     28 import java.util.EnumMap;
     29 
     30 /**
     31  * Describes the state of any Wifi connection that is active or
     32  * is in the process of being set up.
     33  */
     34 public class WifiInfo implements Parcelable {
     35     private static final String TAG = "WifiInfo";
     36     /**
     37      * This is the map described in the Javadoc comment above. The positions
     38      * of the elements of the array must correspond to the ordinal values
     39      * of <code>DetailedState</code>.
     40      */
     41     private static final EnumMap<SupplicantState, DetailedState> stateMap =
     42         new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
     43 
     44     static {
     45         stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
     46         stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
     47         stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
     48         stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
     49         stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
     50         stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
     51         stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
     52         stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
     53         stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
     54         stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
     55         stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
     56         stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
     57         stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
     58     }
     59 
     60     private SupplicantState mSupplicantState;
     61     private String mBSSID;
     62     private WifiSsid mWifiSsid;
     63     private int mNetworkId;
     64     private boolean mHiddenSSID;
     65     /** Received Signal Strength Indicator */
     66     private int mRssi;
     67 
     68     /** Link speed in Mbps */
     69     public static final String LINK_SPEED_UNITS = "Mbps";
     70     private int mLinkSpeed;
     71 
     72     private InetAddress mIpAddress;
     73     private String mMacAddress;
     74 
     75     /**
     76      * Flag indicating that AP has hinted that upstream connection is metered,
     77      * and sensitive to heavy data transfers.
     78      */
     79     private boolean mMeteredHint;
     80 
     81     WifiInfo() {
     82         mWifiSsid = null;
     83         mBSSID = null;
     84         mNetworkId = -1;
     85         mSupplicantState = SupplicantState.UNINITIALIZED;
     86         mRssi = -9999;
     87         mLinkSpeed = -1;
     88         mHiddenSSID = false;
     89     }
     90 
     91     /**
     92      * Copy constructor
     93      * @hide
     94      */
     95     public WifiInfo(WifiInfo source) {
     96         if (source != null) {
     97             mSupplicantState = source.mSupplicantState;
     98             mBSSID = source.mBSSID;
     99             mWifiSsid = source.mWifiSsid;
    100             mNetworkId = source.mNetworkId;
    101             mHiddenSSID = source.mHiddenSSID;
    102             mRssi = source.mRssi;
    103             mLinkSpeed = source.mLinkSpeed;
    104             mIpAddress = source.mIpAddress;
    105             mMacAddress = source.mMacAddress;
    106             mMeteredHint = source.mMeteredHint;
    107         }
    108     }
    109 
    110     void setSSID(WifiSsid wifiSsid) {
    111         mWifiSsid = wifiSsid;
    112         // network is considered not hidden by default
    113         mHiddenSSID = false;
    114     }
    115 
    116     /**
    117      * Returns the service set identifier (SSID) of the current 802.11 network.
    118      * If the SSID can be decoded as UTF-8, it will be returned surrounded by double
    119      * quotation marks. Otherwise, it is returned as a string of hex digits. The
    120      * SSID may be {@code null} if there is no network currently connected.
    121      * @return the SSID
    122      */
    123     public String getSSID() {
    124         if (mWifiSsid != null) {
    125             String unicode = mWifiSsid.toString();
    126             if (!TextUtils.isEmpty(unicode)) {
    127                 return "\"" + unicode + "\"";
    128             } else {
    129                 return mWifiSsid.getHexString();
    130             }
    131         }
    132         return WifiSsid.NONE;
    133     }
    134 
    135     /** @hide */
    136     public WifiSsid getWifiSsid() {
    137         return mWifiSsid;
    138     }
    139 
    140     void setBSSID(String BSSID) {
    141         mBSSID = BSSID;
    142     }
    143 
    144     /**
    145      * Return the basic service set identifier (BSSID) of the current access point.
    146      * The BSSID may be {@code null} if there is no network currently connected.
    147      * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
    148      */
    149     public String getBSSID() {
    150         return mBSSID;
    151     }
    152 
    153     /**
    154      * Returns the received signal strength indicator of the current 802.11
    155      * network.
    156      * <p><strong>This is not normalized, but should be!</strong></p>
    157      * @return the RSSI, in the range ??? to ???
    158      */
    159     public int getRssi() {
    160         return mRssi;
    161     }
    162 
    163     void setRssi(int rssi) {
    164         mRssi = rssi;
    165     }
    166 
    167     /**
    168      * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
    169      * @return the link speed.
    170      * @see #LINK_SPEED_UNITS
    171      */
    172     public int getLinkSpeed() {
    173         return mLinkSpeed;
    174     }
    175 
    176     void setLinkSpeed(int linkSpeed) {
    177         this.mLinkSpeed = linkSpeed;
    178     }
    179 
    180     /**
    181      * Record the MAC address of the WLAN interface
    182      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
    183      */
    184     void setMacAddress(String macAddress) {
    185         this.mMacAddress = macAddress;
    186     }
    187 
    188     public String getMacAddress() {
    189         return mMacAddress;
    190     }
    191 
    192     /** {@hide} */
    193     public void setMeteredHint(boolean meteredHint) {
    194         mMeteredHint = meteredHint;
    195     }
    196 
    197     /** {@hide} */
    198     public boolean getMeteredHint() {
    199         return mMeteredHint;
    200     }
    201 
    202     void setNetworkId(int id) {
    203         mNetworkId = id;
    204     }
    205 
    206     /**
    207      * Each configured network has a unique small integer ID, used to identify
    208      * the network when performing operations on the supplicant. This method
    209      * returns the ID for the currently connected network.
    210      * @return the network ID, or -1 if there is no currently connected network
    211      */
    212     public int getNetworkId() {
    213         return mNetworkId;
    214     }
    215 
    216     /**
    217      * Return the detailed state of the supplicant's negotiation with an
    218      * access point, in the form of a {@link SupplicantState SupplicantState} object.
    219      * @return the current {@link SupplicantState SupplicantState}
    220      */
    221     public SupplicantState getSupplicantState() {
    222         return mSupplicantState;
    223     }
    224 
    225     void setSupplicantState(SupplicantState state) {
    226         mSupplicantState = state;
    227     }
    228 
    229     void setInetAddress(InetAddress address) {
    230         mIpAddress = address;
    231     }
    232 
    233     public int getIpAddress() {
    234         int result = 0;
    235         if (mIpAddress instanceof Inet4Address) {
    236             result = NetworkUtils.inetAddressToInt((Inet4Address)mIpAddress);
    237         }
    238         return result;
    239     }
    240 
    241     /**
    242      * @return {@code true} if this network does not broadcast its SSID, so an
    243      * SSID-specific probe request must be used for scans.
    244      */
    245     public boolean getHiddenSSID() {
    246         return mHiddenSSID;
    247     }
    248 
    249     /** {@hide} */
    250     public void setHiddenSSID(boolean hiddenSSID) {
    251         mHiddenSSID = hiddenSSID;
    252     }
    253 
    254    /**
    255      * Map a supplicant state into a fine-grained network connectivity state.
    256      * @param suppState the supplicant state
    257      * @return the corresponding {@link DetailedState}
    258      */
    259     public static DetailedState getDetailedStateOf(SupplicantState suppState) {
    260         return stateMap.get(suppState);
    261     }
    262 
    263     /**
    264      * Set the <code>SupplicantState</code> from the string name
    265      * of the state.
    266      * @param stateName the name of the state, as a <code>String</code> returned
    267      * in an event sent by {@code wpa_supplicant}.
    268      */
    269     void setSupplicantState(String stateName) {
    270         mSupplicantState = valueOf(stateName);
    271     }
    272 
    273     static SupplicantState valueOf(String stateName) {
    274         if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
    275             return SupplicantState.FOUR_WAY_HANDSHAKE;
    276         else {
    277             try {
    278                 return SupplicantState.valueOf(stateName.toUpperCase());
    279             } catch (IllegalArgumentException e) {
    280                 return SupplicantState.INVALID;
    281             }
    282         }
    283     }
    284 
    285     /** {@hide} */
    286     public static String removeDoubleQuotes(String string) {
    287         if (string == null) return null;
    288         final int length = string.length();
    289         if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
    290             return string.substring(1, length - 1);
    291         }
    292         return string;
    293     }
    294 
    295     @Override
    296     public String toString() {
    297         StringBuffer sb = new StringBuffer();
    298         String none = "<none>";
    299 
    300         sb.append("SSID: ").append(mWifiSsid == null ? WifiSsid.NONE : mWifiSsid).
    301             append(", BSSID: ").append(mBSSID == null ? none : mBSSID).
    302             append(", MAC: ").append(mMacAddress == null ? none : mMacAddress).
    303             append(", Supplicant state: ").
    304             append(mSupplicantState == null ? none : mSupplicantState).
    305             append(", RSSI: ").append(mRssi).
    306             append(", Link speed: ").append(mLinkSpeed).
    307             append(", Net ID: ").append(mNetworkId).
    308             append(", Metered hint: ").append(mMeteredHint);
    309 
    310         return sb.toString();
    311     }
    312 
    313     /** Implement the Parcelable interface {@hide} */
    314     public int describeContents() {
    315         return 0;
    316     }
    317 
    318     /** Implement the Parcelable interface {@hide} */
    319     public void writeToParcel(Parcel dest, int flags) {
    320         dest.writeInt(mNetworkId);
    321         dest.writeInt(mRssi);
    322         dest.writeInt(mLinkSpeed);
    323         if (mIpAddress != null) {
    324             dest.writeByte((byte)1);
    325             dest.writeByteArray(mIpAddress.getAddress());
    326         } else {
    327             dest.writeByte((byte)0);
    328         }
    329         if (mWifiSsid != null) {
    330             dest.writeInt(1);
    331             mWifiSsid.writeToParcel(dest, flags);
    332         } else {
    333             dest.writeInt(0);
    334         }
    335         dest.writeString(mBSSID);
    336         dest.writeString(mMacAddress);
    337         dest.writeInt(mMeteredHint ? 1 : 0);
    338         mSupplicantState.writeToParcel(dest, flags);
    339     }
    340 
    341     /** Implement the Parcelable interface {@hide} */
    342     public static final Creator<WifiInfo> CREATOR =
    343         new Creator<WifiInfo>() {
    344             public WifiInfo createFromParcel(Parcel in) {
    345                 WifiInfo info = new WifiInfo();
    346                 info.setNetworkId(in.readInt());
    347                 info.setRssi(in.readInt());
    348                 info.setLinkSpeed(in.readInt());
    349                 if (in.readByte() == 1) {
    350                     try {
    351                         info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
    352                     } catch (UnknownHostException e) {}
    353                 }
    354                 if (in.readInt() == 1) {
    355                     info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(in);
    356                 }
    357                 info.mBSSID = in.readString();
    358                 info.mMacAddress = in.readString();
    359                 info.mMeteredHint = in.readInt() != 0;
    360                 info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
    361                 return info;
    362             }
    363 
    364             public WifiInfo[] newArray(int size) {
    365                 return new WifiInfo[size];
    366             }
    367         };
    368 }
    369