Merge "Handle EAP authentication failure" into honeycomb
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index f96a5ae..3cde949 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -31,7 +31,7 @@
  * Tracks the state changes in supplicant and provides functionality
  * that is based on these state changes:
  * - detect a failed WPA handshake that loops indefinitely
- * - password failure handling
+ * - authentication failure handling
  */
 class SupplicantStateTracker extends HierarchicalStateMachine {
 
@@ -39,14 +39,14 @@
     private static final boolean DBG = false;
 
     private WifiStateMachine mWifiStateMachine;
-    private int mPasswordFailuresCount = 0;
+    private int mAuthenticationFailuresCount = 0;
     /* Indicates authentication failure in supplicant broadcast.
      * TODO: enhance auth failure reporting to include notification
      * for all type of failures: EAP, WPS & WPA networks */
     private boolean mAuthFailureInSupplicantBroadcast = false;
 
-    /* Maximum retries on a password failure notification */
-    private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
+    /* Maximum retries on a authentication failure notification */
+    private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
 
     /* Tracks if networks have been disabled during a connection */
     private boolean mNetworksDisabledDuringConnect = false;
@@ -155,8 +155,8 @@
         public boolean processMessage(Message message) {
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             switch (message.what) {
-                case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
-                    mPasswordFailuresCount++;
+                case WifiStateMachine.AUTHENTICATION_FAILURE_EVENT:
+                    mAuthenticationFailuresCount++;
                     mAuthFailureInSupplicantBroadcast = true;
                     break;
                 case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
@@ -206,18 +206,17 @@
         @Override
          public void enter() {
              if (DBG) Log.d(TAG, getName() + "\n");
-             /* If a disconnect event happens after password key failure
+             /* If a disconnect event happens after authentication failure
               * exceeds maximum retries, disable the network
               */
-
              Message message = getCurrentMessage();
              StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
 
-             if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
+             if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
                  Log.d(TAG, "Failed to authenticate, disabling network " +
                          stateChangeResult.networkId);
                  handleNetworkConnectionFailure(stateChangeResult.networkId);
-                 mPasswordFailuresCount = 0;
+                 mAuthenticationFailuresCount = 0;
              }
          }
     }
@@ -282,8 +281,8 @@
         @Override
          public void enter() {
              if (DBG) Log.d(TAG, getName() + "\n");
-             /* Reset password failure count */
-             mPasswordFailuresCount = 0;
+             /* Reset authentication failure count */
+             mAuthenticationFailuresCount = 0;
              if (mNetworksDisabledDuringConnect) {
                  WifiConfigStore.enableAllNetworks();
                  mNetworksDisabledDuringConnect = false;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 090ad3b..ce38261 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -42,7 +42,8 @@
     private static final int LINK_SPEED   = 5;
     private static final int TERMINATING  = 6;
     private static final int DRIVER_STATE = 7;
-    private static final int UNKNOWN      = 8;
+    private static final int EAP_FAILURE  = 8;
+    private static final int UNKNOWN      = 9;
 
     /** All events coming from the supplicant start with this prefix */
     private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@
      * <code>state</code> is either STARTED or STOPPED
      */
     private static final String driverStateEvent = "DRIVER-STATE";
+    /**
+     * <pre>
+     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
+     * </pre>
+     */
+    private static final String eapFailureEvent = "EAP-FAILURE";
+
+    /**
+     * This indicates an authentication failure on EAP FAILURE event
+     */
+    private static final String eapAuthFailure = "EAP authentication failed";
 
     /**
      * Regex pattern for extracting an Ethernet-style MAC address from a string.
@@ -176,7 +188,7 @@
                 if (!eventStr.startsWith(eventPrefix)) {
                     if (eventStr.startsWith(wpaEventPrefix) &&
                             0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
-                        handlePasswordKeyMayBeIncorrect();
+                        mWifiStateMachine.notifyAuthenticationFailure();
                     } else if (eventStr.startsWith(wpsOverlapEvent)) {
                         mWifiStateMachine.notifyWpsOverlap();
                     }
@@ -207,16 +219,17 @@
                     event = LINK_SPEED;
                 else if (eventName.equals(terminatingEvent))
                     event = TERMINATING;
-                else if (eventName.equals(driverStateEvent)) {
+                else if (eventName.equals(driverStateEvent))
                     event = DRIVER_STATE;
-                }
+                else if (eventName.equals(eapFailureEvent))
+                    event = EAP_FAILURE;
                 else
                     event = UNKNOWN;
 
                 String eventData = eventStr;
                 if (event == DRIVER_STATE || event == LINK_SPEED)
                     eventData = eventData.split(" ")[1];
-                else if (event == STATE_CHANGE) {
+                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
                     int ind = eventStr.indexOf(" ");
                     if (ind != -1) {
                         eventData = eventStr.substring(ind + 1);
@@ -261,6 +274,10 @@
                     // notify and exit
                     mWifiStateMachine.notifySupplicantLost();
                     break;
+                } else if (event == EAP_FAILURE) {
+                    if (eventData.startsWith(eapAuthFailure)) {
+                        mWifiStateMachine.notifyAuthenticationFailure();
+                    }
                 } else {
                     handleEvent(event, eventData);
                 }
@@ -284,10 +301,6 @@
             return false;
         }
 
-        private void handlePasswordKeyMayBeIncorrect() {
-            mWifiStateMachine.notifyPasswordKeyMayBeIncorrect();
-        }
-
         private void handleDriverEvent(String state) {
             if (state == null) {
                 return;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index df21399..4d0acdd 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -212,8 +212,8 @@
     static final int SCAN_RESULTS_EVENT                   = 38;
     /* Supplicate state changed */
     static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
-    /* Password may be incorrect */
-    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
+    /* Password failure and EAP authentication failure */
+    static final int AUTHENTICATION_FAILURE_EVENT         = 40;
     /* WPS overlap detected */
     static final int WPS_OVERLAP_EVENT                    = 41;
 
@@ -1383,11 +1383,12 @@
     }
 
     /**
-     * Send the tracker a notification that a user-entered password key
-     * may be incorrect (i.e., caused authentication to fail).
+     * Send the tracker a notification that a user provided
+     * configuration caused authentication failure - this could
+     * be a password failure or a EAP authentication failure
      */
-    void notifyPasswordKeyMayBeIncorrect() {
-        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+    void notifyAuthenticationFailure() {
+        sendMessage(AUTHENTICATION_FAILURE_EVENT);
     }
 
     /**
@@ -1515,7 +1516,7 @@
                 case NETWORK_DISCONNECTION_EVENT:
                 case SCAN_RESULTS_EVENT:
                 case SUPPLICANT_STATE_CHANGE_EVENT:
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
+                case AUTHENTICATION_FAILURE_EVENT:
                 case WPS_OVERLAP_EVENT:
                 case CMD_BLACKLIST_NETWORK:
                 case CMD_CLEAR_BLACKLIST:
@@ -2067,7 +2068,7 @@
                 case SUPPLICANT_STATE_CHANGE_EVENT:
                 case NETWORK_CONNECTION_EVENT:
                 case NETWORK_DISCONNECTION_EVENT:
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
+                case AUTHENTICATION_FAILURE_EVENT:
                 case WPS_OVERLAP_EVENT:
                 case CMD_SET_SCAN_TYPE:
                 case CMD_SET_HIGH_PERF_MODE:
@@ -2300,8 +2301,8 @@
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             StateChangeResult stateChangeResult;
             switch(message.what) {
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
-                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+                case AUTHENTICATION_FAILURE_EVENT:
+                    mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
                     break;
                 case WPS_OVERLAP_EVENT:
                     /* We just need to broadcast the error */