summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/SupplicantP2pIfaceHal.java223
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java76
-rw-r--r--service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java11
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SupplicantP2pIfaceHalTest.java2
4 files changed, 287 insertions, 25 deletions
diff --git a/service/java/com/android/server/wifi/SupplicantP2pIfaceHal.java b/service/java/com/android/server/wifi/SupplicantP2pIfaceHal.java
index 618f13b9b..0932363c8 100644
--- a/service/java/com/android/server/wifi/SupplicantP2pIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantP2pIfaceHal.java
@@ -36,13 +36,18 @@ import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import android.os.HwRemoteBinder;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.util.NativeUtil;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Native calls sending requests to the P2P Hals, and callbacks for receiving P2P events
@@ -54,6 +59,12 @@ public class SupplicantP2pIfaceHal {
private static final String TAG = "SupplicantP2pIfaceHal";
private static final int RESULT_NOT_VALID = -1;
private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
+ /**
+ * Regex pattern for extracting the wps device type bytes.
+ * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
+ */
+ private static final Pattern WPS_DEVICE_TYPE_PATTERN =
+ Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
private Object mLock = new Object();
@@ -420,7 +431,7 @@ public class SupplicantP2pIfaceHal {
/**
* Initiate a P2P service discovery with a (optional) timeout.
*
- * @param timeoutInSec Max time to be spent is peforming discovery.
+ * @param timeout Max time to be spent is peforming discovery.
* Set to 0 to indefinely continue discovery untill and explicit
* |stopFind| is sent.
* @return boolean value indicating whether operation was successful.
@@ -444,10 +455,6 @@ public class SupplicantP2pIfaceHal {
}
}
- public boolean find() {
- return find(0);
- }
-
/**
* Stop an ongoing P2P service discovery.
@@ -616,6 +623,7 @@ public class SupplicantP2pIfaceHal {
* uses PIN.
*/
public String connect(WifiP2pConfig config, boolean joinExistingGroup) {
+ if (config == null) return null;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("setSsidPostfix")) return null;
@@ -716,6 +724,7 @@ public class SupplicantP2pIfaceHal {
* @return boolean value indicating whether operation was successful.
*/
public boolean provisionDiscovery(WifiP2pConfig config) {
+ if (config == null) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("provisionDiscovery")) return false;
@@ -759,13 +768,13 @@ public class SupplicantP2pIfaceHal {
* the group owner device address for Invitation Request should it not be
* known for some reason (this should not be needed in most cases).
*
- * @param groupIfName Group interface name to use.
- * @param goDeviceAddress MAC address of the group owner device.
+ * @param group Group object to use.
* @param peerAddress MAC address of the device to invite.
*
* @return boolean value indicating whether operation was successful.
*/
public boolean invite(WifiP2pGroup group, String peerAddress) {
+ if (TextUtils.isEmpty(peerAddress)) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("invite")) return false;
if (group == null) {
@@ -892,7 +901,7 @@ public class SupplicantP2pIfaceHal {
/**
* Gets the operational SSID of the device.
*
- * @param peerAddress MAC address of the peer.
+ * @param address MAC address of the peer.
*
* @return SSID of the device.
*/
@@ -947,6 +956,7 @@ public class SupplicantP2pIfaceHal {
* @return true, if operation was successful.
*/
public boolean reinvoke(int networkId, String peerAddress) {
+ if (TextUtils.isEmpty(peerAddress) || networkId < 0) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("reinvoke")) return false;
if (peerAddress == null) {
@@ -1019,11 +1029,12 @@ public class SupplicantP2pIfaceHal {
* the group, it must also be removed. The network interface name of the
* group interface is used as a parameter for this command.
*
- * @param groupIfName Group interface name to use.
+ * @param groupName Group interface name to use.
*
* @return true, if operation was successful.
*/
public boolean groupRemove(String groupName) {
+ if (TextUtils.isEmpty(groupName)) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("groupRemove")) return false;
SupplicantResult<Void> result = new SupplicantResult("groupRemove(" + groupName + ")");
@@ -1101,6 +1112,9 @@ public class SupplicantP2pIfaceHal {
* @return true, if operation was successful.
*/
public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
+ if (enable && intervalInMillis < periodInMillis) {
+ return false;
+ }
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("configureExtListen")) return false;
@@ -1174,8 +1188,7 @@ public class SupplicantP2pIfaceHal {
/**
* This command can be used to add a upnp/bonjour service.
*
- * @param query Hex dump of the query data.
- * @param return Hex dump of the response data.
+ * @param servInfo List of service queries.
*
* @return true, if operation was successful.
*/
@@ -1251,7 +1264,7 @@ public class SupplicantP2pIfaceHal {
/**
* This command can be used to remove a upnp/bonjour service.
*
- * @param query Hex dump of the query data.
+ * @param servInfo List of service queries.
*
* @return true, if operation was successful.
*/
@@ -1459,6 +1472,7 @@ public class SupplicantP2pIfaceHal {
* @return true, if operation was successful.
*/
public boolean startWpsPbc(String groupIfName, String bssid) {
+ if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(bssid)) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPbc")) return false;
if (groupIfName == null) {
@@ -1499,6 +1513,7 @@ public class SupplicantP2pIfaceHal {
* @return true, if operation was successful.
*/
public boolean startWpsPinKeypad(String groupIfName, String pin) {
+ if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(pin)) return false;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinKeypad")) return false;
if (groupIfName == null) {
@@ -1532,6 +1547,7 @@ public class SupplicantP2pIfaceHal {
* @return true, if operation was successful.
*/
public String startWpsPinDisplay(String groupIfName, String bssid) {
+ if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(bssid)) return null;
synchronized (mLock) {
if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinDisplay")) return null;
if (groupIfName == null) {
@@ -1657,6 +1673,29 @@ public class SupplicantP2pIfaceHal {
}
/**
+ * Remove network with provided id.
+ *
+ * @param networkId Id of the network to lookup.
+ * @return true, if operation was successful.
+ */
+ public boolean removeNetwork(int networkId) {
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("removeNetwork")) return false;
+
+ SupplicantResult<Void> result = new SupplicantResult(
+ "removeNetwork(" + networkId + ")");
+ try {
+ result.setResult(mISupplicantP2pIface.removeNetwork(networkId));
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+
+ return result.isSuccess();
+ }
+ }
+
+ /**
* List the networks saved in wpa_supplicant.
*
* @return List of network ids.
@@ -1799,6 +1838,166 @@ public class SupplicantP2pIfaceHal {
return true;
}
+ /**
+ * Set WPS device name.
+ *
+ * @param name String to be set.
+ * @return true if request is sent successfully, false otherwise.
+ */
+ public boolean setWpsDeviceName(String name) {
+ if (name == null) {
+ return false;
+ }
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceName")) return false;
+ SupplicantResult<Void> result = new SupplicantResult(
+ "setWpsDeviceName(" + name + ")");
+ try {
+ result.setResult(mISupplicantP2pIface.setWpsDeviceName(name));
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ return result.isSuccess();
+ }
+ }
+
+ /**
+ * Set WPS device type.
+ *
+ * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
+ * @return true if request is sent successfully, false otherwise.
+ */
+ public boolean setWpsDeviceType(String typeStr) {
+ Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
+ if (!match.find() || match.groupCount() != 3) {
+ Log.e(TAG, "Malformed WPS device type " + typeStr);
+ return false;
+ }
+ short categ = Short.parseShort(match.group(1));
+ byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
+ short subCateg = Short.parseShort(match.group(3));
+
+ byte[] bytes = new byte[8];
+ ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
+ byteBuffer.putShort(categ);
+ byteBuffer.put(oui);
+ byteBuffer.putShort(subCateg);
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceType")) return false;
+ SupplicantResult<Void> result = new SupplicantResult(
+ "setWpsDeviceType(" + typeStr + ")");
+ try {
+ result.setResult(mISupplicantP2pIface.setWpsDeviceType(bytes));
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ return result.isSuccess();
+ }
+ }
+
+ /**
+ * Get NFC handover request message.
+ *
+ * @return select message if created successfully, null otherwise.
+ */
+ public String getNfcHandoverRequest() {
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverRequest")) return null;
+ SupplicantResult<ArrayList> result = new SupplicantResult(
+ "getNfcHandoverRequest()");
+ try {
+ mISupplicantP2pIface.createNfcHandoverRequestMessage(
+ (SupplicantStatus status, ArrayList<Byte> message) -> {
+ result.setResult(status, message);
+ });
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ if (!result.isSuccess()) {
+ return null;
+
+ }
+ return NativeUtil.hexStringFromByteArray(
+ NativeUtil.byteArrayFromArrayList(result.getResult()));
+ }
+ }
+
+ /**
+ * Get NFC handover select message.
+ *
+ * @return select message if created successfully, null otherwise.
+ */
+ public String getNfcHandoverSelect() {
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverSelect")) return null;
+ SupplicantResult<ArrayList> result = new SupplicantResult(
+ "getNfcHandoverSelect()");
+ try {
+ mISupplicantP2pIface.createNfcHandoverSelectMessage(
+ (SupplicantStatus status, ArrayList<Byte> message) -> {
+ result.setResult(status, message);
+ });
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ if (!result.isSuccess()) {
+ return null;
+
+ }
+ return NativeUtil.hexStringFromByteArray(
+ NativeUtil.byteArrayFromArrayList(result.getResult()));
+ }
+ }
+
+ /**
+ * Report NFC handover select message.
+ *
+ * @return true if reported successfully, false otherwise.
+ */
+ public boolean initiatorReportNfcHandover(String selectMessage) {
+ if (selectMessage == null) return false;
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("initiatorReportNfcHandover")) return false;
+ SupplicantResult<Void> result = new SupplicantResult(
+ "initiatorReportNfcHandover(" + selectMessage + ")");
+ try {
+ result.setResult(mISupplicantP2pIface.reportNfcHandoverInitiation(
+ NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
+ selectMessage))));
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ return result.isSuccess();
+ }
+ }
+
+ /**
+ * Report NFC handover request message.
+ *
+ * @return true if reported successfully, false otherwise.
+ */
+ public boolean responderReportNfcHandover(String requestMessage) {
+ if (requestMessage == null) return false;
+ synchronized (mLock) {
+ if (!checkSupplicantP2pIfaceAndLogFailure("responderReportNfcHandover")) return false;
+ SupplicantResult<Void> result = new SupplicantResult(
+ "responderReportNfcHandover(" + requestMessage + ")");
+ try {
+ result.setResult(mISupplicantP2pIface.reportNfcHandoverResponse(
+ NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
+ requestMessage))));
+ } catch (RemoteException e) {
+ Log.e(TAG, "ISupplicantP2pIface exception: " + e);
+ supplicantServiceDiedHandler();
+ }
+ return result.isSuccess();
+ }
+ }
/** Container class allowing propagation of status and/or value
* from callbacks.
*
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index fea8263b8..d84dd23e8 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -138,7 +138,7 @@ public class WifiNative {
// TODO(b/34884202): Set this to true to enable HIDL once we're fully ready.
private static final boolean HIDL_VENDOR_ENABLE = true;
public static final boolean HIDL_SUP_ENABLE = true;
- private static final boolean HIDL_P2P_ENABLE = false;
+ private static final boolean HIDL_P2P_ENABLE = true;
private final String mTAG;
private final String mInterfaceName;
private final String mInterfacePrefix;
@@ -1182,6 +1182,31 @@ public class WifiNative {
}
}
+ public boolean removeP2pNetwork(int netId) {
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.removeNetwork(netId);
+ } else {
+ return doBooleanCommand("REMOVE_NETWORK " + netId);
+ }
+
+ }
+
+ public boolean setP2pDeviceName(String name) {
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.setWpsDeviceName(name);
+ } else {
+ return doBooleanCommand("SET device_name " + name);
+ }
+ }
+
+ public boolean setP2pDeviceType(String type) {
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.setWpsDeviceType(type);
+ } else {
+ return doBooleanCommand("SET device_type " + type);
+ }
+ }
+
public boolean setP2pSsidPostfix(String postfix) {
if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
return mSupplicantP2pIfaceHal.setSsidPostfix(postfix);
@@ -1695,25 +1720,64 @@ public class WifiNative {
* NFC-related calls
*/
public String getNfcWpsConfigurationToken(int netId) {
- return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
+ if (HIDL_SUP_ENABLE) {
+ return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken();
+ } else {
+ return doStringCommand("WPS_NFC_CONFIG_TOKEN WPS " + netId);
+ }
}
public String getNfcHandoverRequest() {
- return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.getNfcHandoverRequest();
+ } else {
+ return doStringCommand("NFC_GET_HANDOVER_REQ NDEF P2P-CR");
+ }
}
public String getNfcHandoverSelect() {
- return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.getNfcHandoverSelect();
+ } else {
+ return doStringCommand("NFC_GET_HANDOVER_SEL NDEF P2P-CR");
+ }
}
public boolean initiatorReportNfcHandover(String selectMessage) {
- return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.initiatorReportNfcHandover(selectMessage);
+ } else {
+ return doBooleanCommand("NFC_REPORT_HANDOVER INIT P2P 00 " + selectMessage);
+ }
}
public boolean responderReportNfcHandover(String requestMessage) {
- return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ return mSupplicantP2pIfaceHal.responderReportNfcHandover(requestMessage);
+ } else {
+ return doBooleanCommand("NFC_REPORT_HANDOVER RESP P2P " + requestMessage + " 00");
+ }
}
+ public String getP2pClientList(int netId) {
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ // TODO(b/36042785): Add HIDL method.
+ return null;
+ } else {
+ return getNetworkVariable(netId, "p2p_client_list");
+ }
+ }
+
+ public boolean setP2pClientList(int netId, String list) {
+ if (HIDL_P2P_ENABLE && mSupplicantP2pIfaceHal != null) {
+ // TODO(b/36042785): Add HIDL method.
+ return false;
+ } else {
+ return setNetworkVariable(netId, "p2p_client_list", list);
+ }
+ }
+
+
/** WifiSupplicantControl methods. TODO: These should use HIDL soon. */
/**
* Migrate all the configured networks from wpa_supplicant.
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index bb8db39e6..58bce4a84 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -593,7 +593,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
@Override
public void onDeleteGroup(int netId) {
if (DBG) logd("called onDeleteGroup() netId=" + netId);
- mWifiNative.removeNetwork(netId);
+ mWifiNative.removeP2pNetwork(netId);
mWifiNative.saveConfig();
sendP2pPersistentGroupsChangedBroadcast();
}
@@ -2711,7 +2711,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
* @return p2p client list. if not found, return null.
*/
private String[] getClientList(int netId) {
- String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
+ String p2pClients = mWifiNative.getP2pClientList(netId);
if (p2pClients == null) {
return null;
}
@@ -2756,8 +2756,7 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
if (modifiedClientList.length() == 0) {
modifiedClientList.append("\"\"");
}
- mWifiNative.setNetworkVariable(netId,
- "p2p_client_list", modifiedClientList.toString());
+ mWifiNative.setP2pClientList(netId, modifiedClientList.toString());
mWifiNative.saveConfig();
return true;
}
@@ -2837,10 +2836,10 @@ public class WifiP2pServiceImpl extends IWifiP2pManager.Stub {
private void initializeP2pSettings() {
mWifiNative.setPersistentReconnect(true);
mThisDevice.deviceName = getPersistedDeviceName();
- mWifiNative.setDeviceName(mThisDevice.deviceName);
+ mWifiNative.setP2pDeviceName(mThisDevice.deviceName);
// DIRECT-XY-DEVICENAME (XY is randomly generated)
mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
- mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
+ mWifiNative.setP2pDeviceType(mThisDevice.primaryDeviceType);
// Supplicant defaults to using virtual display with display
// which refers to a remote display. Use physical_display
mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantP2pIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantP2pIfaceHalTest.java
index 665b47f7f..2ea492e60 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantP2pIfaceHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantP2pIfaceHalTest.java
@@ -305,7 +305,7 @@ public class SupplicantP2pIfaceHalTest {
public void testFind_exception() throws Exception {
executeAndValidateInitializationSequence(false, false, false);
when(mISupplicantP2pIfaceMock.find(anyInt())).thenThrow(mRemoteException);
- assertFalse(mDut.find());
+ assertFalse(mDut.find(0));
// Check service is dead.
assertFalse(mDut.isInitializationComplete());
}