• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED)45         stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED)46         stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE)47         stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING)48         stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING)49         stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING)50         stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING)51         stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING)52         stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING)53         stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR)54         stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED)55         stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE)56         stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
stateMap.put(SupplicantState.INVALID, DetailedState.FAILED)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 
WifiInfo()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      */
WifiInfo(WifiInfo source)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 
setSSID(WifiSsid wifiSsid)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      */
getSSID()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 */
getWifiSsid()136     public WifiSsid getWifiSsid() {
137         return mWifiSsid;
138     }
139 
setBSSID(String BSSID)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      */
getBSSID()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      */
getRssi()159     public int getRssi() {
160         return mRssi;
161     }
162 
setRssi(int rssi)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      */
getLinkSpeed()172     public int getLinkSpeed() {
173         return mLinkSpeed;
174     }
175 
setLinkSpeed(int linkSpeed)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      */
setMacAddress(String macAddress)184     void setMacAddress(String macAddress) {
185         this.mMacAddress = macAddress;
186     }
187 
getMacAddress()188     public String getMacAddress() {
189         return mMacAddress;
190     }
191 
192     /** {@hide} */
setMeteredHint(boolean meteredHint)193     public void setMeteredHint(boolean meteredHint) {
194         mMeteredHint = meteredHint;
195     }
196 
197     /** {@hide} */
getMeteredHint()198     public boolean getMeteredHint() {
199         return mMeteredHint;
200     }
201 
setNetworkId(int id)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      */
getNetworkId()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      */
getSupplicantState()221     public SupplicantState getSupplicantState() {
222         return mSupplicantState;
223     }
224 
setSupplicantState(SupplicantState state)225     void setSupplicantState(SupplicantState state) {
226         mSupplicantState = state;
227     }
228 
setInetAddress(InetAddress address)229     void setInetAddress(InetAddress address) {
230         mIpAddress = address;
231     }
232 
getIpAddress()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      */
getHiddenSSID()245     public boolean getHiddenSSID() {
246         return mHiddenSSID;
247     }
248 
249     /** {@hide} */
setHiddenSSID(boolean hiddenSSID)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      */
getDetailedStateOf(SupplicantState suppState)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      */
setSupplicantState(String stateName)269     void setSupplicantState(String stateName) {
270         mSupplicantState = valueOf(stateName);
271     }
272 
valueOf(String stateName)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} */
removeDoubleQuotes(String string)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
toString()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} */
describeContents()314     public int describeContents() {
315         return 0;
316     }
317 
318     /** Implement the Parcelable interface {@hide} */
writeToParcel(Parcel dest, int flags)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