diff options
author | Etan Cohen <etancohen@google.com> | 2018-11-09 09:53:31 -0800 |
---|---|---|
committer | Etan Cohen <etancohen@google.com> | 2019-01-05 17:09:54 -0800 |
commit | b4be2b26ac9b15299d2d0884d765a9d629f14396 (patch) | |
tree | 61c1ed1a2cec5de32e97ac22cb72b37db75d0280 | |
parent | 134a49ce07083b21b76110e1fe35c3bccf77d803 (diff) | |
download | android_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
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; |