summaryrefslogtreecommitdiffstats
path: root/wifi/java/android/net/wifi/p2p
diff options
context:
space:
mode:
authorIrfan Sheriff <isheriff@google.com>2012-12-13 12:33:42 -0800
committerIrfan Sheriff <isheriff@google.com>2012-12-14 14:48:10 -0800
commitf118043ca726c65f04cddc6321c9e820b577fc6f (patch)
tree25c0a688b56e0b64d9858e0f52ccf84005f53629 /wifi/java/android/net/wifi/p2p
parent3a67e2515bff73fab57621b1f9966662e83b7881 (diff)
downloadframeworks_base-f118043ca726c65f04cddc6321c9e820b577fc6f.zip
frameworks_base-f118043ca726c65f04cddc6321c9e820b577fc6f.tar.gz
frameworks_base-f118043ca726c65f04cddc6321c9e820b577fc6f.tar.bz2
P2p cleanup
- Clean up handling of mSavedPeerConfig - Add argument protection - Split out WPS handling on GO into a separate API. This was almost hacky right now for applications and was working in an undocumented way - Refactor connect function call and fix updating group capability Change-Id: I26211c72ad60c6b6c939ad7473fcf2fc633f3010
Diffstat (limited to 'wifi/java/android/net/wifi/p2p')
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pConfig.java6
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java36
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pManager.java108
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pService.java344
4 files changed, 296 insertions, 198 deletions
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index b1501ed..482d9cb 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -30,7 +30,7 @@ public class WifiP2pConfig implements Parcelable {
/**
* The device MAC address uniquely identifies a Wi-Fi p2p device
*/
- public String deviceAddress;
+ public String deviceAddress = "";
/**
* Wi-Fi Protected Setup information
@@ -60,6 +60,10 @@ public class WifiP2pConfig implements Parcelable {
wps.setup = WpsInfo.PBC;
}
+ void invalidate() {
+ deviceAddress = "";
+ }
+
/** P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 {@hide}*/
public WifiP2pConfig(String supplicantEvent) throws IllegalArgumentException {
String[] tokens = supplicantEvent.split(" ");
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index f7bceac..4f40ebc 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -58,6 +58,19 @@ public class WifiP2pDeviceList implements Parcelable {
}
}
+ private void validateDevice(WifiP2pDevice device) {
+ if (device == null) throw new IllegalArgumentException("Null device");
+ if (TextUtils.isEmpty(device.deviceAddress)) {
+ throw new IllegalArgumentException("Empty deviceAddress");
+ }
+ }
+
+ private void validateDeviceAddress(String deviceAddress) {
+ if (TextUtils.isEmpty(deviceAddress)) {
+ throw new IllegalArgumentException("Empty deviceAddress");
+ }
+ }
+
/** Clear the list @hide */
public boolean clear() {
if (mDevices.isEmpty()) return false;
@@ -72,14 +85,13 @@ public class WifiP2pDeviceList implements Parcelable {
* @hide
*/
public void update(WifiP2pDevice device) {
- if (device == null || device.deviceAddress == null) return;
updateSupplicantDetails(device);
mDevices.get(device.deviceAddress).status = device.status;
}
/** Only updates details fetched from the supplicant @hide */
void updateSupplicantDetails(WifiP2pDevice device) {
- if (device == null || device.deviceAddress == null) return;
+ validateDevice(device);
WifiP2pDevice d = mDevices.get(device.deviceAddress);
if (d != null) {
d.deviceName = device.deviceName;
@@ -97,7 +109,7 @@ public class WifiP2pDeviceList implements Parcelable {
/** @hide */
void updateGroupCapability(String deviceAddress, int groupCapab) {
- if (TextUtils.isEmpty(deviceAddress)) return;
+ validateDeviceAddress(deviceAddress);
WifiP2pDevice d = mDevices.get(deviceAddress);
if (d != null) {
d.groupCapability = groupCapab;
@@ -106,7 +118,7 @@ public class WifiP2pDeviceList implements Parcelable {
/** @hide */
void updateStatus(String deviceAddress, int status) {
- if (TextUtils.isEmpty(deviceAddress)) return;
+ validateDeviceAddress(deviceAddress);
WifiP2pDevice d = mDevices.get(deviceAddress);
if (d != null) {
d.status = status;
@@ -119,14 +131,13 @@ public class WifiP2pDeviceList implements Parcelable {
* @return WifiP2pDevice device found, or null if none found
*/
public WifiP2pDevice get(String deviceAddress) {
- if (deviceAddress == null) return null;
-
+ validateDeviceAddress(deviceAddress);
return mDevices.get(deviceAddress);
}
/** @hide */
public boolean remove(WifiP2pDevice device) {
- if (device == null || device.deviceAddress == null) return false;
+ validateDevice(device);
return mDevices.remove(device.deviceAddress) != null;
}
@@ -137,7 +148,7 @@ public class WifiP2pDeviceList implements Parcelable {
* @hide
*/
public WifiP2pDevice remove(String deviceAddress) {
- if (deviceAddress == null) return null;
+ validateDeviceAddress(deviceAddress);
return mDevices.remove(deviceAddress);
}
@@ -157,11 +168,12 @@ public class WifiP2pDeviceList implements Parcelable {
/** @hide */
public boolean isGroupOwner(String deviceAddress) {
- if (deviceAddress != null) {
- WifiP2pDevice device = mDevices.get(deviceAddress);
- if (device != null) return device.isGroupOwner();
+ validateDeviceAddress(deviceAddress);
+ WifiP2pDevice device = mDevices.get(deviceAddress);
+ if (device == null) {
+ throw new IllegalArgumentException("Device not found " + deviceAddress);
}
- return false;
+ return device.isGroupOwner();
}
public String toString() {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 5bd0349..2e80064 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -21,6 +21,7 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
+import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
@@ -37,6 +38,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.WorkSource;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.util.AsyncChannel;
@@ -421,6 +423,13 @@ public class WifiP2pManager {
/** @hide */
public static final int SET_WFD_INFO_SUCCEEDED = BASE + 61;
+ /** @hide */
+ public static final int START_WPS = BASE + 62;
+ /** @hide */
+ public static final int START_WPS_FAILED = BASE + 63;
+ /** @hide */
+ public static final int START_WPS_SUCCEEDED = BASE + 64;
+
/**
* Create a new WifiP2pManager instance. Applications use
* {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve
@@ -641,70 +650,72 @@ public class WifiP2pManager {
}
break;
/* ActionListeners grouped together */
- case WifiP2pManager.DISCOVER_PEERS_FAILED:
- case WifiP2pManager.STOP_DISCOVERY_FAILED:
- case WifiP2pManager.DISCOVER_SERVICES_FAILED:
- case WifiP2pManager.CONNECT_FAILED:
- case WifiP2pManager.CANCEL_CONNECT_FAILED:
- case WifiP2pManager.CREATE_GROUP_FAILED:
- case WifiP2pManager.REMOVE_GROUP_FAILED:
- case WifiP2pManager.ADD_LOCAL_SERVICE_FAILED:
- case WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED:
- case WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED:
- case WifiP2pManager.ADD_SERVICE_REQUEST_FAILED:
- case WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED:
- case WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED:
- case WifiP2pManager.SET_DEVICE_NAME_FAILED:
- case WifiP2pManager.DELETE_PERSISTENT_GROUP_FAILED:
- case WifiP2pManager.SET_WFD_INFO_FAILED:
+ case DISCOVER_PEERS_FAILED:
+ case STOP_DISCOVERY_FAILED:
+ case DISCOVER_SERVICES_FAILED:
+ case CONNECT_FAILED:
+ case CANCEL_CONNECT_FAILED:
+ case CREATE_GROUP_FAILED:
+ case REMOVE_GROUP_FAILED:
+ case ADD_LOCAL_SERVICE_FAILED:
+ case REMOVE_LOCAL_SERVICE_FAILED:
+ case CLEAR_LOCAL_SERVICES_FAILED:
+ case ADD_SERVICE_REQUEST_FAILED:
+ case REMOVE_SERVICE_REQUEST_FAILED:
+ case CLEAR_SERVICE_REQUESTS_FAILED:
+ case SET_DEVICE_NAME_FAILED:
+ case DELETE_PERSISTENT_GROUP_FAILED:
+ case SET_WFD_INFO_FAILED:
+ case START_WPS_FAILED:
if (listener != null) {
((ActionListener) listener).onFailure(message.arg1);
}
break;
/* ActionListeners grouped together */
- case WifiP2pManager.DISCOVER_PEERS_SUCCEEDED:
- case WifiP2pManager.STOP_DISCOVERY_SUCCEEDED:
- case WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED:
- case WifiP2pManager.CONNECT_SUCCEEDED:
- case WifiP2pManager.CANCEL_CONNECT_SUCCEEDED:
- case WifiP2pManager.CREATE_GROUP_SUCCEEDED:
- case WifiP2pManager.REMOVE_GROUP_SUCCEEDED:
- case WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED:
- case WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED:
- case WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED:
- case WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED:
- case WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED:
- case WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED:
- case WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED:
- case WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED:
- case WifiP2pManager.SET_WFD_INFO_SUCCEEDED:
+ case DISCOVER_PEERS_SUCCEEDED:
+ case STOP_DISCOVERY_SUCCEEDED:
+ case DISCOVER_SERVICES_SUCCEEDED:
+ case CONNECT_SUCCEEDED:
+ case CANCEL_CONNECT_SUCCEEDED:
+ case CREATE_GROUP_SUCCEEDED:
+ case REMOVE_GROUP_SUCCEEDED:
+ case ADD_LOCAL_SERVICE_SUCCEEDED:
+ case REMOVE_LOCAL_SERVICE_SUCCEEDED:
+ case CLEAR_LOCAL_SERVICES_SUCCEEDED:
+ case ADD_SERVICE_REQUEST_SUCCEEDED:
+ case REMOVE_SERVICE_REQUEST_SUCCEEDED:
+ case CLEAR_SERVICE_REQUESTS_SUCCEEDED:
+ case SET_DEVICE_NAME_SUCCEEDED:
+ case DELETE_PERSISTENT_GROUP_SUCCEEDED:
+ case SET_WFD_INFO_SUCCEEDED:
+ case START_WPS_SUCCEEDED:
if (listener != null) {
((ActionListener) listener).onSuccess();
}
break;
- case WifiP2pManager.RESPONSE_PEERS:
+ case RESPONSE_PEERS:
WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj;
if (listener != null) {
((PeerListListener) listener).onPeersAvailable(peers);
}
break;
- case WifiP2pManager.RESPONSE_CONNECTION_INFO:
+ case RESPONSE_CONNECTION_INFO:
WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj;
if (listener != null) {
((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo);
}
break;
- case WifiP2pManager.RESPONSE_GROUP_INFO:
+ case RESPONSE_GROUP_INFO:
WifiP2pGroup group = (WifiP2pGroup) message.obj;
if (listener != null) {
((GroupInfoListener) listener).onGroupInfoAvailable(group);
}
break;
- case WifiP2pManager.RESPONSE_SERVICE:
+ case RESPONSE_SERVICE:
WifiP2pServiceResponse resp = (WifiP2pServiceResponse) message.obj;
handleServiceResponse(resp);
break;
- case WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO:
+ case RESPONSE_PERSISTENT_GROUP_INFO:
WifiP2pGroupList groups = (WifiP2pGroupList) message.obj;
if (listener != null) {
((PersistentGroupInfoListener) listener).
@@ -790,6 +801,13 @@ public class WifiP2pManager {
if (req == null) throw new IllegalArgumentException("service request is null");
}
+ private static void checkP2pConfig(WifiP2pConfig c) {
+ if (c == null) throw new IllegalArgumentException("config cannot be null");
+ if (TextUtils.isEmpty(c.deviceAddress)) {
+ throw new IllegalArgumentException("deviceAddress cannot be empty");
+ }
+ }
+
/**
* Registers the application with the Wi-Fi framework. This function
* must be the first to be called before any p2p operations are performed.
@@ -876,6 +894,7 @@ public class WifiP2pManager {
*/
public void connect(Channel c, WifiP2pConfig config, ActionListener listener) {
checkChannel(c);
+ checkP2pConfig(config);
c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config);
}
@@ -937,6 +956,21 @@ public class WifiP2pManager {
}
/**
+ * Start a Wi-Fi Protected Setup (WPS) session.
+ *
+ * <p> The function call immediately returns after sending a request to start a
+ * WPS session. Currently, this is only valid if the current device is running
+ * as a group owner to allow any new clients to join the group. The application
+ * is notified of a success or failure to initiate WPS through listener callbacks
+ * {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}.
+ * @hide
+ */
+ public void startWps(Channel c, WpsInfo wps, ActionListener listener) {
+ checkChannel(c);
+ c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), wps);
+ }
+
+ /**
* Register a local service for service discovery. If a local service is registered,
* the framework automatically responds to a service discovery request from a peer.
*
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index c1d177d..debf988 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -114,16 +114,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
private static final Boolean JOIN_GROUP = true;
private static final Boolean FORM_GROUP = false;
- private static final Boolean TRY_REINVOCATION = true;;
- private static final Boolean NO_REINVOCATION = false;
-
private static final Boolean RELOAD = true;
private static final Boolean NO_RELOAD = false;
- private static final int CONNECT_FAILURE = -1;
- private static final int CONNECT_SUCCESS = 0;
- private static final int NEEDS_PROVISION_REQ = 1;
-
/* Two minutes comes from the wpa_supplicant setting */
private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
private static int mGroupCreatingTimeoutIndex = 0;
@@ -361,8 +354,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
// Inactive is when p2p is enabled with no connectivity
private InactiveState mInactiveState = new InactiveState();
private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
- private UserAuthorizingInvitationState mUserAuthorizingInvitationState
- = new UserAuthorizingInvitationState();
+ private UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState
+ = new UserAuthorizingInviteRequestState();
+ private UserAuthorizingNegotiationRequestState mUserAuthorizingNegotiationRequestState
+ = new UserAuthorizingNegotiationRequestState();
private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
private FrequencyConflictState mFrequencyConflictState =new FrequencyConflictState();
@@ -397,8 +392,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
private WifiP2pGroup mGroup;
- // Saved WifiP2pConfig for a peer connection
- private WifiP2pConfig mSavedPeerConfig;
+ // Saved WifiP2pConfig for an ongoing peer connection. This will never be null.
+ // The deviceAddress will be an empty string when the device is inactive
+ // or if it is connected without any ongoing join request
+ private WifiP2pConfig mSavedPeerConfig = new WifiP2pConfig();
// Saved WifiP2pGroup from invitation request
private WifiP2pGroup mSavedP2pGroup;
@@ -414,7 +411,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
addState(mP2pEnabledState, mDefaultState);
addState(mInactiveState, mP2pEnabledState);
addState(mGroupCreatingState, mP2pEnabledState);
- addState(mUserAuthorizingInvitationState, mGroupCreatingState);
+ addState(mUserAuthorizingInviteRequestState, mGroupCreatingState);
+ addState(mUserAuthorizingNegotiationRequestState, mGroupCreatingState);
addState(mProvisionDiscoveryState, mGroupCreatingState);
addState(mGroupNegotiationState, mGroupCreatingState);
addState(mFrequencyConflictState, mGroupCreatingState);
@@ -541,6 +539,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
new WifiP2pGroupList(mGroups, null));
break;
+ case WifiP2pManager.START_WPS:
+ replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
+ WifiP2pManager.BUSY);
+ break;
// Ignore
case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
case WifiMonitor.SCAN_RESULTS_EVENT:
@@ -667,6 +669,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
WifiP2pManager.P2P_UNSUPPORTED);
break;
+ case WifiP2pManager.START_WPS:
+ replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
+ WifiP2pManager.P2P_UNSUPPORTED);
+ break;
default:
return NOT_HANDLED;
}
@@ -943,9 +949,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
@Override
public void enter() {
if (DBG) logd(getName());
- //Start listening every time we get inactive
- //TODO: Fix listen after driver behavior is fixed
- //mWifiNative.p2pListen();
+ mSavedPeerConfig.invalidate();
}
@Override
@@ -955,25 +959,23 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
case WifiP2pManager.CONNECT:
if (DBG) logd(getName() + " sending connect");
WifiP2pConfig config = (WifiP2pConfig) message.obj;
- mAutonomousGroup = false;
-
- /* Update group capability before connect */
- int gc = mWifiNative.getGroupCapability(config.deviceAddress);
- mPeers.updateGroupCapability(config.deviceAddress, gc);
- int connectRet = connect(config, TRY_REINVOCATION);
- if (connectRet == CONNECT_FAILURE) {
+ if (isConfigInvalid(config)) {
+ loge("Dropping connect requeset " + config);
replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
break;
}
+
+ mAutonomousGroup = false;
+ mWifiNative.p2pStopFind();
+ if (reinvokePersistentGroup(config)) {
+ transitionTo(mGroupNegotiationState);
+ } else {
+ transitionTo(mProvisionDiscoveryState);
+ }
+ mSavedPeerConfig = config;
mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
sendPeersChangedBroadcast();
replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
- if (connectRet == NEEDS_PROVISION_REQ) {
- if (DBG) logd("Sending prov disc");
- transitionTo(mProvisionDiscoveryState);
- break;
- }
- transitionTo(mGroupNegotiationState);
break;
case WifiP2pManager.STOP_DISCOVERY:
if (mWifiNative.p2pStopFind()) {
@@ -988,22 +990,33 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
}
break;
case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
- mSavedPeerConfig = (WifiP2pConfig) message.obj;
+ config = (WifiP2pConfig) message.obj;
+ if (isConfigInvalid(config)) {
+ loge("Dropping GO neg request " + config);
+ break;
+ }
+ mSavedPeerConfig = config;
mAutonomousGroup = false;
mJoinExistingGroup = false;
- transitionTo(mUserAuthorizingInvitationState);
+ transitionTo(mUserAuthorizingNegotiationRequestState);
break;
case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
WifiP2pGroup group = (WifiP2pGroup) message.obj;
WifiP2pDevice owner = group.getOwner();
if (owner == null) {
- if (DBG) loge("Ignored invitation from null owner");
+ loge("Ignored invitation from null owner");
break;
}
- mSavedPeerConfig = new WifiP2pConfig();
- mSavedPeerConfig.deviceAddress = group.getOwner().deviceAddress;
+ config = new WifiP2pConfig();
+ config.deviceAddress = group.getOwner().deviceAddress;
+
+ if (isConfigInvalid(config)) {
+ loge("Dropping invitation request " + config);
+ break;
+ }
+ mSavedPeerConfig = config;
//Check if we have the owner in peer list and use appropriate
//wps method. Default is to use PBC.
@@ -1019,7 +1032,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
mAutonomousGroup = false;
mJoinExistingGroup = true;
- transitionTo(mUserAuthorizingInvitationState);
+ transitionTo(mUserAuthorizingInviteRequestState);
break;
case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
@@ -1097,11 +1110,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
break;
case WifiMonitor.P2P_DEVICE_LOST_EVENT:
WifiP2pDevice device = (WifiP2pDevice) message.obj;
-
- // If we lose a device during an autonomous group creation,
- // mSavedPeerConfig can be empty
- if (mSavedPeerConfig != null &&
- !mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
+ if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
if (DBG) {
logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress +
"device " + device.deviceAddress);
@@ -1137,7 +1146,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
}
}
- class UserAuthorizingInvitationState extends State {
+ class UserAuthorizingNegotiationRequestState extends State {
@Override
public void enter() {
if (DBG) logd(getName());
@@ -1150,18 +1159,52 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
boolean ret = HANDLED;
switch (message.what) {
case PEER_CONNECTION_USER_ACCEPT:
- if (connect(mSavedPeerConfig, TRY_REINVOCATION) == CONNECT_FAILURE) {
- handleGroupCreationFailure();
- transitionTo(mInactiveState);
- break;
- }
+ mWifiNative.p2pStopFind();
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
sendPeersChangedBroadcast();
transitionTo(mGroupNegotiationState);
+ break;
+ case PEER_CONNECTION_USER_REJECT:
+ if (DBG) logd("User rejected negotiation " + mSavedPeerConfig);
+ transitionTo(mInactiveState);
break;
+ default:
+ return NOT_HANDLED;
+ }
+ return ret;
+ }
+
+ @Override
+ public void exit() {
+ //TODO: dismiss dialog if not already done
+ }
+ }
+
+ class UserAuthorizingInviteRequestState extends State {
+ @Override
+ public void enter() {
+ if (DBG) logd(getName());
+ notifyInvitationReceived();
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) logd(getName() + message.toString());
+ boolean ret = HANDLED;
+ switch (message.what) {
+ case PEER_CONNECTION_USER_ACCEPT:
+ mWifiNative.p2pStopFind();
+ if (!reinvokePersistentGroup(mSavedPeerConfig)) {
+ // Do negotiation when persistence fails
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
+ }
+ mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
+ sendPeersChangedBroadcast();
+ transitionTo(mGroupNegotiationState);
+ break;
case PEER_CONNECTION_USER_REJECT:
if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
- mSavedPeerConfig = null;
transitionTo(mInactiveState);
break;
default:
@@ -1176,6 +1219,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
}
}
+
+
class ProvisionDiscoveryState extends State {
@Override
public void enter() {
@@ -1213,7 +1258,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
transitionTo(mGroupNegotiationState);
} else {
mJoinExistingGroup = false;
- transitionTo(mUserAuthorizingInvitationState);
+ transitionTo(mUserAuthorizingNegotiationRequestState);
}
}
break;
@@ -1292,7 +1337,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
sendPeersChangedBroadcast();
}
- mSavedPeerConfig = null;
transitionTo(mGroupCreatedState);
break;
case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
@@ -1323,7 +1367,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
// invocation was succeeded.
// wait P2P_GROUP_STARTED_EVENT.
break;
- } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+ }
+ loge("Invitation result " + status);
+ if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
// target device has already removed the credential.
// So, remove this credential accordingly.
int netId = mSavedPeerConfig.netId;
@@ -1332,12 +1378,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
}
- // invocation is failed. Try another way to connect.
+ // Reinvocation has failed, try group negotiation
mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
- if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
- handleGroupCreationFailure();
- transitionTo(mInactiveState);
- }
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
} else if (status == P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE) {
// Devices setting persistent_reconnect to 0 in wpa_supplicant
@@ -1345,10 +1388,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
// "information is currently unable" error.
// So, try another way to connect for interoperability.
mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
- if (connect(mSavedPeerConfig, NO_REINVOCATION) == CONNECT_FAILURE) {
- handleGroupCreationFailure();
- transitionTo(mInactiveState);
- }
+ p2pConnectWithPinDisplay(mSavedPeerConfig);
} else if (status == P2pStatus.NO_COMMON_CHANNEL) {
transitionTo(mFrequencyConflictState);
} else {
@@ -1452,6 +1492,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
@Override
public void enter() {
if (DBG) logd(getName());
+ // Once connected, peer config details are invalid
+ mSavedPeerConfig.invalidate();
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
updateThisDevice(WifiP2pDevice.CONNECTED);
@@ -1497,7 +1539,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
if (mGroup.removeClient(deviceAddress)) {
if (DBG) logd("Removed client " + deviceAddress);
if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
- Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
+ logd("Client list empty, remove non-persistent p2p group");
mWifiNative.p2pGroupRemove(mGroup.getInterface());
// We end up sending connection changed broadcast
// when this happens at exit()
@@ -1573,50 +1615,61 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
sendMessage(WifiP2pManager.REMOVE_GROUP);
deferMessage(message);
break;
- case WifiP2pManager.CONNECT:
- WifiP2pConfig config = (WifiP2pConfig) message.obj;
// This allows any client to join the GO during the
// WPS window
- if (config.deviceAddress == null) {
- if (config.wps.setup == WpsInfo.PBC) {
- mWifiNative.startWpsPbc(mGroup.getInterface(), null);
- } else {
- if (config.wps.pin == null) {
- String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
- try {
- Integer.parseInt(pin);
- notifyInvitationSent(pin, config.deviceAddress != null ?
- config.deviceAddress : "any");
- } catch (NumberFormatException ignore) {
- // do nothing if pin is invalid
- }
- } else {
- mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
- config.wps.pin);
- }
- }
- replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ case WifiP2pManager.START_WPS:
+ WpsInfo wps = (WpsInfo) message.obj;
+ if (wps == null) {
+ replyToMessage(message, WifiP2pManager.START_WPS_FAILED);
+ break;
+ }
+ boolean ret = true;
+ if (wps.setup == WpsInfo.PBC) {
+ ret = mWifiNative.startWpsPbc(mGroup.getInterface(), null);
} else {
- logd("Inviting device : " + config.deviceAddress);
- mSavedPeerConfig = config;
- if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
- mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
- sendPeersChangedBroadcast();
- replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ if (wps.pin == null) {
+ String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
+ try {
+ Integer.parseInt(pin);
+ notifyInvitationSent(pin, "any");
+ } catch (NumberFormatException ignore) {
+ ret = false;
+ }
} else {
- replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
- WifiP2pManager.ERROR);
+ ret = mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
+ wps.pin);
}
}
+ replyToMessage(message, ret ? WifiP2pManager.START_WPS_SUCCEEDED :
+ WifiP2pManager.START_WPS_FAILED);
+ break;
+ case WifiP2pManager.CONNECT:
+ WifiP2pConfig config = (WifiP2pConfig) message.obj;
+ if (isConfigInvalid(config)) {
+ loge("Dropping connect requeset " + config);
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
+ break;
+ }
+ logd("Inviting device : " + config.deviceAddress);
+ mSavedPeerConfig = config;
+ if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
+ mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
+ sendPeersChangedBroadcast();
+ replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+ } else {
+ replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
+ WifiP2pManager.ERROR);
+ }
// TODO: figure out updating the status to declined when invitation is rejected
break;
case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
P2pStatus status = (P2pStatus)message.obj;
- logd("===> INVITATION RESULT EVENT : " + status);
if (status == P2pStatus.SUCCESS) {
// invocation was succeeded.
break;
- } else if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
+ }
+ loge("Invitation result " + status);
+ if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
// target device has already removed the credential.
// So, remove this credential accordingly.
int netId = mGroup.getNetworkId();
@@ -1625,7 +1678,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
if (!removeClientFromList(netId,
mSavedPeerConfig.deviceAddress, false)) {
// not found the client on the list
- Slog.e(TAG, "Already removed the client, ignore");
+ loge("Already removed the client, ignore");
break;
}
// try invitation.
@@ -1650,7 +1703,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
transitionTo(mUserAuthorizingJoinState);
break;
case WifiMonitor.P2P_GROUP_STARTED_EVENT:
- Slog.e(TAG, "Duplicate group creation event notice, ignore");
+ loge("Duplicate group creation event notice, ignore");
break;
default:
return NOT_HANDLED;
@@ -1689,12 +1742,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
mSavedPeerConfig.wps.pin);
}
- mSavedPeerConfig = null;
transitionTo(mGroupCreatedState);
break;
case PEER_CONNECTION_USER_REJECT:
if (DBG) logd("User rejected incoming request");
- mSavedPeerConfig = null;
transitionTo(mGroupCreatedState);
break;
default:
@@ -2025,30 +2076,52 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
}
/**
- * Try to connect to the target device.
- *
- * Use the persistent credential if it has been stored.
- *
- * @param config
- * @param tryInvocation if true, try to invoke. Otherwise, never try to invoke.
- * @return
+ * A config is valid if it has a peer address that has already been
+ * discovered
+ * @return true if it is invalid, false otherwise
*/
- private int connect(WifiP2pConfig config, boolean tryInvocation) {
+ private boolean isConfigInvalid(WifiP2pConfig config) {
+ if (config == null) return true;
+ if (TextUtils.isEmpty(config.deviceAddress)) return true;
+ if (mPeers.get(config.deviceAddress) == null) return true;
+ return false;
+ }
- if (config == null) {
- loge("config is null");
- return CONNECT_FAILURE;
- }
+ /* TODO: The supplicant does not provide group capability changes as an event.
+ * Having it pushed as an event would avoid polling for this information right
+ * before a connection
+ */
+ private WifiP2pDevice fetchCurrentDeviceDetails(WifiP2pConfig config) {
+ /* Fetch & update group capability from supplicant on the device */
+ int gc = mWifiNative.getGroupCapability(config.deviceAddress);
+ mPeers.updateGroupCapability(config.deviceAddress, gc);
+ return mPeers.get(config.deviceAddress);
+ }
- boolean isResp = (mSavedPeerConfig != null &&
- config.deviceAddress.equals(mSavedPeerConfig.deviceAddress));
- mSavedPeerConfig = config;
+ /**
+ * Start a p2p group negotiation and display pin if necessary
+ * @param config for the peer
+ */
+ private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
+ WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
- WifiP2pDevice dev = mPeers.get(config.deviceAddress);
- if (dev == null) {
- loge("target device not found " + config.deviceAddress);
- return CONNECT_FAILURE;
+ String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
+ try {
+ Integer.parseInt(pin);
+ notifyInvitationSent(pin, config.deviceAddress);
+ } catch (NumberFormatException ignore) {
+ // do nothing if p2pConnect did not return a pin
}
+ }
+
+ /**
+ * Reinvoke a persistent group.
+ *
+ * @param config for the peer
+ * @return true on success, false on failure
+ */
+ private boolean reinvokePersistentGroup(WifiP2pConfig config) {
+ WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
boolean join = dev.isGroupOwner();
String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
@@ -2065,18 +2138,18 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
if (netId >= 0) {
// Skip WPS and start 4way handshake immediately.
if (!mWifiNative.p2pGroupAdd(netId)) {
- return CONNECT_FAILURE;
+ return false;
}
- return CONNECT_SUCCESS;
+ return true;
}
}
if (!join && dev.isDeviceLimit()) {
loge("target device reaches the device limit.");
- return CONNECT_FAILURE;
+ return false;
}
- if (!join && tryInvocation && dev.isInvitationCapable()) {
+ if (!join && dev.isInvitationCapable()) {
int netId = WifiP2pGroup.PERSISTENT_NET_ID;
if (config.netId >= 0) {
if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
@@ -2093,25 +2166,17 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
// Invoke the persistent group.
if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
// Save network id. It'll be used when an invitation result event is received.
- mSavedPeerConfig.netId = netId;
- return CONNECT_SUCCESS;
+ config.netId = netId;
+ return true;
} else {
loge("p2pReinvoke() failed, update networks");
updatePersistentNetworks(RELOAD);
- // continue with negotiation
+ return false;
}
}
}
- //Stop discovery before issuing connect
- mWifiNative.p2pStopFind();
-
- if (!isResp) {
- return NEEDS_PROVISION_REQ;
- }
-
- p2pConnectWithPinDisplay(config);
- return CONNECT_SUCCESS;
+ return false;
}
/**
@@ -2217,22 +2282,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
return deviceAddress;
}
- private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
- WifiP2pDevice dev = mPeers.get(config.deviceAddress);
- if (dev == null) {
- loge("target device is not found " + config.deviceAddress);
- return;
- }
-
- String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
- try {
- Integer.parseInt(pin);
- notifyInvitationSent(pin, config.deviceAddress);
- } catch (NumberFormatException ignore) {
- // do nothing if p2pConnect did not return a pin
- }
- }
-
private String getPersistedDeviceName() {
String deviceName = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.WIFI_P2P_DEVICE_NAME);
@@ -2299,7 +2348,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
updateThisDevice(WifiP2pDevice.AVAILABLE);
- if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress);
+ if (DBG) logd("DeviceAddress: " + mThisDevice.deviceAddress);
mClientInfoList.clear();
mWifiNative.p2pFlush();
@@ -2323,14 +2372,13 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
// Remove only the peer we failed to connect to so that other devices discovered
// that have not timed out still remain in list for connection
boolean peersChanged = mPeers.remove(mPeersLostDuringConnection);
- if (mSavedPeerConfig != null && mPeers.remove(mSavedPeerConfig.deviceAddress) != null) {
+ if (mPeers.remove(mSavedPeerConfig.deviceAddress) != null) {
peersChanged = true;
}
if (peersChanged) {
sendPeersChangedBroadcast();
}
- mSavedPeerConfig = null;
mPeersLostDuringConnection.clear();
mServiceDiscReqId = null;
sendMessage(WifiP2pManager.DISCOVER_PEERS);