diff options
| -rw-r--r-- | core/jni/android_net_wifi_Wifi.cpp | 17 | ||||
| -rw-r--r-- | services/java/com/android/server/WifiService.java | 17 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 7 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/SupplicantStateTracker.java | 23 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiConfigStore.java | 28 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 41 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 4 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 151 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WpsConfiguration.aidl | 19 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WpsConfiguration.java | 127 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WpsStateMachine.java | 200 |
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 |
