summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEtan Cohen <etancohen@google.com>2018-11-09 09:53:31 -0800
committerEtan Cohen <etancohen@google.com>2019-01-05 17:09:54 -0800
commitb4be2b26ac9b15299d2d0884d765a9d629f14396 (patch)
tree61c1ed1a2cec5de32e97ac22cb72b37db75d0280
parent134a49ce07083b21b76110e1fe35c3bccf77d803 (diff)
downloadandroid_frameworks_opt_net_wifi-b4be2b26ac9b15299d2d0884d765a9d629f14396.tar.gz
android_frameworks_opt_net_wifi-b4be2b26ac9b15299d2d0884d765a9d629f14396.tar.bz2
android_frameworks_opt_net_wifi-b4be2b26ac9b15299d2d0884d765a9d629f14396.zip
[AWARE] Add Wi-Fi Aware-specific Network info: port, transport protocol
Add port and transport protocol to the network specification and network capabilities. Bug: 117605977 Test: atest com.android.server.wifi.aware Test: (ACTS) DataPathTest Change-Id: Ie350ba1f6bddff5513f37c4e0cc2c5f69117df6c
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java190
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java21
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java10
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java32
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java268
-rw-r--r--tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java2
7 files changed, 466 insertions, 63 deletions
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
index 2b1a27415..76590269e 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java
@@ -35,6 +35,7 @@ import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.RouteInfo;
+import android.net.wifi.aware.TlvBufferUtils;
import android.net.wifi.aware.WifiAwareAgentNetworkSpecifier;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareNetworkInfo;
@@ -49,6 +50,7 @@ import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.WifiPermissionsUtil;
@@ -324,9 +326,11 @@ public class WifiAwareDataPathStateManager {
* related to a discovery session.
* @param mac The discovery MAC address of the peer.
* @param ndpId The locally assigned ID for the data-path.
+ * @param message The app_info HAL field (peer's info: binary blob)
* @return The network specifier of the data-path (or null if none/error)
*/
- public WifiAwareNetworkSpecifier onDataPathRequest(int pubSubId, byte[] mac, int ndpId) {
+ public WifiAwareNetworkSpecifier onDataPathRequest(int pubSubId, byte[] mac, int ndpId,
+ byte[] message) {
if (VDBG) {
Log.v(TAG,
"onDataPathRequest: pubSubId=" + pubSubId + ", mac=" + String.valueOf(
@@ -374,6 +378,15 @@ public class WifiAwareDataPathStateManager {
Log.v(TAG,
"onDataPathRequest: initiator-side indication for " + nnriE.getValue());
}
+
+ // potential transmission mechanism for port/transport-protocol information from
+ // Responder (alternative to confirm message)
+ Pair<Integer, Byte> peerServerInfo = NetworkInformationData.parseTlv(message);
+ if (peerServerInfo != null) {
+ nnriE.getValue().peerPort = peerServerInfo.first;
+ nnriE.getValue().peerTransportProtocol = peerServerInfo.second;
+ }
+
return null; // ignore this for NDP set up flow: it is used to obtain app_info from Resp
}
@@ -383,7 +396,7 @@ public class WifiAwareDataPathStateManager {
if (VDBG) {
Log.v(TAG, "onDataPathRequest: network request cache = " + mNetworkRequestsCache);
}
- mMgr.respondToDataPathRequest(false, ndpId, "", null, null, false);
+ mMgr.respondToDataPathRequest(false, ndpId, "", null, null, null, false);
return null;
}
@@ -395,7 +408,7 @@ public class WifiAwareDataPathStateManager {
if (nnri.interfaceName == null) {
Log.w(TAG,
"onDataPathRequest: request " + networkSpecifier + " no interface available");
- mMgr.respondToDataPathRequest(false, ndpId, "", null, null, false);
+ mMgr.respondToDataPathRequest(false, ndpId, "", null, null, null, false);
mNetworkRequestsCache.remove(networkSpecifier);
return null;
}
@@ -404,7 +417,10 @@ public class WifiAwareDataPathStateManager {
nnri.ndpId = ndpId;
nnri.startTimestamp = SystemClock.elapsedRealtime();
mMgr.respondToDataPathRequest(true, ndpId, nnri.interfaceName, nnri.networkSpecifier.pmk,
- nnri.networkSpecifier.passphrase, nnri.networkSpecifier.isOutOfBand());
+ nnri.networkSpecifier.passphrase,
+ NetworkInformationData.buildTlv(nnri.networkSpecifier.port,
+ nnri.networkSpecifier.transportProtocol),
+ nnri.networkSpecifier.isOutOfBand());
return networkSpecifier;
}
@@ -486,6 +502,7 @@ public class WifiAwareDataPathStateManager {
if (VDBG) {
Log.v(TAG, "onDataPathConfirm: ndpId=" + ndpId + ", mac=" + String.valueOf(
HexEncoding.encode(mac)) + ", accept=" + accept + ", reason=" + reason
+ + ", message.length=" + ((message == null) ? 0 : message.length)
+ ", channelInfo=" + channelInfo);
}
@@ -551,9 +568,20 @@ public class WifiAwareDataPathStateManager {
Log.e(TAG, "onDataPathConfirm: error obtaining scoped IPv6 address -- " + e);
nnri.peerIpv6 = null;
}
+ // only relevant for the initiator
+ if (nnri.networkSpecifier.role
+ == WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
+ Pair<Integer, Byte> peerServerInfo = NetworkInformationData.parseTlv(message);
+ if (peerServerInfo != null) {
+ nnri.peerPort = peerServerInfo.first;
+ nnri.peerTransportProtocol = peerServerInfo.second;
+ }
+ }
if (nnri.peerIpv6 != null) {
- networkCapabilities.setTransportInfo(new WifiAwareNetworkInfo(nnri.peerIpv6));
+ networkCapabilities.setTransportInfo(
+ new WifiAwareNetworkInfo(nnri.peerIpv6, nnri.peerPort,
+ nnri.peerTransportProtocol));
}
if (VDBG) {
Log.v(TAG, "onDataPathConfirm: AwareNetworkInfo="
@@ -826,7 +854,8 @@ public class WifiAwareDataPathStateManager {
mMgr.initiateDataPathSetup(networkSpecifier, nnri.peerInstanceId,
NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED, selectChannelForRequest(nnri),
nnri.peerDiscoveryMac, nnri.interfaceName, nnri.networkSpecifier.pmk,
- nnri.networkSpecifier.passphrase, nnri.networkSpecifier.isOutOfBand());
+ nnri.networkSpecifier.passphrase, nnri.networkSpecifier.isOutOfBand(),
+ null);
nnri.state =
AwareNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE;
nnri.startTimestamp = SystemClock.elapsedRealtime();
@@ -1046,6 +1075,8 @@ public class WifiAwareDataPathStateManager {
public int ndpId = 0; // 0 is never a valid ID!
public byte[] peerDataMac;
public Inet6Address peerIpv6;
+ public int peerPort = 0; // uninitialized (invalid) value
+ public byte peerTransportProtocol = -1; // uninitialized (invalid) value
public WifiAwareNetworkSpecifier networkSpecifier;
public List<NanDataPathChannelInfo> channelInfo;
public long startTimestamp = 0; // request is made (initiator) / get request (responder)
@@ -1084,7 +1115,8 @@ public class WifiAwareDataPathStateManager {
nc.setNetworkSpecifier(new WifiAwareAgentNetworkSpecifier(equivalentSpecifiers.toArray(
new WifiAwareNetworkSpecifier[equivalentSpecifiers.size()])));
if (peerIpv6 != null) {
- nc.setTransportInfo(new WifiAwareNetworkInfo(peerIpv6));
+ nc.setTransportInfo(
+ new WifiAwareNetworkInfo(peerIpv6, peerPort, peerTransportProtocol));
}
return nc;
}
@@ -1157,6 +1189,25 @@ public class WifiAwareDataPathStateManager {
}
}
+ // validate the port & transportProtocol
+ if (ns.port < 0 || ns.transportProtocol < -1) {
+ Log.e(TAG, "processNetworkSpecifier: networkSpecifier=" + ns
+ + " -- invalid port/transportProtocol");
+ return null;
+ }
+ if (ns.port != 0 || ns.transportProtocol != -1) {
+ if (ns.role != WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
+ Log.e(TAG, "processNetworkSpecifier: networkSpecifier=" + ns
+ + " -- port/transportProtocol can only be specified on responder");
+ return null;
+ }
+ if (TextUtils.isEmpty(ns.passphrase) && ns.pmk == null) {
+ Log.e(TAG, "processNetworkSpecifier: networkSpecifier=" + ns
+ + " -- port/transportProtocol can only be specified on secure ndp");
+ return null;
+ }
+ }
+
// validate the role (if session ID provided: i.e. session 1xx)
if (ns.type == WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB
|| ns.type == WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER) {
@@ -1259,8 +1310,10 @@ public class WifiAwareDataPathStateManager {
", ndpId=").append(ndpId).append(", peerDataMac=").append(
peerDataMac == null ? ""
: String.valueOf(HexEncoding.encode(peerDataMac)))
- .append(", peerIpv6=").append(peerIpv6).append(
- ", startTimestamp=").append(startTimestamp).append(", channelInfo=").append(
+ .append(", peerIpv6=").append(peerIpv6).append(", peerPort=").append(
+ peerPort).append(", peerTransportProtocol=").append(
+ peerTransportProtocol).append(", startTimestamp=").append(
+ startTimestamp).append(", channelInfo=").append(
channelInfo).append(", equivalentSpecifiers=[");
for (WifiAwareNetworkSpecifier ns: equivalentSpecifiers) {
sb.append(ns.toString()).append(", ");
@@ -1378,6 +1431,125 @@ public class WifiAwareDataPathStateManager {
}
/**
+ * Utility (hence static) class encapsulating the data structure used to communicate Wi-Fi Aware
+ * specific network capabilities. These include:
+ *
+ * - Port
+ * - Transport protocol
+ *
+ * The utility class creates and parses a set of TLVs encoded on a byte array. The TLV will use
+ * :
+ * - Type (T): 1 byte
+ * - Value (V): 1 byte
+ */
+ @VisibleForTesting
+ public static class NetworkInformationData {
+ // signature to be used in first bytes (with T & V) - used as additional insurance against
+ // random data.
+ @VisibleForTesting
+ public static final int SIGNATURE = 0xFAAFABAB;
+
+ // the type (T) of the TLVs
+ @VisibleForTesting
+ public static final byte TYPE_SIGNATURE = 0x00;
+ @VisibleForTesting
+ public static final byte TYPE_PORT = 0x01;
+ @VisibleForTesting
+ public static final byte TYPE_TRANSPORT_PROTOCOL = 0x02;
+
+ /**
+ * Construct the TLV.
+ */
+ public static byte[] buildTlv(int port, int transportProtocol) {
+ if (port == 0 && transportProtocol == -1) {
+ return null;
+ }
+
+ TlvBufferUtils.TlvConstructor tlvc = new TlvBufferUtils.TlvConstructor(1, 1);
+ tlvc.allocate(20); // safe size for now
+ tlvc.putInt(TYPE_SIGNATURE, SIGNATURE);
+
+ if (port != 0) {
+ tlvc.putInt(TYPE_PORT, port);
+ }
+ if (transportProtocol != -1) {
+ tlvc.putByte(TYPE_TRANSPORT_PROTOCOL, (byte) transportProtocol);
+ }
+
+ return tlvc.getArray();
+ }
+
+ /**
+ * Parse the TLV and return <port, transportProtocol> or null on error.
+ */
+ public static Pair<Integer, Byte> parseTlv(byte[] tlvs) {
+ boolean signatureFound = false;
+ int port = 0;
+ byte transportProtocol = -1;
+
+ if (VDBG) {
+ Log.v(TAG, "parseTlv: tlvs.length=" + ((tlvs == null) ? "null" : tlvs.length)
+ + ", bytes=" + Arrays.toString(tlvs));
+ }
+ if (tlvs == null || tlvs.length == 0) {
+ return null;
+ }
+
+ TlvBufferUtils.TlvIterable tlvi = new TlvBufferUtils.TlvIterable(1, 1, tlvs);
+ for (TlvBufferUtils.TlvElement tlve : tlvi) {
+ switch (tlve.type) {
+ case TYPE_SIGNATURE:
+ if (tlve.length != 4) {
+ Log.e(TAG, "NetworkInformationData: invalid signature length");
+ return null;
+ }
+ if (tlve.getInt() != SIGNATURE) {
+ Log.e(TAG, "NetworkInformationData: invalid signature value");
+ return null;
+ }
+ signatureFound = true;
+ break;
+ case TYPE_PORT:
+ if (tlve.length != 4) {
+ Log.e(TAG, "NetworkInformationData: invalid port info length");
+ return null;
+ }
+ port = tlve.getInt();
+ if (port <= 0) {
+ Log.e(TAG, "NetworkInformationData: invalid port value - non-positive");
+ return null;
+ }
+ break;
+ case TYPE_TRANSPORT_PROTOCOL:
+ if (tlve.length != 1) {
+ Log.e(TAG, "NetworkInformationData: invalid transport protocol info "
+ + "length");
+ return null;
+ }
+ transportProtocol = tlve.getByte();
+ if (transportProtocol < 0) {
+ Log.e(TAG, "NetworkInformationData: invalid transport protocol info - "
+ + "negative");
+ return null;
+ }
+ break;
+ default:
+ Log.w(TAG,
+ "NetworkInformationData: ignoring invalid T -- " + tlve.type);
+ break;
+ }
+ }
+
+ if (!signatureFound) {
+ Log.e(TAG, "NetworkInformationData: parseTlv - signature not found!");
+ return null;
+ }
+
+ return Pair.create(port, transportProtocol);
+ }
+ }
+
+ /**
* Dump the internal state of the class.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
index e5072c899..d7782f9a3 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java
@@ -39,6 +39,7 @@ import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.SubscribeConfig;
import android.os.RemoteException;
import android.os.ShellCommand;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
@@ -883,16 +884,22 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
* @param interfaceName The interface on which to create the data connection.
* @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
* @param passphrase Passphrase for the data-path.
+ * @param isOutOfBand Is the data-path out-of-band (i.e. without a corresponding Aware discovery
+ * session).
+ * @param appInfo Arbitrary binary blob transmitted to the peer.
* @param capabilities The capabilities of the firmware.
*/
public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase,
- boolean isOutOfBand, Capabilities capabilities) {
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities) {
if (mDbg) {
Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId
+ ", channelRequestType=" + channelRequestType + ", channel=" + channel
+ ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName="
- + interfaceName);
+ + interfaceName + ", pmk=" + ((pmk == null) ? "<null>" : "<*>")
+ + ", passphrase=" + (TextUtils.isEmpty(passphrase) ? "<empty>" : "<*>")
+ + ", isOutOfBand=" + isOutOfBand + ", appInfo.length="
+ + ((appInfo == null) ? 0 : appInfo.length) + ", capabilities=" + capabilities);
}
recordTransactionId(transactionId);
@@ -932,6 +939,7 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
req.serviceNameOutOfBand);
}
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
try {
WifiStatus status = iface.initiateDataPathRequest(transactionId, req);
@@ -959,16 +967,18 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
* request callback.
* @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
* @param passphrase Passphrase for the data-path.
+ * @param appInfo Arbitrary binary blob transmitted to the peer.
* @param isOutOfBand Is the data-path out-of-band (i.e. without a corresponding Aware discovery
* session).
* @param capabilities The capabilities of the firmware.
*/
public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
- String interfaceName, byte[] pmk, String passphrase, boolean isOutOfBand,
- Capabilities capabilities) {
+ String interfaceName, byte[] pmk, String passphrase, byte[] appInfo,
+ boolean isOutOfBand, Capabilities capabilities) {
if (mDbg) {
Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept="
- + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName);
+ + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName
+ + ", appInfo.length=" + ((appInfo == null) ? 0 : appInfo.length));
}
recordTransactionId(transactionId);
@@ -1006,6 +1016,7 @@ public class WifiAwareNativeApi implements WifiAwareShellCommand.DelegatedShellC
SERVICE_NAME_FOR_OOB_DATA_PATH.getBytes(StandardCharsets.UTF_8),
req.serviceNameOutOfBand);
}
+ convertNativeByteArrayToArrayList(appInfo, req.appInfo);
try {
WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req);
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
index ed06015d4..366af13f3 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java
@@ -468,12 +468,13 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId
+ ", peerDiscMacAddr=" + String.valueOf(
HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId="
- + event.ndpInstanceId);
+ + event.ndpInstanceId + ", appInfo.size()=" + event.appInfo.size());
}
incrementCbCount(CB_EV_DATA_PATH_REQUEST);
mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId,
- event.peerDiscMacAddr, event.ndpInstanceId);
+ event.peerDiscMacAddr, event.ndpInstanceId,
+ convertArrayListToNativeByteArray(event.appInfo));
}
@Override
@@ -482,7 +483,7 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId
+ ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr))
+ ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason="
- + event.status.status);
+ + event.status.status + ", appInfo.size()=" + event.appInfo.size());
}
if (mIsHal12OrLater) {
Log.wtf(TAG, "eventDataPathConfirm should not be called by a >=1.2 HAL!");
@@ -500,7 +501,8 @@ public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub imp
Log.v(TAG, "eventDataPathConfirm_1_2: ndpInstanceId=" + event.V1_0.ndpInstanceId
+ ", peerNdiMacAddr=" + String.valueOf(
HexEncoding.encode(event.V1_0.peerNdiMacAddr)) + ", dataPathSetupSuccess="
- + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status);
+ + event.V1_0.dataPathSetupSuccess + ", reason=" + event.V1_0.status.status
+ + ", appInfo.size()=" + event.V1_0.appInfo.size());
}
if (!mIsHal12OrLater) {
Log.wtf(TAG, "eventDataPathConfirm_1_2 should not be called by a <1.2 HAL!");
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index f08ca1725..6af4740ba 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -196,6 +196,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private static final String MESSAGE_RANGING_INDICATION = "ranging_indication";
private static final String MESSAGE_RANGE_MM = "range_mm";
private static final String MESSAGE_BUNDLE_KEY_NDP_IDS = "ndp_ids";
+ private static final String MESSAGE_BUNDLE_KEY_APP_INFO = "app_info";
private WifiAwareNativeApi mWifiAwareNativeApi;
private WifiAwareNativeManager mWifiAwareNativeManager;
@@ -776,7 +777,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
*/
public void initiateDataPathSetup(WifiAwareNetworkSpecifier networkSpecifier, int peerId,
int channelRequestType, int channel, byte[] peer, String interfaceName, byte[] pmk,
- String passphrase, boolean isOutOfBand) {
+ String passphrase, boolean isOutOfBand, byte[] appInfo) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_INITIATE_DATA_PATH_SETUP;
msg.obj = networkSpecifier;
@@ -788,6 +789,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PMK, pmk);
msg.getData().putString(MESSAGE_BUNDLE_KEY_PASSPHRASE, passphrase);
msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_OOB, isOutOfBand);
+ msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_APP_INFO, appInfo);
mSm.sendMessage(msg);
}
@@ -795,7 +797,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
* Command to respond to the data-path request (executed by the responder).
*/
public void respondToDataPathRequest(boolean accept, int ndpId, String interfaceName,
- byte[] pmk, String passphrase, boolean isOutOfBand) {
+ byte[] pmk, String passphrase, byte[] appInfo, boolean isOutOfBand) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST;
msg.arg2 = ndpId;
@@ -803,6 +805,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PMK, pmk);
msg.getData().putString(MESSAGE_BUNDLE_KEY_PASSPHRASE, passphrase);
+ msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_APP_INFO, appInfo);
msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_OOB, isOutOfBand);
mSm.sendMessage(msg);
}
@@ -1119,12 +1122,13 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
/**
* Place a callback request on the state machine queue: data-path request (from peer) received.
*/
- public void onDataPathRequestNotification(int pubSubId, byte[] mac, int ndpId) {
+ public void onDataPathRequestNotification(int pubSubId, byte[] mac, int ndpId, byte[] message) {
Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST;
msg.arg2 = pubSubId;
msg.obj = ndpId;
msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac);
+ msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
mSm.sendMessage(msg);
}
@@ -1473,7 +1477,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST: {
WifiAwareNetworkSpecifier networkSpecifier = mDataPathMgr.onDataPathRequest(
msg.arg2, msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS),
- (int) msg.obj);
+ (int) msg.obj, msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE));
if (networkSpecifier != null) {
WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
@@ -1716,10 +1720,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PMK);
String passphrase = data.getString(MESSAGE_BUNDLE_KEY_PASSPHRASE);
boolean isOutOfBand = data.getBoolean(MESSAGE_BUNDLE_KEY_OOB);
+ byte[] appInfo = data.getByteArray(MESSAGE_BUNDLE_KEY_APP_INFO);
waitForResponse = initiateDataPathSetupLocal(mCurrentTransactionId,
networkSpecifier, peerId, channelRequestType, channel, peer,
- interfaceName, pmk, passphrase, isOutOfBand);
+ interfaceName, pmk, passphrase, isOutOfBand, appInfo);
if (waitForResponse) {
WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
@@ -1739,10 +1744,11 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME);
byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PMK);
String passphrase = data.getString(MESSAGE_BUNDLE_KEY_PASSPHRASE);
+ byte[] appInfo = data.getByteArray(MESSAGE_BUNDLE_KEY_APP_INFO);
boolean isOutOfBand = data.getBoolean(MESSAGE_BUNDLE_KEY_OOB);
waitForResponse = respondToDataPathRequestLocal(mCurrentTransactionId, accept,
- ndpId, interfaceName, pmk, passphrase, isOutOfBand);
+ ndpId, interfaceName, pmk, passphrase, appInfo, isOutOfBand);
break;
}
@@ -2469,7 +2475,7 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
private boolean initiateDataPathSetupLocal(short transactionId,
WifiAwareNetworkSpecifier networkSpecifier, int peerId, int channelRequestType,
int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase,
- boolean isOutOfBand) {
+ boolean isOutOfBand, byte[] appInfo) {
if (VDBG) {
Log.v(TAG, "initiateDataPathSetupLocal(): transactionId=" + transactionId
+ ", networkSpecifier=" + networkSpecifier + ", peerId=" + peerId
@@ -2478,12 +2484,12 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
+ String.valueOf(HexEncoding.encode(peer)) + ", interfaceName=" + interfaceName
+ ", pmk=" + ((pmk == null) ? "" : "*") + ", passphrase=" + (
(passphrase == null) ? "" : "*") + ", isOutOfBand="
- + isOutOfBand);
+ + isOutOfBand + ", appInfo=" + (appInfo == null ? "<null>" : "<non-null>"));
}
boolean success = mWifiAwareNativeApi.initiateDataPath(transactionId, peerId,
channelRequestType, channel, peer, interfaceName, pmk, passphrase, isOutOfBand,
- mCapabilities);
+ appInfo, mCapabilities);
if (!success) {
mDataPathMgr.onDataPathInitiateFail(networkSpecifier, NanStatusType.INTERNAL_FAILURE);
}
@@ -2492,17 +2498,19 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
}
private boolean respondToDataPathRequestLocal(short transactionId, boolean accept,
- int ndpId, String interfaceName, byte[] pmk, String passphrase, boolean isOutOfBand) {
+ int ndpId, String interfaceName, byte[] pmk, String passphrase, byte[] appInfo,
+ boolean isOutOfBand) {
if (VDBG) {
Log.v(TAG,
"respondToDataPathRequestLocal(): transactionId=" + transactionId + ", accept="
+ accept + ", ndpId=" + ndpId + ", interfaceName=" + interfaceName
+ ", pmk=" + ((pmk == null) ? "" : "*") + ", passphrase="
+ ((passphrase == null) ? "" : "*") + ", isOutOfBand="
- + isOutOfBand);
+ + isOutOfBand + ", appInfo=" + (appInfo == null ? "<null>"
+ : "<non-null>"));
}
boolean success = mWifiAwareNativeApi.respondToDataPathRequest(transactionId, accept, ndpId,
- interfaceName, pmk, passphrase, isOutOfBand, mCapabilities);
+ interfaceName, pmk, passphrase, appInfo, isOutOfBand, mCapabilities);
if (!success) {
mDataPathMgr.onRespondToDataPathRequest(ndpId, false, NanStatusType.INTERNAL_FAILURE);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java b/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
index 0e21f1713..555e89115 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/TestUtils.java
@@ -103,14 +103,14 @@ public class TestUtils {
public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase,
- boolean isOutOfBand, Capabilities capabilities) {
+ boolean isOutOfBand, byte[] appInfo, Capabilities capabilities) {
addTransactionId(transactionId);
return true;
}
public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
- String interfaceName, byte[] pmk, String passphrase, boolean isOutOfBand,
- Capabilities capabilities) {
+ String interfaceName, byte[] pmk, String passphrase, byte[] appInfo,
+ boolean isOutOfBand, Capabilities capabilities) {
addTransactionId(transactionId);
return true;
}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
index 5f811899f..c926039a9 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java
@@ -31,6 +31,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -60,6 +61,7 @@ import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.SubscribeDiscoverySession;
+import android.net.wifi.aware.TlvBufferUtils;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareNetworkInfo;
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
@@ -97,6 +99,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+
/**
* Unit test harness for WifiAwareDataPathStateManager class.
*/
@@ -306,6 +309,112 @@ public class WifiAwareDataPathStateManagerTest {
}
/**
+ * Validate that trying to specify port info on subscriber results in failure.
+ */
+ @Test
+ public void testDataPathWithPortInfoOnPublisher() throws Exception {
+ final int clientId = 123;
+ final byte pubSubId = 55;
+ final int requestorId = 1341234;
+ final String passphrase = "SomeSecurePassword";
+ final int ndpId = 1;
+ final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+
+ InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+ InOrder inOrderM = inOrder(mAwareMetricsMock);
+
+ // (0) initialize
+ DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
+ peerDiscoveryMac, inOrder, inOrderM, false);
+
+ // (1) request network
+ NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
+ null, passphrase, true, 0, 5, 6);
+
+ Message reqNetworkMsg = Message.obtain();
+ reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+ reqNetworkMsg.obj = nr;
+ reqNetworkMsg.arg1 = 0;
+ res.mMessenger.send(reqNetworkMsg);
+ mMockLooper.dispatchAll();
+
+ // (2) provide a request
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
+ mMockLooper.dispatchAll();
+
+ // do not respond/create a data-path!
+ verify(mMockNative, never()).respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(),
+ anyString(), any(), anyString(), any(), anyBoolean(), any());
+ }
+
+ /**
+ * Validate that trying to specify invalid port info results in failure.
+ */
+ @Test
+ public void testDataPathWithPortInfoInvalidPort() throws Exception {
+ final int clientId = 123;
+ final byte pubSubId = 55;
+ final int requestorId = 1341234;
+ final String passphrase = "SomeSecurePassword";
+ final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+
+ InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+ InOrder inOrderM = inOrder(mAwareMetricsMock);
+
+ // (0) initialize
+ DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
+ peerDiscoveryMac, inOrder, inOrderM, false);
+
+ // (1) request network
+ NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
+ null, passphrase, false, 0, -3, 6);
+
+ Message reqNetworkMsg = Message.obtain();
+ reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+ reqNetworkMsg.obj = nr;
+ reqNetworkMsg.arg1 = 0;
+ res.mMessenger.send(reqNetworkMsg);
+ mMockLooper.dispatchAll();
+
+ // do not create a data-path!
+ verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
+ any(), anyString(), any(), anyString(), anyBoolean(), any(), any());
+ }
+
+ /**
+ * Validate that trying to specify port info without security results in failure.
+ */
+ @Test
+ public void testDataPathWithPortInfoButNoSecurityOnSubscriber() throws Exception {
+ final int clientId = 123;
+ final byte pubSubId = 55;
+ final int requestorId = 1341234;
+ final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+
+ InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+ InOrder inOrderM = inOrder(mAwareMetricsMock);
+
+ // (0) initialize
+ DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId,
+ peerDiscoveryMac, inOrder, inOrderM, false);
+
+ // (1) request network
+ NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle,
+ null, null, false, 0, 10, 6);
+
+ Message reqNetworkMsg = Message.obtain();
+ reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+ reqNetworkMsg.obj = nr;
+ reqNetworkMsg.arg1 = 0;
+ res.mMessenger.send(reqNetworkMsg);
+ mMockLooper.dispatchAll();
+
+ // do not create a data-path!
+ verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
+ any(), anyString(), any(), anyString(), anyBoolean(), any(), any());
+ }
+
+ /**
* Validate that if the data-interfaces are deleted while a data-path is being created, the
* process will terminate.
*/
@@ -346,12 +455,12 @@ public class WifiAwareDataPathStateManagerTest {
mMockLooper.dispatchAll();
// (3) have responder receive request
- mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
mMockLooper.dispatchAll();
// (4) verify that responder aborts (i.e. refuses request)
inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(false),
- eq(ndpId), eq(""), eq(null), eq(null), eq(false), any());
+ eq(ndpId), eq(""), eq(null), eq(null), eq(null), eq(false), any());
mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();
@@ -375,6 +484,8 @@ public class WifiAwareDataPathStateManagerTest {
final int requestorId = 1341234;
final int ndpId = 2;
final String interfaceName = sAwareInterfacePrefix + "0";
+ final int port = 23;
+ final byte transportProtocol = 6;
final int[] startOrder = {0, 1, 2};
final int[] endOrder = {1, 0, 2};
@@ -421,13 +532,14 @@ public class WifiAwareDataPathStateManagerTest {
eq(requestorId + i),
eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
eq(interfaceName), eq(null),
- eq(null), eq(false), any());
+ eq(null), eq(false), any(), any());
mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
mMockLooper.dispatchAll();
// (2) get confirmation
- mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null);
+ mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0,
+ buildTlv(true, port, transportProtocol, true), null);
mMockLooper.dispatchAll();
if (first) {
inOrder.verify(mMockNwMgt).setInterfaceUp(anyString());
@@ -446,6 +558,8 @@ public class WifiAwareDataPathStateManagerTest {
assertArrayEquals(MacAddress.fromBytes(
peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
netInfo.getPeerIpv6Addr().getAddress());
+ assertEquals(port, netInfo.getPort());
+ assertEquals(transportProtocol, netInfo.getTransportProtocol());
}
// (3) end data-path (unless didn't get confirmation)
@@ -486,8 +600,11 @@ public class WifiAwareDataPathStateManagerTest {
final int numRequestsPost = 5;
final int clientId = 123;
final int ndpId = 5;
+ final int port = 0;
+ final int transportProtocol = 6; // can't specify transport protocol without port
final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+ final byte[] allZeros = HexEncoding.decode("000000000000".toCharArray(), false);
NetworkRequest[] nrs = new NetworkRequest[numRequestsPre + numRequestsPost + 1];
ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
@@ -524,7 +641,7 @@ public class WifiAwareDataPathStateManagerTest {
// (3) verify the start NDP HAL request
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
- eq(sAwareInterfacePrefix + "0"), eq(null), eq(null), eq(true), any());
+ eq(sAwareInterfacePrefix + "0"), eq(null), eq(null), eq(true), any(), any());
// (4) unregister request #0 (the primary)
Message endNetworkReqMsg = Message.obtain();
@@ -544,6 +661,11 @@ public class WifiAwareDataPathStateManagerTest {
messenger.send(endNetworkReqMsg);
mMockLooper.dispatchAll();
+ // (6.5) provide a (semi) bogus NDP Requst Indication - mostly bogus on Initiator but
+ // may contain the peer's TLVs (in this case it does)
+ mDut.onDataPathRequestNotification(0, allZeros, ndpId,
+ buildTlv(true, port, transportProtocol, true));
+
// (7) confirm the NDP creation
mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null);
mMockLooper.dispatchAll();
@@ -560,6 +682,8 @@ public class WifiAwareDataPathStateManagerTest {
assertArrayEquals(MacAddress.fromBytes(
peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
netInfo.getPeerIpv6Addr().getAddress());
+ assertEquals(port, netInfo.getPort());
+ assertEquals(-1, netInfo.getTransportProtocol()); // without port will get a -1 (invalid)
// (8) execute 'post' requests
for (int i = numRequestsPre; i < numRequestsPre + numRequestsPost; ++i) {
@@ -657,7 +781,7 @@ public class WifiAwareDataPathStateManagerTest {
if (i < numNdis) {
inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0),
eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
- ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any());
+ ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any());
interfaces.add(ifNameCaptor.getValue());
mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i);
@@ -676,6 +800,8 @@ public class WifiAwareDataPathStateManagerTest {
assertArrayEquals(MacAddress.fromBytes(
peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
netInfo.getPeerIpv6Addr().getAddress());
+ assertEquals(0, netInfo.getPort()); // uninitialized -> 0
+ assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1
}
}
@@ -728,6 +854,36 @@ public class WifiAwareDataPathStateManagerTest {
}
/**
+ * Verify that an invalid TLV configuration results in the default port (0), and transport
+ * protocol (-1) values.
+ */
+ @Test
+ public void testDataPathInitiatorNetInfoNoSignature() throws Exception {
+ testDataPathInitiatorUtilityMore(false, true, true, false, true, false,
+ buildTlv(false, 5, 10, true), 0, -1);
+ }
+
+ /**
+ * Verify that an invalid TLV configuration (non-positive port value) results in the default
+ * port (0), and transport protocol (-1) values.
+ */
+ @Test
+ public void testDataPathInitiatorNetInfoBadPort() throws Exception {
+ testDataPathInitiatorUtilityMore(false, true, true, false, true, false,
+ buildTlv(true, -1, 10, true), 0, -1);
+ }
+
+ /**
+ * Verify that an invalid TLV configuration (negative transport protocol value) results in
+ * the default port (0), and transport protocol (-1) values.
+ */
+ @Test
+ public void testDataPathInitiatorNetInfoBadTransportProtocol() throws Exception {
+ testDataPathInitiatorUtilityMore(false, true, true, false, true, false,
+ buildTlv(true, 5, -2, true), 0, -1);
+ }
+
+ /**
* Validate the fail flow of a mis-configured request: Publisher as Initiator
*/
@Test
@@ -938,6 +1094,8 @@ public class WifiAwareDataPathStateManagerTest {
ns.peerMac,
ns.pmk,
ns.passphrase,
+ 0,
+ 0,
ns.requestorUid);
nr.networkCapabilities.setNetworkSpecifier(ns);
@@ -953,10 +1111,10 @@ public class WifiAwareDataPathStateManagerTest {
// Initiator (subscribe): doesn't initiate (i.e. no HAL requests)
if (doPublish) {
// (2) get request & respond
- mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
- eq(ndpId), eq(""), eq(null), eq(null), anyBoolean(), any());
+ eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any());
}
verifyNoMoreInteractions(mMockNative, mMockCm, mAwareMetricsMock, mMockNwMgt);
@@ -994,6 +1152,8 @@ public class WifiAwareDataPathStateManagerTest {
ns.peerMac,
ns.pmk,
ns.passphrase,
+ 0,
+ 0,
ns.requestorUid + 1); // corruption hack
nr.networkCapabilities.setNetworkSpecifier(ns);
@@ -1010,10 +1170,10 @@ public class WifiAwareDataPathStateManagerTest {
// Initiator (subscribe): doesn't initiate (i.e. no HAL requests)
if (doPublish) {
// (2) get request & respond
- mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false),
- eq(ndpId), eq(""), eq(null), eq(null), anyBoolean(), any());
+ eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any());
}
verifyNoMoreInteractions(mMockNative, mMockCm, mAwareMetricsMock, mMockNwMgt);
@@ -1022,13 +1182,20 @@ public class WifiAwareDataPathStateManagerTest {
private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac,
boolean providePmk, boolean providePassphrase, boolean getConfirmation,
boolean immediateHalFailure) throws Exception {
+ testDataPathInitiatorUtilityMore(useDirect, provideMac, providePmk, providePassphrase,
+ getConfirmation, immediateHalFailure, null, 0, -1);
+ }
+
+ private void testDataPathInitiatorUtilityMore(boolean useDirect, boolean provideMac,
+ boolean providePmk, boolean providePassphrase, boolean getConfirmation,
+ boolean immediateHalFailure, byte[] peerToken, int port, int transportProtocol)
+ throws Exception {
final int clientId = 123;
final byte pubSubId = 58;
final int requestorId = 1341234;
final int ndpId = 2;
final byte[] pmk = "01234567890123456789012345678901".getBytes();
final String passphrase = "some passphrase";
- final String peerToken = "let's go!";
final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
@@ -1048,7 +1215,7 @@ public class WifiAwareDataPathStateManagerTest {
if (immediateHalFailure) {
when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), any(),
- any(), any(), any(), anyBoolean(), any())).thenReturn(false);
+ any(), any(), any(), anyBoolean(), any(), any())).thenReturn(false);
}
@@ -1079,7 +1246,7 @@ public class WifiAwareDataPathStateManagerTest {
eq(useDirect ? 0 : requestorId),
eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac),
eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
- eq(providePassphrase ? passphrase : null), eq(useDirect), any());
+ eq(providePassphrase ? passphrase : null), eq(useDirect), any(), any());
if (immediateHalFailure) {
// short-circuit the rest of this test
inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE),
@@ -1093,8 +1260,7 @@ public class WifiAwareDataPathStateManagerTest {
// (2) get confirmation OR timeout
if (getConfirmation) {
- mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0,
- peerToken.getBytes(), null);
+ mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, peerToken, null);
mMockLooper.dispatchAll();
inOrder.verify(mMockNwMgt).setInterfaceUp(anyString());
inOrder.verify(mMockNwMgt).enableIpv6(anyString());
@@ -1108,6 +1274,8 @@ public class WifiAwareDataPathStateManagerTest {
assertArrayEquals(MacAddress.fromBytes(
peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
netInfo.getPeerIpv6Addr().getAddress());
+ assertEquals(port, netInfo.getPort());
+ assertEquals(transportProtocol, netInfo.getTransportProtocol());
} else {
assertTrue(mAlarmManager.dispatch(
WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
@@ -1150,7 +1318,6 @@ public class WifiAwareDataPathStateManagerTest {
final int ndpId = 2;
final byte[] pmk = "01234567890123456789012345678901".getBytes();
final String passphrase = "some passphrase";
- final String peerToken = "let's go!";
final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
@@ -1195,19 +1362,18 @@ public class WifiAwareDataPathStateManagerTest {
mMockLooper.dispatchAll();
// (2) get request & respond (if legacy)
- mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId);
+ mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null);
mMockLooper.dispatchAll();
if (isLegacy) {
inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true),
eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null),
- eq(providePassphrase ? passphrase : null), eq(useDirect), any());
+ eq(providePassphrase ? passphrase : null), eq(null), eq(useDirect), any());
mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();
// (3) get confirmation OR timeout
if (getConfirmation) {
- mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0,
- peerToken.getBytes(), null);
+ mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null);
mMockLooper.dispatchAll();
inOrder.verify(mMockNwMgt).setInterfaceUp(anyString());
inOrder.verify(mMockNwMgt).enableIpv6(anyString());
@@ -1221,6 +1387,8 @@ public class WifiAwareDataPathStateManagerTest {
assertArrayEquals(MacAddress.fromBytes(
peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(),
netInfo.getPeerIpv6Addr().getAddress());
+ assertEquals(0, netInfo.getPort());
+ assertEquals(-1, netInfo.getTransportProtocol());
} else {
assertTrue(mAlarmManager.dispatch(
WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
@@ -1253,7 +1421,7 @@ public class WifiAwareDataPathStateManagerTest {
}
} else {
inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(false),
- eq(ndpId), eq(""), eq(null), eq(null), eq(false), any());
+ eq(ndpId), eq(""), eq(null), eq(null), eq(null), eq(false), any());
mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
mMockLooper.dispatchAll();
}
@@ -1264,6 +1432,14 @@ public class WifiAwareDataPathStateManagerTest {
private NetworkRequest getSessionNetworkRequest(int clientId, int sessionId,
PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId)
throws Exception {
+ return getSessionNetworkRequestMore(clientId, sessionId, peerHandle, pmk, passphrase,
+ doPublish, requestId, 0, -1);
+ }
+
+ private NetworkRequest getSessionNetworkRequestMore(int clientId, int sessionId,
+ PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId,
+ int port, int transportProtocol)
+ throws Exception {
final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class);
final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService);
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
@@ -1318,17 +1494,17 @@ public class WifiAwareDataPathStateManagerTest {
ns = createNetworkSpecifier(clientId,
doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
- peerHandle, null, null);
+ peerHandle, null, null, port, transportProtocol);
} else if (passphrase == null) {
ns = createNetworkSpecifier(clientId,
doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
- peerHandle, pmk, null);
+ peerHandle, pmk, null, port, transportProtocol);
} else {
ns = createNetworkSpecifier(clientId,
doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER
: WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId,
- peerHandle, null, passphrase);
+ peerHandle, null, passphrase, port, transportProtocol);
}
NetworkCapabilities nc = new NetworkCapabilities();
@@ -1346,6 +1522,12 @@ public class WifiAwareDataPathStateManagerTest {
private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer,
byte[] pmk, String passphrase, int requestId) throws Exception {
+ return getDirectNetworkRequestMore(clientId, role, peer, pmk, passphrase, requestId, 0, -1);
+ }
+
+ private NetworkRequest getDirectNetworkRequestMore(int clientId, int role, byte[] peer,
+ byte[] pmk, String passphrase, int requestId, int port, int transportProtocol)
+ throws Exception {
final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class);
final ConfigRequest configRequest = new ConfigRequest.Builder().build();
final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService);
@@ -1366,11 +1548,12 @@ public class WifiAwareDataPathStateManagerTest {
NetworkSpecifier ns;
if (pmk == null && passphrase == null) {
- ns = createNetworkSpecifier(clientId, role, peer, null, null);
+ ns = createNetworkSpecifier(clientId, role, peer, null, null, port, transportProtocol);
} else if (passphrase == null) {
- ns = createNetworkSpecifier(clientId, role, peer, pmk, null);
+ ns = createNetworkSpecifier(clientId, role, peer, pmk, null, port, transportProtocol);
} else {
- ns = createNetworkSpecifier(clientId, role, peer, null, passphrase);
+ ns = createNetworkSpecifier(clientId, role, peer, null, passphrase, port,
+ transportProtocol);
}
NetworkCapabilities nc = new NetworkCapabilities();
nc.clearAll();
@@ -1502,7 +1685,7 @@ public class WifiAwareDataPathStateManagerTest {
* network requests which may not be valid (e.g. for the API level).
*/
public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId,
- PeerHandle peerHandle, byte[] pmk, String passphrase) {
+ PeerHandle peerHandle, byte[] pmk, String passphrase, int port, int transportProtocol) {
return new WifiAwareNetworkSpecifier(
(peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
: WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB,
@@ -1513,6 +1696,8 @@ public class WifiAwareDataPathStateManagerTest {
null, // peerMac (not used in this method)
pmk,
passphrase,
+ port,
+ transportProtocol,
Process.myUid());
}
@@ -1521,7 +1706,7 @@ public class WifiAwareDataPathStateManagerTest {
* network requests which may not be valid (e.g. for the API level).
*/
private NetworkSpecifier createNetworkSpecifier(int clientId, int role, byte[] peer, byte[] pmk,
- String passphrase) {
+ String passphrase, int port, int transportProtocol) {
return new WifiAwareNetworkSpecifier(
(peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER
: WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB,
@@ -1532,6 +1717,8 @@ public class WifiAwareDataPathStateManagerTest {
peer,
pmk,
passphrase,
+ port,
+ transportProtocol,
Process.myUid());
}
@@ -1546,4 +1733,27 @@ public class WifiAwareDataPathStateManagerTest {
mMessenger = messenger;
}
}
+
+ // copy of the method in WifiAwareDataPathStateManager - but without error checking (so we can
+ // construct invalid TLVs for testing).
+ private static byte[] buildTlv(boolean includeSignature, int port, int transportProtocol,
+ boolean includeGarbageTlv) {
+ TlvBufferUtils.TlvConstructor tlvc = new TlvBufferUtils.TlvConstructor(1, 1);
+ tlvc.allocate(30); // safe size for now
+
+ if (includeSignature) {
+ tlvc.putInt(WifiAwareDataPathStateManager.NetworkInformationData.TYPE_SIGNATURE,
+ WifiAwareDataPathStateManager.NetworkInformationData.SIGNATURE);
+ }
+
+ tlvc.putInt(WifiAwareDataPathStateManager.NetworkInformationData.TYPE_PORT, port);
+ tlvc.putByte(WifiAwareDataPathStateManager.NetworkInformationData.TYPE_TRANSPORT_PROTOCOL,
+ (byte) transportProtocol);
+
+ if (includeGarbageTlv) {
+ tlvc.putInt(WifiAwareDataPathStateManager.NetworkInformationData.TYPE_PORT + 55, 23);
+ }
+
+ return tlvc.getArray();
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
index f7a0ed7fa..cb6cd15fe 100644
--- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareMetricsTest.java
@@ -633,7 +633,7 @@ public class WifiAwareMetricsTest {
.AwareNetworkRequestInformation> networkRequestCache,
int index, int uid, String interfaceName, String passphrase) {
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier(0, 0, 0, index, 0, null, null,
- passphrase, 0);
+ passphrase, 0, 0, 0);
WifiAwareDataPathStateManager.AwareNetworkRequestInformation anri =
new WifiAwareDataPathStateManager.AwareNetworkRequestInformation();
anri.networkSpecifier = ns;