WifiInfo.java revision 00a10a1494954d124e1b11bc1ba3128e47b8ffbd
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
17package android.net.wifi;
18
19import android.os.Parcelable;
20import android.os.Parcel;
21import android.net.NetworkInfo.DetailedState;
22import android.net.NetworkUtils;
23
24import java.net.InetAddress;
25import java.net.Inet6Address;
26import java.net.UnknownHostException;
27import 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 */
33public 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    private String mMacAddress;
72
73    /**
74     * Flag indicating that AP has hinted that upstream connection is metered,
75     * and sensitive to heavy data transfers.
76     */
77    private boolean mMeteredHint;
78
79    WifiInfo() {
80        mSSID = null;
81        mBSSID = null;
82        mNetworkId = -1;
83        mSupplicantState = SupplicantState.UNINITIALIZED;
84        mRssi = -9999;
85        mLinkSpeed = -1;
86        mHiddenSSID = false;
87    }
88
89    /**
90     * Copy constructor
91     * @hide
92     */
93    public WifiInfo(WifiInfo source) {
94        if (source != null) {
95            mSupplicantState = source.mSupplicantState;
96            mBSSID = source.mBSSID;
97            mSSID = source.mSSID;
98            mNetworkId = source.mNetworkId;
99            mHiddenSSID = source.mHiddenSSID;
100            mRssi = source.mRssi;
101            mLinkSpeed = source.mLinkSpeed;
102            mIpAddress = source.mIpAddress;
103            mMacAddress = source.mMacAddress;
104            mMeteredHint = source.mMeteredHint;
105        }
106    }
107
108    void setSSID(String SSID) {
109        mSSID = SSID;
110        // network is considered not hidden by default
111        mHiddenSSID = false;
112    }
113
114    /**
115     * Returns the service set identifier (SSID) of the current 802.11 network.
116     * If the SSID is an ASCII string, it will be returned surrounded by double
117     * quotation marks.Otherwise, it is returned as a string of hex digits. The
118     * SSID may be {@code null} if there is no network currently connected.
119     * @return the SSID
120     */
121    public String getSSID() {
122        return mSSID;
123    }
124
125    void setBSSID(String BSSID) {
126        mBSSID = BSSID;
127    }
128
129    /**
130     * Return the basic service set identifier (BSSID) of the current access point.
131     * The BSSID may be {@code null} if there is no network currently connected.
132     * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
133     */
134    public String getBSSID() {
135        return mBSSID;
136    }
137
138    /**
139     * Returns the received signal strength indicator of the current 802.11
140     * network.
141     * <p><strong>This is not normalized, but should be!</strong></p>
142     * @return the RSSI, in the range ??? to ???
143     */
144    public int getRssi() {
145        return mRssi;
146    }
147
148    void setRssi(int rssi) {
149        mRssi = rssi;
150    }
151
152    /**
153     * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
154     * @return the link speed.
155     * @see #LINK_SPEED_UNITS
156     */
157    public int getLinkSpeed() {
158        return mLinkSpeed;
159    }
160
161    void setLinkSpeed(int linkSpeed) {
162        this.mLinkSpeed = linkSpeed;
163    }
164
165    /**
166     * Record the MAC address of the WLAN interface
167     * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
168     */
169    void setMacAddress(String macAddress) {
170        this.mMacAddress = macAddress;
171    }
172
173    public String getMacAddress() {
174        return mMacAddress;
175    }
176
177    /** {@hide} */
178    public void setMeteredHint(boolean meteredHint) {
179        mMeteredHint = meteredHint;
180    }
181
182    /** {@hide} */
183    public boolean getMeteredHint() {
184        return mMeteredHint;
185    }
186
187    void setNetworkId(int id) {
188        mNetworkId = id;
189    }
190
191    /**
192     * Each configured network has a unique small integer ID, used to identify
193     * the network when performing operations on the supplicant. This method
194     * returns the ID for the currently connected network.
195     * @return the network ID, or -1 if there is no currently connected network
196     */
197    public int getNetworkId() {
198        return mNetworkId;
199    }
200
201    /**
202     * Return the detailed state of the supplicant's negotiation with an
203     * access point, in the form of a {@link SupplicantState SupplicantState} object.
204     * @return the current {@link SupplicantState SupplicantState}
205     */
206    public SupplicantState getSupplicantState() {
207        return mSupplicantState;
208    }
209
210    void setSupplicantState(SupplicantState state) {
211        mSupplicantState = state;
212    }
213
214    void setInetAddress(InetAddress address) {
215        mIpAddress = address;
216    }
217
218    public int getIpAddress() {
219        if (mIpAddress == null || mIpAddress instanceof Inet6Address) return 0;
220        return NetworkUtils.inetAddressToInt(mIpAddress);
221    }
222
223    /**
224     * @return {@code true} if this network does not broadcast its SSID, so an
225     * SSID-specific probe request must be used for scans.
226     */
227    public boolean getHiddenSSID() {
228        return mHiddenSSID;
229    }
230
231    /** {@hide} */
232    public void setHiddenSSID(boolean hiddenSSID) {
233        mHiddenSSID = hiddenSSID;
234    }
235
236   /**
237     * Map a supplicant state into a fine-grained network connectivity state.
238     * @param suppState the supplicant state
239     * @return the corresponding {@link DetailedState}
240     */
241    public static DetailedState getDetailedStateOf(SupplicantState suppState) {
242        return stateMap.get(suppState);
243    }
244
245    /**
246     * Set the <code>SupplicantState</code> from the string name
247     * of the state.
248     * @param stateName the name of the state, as a <code>String</code> returned
249     * in an event sent by {@code wpa_supplicant}.
250     */
251    void setSupplicantState(String stateName) {
252        mSupplicantState = valueOf(stateName);
253    }
254
255    static SupplicantState valueOf(String stateName) {
256        if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
257            return SupplicantState.FOUR_WAY_HANDSHAKE;
258        else {
259            try {
260                return SupplicantState.valueOf(stateName.toUpperCase());
261            } catch (IllegalArgumentException e) {
262                return SupplicantState.INVALID;
263            }
264        }
265    }
266
267    /** {@hide} */
268    public static String removeDoubleQuotes(String string) {
269        if (string == null) return null;
270        final int length = string.length();
271        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
272            return string.substring(1, length - 1);
273        }
274        return string;
275    }
276
277    @Override
278    public String toString() {
279        StringBuffer sb = new StringBuffer();
280        String none = "<none>";
281
282        sb.append("SSID: ").append(mSSID == null ? none : mSSID).
283            append(", BSSID: ").append(mBSSID == null ? none : mBSSID).
284            append(", MAC: ").append(mMacAddress == null ? none : mMacAddress).
285            append(", Supplicant state: ").
286            append(mSupplicantState == null ? none : mSupplicantState).
287            append(", RSSI: ").append(mRssi).
288            append(", Link speed: ").append(mLinkSpeed).
289            append(", Net ID: ").append(mNetworkId).
290            append(", Metered hint: ").append(mMeteredHint);
291
292        return sb.toString();
293    }
294
295    /** Implement the Parcelable interface {@hide} */
296    public int describeContents() {
297        return 0;
298    }
299
300    /** Implement the Parcelable interface {@hide} */
301    public void writeToParcel(Parcel dest, int flags) {
302        dest.writeInt(mNetworkId);
303        dest.writeInt(mRssi);
304        dest.writeInt(mLinkSpeed);
305        if (mIpAddress != null) {
306            dest.writeByte((byte)1);
307            dest.writeByteArray(mIpAddress.getAddress());
308        } else {
309            dest.writeByte((byte)0);
310        }
311        dest.writeString(getSSID());
312        dest.writeString(mBSSID);
313        dest.writeString(mMacAddress);
314        dest.writeInt(mMeteredHint ? 1 : 0);
315        mSupplicantState.writeToParcel(dest, flags);
316    }
317
318    /** Implement the Parcelable interface {@hide} */
319    public static final Creator<WifiInfo> CREATOR =
320        new Creator<WifiInfo>() {
321            public WifiInfo createFromParcel(Parcel in) {
322                WifiInfo info = new WifiInfo();
323                info.setNetworkId(in.readInt());
324                info.setRssi(in.readInt());
325                info.setLinkSpeed(in.readInt());
326                if (in.readByte() == 1) {
327                    try {
328                        info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
329                    } catch (UnknownHostException e) {}
330                }
331                info.setSSID(in.readString());
332                info.mBSSID = in.readString();
333                info.mMacAddress = in.readString();
334                info.mMeteredHint = in.readInt() != 0;
335                info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
336                return info;
337            }
338
339            public WifiInfo[] newArray(int size) {
340                return new WifiInfo[size];
341            }
342        };
343}
344