OSDN Git Service

P2p fixes
authorIrfan Sheriff <isheriff@google.com>
Fri, 6 Apr 2012 22:25:41 +0000 (15:25 -0700)
committerIrfan Sheriff <isheriff@google.com>
Fri, 6 Apr 2012 22:40:17 +0000 (15:40 -0700)
Add powersave on client after connect
Set concurrency priority to STA
Fix connection cancellation

Change-Id: I76fd9d1085c611a8c4068047b64289ef539ab389

wifi/java/android/net/wifi/WifiNative.java
wifi/java/android/net/wifi/p2p/WifiP2pService.java

index c11d082..db73ea8 100644 (file)
@@ -396,11 +396,25 @@ public class WifiNative {
         }
     }
 
+    public boolean startWpsPbc(String iface, String bssid) {
+        if (TextUtils.isEmpty(bssid)) {
+            return doBooleanCommand("WPS_PBC interface=" + iface);
+        } else {
+            return doBooleanCommand("WPS_PBC interface=" + iface + " " + bssid);
+        }
+    }
+
     public boolean startWpsPinKeypad(String pin) {
         if (TextUtils.isEmpty(pin)) return false;
         return doBooleanCommand("WPS_PIN any " + pin);
     }
 
+    public boolean startWpsPinKeypad(String iface, String pin) {
+        if (TextUtils.isEmpty(pin)) return false;
+        return doBooleanCommand("WPS_PIN interface=" + iface + " any " + pin);
+    }
+
+
     public String startWpsPinDisplay(String bssid) {
         if (TextUtils.isEmpty(bssid)) {
             return doStringCommand("WPS_PIN any");
@@ -409,6 +423,14 @@ public class WifiNative {
         }
     }
 
+    public String startWpsPinDisplay(String iface, String bssid) {
+        if (TextUtils.isEmpty(bssid)) {
+            return doStringCommand("WPS_PIN interface=" + iface + " any");
+        } else {
+            return doStringCommand("WPS_PIN interface=" + iface + " " + bssid);
+        }
+    }
+
     /* Configures an access point connection */
     public boolean startWpsRegistrar(String bssid, String pin) {
         if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
@@ -440,6 +462,26 @@ public class WifiNative {
         return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
     }
 
+    public boolean setP2pGroupIdle(String iface, int time) {
+        return doBooleanCommand("SET interface=" + iface + " p2p_group_idle " + time);
+    }
+
+    public boolean setP2pPowerSave(String iface, boolean enabled) {
+        if (enabled) {
+            return doBooleanCommand("P2P_SET interface=" + iface + " ps 1");
+        } else {
+            return doBooleanCommand("P2P_SET interface=" + iface + " ps 0");
+        }
+    }
+
+    /**
+     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
+     * P2P connection over STA
+     */
+    public boolean setConcurrencyPriority(String s) {
+        return doBooleanCommand("P2P_SET conc_priority " + s);
+    }
+
     public boolean p2pFind() {
         return doBooleanCommand("P2P_FIND");
     }
index 3d3a746..32e1053 100644 (file)
@@ -109,6 +109,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
     /* Set a two minute discover timeout to avoid STA scans from being blocked */
     private static final int DISCOVER_TIMEOUT_S = 120;
 
+    /* Idle time after a peer is gone when the group is torn down */
+    private static final int GROUP_IDLE_TIME_S = 2;
+
     /**
      * Delay between restarts upon failure to setup connection with supplicant
      */
@@ -343,10 +346,21 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
+                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
                 case PEER_CONNECTION_USER_ACCEPT:
                 case PEER_CONNECTION_USER_REJECT:
                 case GROUP_CREATING_TIMED_OUT:
                     break;
+                /* unexpected group created, remove */
+                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
+                    mGroup = (WifiP2pGroup) message.obj;
+                    loge("Unexpected group creation, remove " + mGroup);
+                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
+                    break;
+                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
+                    loge("Unexpected group failure, flush peers");
+                    mWifiNative.p2pFlush();
+                    break;
                 default:
                     loge("Unhandled message " + message);
                     return NOT_HANDLED;
@@ -476,6 +490,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
             if (DBG) logd(getName());
             sendP2pStateChangedBroadcast(true);
             mNetworkInfo.setIsAvailable(true);
+            sendP2pConnectionChangedBroadcast();
             initializeP2pSettings();
         }
 
@@ -561,9 +576,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                         //If peer is a GO, we do not need to send provisional discovery,
                         //the supplicant takes care of it.
                         if (mWifiNative.isGroupOwner(mSavedPeerConfig.deviceAddress)) {
+                            if (DBG) logd("Sending join to GO");
                             p2pConnectWithPinDisplay(mSavedPeerConfig, JOIN_GROUP);
                             transitionTo(mGroupNegotiationState);
                         } else {
+                            if (DBG) logd("Sending prov disc");
                             transitionTo(mProvisionDiscoveryState);
                         }
                     }
