diff options
author | Ecco Park <eccopark@google.com> | 2018-10-01 16:53:20 -0700 |
---|---|---|
committer | Ecco Park <eccopark@google.com> | 2018-10-11 13:14:23 -0700 |
commit | 53eb6d52d7e110c8e9098226b62c665c8e3bef83 (patch) | |
tree | 5ff0d166145f9fac22077dd8a5e39064b0f728f9 /service | |
parent | da556945c630d816b1a195b7d8064575857dfd4f (diff) |
passpoint-r2: sending a third SOAP message and receiving a response
Bug: 74244324
Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Test: live test with Passpoint R2 service provider AP.
Change-Id: I981b94c7bdc27e52921861af9f7d342c7c9b0e9e
Signed-off-by: Ecco Park <eccopark@google.com>
Diffstat (limited to 'service')
4 files changed, 184 insertions, 1 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; + } +} |