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.Parcel;
20 import android.os.Parcelable;
21 
22 /**
23  * From <code>defs.h</code> in <code>wpa_supplicant</code>.
24  * <p/>
25  * These enumeration values are used to indicate the current wpa_supplicant
26  * state. This is more fine-grained than most users will be interested in.
27  * In general, it is better to use
28  * {@link android.net.NetworkInfo.State NetworkInfo.State}.
29  * <p/>
30  * Note, the order of these enum constants must match the numerical values of the
31  * state constants in <code>defs.h</code> in <code>wpa_supplicant</code>.
32  */
33 public enum SupplicantState implements Parcelable {
34     /**
35      * This state indicates that client is not associated, but is likely to
36      * start looking for an access point. This state is entered when a
37      * connection is lost.
38      */
39     DISCONNECTED,
40 
41     /**
42      * Interface is disabled
43      * <p/>
44      * This state is entered if the network interface is disabled.
45      * wpa_supplicant refuses any new operations that would
46      * use the radio until the interface has been enabled.
47      */
48     INTERFACE_DISABLED,
49 
50     /**
51      * Inactive state (wpa_supplicant disabled).
52      * <p/>
53      * This state is entered if there are no enabled networks in the
54      * configuration. wpa_supplicant is not trying to associate with a new
55      * network and external interaction (e.g., ctrl_iface call to add or
56      * enable a network) is needed to start association.
57      */
58     INACTIVE,
59 
60     /**
61      * Scanning for a network.
62      * <p/>
63      * This state is entered when wpa_supplicant starts scanning for a
64      * network.
65      */
66     SCANNING,
67 
68     /**
69      * Trying to authenticate with a BSS/SSID
70      * <p/>
71      * This state is entered when wpa_supplicant has found a suitable BSS
72      * to authenticate with and the driver is configured to try to
73      * authenticate with this BSS.
74      */
75     AUTHENTICATING,
76 
77     /**
78      * Trying to associate with a BSS/SSID.
79      * <p/>
80      * This state is entered when wpa_supplicant has found a suitable BSS
81      * to associate with and the driver is configured to try to associate
82      * with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
83      * state is entered when the driver is configured to try to associate
84      * with a network using the configured SSID and security policy.
85      */
86     ASSOCIATING,
87 
88     /**
89      * Association completed.
90      * <p/>
91      * This state is entered when the driver reports that association has
92      * been successfully completed with an AP. If IEEE 802.1X is used
93      * (with or without WPA/WPA2), wpa_supplicant remains in this state
94      * until the IEEE 802.1X/EAPOL authentication has been completed.
95      */
96     ASSOCIATED,
97 
98     /**
99      * WPA 4-Way Key Handshake in progress.
100      * <p/>
101      * This state is entered when WPA/WPA2 4-Way Handshake is started. In
102      * case of WPA-PSK, this happens when receiving the first EAPOL-Key
103      * frame after association. In case of WPA-EAP, this state is entered
104      * when the IEEE 802.1X/EAPOL authentication has been completed.
105      */
106     FOUR_WAY_HANDSHAKE,
107 
108     /**
109      * WPA Group Key Handshake in progress.
110      * <p/>
111      * This state is entered when 4-Way Key Handshake has been completed
112      * (i.e., when the supplicant sends out message 4/4) and when Group
113      * Key rekeying is started by the AP (i.e., when supplicant receives
114      * message 1/2).
115      */
116     GROUP_HANDSHAKE,
117 
118     /**
119      * All authentication completed.
120      * <p/>
121      * This state is entered when the full authentication process is
122      * completed. In case of WPA2, this happens when the 4-Way Handshake is
123      * successfully completed. With WPA, this state is entered after the
124      * Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
125      * completed after dynamic keys are received (or if not used, after
126      * the EAP authentication has been completed). With static WEP keys and
127      * plaintext connections, this state is entered when an association
128      * has been completed.
129      * <p/>
130      * This state indicates that the supplicant has completed its
131      * processing for the association phase and that data connection is
132      * fully configured. Note, however, that there may not be any IP
133      * address associated with the connection yet. Typically, a DHCP
134      * request needs to be sent at this point to obtain an address.
135      */
136     COMPLETED,
137 
138     /**
139      * An Android-added state that is reported when a client issues an
140      * explicit DISCONNECT command. In such a case, the supplicant is
141      * not only dissociated from the current access point (as for the
142      * DISCONNECTED state above), but it also does not attempt to connect
143      * to any access point until a RECONNECT or REASSOCIATE command
144      * is issued by the client.
145      */
146     DORMANT,
147 
148     /**
149      * No connection to wpa_supplicant.
150      * <p/>
151      * This is an additional pseudo-state to handle the case where
152      * wpa_supplicant is not running and/or we have not been able
153      * to establish a connection to it.
154      */
155     UNINITIALIZED,
156 
157     /**
158      * A pseudo-state that should normally never be seen.
159      */
160     INVALID;
161 
162     /**
163      * Returns {@code true} if the supplicant state is valid and {@code false}
164      * otherwise.
165      * @param state The supplicant state
166      * @return {@code true} if the supplicant state is valid and {@code false}
167      * otherwise.
168      */
isValidState(SupplicantState state)169     public static boolean isValidState(SupplicantState state) {
170         return state != UNINITIALIZED && state != INVALID;
171     }
172 
173 
174     /** Supplicant associating or authenticating is considered a handshake state {@hide} */
isHandshakeState(SupplicantState state)175     public static boolean isHandshakeState(SupplicantState state) {
176         switch(state) {
177             case AUTHENTICATING:
178             case ASSOCIATING:
179             case ASSOCIATED:
180             case FOUR_WAY_HANDSHAKE:
181             case GROUP_HANDSHAKE:
182                 return true;
183             case COMPLETED:
184             case DISCONNECTED:
185             case INTERFACE_DISABLED:
186             case INACTIVE:
187             case SCANNING:
188             case DORMANT:
189             case UNINITIALIZED:
190             case INVALID:
191                 return false;
192             default:
193                 throw new IllegalArgumentException("Unknown supplicant state");
194         }
195     }
196 
197     /** @hide */
isConnecting(SupplicantState state)198     public static boolean isConnecting(SupplicantState state) {
199         switch(state) {
200             case AUTHENTICATING:
201             case ASSOCIATING:
202             case ASSOCIATED:
203             case FOUR_WAY_HANDSHAKE:
204             case GROUP_HANDSHAKE:
205             case COMPLETED:
206                 return true;
207             case DISCONNECTED:
208             case INTERFACE_DISABLED:
209             case INACTIVE:
210             case SCANNING:
211             case DORMANT:
212             case UNINITIALIZED:
213             case INVALID:
214                 return false;
215             default:
216                 throw new IllegalArgumentException("Unknown supplicant state");
217         }
218     }
219 
220     /** @hide */
isDriverActive(SupplicantState state)221     public static boolean isDriverActive(SupplicantState state) {
222         switch(state) {
223             case DISCONNECTED:
224             case DORMANT:
225             case INACTIVE:
226             case AUTHENTICATING:
227             case ASSOCIATING:
228             case ASSOCIATED:
229             case SCANNING:
230             case FOUR_WAY_HANDSHAKE:
231             case GROUP_HANDSHAKE:
232             case COMPLETED:
233                 return true;
234             case INTERFACE_DISABLED:
235             case UNINITIALIZED:
236             case INVALID:
237                 return false;
238             default:
239                 throw new IllegalArgumentException("Unknown supplicant state");
240         }
241     }
242 
243     /** Implement the Parcelable interface {@hide} */
describeContents()244     public int describeContents() {
245         return 0;
246     }
247 
248     /** Implement the Parcelable interface {@hide} */
writeToParcel(Parcel dest, int flags)249     public void writeToParcel(Parcel dest, int flags) {
250         dest.writeString(name());
251     }
252 
253     /** Implement the Parcelable interface {@hide} */
254     public static final @android.annotation.NonNull Creator<SupplicantState> CREATOR =
255         new Creator<SupplicantState>() {
256             public SupplicantState createFromParcel(Parcel in) {
257                 return SupplicantState.valueOf(in.readString());
258             }
259 
260             public SupplicantState[] newArray(int size) {
261                 return new SupplicantState[size];
262             }
263         };
264 
265 }
266