@@ -651,9 +668,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                case GROUP_CREATING_TIMED_OUT:
                     if (mGroupCreatingTimeoutIndex == message.arg1) {
                         if (DBG) logd("Group negotiation timed out");
-                        updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.FAILED);
-                        mSavedPeerConfig = null;
-                        sendP2pPeersChangedBroadcast();
+                        handleGroupCreationFailure();
                         transitionTo(mInactiveState);
                     }
                     break;
@@ -663,12 +678,15 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                             WifiP2pManager.BUSY);
                     break;
                 case WifiP2pManager.CANCEL_CONNECT:
-                    if (mWifiNative.p2pCancelConnect()) {
-                        replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
+                    //Do a supplicant p2p_cancel which only cancels an ongoing
+                    //group negotiation. This will fail for a pending provision
+                    //discovery or for a pending user action, but at the framework
+                    //level, we always treat cancel as succeded and enter
+                    //an inactive state
+                    mWifiNative.p2pCancelConnect();
+                    handleGroupCreationFailure();
+                    transitionTo(mInactiveState);
+                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -811,9 +829,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                 case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
                 case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
                     if (DBG) logd(getName() + " go failure");
-                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.FAILED);
-                    mSavedPeerConfig = null;
-                    sendP2pPeersChangedBroadcast();
+                    handleGroupCreationFailure();
                     transitionTo(mInactiveState);
                     break;
                 default:
@@ -838,6 +854,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                 setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS);
                 sendP2pConnectionChangedBroadcast();
             }
+
+            if (!mPersistGroup) {
+                mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
+            }
         }
 
         @Override
@@ -886,6 +906,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                         if (DBG) logd("DhcpInfo: " + dhcpInfo);
                         setWifiP2pInfoOnGroupFormation(dhcpInfo.serverAddress);
                         sendP2pConnectionChangedBroadcast();
+                        //Turn on power save on client
+                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
                     } else {
                         loge("DHCP failed");
                         mWifiNative.p2pGroupRemove(mGroup.getInterface());
@@ -1258,6 +1280,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
         //The supplicant default is to support everything, but a bug necessitates
         //the framework to specify this explicitly
         mWifiNative.setConfigMethods("keypad display push_button");
+        //STA has higher priority over P2P
+        mWifiNative.setConcurrencyPriority("sta");
 
         mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
         updateThisDevice(WifiP2pDevice.AVAILABLE);
@@ -1269,6 +1293,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
         sendThisDeviceChangedBroadcast();
     }
 
+    private void handleGroupCreationFailure() {
+        mSavedPeerConfig = null;
+        /* After cancelling group formation, new connections on existing peers can fail
+         * at supplicant. Flush and restart discovery */
+        mWifiNative.p2pFlush();
+        sendMessage(WifiP2pManager.DISCOVER_PEERS);
+    }
+
     //State machine initiated requests can have replyTo set to null indicating
     //there are no recepients, we ignore those reply actions
     private void replyToMessage(Message msg, int what) {