Merge "Handle early Success/Failure msgs for EAP-SIM."
diff --git a/src/java/com/android/ike/eap/statemachine/EapSimMethodStateMachine.java b/src/java/com/android/ike/eap/statemachine/EapSimMethodStateMachine.java
index f494911..a9e73f5 100644
--- a/src/java/com/android/ike/eap/statemachine/EapSimMethodStateMachine.java
+++ b/src/java/com/android/ike/eap/statemachine/EapSimMethodStateMachine.java
@@ -163,7 +163,16 @@
         private final String mTAG = CreatedState.class.getSimpleName();
 
         public EapResult process(EapMessage message) {
-            if (message.eapData.eapType == EAP_NOTIFICATION) {
+            if (message.eapCode == EAP_CODE_SUCCESS) {
+                // EAP-SUCCESS is required to be the last EAP message sent during the EAP protocol,
+                // so receiving a premature SUCCESS message is an unrecoverable error.
+                return new EapError(
+                        new EapInvalidRequestException(
+                                "Received an EAP-Success in the CreatedState"));
+            } else if (message.eapCode == EAP_CODE_FAILURE) {
+                transitionTo(new FinalState());
+                return new EapFailure();
+            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
                 return handleEapNotification(mTAG, message);
             }
 
@@ -218,7 +227,16 @@
         }
 
         public EapResult process(EapMessage message) {
-            if (message.eapData.eapType == EAP_NOTIFICATION) {
+            if (message.eapCode == EAP_CODE_SUCCESS) {
+                // EAP-SUCCESS is required to be the last EAP message sent during the EAP protocol,
+                // so receiving a premature SUCCESS message is an unrecoverable error.
+                return new EapError(
+                        new EapInvalidRequestException(
+                                "Received an EAP-Success in the StartState"));
+            } else if (message.eapCode == EAP_CODE_FAILURE) {
+                transitionTo(new FinalState());
+                return new EapFailure();
+            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
                 return handleEapNotification(mTAG, message);
             }
 
diff --git a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimCreatedStateTest.java b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimCreatedStateTest.java
index 20d37eb..4fadc11 100644
--- a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimCreatedStateTest.java
+++ b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimCreatedStateTest.java
@@ -17,6 +17,8 @@
 package com.android.ike.eap.statemachine;
 
 import static com.android.ike.eap.message.EapData.EAP_IDENTITY;
+import static com.android.ike.eap.message.EapMessage.EAP_CODE_FAILURE;
+import static com.android.ike.eap.message.EapMessage.EAP_CODE_SUCCESS;
 import static com.android.ike.eap.message.EapTestMessageDefinitions.ID_INT;
 
 import static org.junit.Assert.assertTrue;
@@ -28,6 +30,7 @@
 
 import com.android.ike.eap.EapResult;
 import com.android.ike.eap.EapResult.EapError;
+import com.android.ike.eap.EapResult.EapFailure;
 import com.android.ike.eap.exceptions.EapInvalidRequestException;
 import com.android.ike.eap.message.EapData;
 import com.android.ike.eap.message.EapMessage;
@@ -36,8 +39,11 @@
 import com.android.ike.eap.message.EapSimAttribute.AtVersionList;
 import com.android.ike.eap.message.EapSimTypeData;
 import com.android.ike.eap.message.EapSimTypeData.EapSimTypeDataDecoder.DecodeResult;
+import com.android.ike.eap.statemachine.EapSimMethodStateMachine.CreatedState;
+import com.android.ike.eap.statemachine.EapSimMethodStateMachine.FinalState;
 import com.android.ike.eap.statemachine.EapSimMethodStateMachine.StartState;
 
+import org.junit.Before;
 import org.junit.Test;
 
 import java.util.Arrays;
@@ -47,6 +53,32 @@
 public class EapSimCreatedStateTest extends EapSimStateTest {
     private static final int EAP_SIM_START = 10;
 
+    private CreatedState mCreatedState;
+
+    @Before
+    public void setUp() {
+        super.setUp();
+        mCreatedState = mEapSimMethodStateMachine.new CreatedState();
+    }
+
+    @Test
+    public void testProcessSuccess() throws Exception {
+        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
+        EapResult result = mCreatedState.process(input);
+
+        EapError eapError = (EapError) result;
+        assertTrue(eapError.cause instanceof EapInvalidRequestException);
+    }
+
+    @Test
+    public void testProcessFailure() throws Exception {
+        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
+        EapResult result = mCreatedState.process(input);
+        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
+
+        assertTrue(result instanceof EapFailure);
+    }
+
     @Test
     public void testTransitionToStartState() throws Exception {
         EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
diff --git a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimStartStateTest.java b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimStartStateTest.java
index 0f6ce80..992a143 100644
--- a/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimStartStateTest.java
+++ b/tests/iketests/src/java/com/android/ike/eap/statemachine/EapSimStartStateTest.java
@@ -17,6 +17,8 @@
 package com.android.ike.eap.statemachine;
 
 import static com.android.ike.eap.message.EapData.EAP_IDENTITY;
+import static com.android.ike.eap.message.EapMessage.EAP_CODE_FAILURE;
+import static com.android.ike.eap.message.EapMessage.EAP_CODE_SUCCESS;
 import static com.android.ike.eap.message.EapSimAttribute.AtNotification.GENERAL_FAILURE_POST_CHALLENGE;
 import static com.android.ike.eap.message.EapSimAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
 import static com.android.ike.eap.message.EapSimAttribute.EAP_AT_ANY_ID_REQ;
@@ -44,6 +46,7 @@
 
 import com.android.ike.eap.EapResult;
 import com.android.ike.eap.EapResult.EapError;
+import com.android.ike.eap.EapResult.EapFailure;
 import com.android.ike.eap.EapResult.EapResponse;
 import com.android.ike.eap.exceptions.EapInvalidRequestException;
 import com.android.ike.eap.exceptions.EapSimIdentityUnavailableException;
@@ -58,6 +61,7 @@
 import com.android.ike.eap.message.EapSimAttribute.AtVersionList;
 import com.android.ike.eap.message.EapSimTypeData;
 import com.android.ike.eap.message.EapSimTypeData.EapSimTypeDataDecoder.DecodeResult;
+import com.android.ike.eap.statemachine.EapSimMethodStateMachine.FinalState;
 import com.android.ike.eap.statemachine.EapSimMethodStateMachine.StartState;
 
 import org.junit.Before;
@@ -82,6 +86,24 @@
     }
 
     @Test
+    public void testProcessSuccess() throws Exception {
+        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
+        EapResult result = mStartState.process(input);
+
+        EapError eapError = (EapError) result;
+        assertTrue(eapError.cause instanceof EapInvalidRequestException);
+    }
+
+    @Test
+    public void testProcessFailure() throws Exception {
+        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
+        EapResult result = mStartState.process(input);
+        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
+
+        assertTrue(result instanceof EapFailure);
+    }
+
+    @Test
     public void testProcessIncorrectEapMethodType() throws Exception {
         EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA);
         EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);