summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEcco Park <eccopark@google.com>2018-10-15 13:15:58 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-10-15 13:15:58 +0000
commit1ff63057eb276526c10e8aab0f8b6687cca38cfe (patch)
treec237b83c5f3b523761d53e1d6b55dbc74ba6bb85
parent1bcfb32f1e784e64d8b956732725b314765a8e29 (diff)
parent53eb6d52d7e110c8e9098226b62c665c8e3bef83 (diff)
Merge "passpoint-r2: sending a third SOAP message and receiving a response"
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java62
-rw-r--r--service/java/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessage.java52
-rw-r--r--service/java/com/android/server/wifi/hotspot2/soap/SoapParser.java3
-rw-r--r--service/java/com/android/server/wifi/hotspot2/soap/UpdateResponseMessage.java68
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java43
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java65
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java91
7 files changed, 381 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
index 825ffe388..25073506e 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
@@ -34,11 +34,13 @@ import android.os.UserHandle;
import android.util.Log;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.hotspot2.soap.ExchangeCompleteMessage;
import com.android.server.wifi.hotspot2.soap.PostDevDataMessage;
import com.android.server.wifi.hotspot2.soap.PostDevDataResponse;
import com.android.server.wifi.hotspot2.soap.RedirectListener;
import com.android.server.wifi.hotspot2.soap.SppConstants;
import com.android.server.wifi.hotspot2.soap.SppResponseMessage;
+import com.android.server.wifi.hotspot2.soap.UpdateResponseMessage;
import com.android.server.wifi.hotspot2.soap.command.BrowserUri;
import com.android.server.wifi.hotspot2.soap.command.PpsMoData;
import com.android.server.wifi.hotspot2.soap.command.SppCommand;
@@ -151,6 +153,7 @@ public class PasspointProvisioner {
static final int STATE_WAITING_FOR_FIRST_SOAP_RESPONSE = 5;
static final int STATE_WAITING_FOR_REDIRECT_RESPONSE = 6;
static final int STATE_WAITING_FOR_SECOND_SOAP_RESPONSE = 7;
+ static final int STATE_WAITING_FOR_THIRD_SOAP_RESPONSE = 8;
private OsuProvider mOsuProvider;
private IProvisioningCallback mProvisioningCallback;
@@ -429,7 +432,37 @@ public class PasspointProvisioner {
PasspointConfiguration passpointConfig = buildPasspointConfiguration(
(PpsMoData) devDataResponse.getSppCommand().getCommandData());
- // TODO(b/74244324): Implement a routine to transmit third SOAP message.
+ thirdSoapExchange(passpointConfig == null);
+ } else if (mState == STATE_WAITING_FOR_THIRD_SOAP_RESPONSE) {
+ if (responseMessage.getMessageType()
+ != SppResponseMessage.MessageType.EXCHANGE_COMPLETE) {
+ Log.e(TAG, "Expected a ExchangeCompleteMessage, but got "
+ + responseMessage.getMessageType());
+ resetStateMachine(
+ ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE);
+ return;
+ }
+
+ ExchangeCompleteMessage exchangeCompleteMessage =
+ (ExchangeCompleteMessage) responseMessage;
+ if (exchangeCompleteMessage.getStatus()
+ != SppConstants.SppStatus.EXCHANGE_COMPLETE) {
+ Log.e(TAG, "Expected a ExchangeCompleteMessage Status, but got "
+ + exchangeCompleteMessage.getStatus());
+ resetStateMachine(
+ ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS);
+ return;
+ }
+
+ if (exchangeCompleteMessage.getError() != SppConstants.INVALID_SPP_CONSTANT) {
+ Log.e(TAG,
+ "In the SppExchangeComplete, got error "
+ + exchangeCompleteMessage.getError());
+ resetStateMachine(ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED);
+ return;
+ }
+
+ // TODO(b/74244324): Implement a routine to get CAs for AAA, Remediation, Policy.
} else {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Received an unexpected SOAP message in state=" + mState);
@@ -629,6 +662,33 @@ public class PasspointProvisioner {
}
}
+ /**
+ * Initiates the third SOAP message exchange with sending the sppUpdateResponse message.
+ */
+ private void thirdSoapExchange(boolean isError) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Initiates the third soap message exchange in state =" + mState);
+ }
+
+ if (mState != STATE_WAITING_FOR_SECOND_SOAP_RESPONSE) {
+ Log.e(TAG, "Initiates the third soap message exchange in wrong state=" + mState);
+ resetStateMachine(ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED);
+ return;
+ }
+
+ // Sending the sppUpdateResponse message.
+ if (mOsuServerConnection.exchangeSoapMessage(
+ UpdateResponseMessage.serializeToSoapEnvelope(mSessionId, isError))) {
+ invokeProvisioningCallback(PROVISIONING_STATUS,
+ ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE);
+ changeState(STATE_WAITING_FOR_THIRD_SOAP_RESPONSE);
+ } else {
+ Log.e(TAG, "HttpsConnection is not established for soap message exchange");
+ resetStateMachine(ProvisioningCallback.OSU_FAILURE_SOAP_MESSAGE_EXCHANGE);
+ return;
+ }
+ }
+
private PasspointConfiguration buildPasspointConfiguration(@NonNull PpsMoData moData) {
String moTree = moData.getPpsMoTree();
diff --git a/service/java/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessage.java b/service/java/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessage.java
new file mode 100644
index 000000000..a07e9c787
--- /dev/null
+++ b/service/java/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessage.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.hotspot2.soap;
+
+import android.annotation.NonNull;
+import android.util.Log;
+
+import org.ksoap2.serialization.SoapObject;
+
+/**
+ * Represents the sppExchangeComplete message sent by the server.
+ * For the details, refer to A.3.2 section in Hotspot2.0 rel2 specification.
+ */
+public class ExchangeCompleteMessage extends SppResponseMessage {
+ private static final String TAG = "ExchangeCompleteMessage";
+
+ private ExchangeCompleteMessage(@NonNull SoapObject response) throws IllegalArgumentException {
+ super(response, MessageType.EXCHANGE_COMPLETE);
+ }
+
+ /**
+ * create an instance of {@link ExchangeCompleteMessage}
+ *
+ * @param response SOAP response message received from server.
+ * @return Instance of {@link ExchangeCompleteMessage}, {@code null} in any failure.
+ */
+ public static ExchangeCompleteMessage createInstance(@NonNull SoapObject response) {
+ ExchangeCompleteMessage exchangeCompleteMessage;
+
+ try {
+ exchangeCompleteMessage = new ExchangeCompleteMessage(response);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "fails to create an Instance: " + e);
+ return null;
+ }
+ return exchangeCompleteMessage;
+ }
+}
diff --git a/service/java/com/android/server/wifi/hotspot2/soap/SoapParser.java b/service/java/com/android/server/wifi/hotspot2/soap/SoapParser.java
index cb7270b48..e8f725440 100644
--- a/service/java/com/android/server/wifi/hotspot2/soap/SoapParser.java
+++ b/service/java/com/android/server/wifi/hotspot2/soap/SoapParser.java
@@ -37,6 +37,9 @@ public class SoapParser {
case "sppPostDevDataResponse":
responseMessage = PostDevDataResponse.createInstance(response);
break;
+ case "sppExchangeComplete":
+ responseMessage = ExchangeCompleteMessage.createInstance(response);
+ break;
default:
responseMessage = null;
}
diff --git a/service/java/com/android/server/wifi/hotspot2/soap/UpdateResponseMessage.java b/service/java/com/android/server/wifi/hotspot2/soap/UpdateResponseMessage.java
new file mode 100644
index 000000000..53c2a5e78
--- /dev/null
+++ b/service/java/com/android/server/wifi/hotspot2/soap/UpdateResponseMessage.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.hotspot2.soap;
+
+import android.annotation.NonNull;
+
+import org.ksoap2.SoapEnvelope;
+import org.ksoap2.serialization.SoapObject;
+import org.ksoap2.serialization.SoapSerializationEnvelope;
+
+/**
+ * This class represents sppUpdateResponse message, as part of the
+ * Subscription Provisioning Protocol.
+ * For the detail, refer to the Hotspot 2.0 rel2 specification.
+ */
+public class UpdateResponseMessage {
+
+ /**
+ * Serialize the given request to a SOAP envelope.
+ *
+ * @param sessionId session id generated by the server to identify the session between device
+ * and server.
+ * @param isError {@code true} if the error happens during updating or installing PPS MO.
+ * @return {@link SoapSerializationEnvelope}
+ */
+ public static SoapSerializationEnvelope serializeToSoapEnvelope(@NonNull String sessionId,
+ boolean isError) {
+ SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
+ envelope.implicitTypes = true; // Do not include type in element attribute
+ envelope.setAddAdornments(false); // Do not generate/include IDs for each element
+
+ SoapObject requestObject =
+ new SoapObject(SoapEnvelope.NS20, SppConstants.METHOD_UPDATE_RESPONSE);
+ requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_VERSION,
+ SppConstants.SUPPORTED_SPP_VERSION);
+ requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SESSION_ID, sessionId);
+ if (isError) {
+ requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_STATUS,
+ SppConstants.mapStatusIntToString(SppConstants.SppStatus.ERROR));
+ SoapObject sppError =
+ new SoapObject(SoapEnvelope.NS20, SppConstants.PROPERTY_SPP_ERROR);
+ sppError.addAttribute(SppConstants.ATTRIBUTE_ERROR_CODE,
+ SppConstants.mapErrorIntToString(
+ SppConstants.SppError.MO_ADD_OR_UPDATE_FAILED));
+ requestObject.addProperty(SoapEnvelope.NS20, SppConstants.PROPERTY_SPP_ERROR, sppError);
+ } else {
+ requestObject.addAttribute(SoapEnvelope.NS20, SppConstants.ATTRIBUTE_SPP_STATUS,
+ SppConstants.mapStatusIntToString(SppConstants.SppStatus.OK));
+ }
+
+ envelope.setOutputSoapObject(requestObject);
+ return envelope;
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
index 4b5a822d3..2214d53d3 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProvisionerTest.java
@@ -50,8 +50,10 @@ import android.telephony.TelephonyManager;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.org.conscrypt.TrustManagerImpl;
import com.android.server.wifi.WifiNative;
+import com.android.server.wifi.hotspot2.soap.ExchangeCompleteMessage;
import com.android.server.wifi.hotspot2.soap.PostDevDataResponse;
import com.android.server.wifi.hotspot2.soap.RedirectListener;
+import com.android.server.wifi.hotspot2.soap.SppConstants;
import com.android.server.wifi.hotspot2.soap.SppResponseMessage;
import com.android.server.wifi.hotspot2.soap.command.BrowserUri;
import com.android.server.wifi.hotspot2.soap.command.PpsMoData;
@@ -83,6 +85,7 @@ public class PasspointProvisionerTest {
private static final int STEP_SERVER_CONNECT = 2;
private static final int STEP_WAIT_FOR_REDIRECT_RESPONSE = 3;
private static final int STEP_WAIT_FOR_SECOND_SOAP_RESPONSE = 4;
+ private static final int STEP_WAIT_FOR_THIRD_SOAP_RESPONSE = 5;
private static final String TEST_DEV_ID = "12312341";
private static final String TEST_MANUFACTURER = Build.MANUFACTURER;
@@ -130,6 +133,7 @@ public class PasspointProvisionerTest {
@Mock SSLContext mTlsContext;
@Mock WifiNative mWifiNative;
@Mock PostDevDataResponse mSppResponseMessage;
+ @Mock ExchangeCompleteMessage mExchangeCompleteMessage;
@Mock SystemInfo mSystemInfo;
@Mock TelephonyManager mTelephonyManager;
@Mock SppCommand mSppCommand;
@@ -184,6 +188,12 @@ public class PasspointProvisionerTest {
when(mSystemInfo.getFirmwareVersion()).thenReturn(TEST_FW_VERSION);
when(mTelephonyManager.getSubscriberId()).thenReturn(TEST_IMSI);
+ when(mExchangeCompleteMessage.getMessageType()).thenReturn(
+ SppResponseMessage.MessageType.EXCHANGE_COMPLETE);
+ when(mExchangeCompleteMessage.getStatus()).thenReturn(
+ SppConstants.SppStatus.EXCHANGE_COMPLETE);
+ when(mExchangeCompleteMessage.getSessionID()).thenReturn(TEST_SESSION_ID);
+ when(mExchangeCompleteMessage.getError()).thenReturn(SppConstants.INVALID_SPP_CONSTANT);
when(mSppResponseMessage.getMessageType()).thenReturn(
SppResponseMessage.MessageType.POST_DEV_DATA_RESPONSE);
when(mSppResponseMessage.getSppCommand()).thenReturn(mSppCommand);
@@ -291,7 +301,14 @@ public class PasspointProvisionerTest {
mOsuServerCallbacks.onReceivedSoapMessage(mOsuServerCallbacks.getSessionId(),
mSppResponseMessage);
mLooper.dispatchAll();
+ } else if (step == STEP_WAIT_FOR_THIRD_SOAP_RESPONSE) {
+ verify(mCallback).onProvisioningStatus(
+ ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE);
+ // Received a third soapMessageResponse
+ mOsuServerCallbacks.onReceivedSoapMessage(mOsuServerCallbacks.getSessionId(),
+ mExchangeCompleteMessage);
+ mLooper.dispatchAll();
}
}
}
@@ -581,7 +598,7 @@ public class PasspointProvisionerTest {
/**
* Verifies that the right provisioning callbacks are invoked when a command of a second soap
- * response is not for ADD MO command.
+ * response {@link PostDevDataResponse} is not for ADD MO command.
*/
@Test
public void verifyNotAddMoCommandFailureForSecondSoapResponse() throws RemoteException {
@@ -607,12 +624,34 @@ public class PasspointProvisionerTest {
}
/**
+ * Verifies that the right provisioning callbacks are invoked when a message of a third soap
+ * response {@link ExchangeCompleteMessage} has an error property.
+ */
+ @Test
+ public void verifyHandlingErrorPropertyInThirdSoapResponse() throws RemoteException {
+ when(mExchangeCompleteMessage.getError()).thenReturn(
+ SppConstants.SppError.PROVISIONING_FAILED);
+ stopAfterStep(STEP_WAIT_FOR_SECOND_SOAP_RESPONSE);
+
+ verify(mCallback).onProvisioningStatus(
+ ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE);
+
+ // Received a third soapMessageResponse
+ mOsuServerCallbacks.onReceivedSoapMessage(mOsuServerCallbacks.getSessionId(),
+ mExchangeCompleteMessage);
+ mLooper.dispatchAll();
+
+ verify(mCallback).onProvisioningFailure(
+ ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED);
+ }
+
+ /**
* Verifies that the right provisioning callbacks are invoked as the provisioner progresses
* to the end as successful case.
*/
@Test
public void verifyProvisioningFlowForSuccessfulCase() throws RemoteException {
- stopAfterStep(STEP_WAIT_FOR_SECOND_SOAP_RESPONSE);
+ stopAfterStep(STEP_WAIT_FOR_THIRD_SOAP_RESPONSE);
// No further runnables posted
verifyNoMoreInteractions(mCallback);
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java
new file mode 100644
index 000000000..dcddb5380
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/ExchangeCompleteMessageTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.hotspot2.soap;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.ksoap2.serialization.SoapObject;
+
+/**
+ * Unit tests for {@link ExchangeCompleteMessage}.
+ */
+@SmallTest
+public class ExchangeCompleteMessageTest {
+ private static final String TEST_STATUS = "OK";
+ private static final String TEST_SESSION_ID = "D215D696517BA138F1D28442DF0F4E07";
+ private static final String TEST_VERSION = "1.0";
+
+ private ExchangeCompleteMessage mExchangeCompleteMessage;
+
+ /**
+ * Verify if the ExchangeCompleteMessage message is properly parsed.
+ */
+ @Test
+ public void verifyValidExchangeComplete() {
+ SoapObject response = new SoapObject();
+ response.addAttribute(SppResponseMessage.SPPStatusAttribute, TEST_STATUS);
+ response.addAttribute(SppResponseMessage.SPPSessionIDAttribute, TEST_SESSION_ID);
+ response.addAttribute(SppResponseMessage.SPPVersionAttribute, TEST_VERSION);
+
+ mExchangeCompleteMessage = ExchangeCompleteMessage.createInstance(response);
+
+ assertNotNull(mExchangeCompleteMessage);
+ }
+
+ /**
+ * Verify if the exchangeComplete message missing session id will return {@code null}
+ */
+ @Test
+ public void verifyInvalidExchangeCompleteReturnNull() {
+ SoapObject response = new SoapObject();
+ response.addAttribute(SppResponseMessage.SPPStatusAttribute, TEST_STATUS);
+ response.addAttribute(SppResponseMessage.SPPVersionAttribute, TEST_VERSION);
+ mExchangeCompleteMessage = ExchangeCompleteMessage.createInstance(response);
+
+ assertNull(mExchangeCompleteMessage);
+ }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java
new file mode 100644
index 000000000..edda5273e
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/soap/UpdateResponseMessageTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.hotspot2.soap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.ksoap2.SoapEnvelope;
+import org.ksoap2.serialization.SoapObject;
+import org.ksoap2.serialization.SoapSerializationEnvelope;
+
+/**
+ * Unit tests for {@link UpdateResponseMessage}.
+ */
+@SmallTest
+public class UpdateResponseMessageTest {
+ private static final String TEST_SESSION_ID = "123456";
+
+ /**
+ * Verify the request is organized correctly with a session id.
+ */
+ @Test
+ public void serializeUpdateResponseMessageWithSessionIdWithoutError() {
+ SoapSerializationEnvelope request = UpdateResponseMessage.serializeToSoapEnvelope(
+ TEST_SESSION_ID, false);
+ assertNotNull(request);
+ assertEquals(SoapEnvelope.VER12, request.version);
+ SoapObject soapRequest = (SoapObject) request.bodyOut;
+ verifyCommonFields(soapRequest);
+
+ // Should have an OK status attribute
+ assertEquals(SppConstants.mapStatusIntToString(SppConstants.SppStatus.OK),
+ soapRequest.getAttributeAsString(SoapEnvelope.NS20,
+ SppConstants.ATTRIBUTE_SPP_STATUS));
+ }
+
+ /**
+ * Verify the request is organized correctly with a session id and an error.
+ */
+ @Test
+ public void serializeUpdateResponseMessageWithError() {
+ SoapSerializationEnvelope request = UpdateResponseMessage.serializeToSoapEnvelope(
+ TEST_SESSION_ID, true);
+ assertNotNull(request);
+ assertEquals(SoapEnvelope.VER12, request.version);
+ SoapObject soapRequest = (SoapObject) request.bodyOut;
+ verifyCommonFields(soapRequest);
+
+ // Should have an error status attribute
+ assertEquals(SppConstants.mapStatusIntToString(SppConstants.SppStatus.ERROR),
+ soapRequest.getAttributeAsString(SoapEnvelope.NS20,
+ SppConstants.ATTRIBUTE_SPP_STATUS));
+ assertEquals(1, soapRequest.getPropertyCount());
+
+ SoapObject sppError = (SoapObject) soapRequest.getProperty(0);
+ assertNotNull(sppError);
+ assertEquals(sppError.getNamespace(), SoapEnvelope.NS20);
+ assertEquals(
+ SppConstants.mapErrorIntToString(SppConstants.SppError.MO_ADD_OR_UPDATE_FAILED),
+ sppError.getAttributeAsString(SppConstants.ATTRIBUTE_ERROR_CODE));
+ }
+
+ private void verifyCommonFields(SoapObject request) {
+ assertEquals(request.getNamespace(), SoapEnvelope.NS20);
+ assertEquals(request.getName(), SppConstants.METHOD_UPDATE_RESPONSE);
+ assertEquals(SppConstants.SUPPORTED_SPP_VERSION,
+ request.getAttributeAsString(SoapEnvelope.NS20,
+ SppConstants.ATTRIBUTE_SPP_VERSION));
+
+ // Should have a session id attribute
+ assertEquals(TEST_SESSION_ID, request.getAttributeAsString(SoapEnvelope.NS20,
+ SppConstants.ATTRIBUTE_SESSION_ID));
+ }
+}