summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorEcco Park <eccopark@google.com>2018-10-24 13:01:27 -0700
committerEcco Park <eccopark@google.com>2018-11-02 03:54:17 +0000
commit5c519d75cd477f51afc3c4c0ee3c6096e9a5131f (patch)
tree0ea08c233de95171eddfe2d23606515adda3b30b /service
parente77a84b320e776d0e783d87b492d5f80ac6f9648 (diff)
passpoint-r2: make the connect function of OsuServerConnection async call
1) Currently connection function in OsuServerConnection class calls HttpsURLConnection.connect, which is blocking function. So, if caller(PasspointProvisioner) might be blocked until connection is established or timeout in the connection function. It needs to be changed to non-blocking call. 2) Remove unnecessary states in ProvisioingStateMachine Bug: 117728536 Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Test: live test with Passpoint R2 service provider AP Change-Id: I51dc1cfdd8ec0bcaab599009a1ac68be77a4816b Signed-off-by: Ecco Park <eccopark@google.com>
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java62
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java113
2 files changed, 110 insertions, 65 deletions
diff --git a/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java b/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
index a6aeab4d1..424aedc80 100644
--- a/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
+++ b/service/java/com/android/server/wifi/hotspot2/OsuServerConnection.java
@@ -152,36 +152,31 @@ public class OsuServerConnection {
}
/**
- * Connect to the OSU server
+ * Connects to the OSU server
*
* @param url Osu Server's URL
* @param network current network connection
- * @return boolean value, true if connection was successful
+ * @return {@code true} if {@code url} and {@code network} are not null
*
* Note: Relies on the caller to ensure that the capability to validate the OSU
* Server is available.
*/
- public boolean connect(URL url, Network network) {
- mNetwork = network;
- mUrl = url;
- HttpsURLConnection urlConnection;
- try {
- urlConnection = (HttpsURLConnection) mNetwork.openConnection(mUrl);
- urlConnection.setSSLSocketFactory(mSocketFactory);
- urlConnection.setConnectTimeout(HttpsServiceConnection.DEFAULT_TIMEOUT_MS);
- urlConnection.setReadTimeout(HttpsServiceConnection.DEFAULT_TIMEOUT_MS);
- urlConnection.connect();
- } catch (IOException e) {
- Log.e(TAG, "Unable to establish a URL connection");
- e.printStackTrace();
+ public boolean connect(@NonNull URL url, @NonNull Network network) {
+ if (url == null) {
+ Log.e(TAG, "url is null");
return false;
}
- mUrlConnection = urlConnection;
+ if (network == null) {
+ Log.e(TAG, "network is null");
+ return false;
+ }
+
+ mHandler.post(() -> performTlsConnection(url, network));
return true;
}
/**
- * Validate the service provider by comparing its identities found in OSU Server cert
+ * Validates the service provider by comparing its identities found in OSU Server cert
* to the friendlyName obtained from ANQP exchange that is displayed to the user.
*
* @param locale a {@link Locale} object used for matching the friendly name in
@@ -219,8 +214,8 @@ public class OsuServerConnection {
* The helper method to exchange a SOAP message.
*
* @param soapEnvelope the soap message to be sent.
- * @return {@code true} if {@link Network} is valid and {@code soapEnvelope} is not null,
- * {@code false} otherwise.
+ * @return {@code true} if {@link Network} is valid and {@code soapEnvelope} is not {@code
+ * null}, {@code false} otherwise.
*/
public boolean exchangeSoapMessage(@NonNull SoapSerializationEnvelope soapEnvelope) {
if (mNetwork == null) {
@@ -249,8 +244,8 @@ public class OsuServerConnection {
* {@code Key} is the cert type.
* {@code Value} is the map that has a key for certUrl and a value for
* fingerprint of the certificate.
- * @return {@code true} if {@link Network} is valid and {@code trustCertsInfo} is not null,
- * {@code false} otherwise.
+ * @return {@code true} if {@link Network} is valid and {@code trustCertsInfo} is not {@code
+ * null}, {@code false} otherwise.
*/
public boolean retrieveTrustRootCerts(
@NonNull Map<Integer, Map<String, byte[]>> trustCertsInfo) {
@@ -272,6 +267,31 @@ public class OsuServerConnection {
return true;
}
+ private void performTlsConnection(URL url, Network network) {
+ mNetwork = network;
+ mUrl = url;
+
+ HttpsURLConnection urlConnection;
+ try {
+ urlConnection = (HttpsURLConnection) mNetwork.openConnection(mUrl);
+ urlConnection.setSSLSocketFactory(mSocketFactory);
+ urlConnection.setConnectTimeout(HttpsServiceConnection.DEFAULT_TIMEOUT_MS);
+ urlConnection.setReadTimeout(HttpsServiceConnection.DEFAULT_TIMEOUT_MS);
+ urlConnection.connect();
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to establish a URL connection: " + e);
+ if (mOsuServerCallbacks != null) {
+ mOsuServerCallbacks.onServerConnectionStatus(mOsuServerCallbacks.getSessionId(),
+ false);
+ }
+ return;
+ }
+ mUrlConnection = urlConnection;
+ if (mOsuServerCallbacks != null) {
+ mOsuServerCallbacks.onServerConnectionStatus(mOsuServerCallbacks.getSessionId(), true);
+ }
+ }
+
private void performSoapMessageExchange(@NonNull SoapSerializationEnvelope soapEnvelope) {
if (mServiceConnection != null) {
mServiceConnection.disconnect();
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
index 753034575..75c5207f6 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvisioner.java
@@ -156,14 +156,13 @@ public class PasspointProvisioner {
private static final String TAG = "PasspointProvisioningStateMachine";
static final int STATE_INIT = 1;
- static final int STATE_WAITING_TO_CONNECT = 2;
- static final int STATE_OSU_AP_CONNECTED = 3;
- static final int STATE_OSU_SERVER_CONNECTED = 4;
- 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;
- static final int STATE_WAITING_FOR_TRUST_ROOT_CERTS = 9;
+ static final int STATE_AP_CONNECTING = 2;
+ static final int STATE_OSU_SERVER_CONNECTING = 3;
+ static final int STATE_WAITING_FOR_FIRST_SOAP_RESPONSE = 4;
+ static final int STATE_WAITING_FOR_REDIRECT_RESPONSE = 5;
+ static final int STATE_WAITING_FOR_SECOND_SOAP_RESPONSE = 6;
+ static final int STATE_WAITING_FOR_THIRD_SOAP_RESPONSE = 7;
+ static final int STATE_WAITING_FOR_TRUST_ROOT_CERTS = 8;
private OsuProvider mOsuProvider;
private IProvisioningCallback mProvisioningCallback;
@@ -241,11 +240,11 @@ public class PasspointProvisioner {
}
invokeProvisioningCallback(PROVISIONING_STATUS,
ProvisioningCallback.OSU_STATUS_AP_CONNECTING);
- changeState(STATE_WAITING_TO_CONNECT);
+ changeState(STATE_AP_CONNECTING);
}
/**
- * Handle Wifi Disable event
+ * Handles Wifi Disable event
*
* Note: Called on main thread (WifiService thread).
*/
@@ -261,8 +260,38 @@ public class PasspointProvisioner {
}
/**
- * Handle server validation failure
+ * Handles server connection status
*
+ * @param sessionId indicating current session ID
+ * @param succeeded boolean indicating success/failure of server connection
+ * Note: Called on main thread (WifiService thread).
+ */
+ public void handleServerConnectionStatus(int sessionId, boolean succeeded) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Server Connection status received in " + mState);
+ }
+ if (sessionId != mCurrentSessionId) {
+ Log.w(TAG, "Expected server connection failure callback for currentSessionId="
+ + mCurrentSessionId);
+ return;
+ }
+ if (mState != STATE_OSU_SERVER_CONNECTING) {
+ Log.wtf(TAG, "Server Validation Failure unhandled in mState=" + mState);
+ return;
+ }
+ if (!succeeded) {
+ resetStateMachineForFailure(ProvisioningCallback.OSU_FAILURE_SERVER_CONNECTION);
+ return;
+ }
+ invokeProvisioningCallback(PROVISIONING_STATUS,
+ ProvisioningCallback.OSU_STATUS_SERVER_CONNECTED);
+ mProvisioningStateMachine.getHandler().post(() -> initSoapExchange());
+ }
+
+ /**
+ * Handles server validation failure
+ *
+ * @param sessionId indicating current session ID
* Note: Called on main thread (WifiService thread).
*/
public void handleServerValidationFailure(int sessionId) {
@@ -274,7 +303,7 @@ public class PasspointProvisioner {
+ mCurrentSessionId);
return;
}
- if (mState != STATE_OSU_SERVER_CONNECTED) {
+ if (mState != STATE_OSU_SERVER_CONNECTING) {
Log.wtf(TAG, "Server Validation Failure unhandled in mState=" + mState);
return;
}
@@ -282,8 +311,9 @@ public class PasspointProvisioner {
}
/**
- * Handle status of server validation success
+ * Handles status of server validation success
*
+ * @param sessionId indicating current session ID
* Note: Called on main thread (WifiService thread).
*/
public void handleServerValidationSuccess(int sessionId) {
@@ -295,13 +325,18 @@ public class PasspointProvisioner {
+ mCurrentSessionId);
return;
}
- if (mState != STATE_OSU_SERVER_CONNECTED) {
+ if (mState != STATE_OSU_SERVER_CONNECTING) {
Log.wtf(TAG, "Server validation success event unhandled in state=" + mState);
return;
}
+ if (!mOsuServerConnection.validateProvider(
+ Locale.getDefault(), mOsuProvider.getFriendlyName())) {
+ resetStateMachineForFailure(
+ ProvisioningCallback.OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION);
+ return;
+ }
invokeProvisioningCallback(PROVISIONING_STATUS,
ProvisioningCallback.OSU_STATUS_SERVER_VALIDATED);
- validateServiceProvider();
}
/**
@@ -352,14 +387,13 @@ public class PasspointProvisioner {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Connected event received in state=" + mState);
}
- if (mState != STATE_WAITING_TO_CONNECT) {
+ if (mState != STATE_AP_CONNECTING) {
// Not waiting for a connection
Log.wtf(TAG, "Connection event unhandled in state=" + mState);
return;
}
invokeProvisioningCallback(PROVISIONING_STATUS,
ProvisioningCallback.OSU_STATUS_AP_CONNECTED);
- changeState(STATE_OSU_AP_CONNECTED);
initiateServerConnection(network);
}
@@ -577,18 +611,15 @@ public class PasspointProvisioner {
if (mVerboseLoggingEnabled) {
Log.v(TAG, "Initiating server connection in state=" + mState);
}
- if (mState != STATE_OSU_AP_CONNECTED) {
- Log.wtf(TAG, "Initiating server connection aborted in invalid state=" + mState);
- return;
- }
+
if (!mOsuServerConnection.connect(mServerUrl, network)) {
resetStateMachineForFailure(ProvisioningCallback.OSU_FAILURE_SERVER_CONNECTION);
return;
}
mNetwork = network;
- changeState(STATE_OSU_SERVER_CONNECTED);
+ changeState(STATE_OSU_SERVER_CONNECTING);
invokeProvisioningCallback(PROVISIONING_STATUS,
- ProvisioningCallback.OSU_STATUS_SERVER_CONNECTED);
+ ProvisioningCallback.OSU_STATUS_SERVER_CONNECTING);
}
private void invokeProvisioningCallback(int callbackType, int status) {
@@ -622,26 +653,6 @@ public class PasspointProvisioner {
}
/**
- * Validate the OSU Server certificate based on the procedure in 7.3.2.2 of Hotspot2.0
- * rel2 spec.
- */
- private void validateServiceProvider() {
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Validating the service provider of OSU Server certificate in state="
- + mState);
- }
- if (!mOsuServerConnection.validateProvider(
- Locale.getDefault(), mOsuProvider.getFriendlyName())) {
- resetStateMachineForFailure(
- ProvisioningCallback.OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION);
- return;
- }
- invokeProvisioningCallback(PROVISIONING_STATUS,
- ProvisioningCallback.OSU_STATUS_SERVICE_PROVIDER_VERIFIED);
- mProvisioningStateMachine.getHandler().post(() -> initSoapExchange());
- }
-
- /**
* Initiates the SOAP message exchange with sending the sppPostDevData message.
*/
private void initSoapExchange() {
@@ -649,7 +660,7 @@ public class PasspointProvisioner {
Log.v(TAG, "Initiates soap message exchange in state =" + mState);
}
- if (mState != STATE_OSU_SERVER_CONNECTED) {
+ if (mState != STATE_OSU_SERVER_CONNECTING) {
Log.e(TAG, "Initiates soap message exchange in wrong state=" + mState);
resetStateMachineForFailure(ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED);
return;
@@ -974,6 +985,20 @@ public class PasspointProvisioner {
}
/**
+ * Callback when a TLS connection to the server is failed.
+ *
+ * @param sessionId indicating current session ID
+ * @param succeeded boolean indicating success/failure of server connection
+ */
+ public void onServerConnectionStatus(int sessionId, boolean succeeded) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "OSU Server connection status=" + succeeded + " sessionId=" + sessionId);
+ }
+ mProvisioningStateMachine.getHandler().post(() ->
+ mProvisioningStateMachine.handleServerConnectionStatus(sessionId, succeeded));
+ }
+
+ /**
* Provides a server validation status for the session ID
*
* @param sessionId integer indicating current session ID