diff options
-rw-r--r-- | services/java/com/android/server/WifiService.java | 4 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiConfigStore.java | 7 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 56 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiMonitor.java | 52 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 32 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 27 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pService.java | 2 |
7 files changed, 154 insertions, 26 deletions
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 6b4c895..8363e6e 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -297,6 +297,10 @@ public class WifiService extends IWifiManager.Stub { mWifiStateMachine.sendMessage(Message.obtain(msg)); break; } + case WifiManager.CANCEL_WPS: { + mWifiStateMachine.sendMessage(Message.obtain(msg)); + break; + } case WifiManager.DISABLE_NETWORK: { mWifiStateMachine.sendMessage(Message.obtain(msg)); break; diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index 8305714..46ad036 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -286,7 +286,10 @@ class WifiConfigStore { config.status = Status.CURRENT; break; case DISCONNECTED: - config.status = Status.ENABLED; + //If network is already disabled, keep the status + if (config.status == Status.CURRENT) { + config.status = Status.ENABLED; + } break; default: //do nothing, retain the existing state @@ -906,7 +909,7 @@ class WifiConfigStore { } } } else { - loge("Missing id while parsing configuration"); + if (DBG) log("Missing id while parsing configuration"); } } } catch (EOFException ignore) { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index bdee12a..bc423a5 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1069,15 +1069,22 @@ public class WifiManager { public static final int START_WPS_SUCCEEDED = BASE + 11; /** @hide */ public static final int WPS_FAILED = BASE + 12; - /** @hide */ + /** @hide */ public static final int WPS_COMPLETED = BASE + 13; /** @hide */ - public static final int DISABLE_NETWORK = BASE + 14; + public static final int CANCEL_WPS = BASE + 14; + /** @hide */ + public static final int CANCEL_WPS_FAILED = BASE + 15; + /** @hide */ + public static final int CANCEL_WPS_SUCCEDED = BASE + 16; + + /** @hide */ + public static final int DISABLE_NETWORK = BASE + 17; /** @hide */ - public static final int DISABLE_NETWORK_FAILED = BASE + 15; + public static final int DISABLE_NETWORK_FAILED = BASE + 18; /** @hide */ - public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 16; + public static final int DISABLE_NETWORK_SUCCEEDED = BASE + 19; /* For system use only */ /** @hide */ @@ -1091,14 +1098,14 @@ public class WifiManager { * Indicates that the operation failed due to an internal error. * @hide */ - public static final int ERROR = 0; + public static final int ERROR = 0; /** * Passed with {@link ActionListener#onFailure}. * Indicates that the operation is already in progress * @hide */ - public static final int IN_PROGRESS = 1; + public static final int IN_PROGRESS = 1; /** * Passed with {@link ActionListener#onFailure}. @@ -1106,11 +1113,19 @@ public class WifiManager { * unable to service the request * @hide */ - public static final int BUSY = 2; + public static final int BUSY = 2; /* WPS specific errors */ /** WPS overlap detected {@hide} */ - public static final int WPS_OVERLAP_ERROR = 3; + public static final int WPS_OVERLAP_ERROR = 3; + /** WEP on WPS is prohibited {@hide} */ + public static final int WPS_WEP_PROHIBITED = 4; + /** TKIP only prohibited {@hide} */ + public static final int WPS_TKIP_ONLY_PROHIBITED = 5; + /** Authentication failure on WPS {@hide} */ + public static final int WPS_AUTH_FAILURE = 6; + /** WPS timed out {@hide} */ + public static final int WPS_TIMED_OUT = 7; /** Interface for callback invocation when framework channel is lost {@hide} */ public interface ChannelListener { @@ -1165,6 +1180,7 @@ public class WifiManager { private SparseArray<Object> mListenerMap = new SparseArray<Object>(); private Object mListenerMapLock = new Object(); private int mListenerKey = 0; + private static final int INVALID_KEY = -1; AsyncChannel mAsyncChannel; WifiHandler mHandler; @@ -1187,6 +1203,7 @@ public class WifiManager { case WifiManager.CONNECT_NETWORK_FAILED: case WifiManager.FORGET_NETWORK_FAILED: case WifiManager.SAVE_NETWORK_FAILED: + case WifiManager.CANCEL_WPS_FAILED: case WifiManager.DISABLE_NETWORK_FAILED: if (listener != null) { ((ActionListener) listener).onFailure(message.arg1); @@ -1196,6 +1213,7 @@ public class WifiManager { case WifiManager.CONNECT_NETWORK_SUCCEEDED: case WifiManager.FORGET_NETWORK_SUCCEEDED: case WifiManager.SAVE_NETWORK_SUCCEEDED: + case WifiManager.CANCEL_WPS_SUCCEDED: case WifiManager.DISABLE_NETWORK_SUCCEEDED: if (listener != null) { ((ActionListener) listener).onSuccess(); @@ -1229,16 +1247,19 @@ public class WifiManager { } int putListener(Object listener) { - if (listener == null) return 0; + if (listener == null) return INVALID_KEY; int key; synchronized (mListenerMapLock) { - key = mListenerKey++; + do { + key = mListenerKey++; + } while (key == INVALID_KEY); mListenerMap.put(key, listener); } return key; } Object removeListener(int key) { + if (key == INVALID_KEY) return null; synchronized (mListenerMapLock) { Object listener = mListenerMap.get(key); mListenerMap.remove(key); @@ -1385,6 +1406,21 @@ public class WifiManager { } /** + * Cancel any ongoing Wi-fi Protected Setup + * + * @param c is the channel created at {@link #initialize} + * @param listener for callbacks on success or failure. Can be null. + * @hide + */ + public void cancelWps(Channel c, ActionListener listener) { + if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + + c.mAsyncChannel.sendMessage(CANCEL_WPS, 0, c.putListener(listener)); + } + + + + /** * Get a reference to WifiService handler. This is used by a client to establish * an AsyncChannel communication with WifiService * diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index e1cfba3..c406fa0 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -65,7 +65,20 @@ public class WifiMonitor { /* WPS events */ private static final String WPS_SUCCESS_STR = "WPS-SUCCESS"; + + /* Format: WPS-FAIL msg=%d [config_error=%d] [reason=%d (%s)] */ private static final String WPS_FAIL_STR = "WPS-FAIL"; + private static final String WPS_FAIL_PATTERN = + "WPS-FAIL msg=\\d+(?: config_error=(\\d+))?(?: reason=(\\d+))?"; + + /* config error code values for config_error=%d */ + private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12; + private static final int CONFIG_AUTH_FAILURE = 18; + + /* reason code values for reason=%d */ + private static final int REASON_TKIP_ONLY_PROHIBITED = 1; + private static final int REASON_WEP_PROHIBITED = 2; + private static final String WPS_OVERLAP_STR = "WPS-OVERLAP-DETECTED"; private static final String WPS_TIMEOUT_STR = "WPS-TIMEOUT"; @@ -316,7 +329,7 @@ public class WifiMonitor { } else if (eventStr.startsWith(WPS_SUCCESS_STR)) { mStateMachine.sendMessage(WPS_SUCCESS_EVENT); } else if (eventStr.startsWith(WPS_FAIL_STR)) { - mStateMachine.sendMessage(WPS_FAIL_EVENT); + handleWpsFailEvent(eventStr); } else if (eventStr.startsWith(WPS_OVERLAP_STR)) { mStateMachine.sendMessage(WPS_OVERLAP_EVENT); } else if (eventStr.startsWith(WPS_TIMEOUT_STR)) { @@ -458,6 +471,43 @@ public class WifiMonitor { } } + private void handleWpsFailEvent(String dataString) { + final Pattern p = Pattern.compile(WPS_FAIL_PATTERN); + Matcher match = p.matcher(dataString); + if (match.find()) { + String cfgErr = match.group(1); + String reason = match.group(2); + + if (reason != null) { + switch(Integer.parseInt(reason)) { + case REASON_TKIP_ONLY_PROHIBITED: + mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT, + WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0)); + return; + case REASON_WEP_PROHIBITED: + mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT, + WifiManager.WPS_WEP_PROHIBITED, 0)); + return; + } + } + if (cfgErr != null) { + switch(Integer.parseInt(cfgErr)) { + case CONFIG_AUTH_FAILURE: + mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT, + WifiManager.WPS_AUTH_FAILURE, 0)); + return; + case CONFIG_MULTIPLE_PBC_DETECTED: + mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT, + WifiManager.WPS_OVERLAP_ERROR, 0)); + return; + } + } + } + //For all other errors, return a generic internal error + mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT, + WifiManager.ERROR, 0)); + } + /** * Handle p2p events */ diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index e3dd3a6..ecd4073 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -388,27 +388,37 @@ public class WifiNative { return doStringCommand("SIGNAL_POLL"); } - public boolean startWpsPbc() { - return doBooleanCommand("WPS_PBC"); - } - public boolean startWpsPbc(String bssid) { - return doBooleanCommand("WPS_PBC " + bssid); + if (TextUtils.isEmpty(bssid)) { + return doBooleanCommand("WPS_PBC"); + } else { + return doBooleanCommand("WPS_PBC " + bssid); + } } public boolean startWpsPinKeypad(String pin) { + if (TextUtils.isEmpty(pin)) return false; return doBooleanCommand("WPS_PIN any " + pin); } public String startWpsPinDisplay(String bssid) { - return doStringCommand("WPS_PIN " + bssid); + if (TextUtils.isEmpty(bssid)) { + return doStringCommand("WPS_PIN any"); + } else { + return doStringCommand("WPS_PIN " + bssid); + } } /* Configures an access point connection */ public boolean startWpsRegistrar(String bssid, String pin) { + if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false; return doBooleanCommand("WPS_REG " + bssid + " " + pin); } + public boolean cancelWps() { + return doBooleanCommand("WPS_CANCEL"); + } + public boolean setPersistentReconnect(boolean enabled) { int value = (enabled == true) ? 1 : 0; return doBooleanCommand("SET persistent_reconnect " + value); @@ -539,7 +549,7 @@ public class WifiNative { } public boolean p2pGroupRemove(String iface) { - if (iface == null) return false; + if (TextUtils.isEmpty(iface)) return false; return doBooleanCommand("P2P_GROUP_REMOVE " + iface); } @@ -549,7 +559,7 @@ public class WifiNative { /* Invite a peer to a group */ public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) { - if (deviceAddress == null) return false; + if (TextUtils.isEmpty(deviceAddress)) return false; if (group == null) { return doBooleanCommand("P2P_INVITE peer=" + deviceAddress); @@ -561,19 +571,19 @@ public class WifiNative { /* Reinvoke a persistent connection */ public boolean p2pReinvoke(int netId, String deviceAddress) { - if (deviceAddress == null || netId < 0) return false; + if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false; return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress); } public String p2pGetInterfaceAddress(String deviceAddress) { - if (deviceAddress == null) return null; + if (TextUtils.isEmpty(deviceAddress)) return null; // "p2p_peer deviceAddress" returns a multi-line result containing // intended_addr=fa:7b:7a:42:82:13 String peerInfo = p2pPeer(deviceAddress); - if (peerInfo == null) return null; + if (TextUtils.isEmpty(peerInfo)) return null; String[] tokens= peerInfo.split("\n"); for (String token : tokens) { diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index d6988cd..843620c 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1844,6 +1844,10 @@ public class WifiStateMachine extends StateMachine { replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.BUSY); break; + case WifiManager.CANCEL_WPS: + replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, + WifiManager.BUSY); + break; case WifiManager.DISABLE_NETWORK: replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED, WifiManager.BUSY); @@ -3321,8 +3325,15 @@ public class WifiStateMachine extends StateMachine { transitionTo(mDisconnectedState); break; case WifiMonitor.WPS_FAIL_EVENT: + //arg1 has the reason for the failure + replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, message.arg1); + mSourceMessage.recycle(); + mSourceMessage = null; + transitionTo(mDisconnectedState); + break; case WifiMonitor.WPS_TIMEOUT_EVENT: - replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, WifiManager.ERROR); + replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, + WifiManager.WPS_TIMED_OUT); mSourceMessage.recycle(); mSourceMessage = null; transitionTo(mDisconnectedState); @@ -3330,6 +3341,14 @@ public class WifiStateMachine extends StateMachine { case WifiManager.START_WPS: replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.IN_PROGRESS); break; + case WifiManager.CANCEL_WPS: + if (mWifiNative.cancelWps()) { + replyToMessage(message, WifiManager.CANCEL_WPS_SUCCEDED); + } else { + replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, WifiManager.ERROR); + } + transitionTo(mDisconnectedState); + break; /* Defer all commands that can cause connections to a different network * or put the state machine out of connect mode */ @@ -3346,6 +3365,11 @@ public class WifiStateMachine extends StateMachine { if (DBG) log("Network connection lost"); handleNetworkDisconnect(); break; + case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: + //Throw away supplicant state changes when WPS is running. + //We will start getting supplicant state changes once we get + //a WPS success or failure + break; default: return NOT_HANDLED; } @@ -3353,6 +3377,7 @@ public class WifiStateMachine extends StateMachine { return HANDLED; } + @Override public void exit() { mWifiConfigStore.enableAllNetworks(); mWifiConfigStore.loadConfiguredNetworks(); diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index 5b0e424..399dc9d 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -996,7 +996,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { break; case PEER_CONNECTION_USER_ACCEPT: if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) { - mWifiNative.startWpsPbc(); + mWifiNative.startWpsPbc(null); } else { mWifiNative.startWpsPinKeypad(mSavedPeerConfig.wps.pin); } |