summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp17
-rw-r--r--services/java/com/android/server/WifiService.java17
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl7
-rw-r--r--wifi/java/android/net/wifi/SupplicantStateTracker.java23
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java28
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java41
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java4
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java151
-rw-r--r--wifi/java/android/net/wifi/WpsConfiguration.aidl19
-rw-r--r--wifi/java/android/net/wifi/WpsConfiguration.java127
-rw-r--r--wifi/java/android/net/wifi/WpsStateMachine.java200
11 files changed, 472 insertions, 162 deletions
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 0663e98..6737501 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -173,14 +173,17 @@ static jboolean android_net_wifi_wpsPbcCommand(JNIEnv* env, jobject clazz, jstri
return doBooleanCommand(cmdstr, "OK");
}
-static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz, jstring bssid, int apPin)
+static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobject clazz,
+ jstring bssid, jstring apPin)
{
char cmdstr[BUF_SIZE];
jboolean isCopy;
const char *bssidStr = env->GetStringUTFChars(bssid, &isCopy);
- int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_REG %s %d", bssidStr, apPin);
+ const char *apPinStr = env->GetStringUTFChars(apPin, &isCopy);
+ int numWritten = snprintf(cmdstr, sizeof(cmdstr), "WPS_REG %s %s", bssidStr, apPinStr);
env->ReleaseStringUTFChars(bssid, bssidStr);
+ env->ReleaseStringUTFChars(apPin, apPinStr);
if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
return false;
@@ -188,7 +191,7 @@ static jboolean android_net_wifi_wpsPinFromAccessPointCommand(JNIEnv* env, jobje
return doBooleanCommand(cmdstr, "OK");
}
-static jint android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
+static jstring android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz, jstring bssid)
{
char cmdstr[BUF_SIZE];
jboolean isCopy;
@@ -198,9 +201,9 @@ static jint android_net_wifi_wpsPinFromDeviceCommand(JNIEnv* env, jobject clazz,
env->ReleaseStringUTFChars(bssid, bssidStr);
if ((numWritten == -1) || (numWritten >= (int)sizeof(cmdstr))) {
- return -1;
+ return NULL;
}
- return doIntCommand(cmdstr);
+ return doStringCommand(env, cmdstr);
}
static jboolean android_net_wifi_setCountryCodeCommand(JNIEnv* env, jobject clazz, jstring country)
@@ -648,9 +651,9 @@ static JNINativeMethod gWifiMethods[] = {
{ "addToBlacklistCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_addToBlacklistCommand },
{ "clearBlacklistCommand", "()Z", (void*) android_net_wifi_clearBlacklistCommand },
{ "startWpsPbcCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_wpsPbcCommand },
- { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;I)Z",
+ { "startWpsWithPinFromAccessPointCommand", "(Ljava/lang/String;Ljava/lang/String;)Z",
(void*) android_net_wifi_wpsPinFromAccessPointCommand },
- { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)I",
+ { "startWpsWithPinFromDeviceCommand", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) android_net_wifi_wpsPinFromDeviceCommand },
{ "setSuspendOptimizationsCommand", "(Z)Z",
(void*) android_net_wifi_setSuspendOptimizationsCommand},
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 7f81a25..07813b0 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -39,6 +39,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WpsConfiguration;
import android.net.ConnectivityManager;
import android.net.InterfaceConfiguration;
import android.net.DhcpInfo;
@@ -843,23 +844,13 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.forgetNetwork(netId);
}
- public void startWpsPbc(String bssid) {
- enforceChangePermission();
- mWifiStateMachine.startWpsPbc(bssid);
- }
-
- public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
- enforceChangePermission();
- mWifiStateMachine.startWpsWithPinFromAccessPoint(bssid, apPin);
- }
-
- public int startWpsWithPinFromDevice(String bssid) {
+ public String startWps(WpsConfiguration config) {
enforceChangePermission();
if (mChannel != null) {
- return mWifiStateMachine.syncStartWpsWithPinFromDevice(mChannel, bssid);
+ return mWifiStateMachine.startWps(mChannel, config);
} else {
Slog.e(TAG, "mChannel is not initialized");
- return -1;
+ return "";
}
}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 24001bb..9dbba20 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -18,6 +18,7 @@ package android.net.wifi;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WpsConfiguration;
import android.net.wifi.ScanResult;
import android.net.DhcpInfo;
@@ -108,10 +109,6 @@ interface IWifiManager
void forgetNetwork(int networkId);
- void startWpsPbc(String bssid);
-
- void startWpsWithPinFromAccessPoint(String bssid, int apPin);
-
- int startWpsWithPinFromDevice(String bssid);
+ String startWps(in WpsConfiguration config);
}
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index a83a0ad..f823314 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -32,7 +32,6 @@ import android.util.Log;
* that is based on these state changes:
* - detect a failed WPA handshake that loops indefinitely
* - password failure handling
- * - Enable networks after a WPS success/failure
*/
class SupplicantStateTracker extends HierarchicalStateMachine {
@@ -49,10 +48,6 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
/* Maximum retries on a password failure notification */
private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
- /* Track if WPS was started since we need to re-enable networks
- * and load configuration afterwards */
- private boolean mWpsStarted = false;
-
private Context mContext;
private HierarchicalState mUninitializedState = new UninitializedState();
@@ -156,11 +151,6 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
mPasswordFailuresCount++;
mAuthFailureInSupplicantBroadcast = true;
break;
- case WifiStateMachine.CMD_START_WPS_PBC:
- case WifiStateMachine.CMD_START_WPS_PIN_FROM_AP:
- case WifiStateMachine.CMD_START_WPS_PIN_FROM_DEVICE:
- mWpsStarted = true;
- break;
case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
sendSupplicantStateChangedBroadcast(stateChangeResult,
@@ -192,12 +182,6 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* A failed WPS connection */
- if (mWpsStarted) {
- Log.e(TAG, "WPS set up failed, enabling other networks");
- WifiConfigStore.enableAllNetworks();
- mWpsStarted = false;
- }
mWifiStateMachine.setNetworkAvailable(false);
}
@Override
@@ -289,13 +273,6 @@ class SupplicantStateTracker extends HierarchicalStateMachine {
if (DBG) Log.d(TAG, getName() + "\n");
/* Reset password failure count */
mPasswordFailuresCount = 0;
-
- /* A successful WPS connection */
- if (mWpsStarted) {
- WifiConfigStore.enableAllNetworks();
- WifiConfigStore.loadConfiguredNetworks();
- mWpsStarted = false;
- }
}
@Override
public boolean processMessage(Message message) {
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index c6b0299..f597934 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -366,8 +366,8 @@ class WifiConfigStore {
* Start WPS pin method configuration with pin obtained
* from the access point
*/
- static boolean startWpsWithPinFromAccessPoint(String bssid, int apPin) {
- if (WifiNative.startWpsWithPinFromAccessPointCommand(bssid, apPin)) {
+ static boolean startWpsWithPinFromAccessPoint(WpsConfiguration config) {
+ if (WifiNative.startWpsWithPinFromAccessPointCommand(config.BSSID, config.pin)) {
/* WPS leaves all networks disabled */
markAllNetworksDisabled();
return true;
@@ -379,14 +379,16 @@ class WifiConfigStore {
/**
* Start WPS pin method configuration with pin obtained
* from the device
+ * @return empty string on failure. null is never returned.
*/
- static int startWpsWithPinFromDevice(String bssid) {
- int pin = WifiNative.startWpsWithPinFromDeviceCommand(bssid);
+ static String startWpsWithPinFromDevice(WpsConfiguration config) {
+ String pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID);
/* WPS leaves all networks disabled */
- if (pin != -1) {
+ if (!TextUtils.isEmpty(pin)) {
markAllNetworksDisabled();
} else {
Log.e(TAG, "Failed to start WPS pin method configuration");
+ pin = "";
}
return pin;
}
@@ -394,8 +396,8 @@ class WifiConfigStore {
/**
* Start WPS push button configuration
*/
- static boolean startWpsPbc(String bssid) {
- if (WifiNative.startWpsPbcCommand(bssid)) {
+ static boolean startWpsPbc(WpsConfiguration config) {
+ if (WifiNative.startWpsPbcCommand(config.BSSID)) {
/* WPS leaves all networks disabled */
markAllNetworksDisabled();
return true;
@@ -527,6 +529,18 @@ class WifiConfigStore {
sendConfiguredNetworksChangedBroadcast();
}
+ static void updateIpAndProxyFromWpsConfig(int netId, WpsConfiguration wpsConfig) {
+ synchronized (sConfiguredNetworks) {
+ WifiConfiguration config = sConfiguredNetworks.get(netId);
+ if (config != null) {
+ config.ipAssignment = wpsConfig.ipAssignment;
+ config.proxySettings = wpsConfig.proxySettings;
+ config.linkProperties = wpsConfig.linkProperties;
+ writeIpAndProxyConfigurations();
+ }
+ }
+ }
+
/* Mark all networks except specified netId as disabled */
private static void markAllNetworksDisabledExcept(int netId) {
synchronized (sConfiguredNetworks) {
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index e3be5b3..4623721 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1071,45 +1071,18 @@ public class WifiManager {
}
/**
- * Start Wi-fi protected setup push button Configuration
+ * Start Wi-fi Protected Setup
*
- * @param bssid BSSID of the access point
+ * @param config WPS configuration
+ * @return pin generated by device, if any
* @hide
+ * TODO: with use of AsyncChannel, return value should go away
*/
- public void startWpsPbc(String bssid) {
+ public String startWps(WpsConfiguration config) {
try {
- mService.startWpsPbc(bssid);
- } catch (RemoteException e) { }
- }
-
- /**
- * Start Wi-fi Protected Setup pin method configuration
- * with pin obtained from the access point
- *
- * @param bssid BSSID of the access point
- * @param apPin PIN issued by the access point
- *
- * @hide
- */
- public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
- try {
- mService.startWpsWithPinFromAccessPoint(bssid, apPin);
- } catch (RemoteException e) { }
- }
-
- /**
- * Start Wi-fi Protected Setup pin method configuration
- * with pin obtained from the device
- *
- * @param bssid BSSID of the access point
- * @return pin generated by device
- * @hide
- */
- public int startWpsWithPinFromDevice(String bssid) {
- try {
- return mService.startWpsWithPinFromDevice(bssid);
+ return mService.startWps(config);
} catch (RemoteException e) {
- return -1;
+ return null;
}
}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 06f945b..0310420 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -149,9 +149,9 @@ public class WifiNative {
public native static boolean startWpsPbcCommand(String bssid);
- public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, int apPin);
+ public native static boolean startWpsWithPinFromAccessPointCommand(String bssid, String apPin);
- public native static int startWpsWithPinFromDeviceCommand(String bssid);
+ public native static String startWpsWithPinFromDeviceCommand(String bssid);
public native static boolean doDhcpRequest(DhcpInfo results);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 18385b7..5474b3f 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -147,6 +147,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private WifiInfo mWifiInfo;
private NetworkInfo mNetworkInfo;
private SupplicantStateTracker mSupplicantStateTracker;
+ private WpsStateMachine mWpsStateMachine;
+
/* Connection to a specific network involves disabling all networks,
* this flag tracks if networks need to be re-enabled */
private boolean mEnableAllNetworks = false;
@@ -307,19 +309,19 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* supplicant config.
*/
static final int CMD_FORGET_NETWORK = 88;
- /* Start Wi-Fi protected setup push button configuration */
- static final int CMD_START_WPS_PBC = 89;
- /* Start Wi-Fi protected setup pin method configuration with pin obtained from AP */
- static final int CMD_START_WPS_PIN_FROM_AP = 90;
- /* Start Wi-Fi protected setup pin method configuration with pin obtained from device */
- static final int CMD_START_WPS_PIN_FROM_DEVICE = 91;
+ /* Start Wi-Fi protected setup */
+ static final int CMD_START_WPS = 89;
/* Set the frequency band */
- static final int CMD_SET_FREQUENCY_BAND = 92;
+ static final int CMD_SET_FREQUENCY_BAND = 90;
/* Commands from the SupplicantStateTracker */
/* Indicates whether a wifi network is available for connection */
static final int CMD_SET_NETWORK_AVAILABLE = 111;
+ /* Commands/events reported by WpsStateMachine */
+ /* Indicates the completion of WPS activity */
+ static final int WPS_COMPLETED_EVENT = 121;
+
private static final int CONNECT_MODE = 1;
private static final int SCAN_ONLY_MODE = 2;
@@ -387,6 +389,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private HierarchicalState mDisconnectingState = new DisconnectingState();
/* Network is not connected, supplicant assoc+auth is not complete */
private HierarchicalState mDisconnectedState = new DisconnectedState();
+ /* Waiting for WPS to be completed*/
+ private HierarchicalState mWaitForWpsCompletionState = new WaitForWpsCompletionState();
/* Soft Ap is running */
private HierarchicalState mSoftApStartedState = new SoftApStartedState();
@@ -457,6 +461,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiInfo = new WifiInfo();
mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
+ mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
mLinkProperties = new LinkProperties();
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -518,6 +523,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
addState(mConnectedState, mConnectModeState);
addState(mDisconnectingState, mConnectModeState);
addState(mDisconnectedState, mConnectModeState);
+ addState(mWaitForWpsCompletionState, mConnectModeState);
addState(mDriverStoppingState, mDriverSupReadyState);
addState(mDriverStoppedState, mDriverSupReadyState);
addState(mSoftApStartedState, mDefaultState);
@@ -808,18 +814,20 @@ public class WifiStateMachine extends HierarchicalStateMachine {
sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0));
}
- public void startWpsPbc(String bssid) {
- sendMessage(obtainMessage(CMD_START_WPS_PBC, bssid));
- }
-
- public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
- sendMessage(obtainMessage(CMD_START_WPS_PIN_FROM_AP, apPin, 0, bssid));
- }
-
- public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN_FROM_DEVICE, bssid);
- int result = resultMsg.arg1;
- resultMsg.recycle();
+ public String startWps(AsyncChannel channel, WpsConfiguration config) {
+ String result = null;
+ switch (config.setup) {
+ case PIN_FROM_DEVICE:
+ //TODO: will go away with AsyncChannel use from settings
+ Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config);
+ result = (String) resultMsg.obj;
+ resultMsg.recycle();
+ break;
+ case PBC:
+ case PIN_FROM_ACCESS_POINT:
+ sendMessage(obtainMessage(CMD_START_WPS, config));
+ break;
+ }
return result;
}
@@ -1554,7 +1562,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_ADD_OR_UPDATE_NETWORK:
case CMD_REMOVE_NETWORK:
case CMD_SAVE_CONFIG:
- case CMD_START_WPS_PIN_FROM_DEVICE:
mReplyChannel.replyToMessage(message, message.what, FAILURE);
break;
case CMD_ENABLE_RSSI_POLL:
@@ -1598,10 +1605,17 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_CONNECT_NETWORK:
case CMD_SAVE_NETWORK:
case CMD_FORGET_NETWORK:
- case CMD_START_WPS_PBC:
- case CMD_START_WPS_PIN_FROM_AP:
case CMD_RSSI_POLL:
break;
+ case CMD_START_WPS:
+ WpsConfiguration config = (WpsConfiguration) message.obj;
+ switch (config.setup) {
+ case PIN_FROM_DEVICE:
+ String pin = "";
+ mReplyChannel.replyToMessage(message, message.what, pin);
+ break;
+ }
+ break;
default:
Log.e(TAG, "Error! unhandled message" + message);
break;
@@ -2306,9 +2320,8 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiInfo.setBSSID(stateChangeResult.BSSID);
}
- Message newMsg = obtainMessage();
- newMsg.copyFrom(message);
- mSupplicantStateTracker.sendMessage(newMsg);
+ mSupplicantStateTracker.sendMessage(Message.obtain(message));
+ mWpsStateMachine.sendMessage(Message.obtain(message));
break;
/* Do a redundant disconnect without transition */
case CMD_DISCONNECT:
@@ -2348,51 +2361,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
break;
- case CMD_START_WPS_PBC:
- String bssid = (String) message.obj;
- /* WPS push button configuration */
- boolean success = WifiConfigStore.startWpsPbc(bssid);
-
- /* During WPS setup, all other networks are disabled. After
- * a successful connect a new config is created in the supplicant.
- *
- * We need to enable all networks after a successful connection
- * or when supplicant goes inactive due to failure. Enabling all
- * networks after a disconnect is observed as done with connectNetwork
- * does not lead to a successful WPS setup.
- *
- * Upon success, the configuration list needs to be reloaded
- */
- if (success) {
- mSupplicantStateTracker.sendMessage(message.what);
- /* Expect a disconnection from the old connection */
- transitionTo(mDisconnectingState);
- }
- break;
- case CMD_START_WPS_PIN_FROM_AP:
- bssid = (String) message.obj;
- int apPin = message.arg1;
-
- /* WPS pin from access point */
- success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
-
- if (success) {
- mSupplicantStateTracker.sendMessage(message.what);
- /* Expect a disconnection from the old connection */
- transitionTo(mDisconnectingState);
- }
- break;
- case CMD_START_WPS_PIN_FROM_DEVICE:
- bssid = (String) message.obj;
- int pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
- success = (pin != FAILURE);
- mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN_FROM_DEVICE, pin);
-
- if (success) {
- mSupplicantStateTracker.sendMessage(message.what);
- /* Expect a disconnection from the old connection */
- transitionTo(mDisconnectingState);
- }
+ case CMD_START_WPS:
+ mWpsStateMachine.sendMessage(Message.obtain(message));
+ transitionTo(mWaitForWpsCompletionState);
break;
case SCAN_RESULTS_EVENT:
/* Set the scan setting back to "connect" mode */
@@ -2436,7 +2407,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
-
mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
if (!mUseStaticIp) {
mDhcpThread = null;
@@ -2799,6 +2769,45 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
}
+ class WaitForWpsCompletionState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ /* Defer all commands that can cause connections to a different network
+ * or put the state machine out of connect mode
+ */
+ case CMD_STOP_DRIVER:
+ case CMD_SET_SCAN_MODE:
+ case CMD_CONNECT_NETWORK:
+ case CMD_ENABLE_NETWORK:
+ case CMD_RECONNECT:
+ case CMD_REASSOCIATE:
+ case NETWORK_CONNECTION_EVENT: /* Handled after IP & proxy update */
+ deferMessage(message);
+ break;
+ case NETWORK_DISCONNECTION_EVENT:
+ Log.d(TAG,"Network connection lost");
+ handleNetworkDisconnect();
+ break;
+ case WPS_COMPLETED_EVENT:
+ /* we are still disconnected until we see a network connection
+ * notification */
+ transitionTo(mDisconnectedState);
+ break;
+ default:
+ return NOT_HANDLED;
+ }
+ EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+ return HANDLED;
+ }
+ }
+
class SoftApStartedState extends HierarchicalState {
@Override
public void enter() {
diff --git a/wifi/java/android/net/wifi/WpsConfiguration.aidl b/wifi/java/android/net/wifi/WpsConfiguration.aidl
new file mode 100644
index 0000000..6c26833
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsConfiguration.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2010, 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 android.net.wifi;
+
+parcelable WpsConfiguration;
diff --git a/wifi/java/android/net/wifi/WpsConfiguration.java b/wifi/java/android/net/wifi/WpsConfiguration.java
new file mode 100644
index 0000000..12d951f
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsConfiguration.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 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 android.net.wifi;
+
+import android.net.LinkProperties;
+import android.net.wifi.WifiConfiguration.IpAssignment;
+import android.net.wifi.WifiConfiguration.ProxySettings;
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import java.util.BitSet;
+
+/**
+ * A class representing a WPS network configuration
+ * @hide
+ */
+public class WpsConfiguration implements Parcelable {
+
+ public enum Setup {
+ /* Wi-Fi protected setup push button configuration */
+ PBC,
+ /* Wi-Fi protected setup pin method configuration with pin obtained from access point */
+ PIN_FROM_ACCESS_POINT,
+ /* Wi-Fi protected setup pin method configuration with pin obtained from device */
+ PIN_FROM_DEVICE,
+ /* Invalid config */
+ INVALID
+ }
+
+ public Setup setup;
+
+ public String BSSID;
+
+ public String pin;
+
+ public IpAssignment ipAssignment;
+
+ public ProxySettings proxySettings;
+
+ public LinkProperties linkProperties;
+
+ public WpsConfiguration() {
+ setup = Setup.INVALID;
+ BSSID = null;
+ pin = null;
+ ipAssignment = IpAssignment.UNASSIGNED;
+ proxySettings = ProxySettings.UNASSIGNED;
+ linkProperties = new LinkProperties();
+ }
+
+ public String toString() {
+ StringBuffer sbuf = new StringBuffer();
+ sbuf.append(" setup: ").append(setup.toString());
+ sbuf.append('\n');
+ sbuf.append(" BSSID: ").append(BSSID);
+ sbuf.append('\n');
+ sbuf.append(" pin: ").append(pin);
+ sbuf.append('\n');
+ sbuf.append("IP assignment: " + ipAssignment.toString());
+ sbuf.append("\n");
+ sbuf.append("Proxy settings: " + proxySettings.toString());
+ sbuf.append("\n");
+ sbuf.append(linkProperties.toString());
+ sbuf.append("\n");
+ return sbuf.toString();
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** copy constructor {@hide} */
+ public WpsConfiguration(WpsConfiguration source) {
+ if (source != null) {
+ setup = source.setup;
+ BSSID = source.BSSID;
+ pin = source.pin;
+ ipAssignment = source.ipAssignment;
+ proxySettings = source.proxySettings;
+ linkProperties = new LinkProperties(source.linkProperties);
+ }
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(setup.name());
+ dest.writeString(BSSID);
+ dest.writeString(pin);
+ dest.writeString(ipAssignment.name());
+ dest.writeString(proxySettings.name());
+ dest.writeParcelable(linkProperties, flags);
+ }
+
+ /** Implement the Parcelable interface {@hide} */
+ public static final Creator<WpsConfiguration> CREATOR =
+ new Creator<WpsConfiguration>() {
+ public WpsConfiguration createFromParcel(Parcel in) {
+ WpsConfiguration config = new WpsConfiguration();
+ config.setup = Setup.valueOf(in.readString());
+ config.BSSID = in.readString();
+ config.pin = in.readString();
+ config.ipAssignment = IpAssignment.valueOf(in.readString());
+ config.proxySettings = ProxySettings.valueOf(in.readString());
+ config.linkProperties = in.readParcelable(null);
+ return config;
+ }
+
+ public WpsConfiguration[] newArray(int size) {
+ return new WpsConfiguration[size];
+ }
+ };
+}
diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java
new file mode 100644
index 0000000..381444c
--- /dev/null
+++ b/wifi/java/android/net/wifi/WpsStateMachine.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2010 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 android.net.wifi;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiStateMachine.StateChangeResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Manages a WPS connection.
+ *
+ * WPS consists as a series of EAP exchange triggered
+ * by a user action that leads to a successful connection
+ * after automatic creation of configuration in the
+ * supplicant. We currently support the following methods
+ * of WPS setup
+ * 1. Pin method: Pin can be either obtained from the device
+ * or from the access point to connect to.
+ * 2. Push button method: This involves pushing a button on
+ * the access point and the device
+ *
+ * After a successful WPS setup, the state machine
+ * reloads the configuration and updates the IP and proxy
+ * settings, if any.
+ */
+class WpsStateMachine extends HierarchicalStateMachine {
+
+ private static final String TAG = "WpsStateMachine";
+ private static final boolean DBG = false;
+
+ private WifiStateMachine mWifiStateMachine;
+
+ private WpsConfiguration mWpsConfig;
+
+ private Context mContext;
+ AsyncChannel mReplyChannel = new AsyncChannel();
+
+ private HierarchicalState mDefaultState = new DefaultState();
+ private HierarchicalState mInactiveState = new InactiveState();
+ private HierarchicalState mActiveState = new ActiveState();
+
+ public WpsStateMachine(Context context, WifiStateMachine wsm, Handler target) {
+ super(TAG, target.getLooper());
+
+ mContext = context;
+ mWifiStateMachine = wsm;
+ addState(mDefaultState);
+ addState(mInactiveState, mDefaultState);
+ addState(mActiveState, mDefaultState);
+
+ setInitialState(mInactiveState);
+
+ //start the state machine
+ start();
+ }
+
+
+ /********************************************************
+ * HSM states
+ *******************************************************/
+
+ class DefaultState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ WpsConfiguration wpsConfig;
+ switch (message.what) {
+ case WifiStateMachine.CMD_START_WPS:
+ mWpsConfig = (WpsConfiguration) message.obj;
+ boolean success = false;
+ switch (mWpsConfig.setup) {
+ case PBC:
+ success = WifiConfigStore.startWpsPbc(mWpsConfig);
+ break;
+ case PIN_FROM_ACCESS_POINT:
+ success = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig);
+ break;
+ case PIN_FROM_DEVICE:
+ String pin = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig);
+ success = (pin != null);
+ mReplyChannel.replyToMessage(message, message.what, pin);
+ break;
+ default:
+ Log.e(TAG, "Invalid setup for WPS");
+ break;
+ }
+ if (success) {
+ transitionTo(mActiveState);
+ } else {
+ Log.e(TAG, "Failed to start WPS with config " + mWpsConfig.toString());
+ }
+ break;
+ default:
+ Log.e(TAG, "Failed to handle " + message);
+ break;
+ }
+ return HANDLED;
+ }
+ }
+
+ class ActiveState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ SupplicantState supState = (SupplicantState) stateChangeResult.state;
+ switch (supState) {
+ case COMPLETED:
+ /* During WPS setup, all other networks are disabled. After
+ * a successful connect a new config is created in the supplicant.
+ *
+ * We need to enable all networks after a successful connection
+ * and the configuration list needs to be reloaded from the supplicant.
+ */
+ Log.d(TAG, "WPS set up successful");
+ WifiConfigStore.enableAllNetworks();
+ WifiConfigStore.loadConfiguredNetworks();
+ WifiConfigStore.updateIpAndProxyFromWpsConfig(
+ stateChangeResult.networkId, mWpsConfig);
+ mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
+ transitionTo(mInactiveState);
+ break;
+ case INACTIVE:
+ /* A failed WPS connection */
+ Log.d(TAG, "WPS set up failed, enabling other networks");
+ WifiConfigStore.enableAllNetworks();
+ mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT);
+ transitionTo(mInactiveState);
+ break;
+ default:
+ if (DBG) Log.d(TAG, "Ignoring supplicant state " + supState.name());
+ break;
+ }
+ break;
+ case WifiStateMachine.CMD_START_WPS:
+ deferMessage(message);
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ }
+ return retValue;
+ }
+ }
+
+ class InactiveState extends HierarchicalState {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = HANDLED;
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch (message.what) {
+ //Ignore supplicant state changes
+ case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
+ break;
+ default:
+ retValue = NOT_HANDLED;
+ }
+ return retValue;
+ }
+ }
+
+} \ No newline at end of file