WifiInfo.java revision 8dc6a1b2823f374a176fb21b8a174664a5f825fa
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
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