summaryrefslogtreecommitdiffstats
path: root/wifi
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2012-02-28 17:03:56 -0800
committerIrfan Sheriff <isheriff@google.com>2012-03-02 14:09:53 -0800
commit86a5f5b9afa97a4ed6f5a2466fb9359ea131e2fb (patch)
treebee6fb52f69b677065cc1ee4e12f53e07ae00023 /wifi
parent1a7dd039f189036709bc2253ba50955913f59d7a (diff)
downloadframeworks_base-86a5f5b9afa97a4ed6f5a2466fb9359ea131e2fb.zip
frameworks_base-86a5f5b9afa97a4ed6f5a2466fb9359ea131e2fb.tar.gz
frameworks_base-86a5f5b9afa97a4ed6f5a2466fb9359ea131e2fb.tar.bz2
Enhance WPS
- Add a cancel API - Add more error reporting on WPS - Fix network status reporting that showed up with new implementation Change-Id: I499796c80d16d18df95fb702d029aa7e7283b603
Diffstat (limited to 'wifi')
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java7
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java56
-rw-r--r--wifi/java/android/net/wifi/WifiMonitor.java52
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java32
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java27
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pService.java2
6 files changed, 150 insertions, 26 deletions
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);
}