1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi.aware; 18 19 import static android.hardware.wifi.V1_0.NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED; 20 21 import static org.hamcrest.core.IsEqual.equalTo; 22 import static org.junit.Assert.assertArrayEquals; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertNotEquals; 25 import static org.junit.Assert.assertTrue; 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.ArgumentMatchers.anyBoolean; 28 import static org.mockito.ArgumentMatchers.anyInt; 29 import static org.mockito.ArgumentMatchers.anyLong; 30 import static org.mockito.ArgumentMatchers.anyShort; 31 import static org.mockito.ArgumentMatchers.anyString; 32 import static org.mockito.ArgumentMatchers.eq; 33 import static org.mockito.Mockito.atLeastOnce; 34 import static org.mockito.Mockito.inOrder; 35 import static org.mockito.Mockito.mock; 36 import static org.mockito.Mockito.never; 37 import static org.mockito.Mockito.reset; 38 import static org.mockito.Mockito.verify; 39 import static org.mockito.Mockito.verifyNoMoreInteractions; 40 import static org.mockito.Mockito.when; 41 42 import android.Manifest; 43 import android.app.test.TestAlarmManager; 44 import android.content.Context; 45 import android.content.pm.PackageManager; 46 import android.hardware.wifi.V1_0.NanStatusType; 47 import android.net.ConnectivityManager; 48 import android.net.MacAddress; 49 import android.net.NetworkCapabilities; 50 import android.net.NetworkFactory; 51 import android.net.NetworkProvider; 52 import android.net.NetworkRequest; 53 import android.net.NetworkSpecifier; 54 import android.net.wifi.WifiManager; 55 import android.net.wifi.aware.AttachCallback; 56 import android.net.wifi.aware.ConfigRequest; 57 import android.net.wifi.aware.DiscoverySession; 58 import android.net.wifi.aware.DiscoverySessionCallback; 59 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback; 60 import android.net.wifi.aware.IWifiAwareEventCallback; 61 import android.net.wifi.aware.IWifiAwareManager; 62 import android.net.wifi.aware.PeerHandle; 63 import android.net.wifi.aware.PublishConfig; 64 import android.net.wifi.aware.PublishDiscoverySession; 65 import android.net.wifi.aware.SubscribeConfig; 66 import android.net.wifi.aware.SubscribeDiscoverySession; 67 import android.net.wifi.aware.TlvBufferUtils; 68 import android.net.wifi.aware.WifiAwareManager; 69 import android.net.wifi.aware.WifiAwareNetworkInfo; 70 import android.net.wifi.aware.WifiAwareNetworkSpecifier; 71 import android.net.wifi.aware.WifiAwareSession; 72 import android.net.wifi.util.HexEncoding; 73 import android.os.Handler; 74 import android.os.Message; 75 import android.os.Messenger; 76 import android.os.PowerManager; 77 import android.os.Process; 78 import android.os.test.TestLooper; 79 80 import androidx.test.filters.SmallTest; 81 82 import com.android.server.wifi.Clock; 83 import com.android.server.wifi.MockResources; 84 import com.android.server.wifi.WifiBaseTest; 85 import com.android.server.wifi.aware.WifiAwareDataPathStateManager.WifiAwareNetworkAgent; 86 import com.android.server.wifi.util.NetdWrapper; 87 import com.android.server.wifi.util.WifiPermissionsUtil; 88 import com.android.server.wifi.util.WifiPermissionsWrapper; 89 import com.android.wifi.resources.R; 90 91 import org.junit.After; 92 import org.junit.Before; 93 import org.junit.Rule; 94 import org.junit.Test; 95 import org.junit.rules.ErrorCollector; 96 import org.mockito.ArgumentCaptor; 97 import org.mockito.InOrder; 98 import org.mockito.Mock; 99 import org.mockito.MockitoAnnotations; 100 import org.mockito.Spy; 101 102 import java.nio.ByteOrder; 103 import java.util.ArrayList; 104 import java.util.Arrays; 105 import java.util.Collections; 106 import java.util.HashSet; 107 import java.util.List; 108 import java.util.Set; 109 110 111 /** 112 * Unit test harness for WifiAwareDataPathStateManager class. 113 */ 114 @SmallTest 115 public class WifiAwareDataPathStateManagerTest extends WifiBaseTest { 116 private static final String sAwareInterfacePrefix = "aware_data"; 117 private static final String TEST_PACKAGE_NAME = "com.android.somePackage"; 118 private static final String TEST_FEATURE_ID = "com.android.someFeature"; 119 120 private TestLooper mMockLooper; 121 private Handler mMockLooperHandler; 122 private WifiAwareStateManager mDut; 123 @Mock private Clock mClock; 124 @Mock private WifiAwareNativeManager mMockNativeManager; 125 @Spy private TestUtils.MonitoredWifiAwareNativeApi mMockNative = 126 new TestUtils.MonitoredWifiAwareNativeApi(); 127 @Mock private Context mMockContext; 128 @Mock private ConnectivityManager mMockCm; 129 @Mock private NetdWrapper mMockNetdWrapper; 130 @Mock private WifiAwareDataPathStateManager.NetworkInterfaceWrapper mMockNetworkInterface; 131 @Mock private IWifiAwareEventCallback mMockCallback; 132 @Mock IWifiAwareDiscoverySessionCallback mMockSessionCallback; 133 @Mock private WifiAwareMetrics mAwareMetricsMock; 134 @Mock private WifiPermissionsUtil mWifiPermissionsUtil; 135 @Mock private WifiPermissionsWrapper mPermissionsWrapperMock; 136 @Mock private WifiManager mMockWifiManager; 137 TestAlarmManager mAlarmManager; 138 @Mock private PowerManager mMockPowerManager; 139 140 @Rule 141 public ErrorCollector collector = new ErrorCollector(); 142 private MockResources mResources; 143 144 /** 145 * Initialize mocks. 146 */ 147 @Before setUp()148 public void setUp() throws Exception { 149 MockitoAnnotations.initMocks(this); 150 151 mAlarmManager = new TestAlarmManager(); 152 when(mMockContext.getSystemService(Context.ALARM_SERVICE)) 153 .thenReturn(mAlarmManager.getAlarmManager()); 154 155 when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager); 156 when(mMockWifiManager.getWifiState()).thenReturn(WifiManager.WIFI_STATE_ENABLED); 157 158 mMockLooper = new TestLooper(); 159 mMockLooperHandler = new Handler(mMockLooper.getLooper()); 160 161 when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm); 162 when(mMockContext.getSystemService(ConnectivityManager.class)).thenReturn(mMockCm); 163 when(mMockContext.getSystemServiceName(PowerManager.class)).thenReturn( 164 Context.POWER_SERVICE); 165 when(mMockContext.getSystemService(PowerManager.class)).thenReturn(mMockPowerManager); 166 167 // by default pretend to be an old API: i.e. allow Responders configured as *ANY*. This 168 // allows older (more extrensive) tests to run. 169 when(mWifiPermissionsUtil.isTargetSdkLessThan(anyString(), anyInt(), anyInt())) 170 .thenReturn(true); 171 when(mWifiPermissionsUtil.isLocationModeEnabled()).thenReturn(true); 172 173 mDut = new WifiAwareStateManager(); 174 mDut.setNative(mMockNativeManager, mMockNative); 175 mDut.start(mMockContext, mMockLooper.getLooper(), mAwareMetricsMock, 176 mWifiPermissionsUtil, mPermissionsWrapperMock, mClock, mMockNetdWrapper); 177 mDut.startLate(); 178 mMockLooper.dispatchAll(); 179 180 when(mMockNetworkInterface.configureAgentProperties(any(), any(), any())).thenReturn(true); 181 when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(true); 182 183 when(mMockPowerManager.isDeviceIdleMode()).thenReturn(false); 184 when(mMockPowerManager.isInteractive()).thenReturn(true); 185 186 mDut.mDataPathMgr.mNetdWrapper = mMockNetdWrapper; 187 mDut.mDataPathMgr.mNiWrapper = mMockNetworkInterface; 188 189 mResources = new MockResources(); 190 mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, false); 191 when(mMockContext.getResources()).thenReturn(mResources); 192 } 193 194 /** 195 * Post-test validation. 196 */ 197 @After tearDown()198 public void tearDown() throws Exception { 199 mMockNative.validateUniqueTransactionIds(); 200 } 201 202 /** 203 * Validates that creating and deleting all interfaces works based on capabilities. 204 */ 205 @Test testCreateDeleteAllInterfaces()206 public void testCreateDeleteAllInterfaces() throws Exception { 207 final int numNdis = 3; 208 final int failCreateInterfaceIndex = 1; 209 210 Capabilities capabilities = new Capabilities(); 211 capabilities.maxNdiInterfaces = numNdis; 212 213 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 214 ArgumentCaptor<String> interfaceName = ArgumentCaptor.forClass(String.class); 215 InOrder inOrder = inOrder(mMockNative); 216 217 // (1) get capabilities 218 mDut.queryCapabilities(); 219 mMockLooper.dispatchAll(); 220 inOrder.verify(mMockNative).getCapabilities(transactionId.capture()); 221 mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities); 222 mMockLooper.dispatchAll(); 223 224 // (2) create all interfaces 225 mDut.createAllDataPathInterfaces(); 226 mMockLooper.dispatchAll(); 227 for (int i = 0; i < numNdis; ++i) { 228 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 229 interfaceName.capture()); 230 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, 231 equalTo(interfaceName.getValue())); 232 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 233 mMockLooper.dispatchAll(); 234 } 235 236 // (3) delete all interfaces [one unsuccessfully] - note that will not necessarily be 237 // done sequentially 238 boolean[] done = new boolean[numNdis]; 239 Arrays.fill(done, false); 240 mDut.deleteAllDataPathInterfaces(); 241 mMockLooper.dispatchAll(); 242 for (int i = 0; i < numNdis; ++i) { 243 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(), 244 interfaceName.capture()); 245 int interfaceIndex = Integer.valueOf( 246 interfaceName.getValue().substring(sAwareInterfacePrefix.length())); 247 done[interfaceIndex] = true; 248 if (interfaceIndex == failCreateInterfaceIndex) { 249 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), false, 0); 250 } else { 251 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0); 252 } 253 mMockLooper.dispatchAll(); 254 } 255 verify(mMockNativeManager, never()).releaseAware(); 256 for (int i = 0; i < numNdis; ++i) { 257 collector.checkThat("interface deleted -- " + i, done[i], equalTo(true)); 258 } 259 260 // (4) create all interfaces (should get a delete for the one which couldn't delete earlier) 261 mDut.createAllDataPathInterfaces(); 262 mMockLooper.dispatchAll(); 263 for (int i = 0; i < numNdis; ++i) { 264 if (i == failCreateInterfaceIndex) { 265 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(), 266 interfaceName.capture()); 267 collector.checkThat("interface delete pre-create -- " + i, 268 sAwareInterfacePrefix + i, equalTo(interfaceName.getValue())); 269 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0); 270 mMockLooper.dispatchAll(); 271 } 272 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 273 interfaceName.capture()); 274 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, 275 equalTo(interfaceName.getValue())); 276 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 277 mMockLooper.dispatchAll(); 278 } 279 280 verifyNoMoreInteractions(mMockNative, mMockNetdWrapper); 281 } 282 283 /** 284 * Validate that trying to specify port info on subscriber results in failure. 285 */ 286 @Test testDataPathWithPortInfoOnPublisher()287 public void testDataPathWithPortInfoOnPublisher() throws Exception { 288 final int clientId = 123; 289 final byte pubSubId = 55; 290 final int requestorId = 1341234; 291 final String passphrase = "SomeSecurePassword"; 292 final int ndpId = 1; 293 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 294 295 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 296 InOrder inOrderM = inOrder(mAwareMetricsMock); 297 298 // (0) initialize 299 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 300 peerDiscoveryMac, inOrder, inOrderM, false); 301 302 // (1) request network 303 NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle, 304 null, passphrase, true, 0, 5, 6); 305 306 Message reqNetworkMsg = Message.obtain(); 307 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 308 reqNetworkMsg.obj = nr; 309 reqNetworkMsg.arg1 = 0; 310 res.mMessenger.send(reqNetworkMsg); 311 mMockLooper.dispatchAll(); 312 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 313 314 // (2) provide a request 315 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 316 mMockLooper.dispatchAll(); 317 318 // do not respond/create a data-path! 319 verify(mMockNative, never()).respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(), 320 anyString(), any(), anyString(), any(), anyBoolean(), any()); 321 } 322 323 /** 324 * Validate that trying to specify invalid port info results in failure. 325 */ 326 @Test testDataPathWithPortInfoInvalidPort()327 public void testDataPathWithPortInfoInvalidPort() throws Exception { 328 final int clientId = 123; 329 final byte pubSubId = 55; 330 final int requestorId = 1341234; 331 final String passphrase = "SomeSecurePassword"; 332 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 333 334 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 335 InOrder inOrderM = inOrder(mAwareMetricsMock); 336 337 // (0) initialize 338 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 339 peerDiscoveryMac, inOrder, inOrderM, false); 340 341 // (1) request network 342 NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle, 343 null, passphrase, false, 0, -3, 6); 344 345 Message reqNetworkMsg = Message.obtain(); 346 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 347 reqNetworkMsg.obj = nr; 348 reqNetworkMsg.arg1 = 0; 349 res.mMessenger.send(reqNetworkMsg); 350 mMockLooper.dispatchAll(); 351 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 352 353 // do not create a data-path! 354 verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), 355 any(), anyString(), any(), anyString(), anyBoolean(), any(), any()); 356 } 357 358 /** 359 * Validate that trying to specify port info without security results in failure. 360 */ 361 @Test testDataPathWithPortInfoButNoSecurityOnSubscriber()362 public void testDataPathWithPortInfoButNoSecurityOnSubscriber() throws Exception { 363 final int clientId = 123; 364 final byte pubSubId = 55; 365 final int requestorId = 1341234; 366 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 367 368 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 369 InOrder inOrderM = inOrder(mAwareMetricsMock); 370 371 // (0) initialize 372 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 373 peerDiscoveryMac, inOrder, inOrderM, false); 374 375 // (1) request network 376 NetworkRequest nr = getSessionNetworkRequestMore(clientId, res.mSessionId, res.mPeerHandle, 377 null, null, false, 0, 10, 6); 378 379 Message reqNetworkMsg = Message.obtain(); 380 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 381 reqNetworkMsg.obj = nr; 382 reqNetworkMsg.arg1 = 0; 383 res.mMessenger.send(reqNetworkMsg); 384 mMockLooper.dispatchAll(); 385 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 386 387 // do not create a data-path! 388 verify(mMockNative, never()).initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), 389 any(), anyString(), any(), anyString(), anyBoolean(), any(), any()); 390 } 391 392 /** 393 * Validate that if the data-interfaces are deleted while a data-path is being created, the 394 * process will terminate. 395 */ 396 @Test testDestroyNdiDuringNdpSetupResponder()397 public void testDestroyNdiDuringNdpSetupResponder() throws Exception { 398 final int clientId = 123; 399 final byte pubSubId = 55; 400 final int requestorId = 1341234; 401 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 402 final int ndpId = 3; 403 404 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 405 InOrder inOrderM = inOrder(mAwareMetricsMock); 406 407 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 408 409 // (0) initialize 410 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 411 peerDiscoveryMac, inOrder, inOrderM, true); 412 413 // (1) request network 414 NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, 415 null, null, true, 0); 416 417 Message reqNetworkMsg = Message.obtain(); 418 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 419 reqNetworkMsg.obj = nr; 420 reqNetworkMsg.arg1 = 0; 421 res.mMessenger.send(reqNetworkMsg); 422 mMockLooper.dispatchAll(); 423 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 424 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB); 425 426 // (2) delete interface(s) 427 mDut.deleteAllDataPathInterfaces(); 428 mMockLooper.dispatchAll(); 429 inOrder.verify(mMockNative).deleteAwareNetworkInterface(transactionId.capture(), 430 anyString()); 431 mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0); 432 mMockLooper.dispatchAll(); 433 434 // (3) have responder receive request 435 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 436 mMockLooper.dispatchAll(); 437 438 // (4) verify that responder aborts (i.e. refuses request) 439 inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(false), 440 eq(ndpId), eq(""), eq(null), eq(null), eq(null), eq(false), any()); 441 mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0); 442 mMockLooper.dispatchAll(); 443 444 verifyRequestDeclaredUnfullfillable(nr); 445 446 // failure if there's further activity 447 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 448 } 449 450 /** 451 * Validate multiple NDPs created on a single NDI when overlay set to enabled multiple NDP on 452 * same aware NDI. Most importantly that the interface is set up on first NDP and torn down on 453 * last NDP - and not when one or the other is created or deleted. 454 * 455 * Procedure: 456 * - create NDP 1, 2, and 3 (interface up only on first) 457 * - delete NDP 2, 1, and 3 (interface down only on last) 458 */ 459 @Test testMultipleNdpsOnSingleNdi()460 public void testMultipleNdpsOnSingleNdi() throws Exception { 461 final int clientId = 123; 462 final byte pubSubId = 58; 463 final int requestorId = 1341234; 464 final int ndpId = 2; 465 final String interfaceName = sAwareInterfacePrefix + "0"; 466 final int port = 23; 467 final byte transportProtocol = 6; 468 469 final int[] startOrder = {0, 1, 2}; 470 final int[] endOrder = {1, 0, 2}; 471 int networkRequestId = 0; 472 473 mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, true); 474 475 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = 476 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class); 477 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 478 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 479 mMockNetdWrapper, mMockNetworkInterface); 480 InOrder inOrderM = inOrder(mAwareMetricsMock); 481 482 NetworkRequest[] nrs = new NetworkRequest[3]; 483 DataPathEndPointInfo[] ress = new DataPathEndPointInfo[3]; 484 WifiAwareNetworkAgent[] agentBinders = new WifiAwareNetworkAgent[3]; 485 Messenger messenger = null; 486 boolean first = true; 487 for (int i : startOrder) { 488 networkRequestId += 1; 489 byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 490 byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 491 peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i); 492 peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i); 493 494 // (0) initialize 495 ress[i] = initDataPathEndPoint(first, clientId, (byte) (pubSubId + i), 496 requestorId + i, peerDiscoveryMac, inOrder, inOrderM, false); 497 if (first) { 498 messenger = ress[i].mMessenger; 499 } 500 501 // (1) request network 502 nrs[i] = getSessionNetworkRequest(clientId, ress[i].mSessionId, ress[i].mPeerHandle, 503 null, null, false, networkRequestId); 504 505 Message reqNetworkMsg = Message.obtain(); 506 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 507 reqNetworkMsg.obj = nrs[i]; 508 reqNetworkMsg.arg1 = 0; 509 messenger.send(reqNetworkMsg); 510 mMockLooper.dispatchAll(); 511 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 512 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB); 513 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), 514 eq(requestorId + i), 515 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 516 eq(interfaceName), eq(null), 517 eq(null), eq(false), any(), any()); 518 519 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i); 520 mMockLooper.dispatchAll(); 521 522 // (2) get confirmation 523 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, 524 buildTlv(port, transportProtocol, true), null); 525 mMockLooper.dispatchAll(); 526 if (first) { 527 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 528 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 529 530 first = false; 531 } 532 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 533 agentBinders[i] = agentCaptor.getValue(); 534 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 535 eq(false), anyLong()); 536 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 537 WifiAwareNetworkInfo netInfo = 538 (WifiAwareNetworkInfo) agentBinders[i].mDataPathCapabilities.getTransportInfo(); 539 assertArrayEquals(MacAddress.fromBytes( 540 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 541 netInfo.getPeerIpv6Addr().getAddress()); 542 assertEquals(port, netInfo.getPort()); 543 assertEquals(transportProtocol, netInfo.getTransportProtocol()); 544 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps()); 545 } 546 547 // (3) end data-path (unless didn't get confirmation) 548 int index = 0; 549 for (int i: endOrder) { 550 Message endNetworkReqMsg = Message.obtain(); 551 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 552 endNetworkReqMsg.obj = nrs[i]; 553 messenger.send(endNetworkReqMsg); 554 555 agentBinders[i].onNetworkUnwanted(); 556 mMockLooper.dispatchAll(); 557 558 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId + i)); 559 560 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 561 mDut.onDataPathEndNotification(ndpId + i); 562 mMockLooper.dispatchAll(); 563 564 if (index++ == endOrder.length - 1) { 565 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString()); 566 } 567 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 568 } 569 570 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 571 } 572 573 /** 574 * Validate that multiple NDP requests which resolve to the same canonical request are treated 575 * as one. 576 */ 577 @Test testMultipleIdenticalRequests()578 public void testMultipleIdenticalRequests() throws Exception { 579 final int numRequestsPre = 6; 580 final int numRequestsPost = 5; 581 final int clientId = 123; 582 final int ndpId = 5; 583 final int port = 0; 584 final int transportProtocol = 6; // can't specify transport protocol without port 585 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 586 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 587 final byte[] allZeros = HexEncoding.decode("000000000000".toCharArray(), false); 588 NetworkRequest[] nrs = new NetworkRequest[numRequestsPre + numRequestsPost + 1]; 589 590 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 591 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = 592 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class); 593 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 594 mMockNetdWrapper, mMockNetworkInterface); 595 InOrder inOrderM = inOrder(mAwareMetricsMock); 596 597 // (1) initialize all clients 598 Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM); 599 for (int i = 1; i < numRequestsPre + numRequestsPost; ++i) { 600 initOobDataPathEndPoint(false, 1, clientId + i, inOrder, inOrderM); 601 } 602 DataPathEndPointInfo ddepi = initDataPathEndPoint(false, 603 clientId + numRequestsPre + numRequestsPost, (byte) 10, 11, peerDiscoveryMac, 604 inOrder, inOrderM, false); 605 606 // (2) make initial network requests (all identical under the hood) 607 for (int i = 0; i < numRequestsPre; ++i) { 608 nrs[i] = getDirectNetworkRequest(clientId + i, 609 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, 610 null, i); 611 612 Message reqNetworkMsg = Message.obtain(); 613 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 614 reqNetworkMsg.obj = nrs[i]; 615 reqNetworkMsg.arg1 = 0; 616 messenger.send(reqNetworkMsg); 617 } 618 mMockLooper.dispatchAll(); 619 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 620 621 // (3) verify the start NDP HAL request 622 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), 623 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 624 eq(sAwareInterfacePrefix + "0"), eq(null), eq(null), eq(true), any(), any()); 625 626 // (4) unregister request #0 (the primary) 627 Message endNetworkReqMsg = Message.obtain(); 628 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 629 endNetworkReqMsg.obj = nrs[0]; 630 messenger.send(endNetworkReqMsg); 631 mMockLooper.dispatchAll(); 632 633 // (5) respond to the registration request 634 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId); 635 mMockLooper.dispatchAll(); 636 637 // (6) unregister request #1 638 endNetworkReqMsg = Message.obtain(); 639 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 640 endNetworkReqMsg.obj = nrs[1]; 641 messenger.send(endNetworkReqMsg); 642 mMockLooper.dispatchAll(); 643 644 // (6.5) provide a (semi) bogus NDP Requst Indication - mostly bogus on Initiator but 645 // may contain the peer's TLVs (in this case it does) 646 mDut.onDataPathRequestNotification(0, allZeros, ndpId, 647 buildTlv(port, transportProtocol, true)); 648 649 // (7) confirm the NDP creation 650 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null); 651 mMockLooper.dispatchAll(); 652 653 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 654 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 655 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 656 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 657 eq(true), anyLong()); 658 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 659 WifiAwareNetworkInfo netInfo = 660 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 661 .getTransportInfo(); 662 assertArrayEquals(MacAddress.fromBytes( 663 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 664 netInfo.getPeerIpv6Addr().getAddress()); 665 assertEquals(port, netInfo.getPort()); 666 assertEquals(transportProtocol, netInfo.getTransportProtocol()); 667 assertEquals(1, mDut.mDataPathMgr.getNumOfNdps()); 668 669 // (8) execute 'post' requests 670 for (int i = numRequestsPre; i < numRequestsPre + numRequestsPost; ++i) { 671 nrs[i] = getDirectNetworkRequest(clientId + i, 672 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, 673 null, i); 674 675 Message reqNetworkMsg = Message.obtain(); 676 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 677 reqNetworkMsg.obj = nrs[i]; 678 reqNetworkMsg.arg1 = 0; 679 messenger.send(reqNetworkMsg); 680 } 681 682 nrs[numRequestsPre + numRequestsPost] = getSessionNetworkRequest( 683 clientId + numRequestsPre + numRequestsPost, ddepi.mSessionId, ddepi.mPeerHandle, 684 null, null, false, 11); 685 Message reqNetworkMsg = Message.obtain(); 686 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 687 reqNetworkMsg.obj = nrs[numRequestsPre + numRequestsPost]; 688 reqNetworkMsg.arg1 = 0; 689 messenger.send(reqNetworkMsg); 690 mMockLooper.dispatchAll(); 691 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 692 693 // (9) unregister all requests 694 for (int i = 2; i < numRequestsPre + numRequestsPost + 1; ++i) { 695 endNetworkReqMsg = Message.obtain(); 696 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 697 endNetworkReqMsg.obj = nrs[i]; 698 messenger.send(endNetworkReqMsg); 699 mMockLooper.dispatchAll(); 700 } 701 702 agentCaptor.getValue().onNetworkUnwanted(); 703 mMockLooper.dispatchAll(); 704 705 // (10) verify that NDP torn down 706 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 707 708 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 709 mDut.onDataPathEndNotification(ndpId); 710 mMockLooper.dispatchAll(); 711 712 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString()); 713 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 714 715 verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback, 716 mAwareMetricsMock, mMockNetdWrapper); 717 } 718 719 /** 720 * Validate that multiple NDP requests to the same peer target different NDIs. 721 */ 722 @Test testMultipleNdiToSamePeer()723 public void testMultipleNdiToSamePeer() throws Exception { 724 final int numNdis = 5; 725 final int clientId = 123; 726 final int ndpId = 5; 727 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 728 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 729 730 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 731 ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class); 732 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass( 733 WifiAwareNetworkAgent.class); 734 735 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 736 mMockNetdWrapper, mMockNetworkInterface); 737 InOrder inOrderM = inOrder(mAwareMetricsMock); 738 739 // (1) initialize all clients 740 Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM); 741 for (int i = 1; i < numNdis + 3; ++i) { 742 initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM); 743 } 744 745 // (2) make N network requests: each unique 746 Set<String> interfaces = new HashSet<>(); 747 for (int i = 0; i < numNdis + 1; ++i) { 748 byte[] pmk = new byte[32]; 749 pmk[0] = (byte) i; 750 751 NetworkRequest nr = getDirectNetworkRequest(clientId + i, 752 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk, 753 null, i); 754 755 Message reqNetworkMsg = Message.obtain(); 756 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 757 reqNetworkMsg.obj = nr; 758 reqNetworkMsg.arg1 = 0; 759 messenger.send(reqNetworkMsg); 760 mMockLooper.dispatchAll(); 761 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 762 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB); 763 764 if (i < numNdis) { 765 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), 766 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 767 ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any()); 768 interfaces.add(ifNameCaptor.getValue()); 769 770 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i); 771 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null); 772 mMockLooper.dispatchAll(); 773 774 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 775 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 776 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 777 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 778 eq(true), anyLong()); 779 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 780 WifiAwareNetworkInfo netInfo = 781 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 782 .getTransportInfo(); 783 assertArrayEquals(MacAddress.fromBytes( 784 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 785 netInfo.getPeerIpv6Addr().getAddress()); 786 assertEquals(0, netInfo.getPort()); // uninitialized -> 0 787 assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1 788 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps()); 789 } else { 790 verifyRequestDeclaredUnfullfillable(nr); 791 } 792 } 793 794 // verify that each interface name is unique 795 assertEquals("Number of unique interface names", numNdis, interfaces.size()); 796 797 verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback, 798 mAwareMetricsMock, mMockNetdWrapper); 799 } 800 801 /** 802 * When overlay set to disabled multiple networks on single Aware NDI, validate that multiple 803 * NDP requests to the different peer target different NDIs. And when number of requests exceeds 804 * the number of NDIs, request will be rejected. 805 */ 806 @Test testMultipleNdiToDifferentPeer()807 public void testMultipleNdiToDifferentPeer() throws Exception { 808 final int numNdis = 5; 809 final int clientId = 123; 810 final int ndpId = 5; 811 812 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 813 ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class); 814 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass( 815 WifiAwareNetworkAgent.class); 816 817 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 818 mMockNetdWrapper, mMockNetworkInterface); 819 InOrder inOrderM = inOrder(mAwareMetricsMock); 820 821 // (1) initialize all clients 822 Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM); 823 for (int i = 1; i < numNdis + 3; ++i) { 824 initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM); 825 } 826 827 // (2) make N network requests: each unique 828 Set<String> interfaces = new HashSet<>(); 829 for (int i = 0; i < numNdis + 1; ++i) { 830 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 831 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 832 peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i); 833 peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i); 834 835 byte[] pmk = new byte[32]; 836 pmk[0] = (byte) i; 837 838 NetworkRequest nr = getDirectNetworkRequest(clientId + i, 839 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk, 840 null, i); 841 842 Message reqNetworkMsg = Message.obtain(); 843 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 844 reqNetworkMsg.obj = nr; 845 reqNetworkMsg.arg1 = 0; 846 messenger.send(reqNetworkMsg); 847 mMockLooper.dispatchAll(); 848 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 849 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB); 850 851 if (i < numNdis) { 852 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), 853 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 854 ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any()); 855 interfaces.add(ifNameCaptor.getValue()); 856 857 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i); 858 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null); 859 mMockLooper.dispatchAll(); 860 861 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 862 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 863 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 864 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 865 eq(true), anyLong()); 866 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 867 WifiAwareNetworkInfo netInfo = 868 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 869 .getTransportInfo(); 870 assertArrayEquals(MacAddress.fromBytes( 871 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 872 netInfo.getPeerIpv6Addr().getAddress()); 873 assertEquals(0, netInfo.getPort()); // uninitialized -> 0 874 assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1 875 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps()); 876 } else { 877 verifyRequestDeclaredUnfullfillable(nr); 878 } 879 } 880 881 // verify that each interface name is unique 882 assertEquals("Number of unique interface names", numNdis, interfaces.size()); 883 884 verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback, 885 mAwareMetricsMock, mMockNetdWrapper); 886 } 887 888 /** 889 * When overlay set to enable multiple networks on single Aware NDI, validate that multiple 890 * NDP requests to the different peer target same NDI when only one NDI is available. Also when 891 * requests to a peer that is already accepted by this NDI, the new request should be reject. 892 */ 893 @Test testMultipleNdpToDifferentPeerOnSingleNdi()894 public void testMultipleNdpToDifferentPeerOnSingleNdi() throws Exception { 895 final int numNdis = 1; 896 final int clientId = 123; 897 final int ndpId = 5; 898 final int numberNdp = 3; 899 900 mResources.setBoolean(R.bool.config_wifiAllowMultipleNetworksOnSameAwareNdi, true); 901 902 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 903 ArgumentCaptor<String> ifNameCaptor = ArgumentCaptor.forClass(String.class); 904 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = ArgumentCaptor.forClass( 905 WifiAwareNetworkAgent.class); 906 907 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 908 mMockNetdWrapper, mMockNetworkInterface); 909 InOrder inOrderM = inOrder(mAwareMetricsMock); 910 911 // (1) initialize all clients 912 Messenger messenger = initOobDataPathEndPoint(true, numNdis, clientId, inOrder, inOrderM); 913 for (int i = 1; i < numberNdp; ++i) { 914 initOobDataPathEndPoint(false, numNdis, clientId + i, inOrder, inOrderM); 915 } 916 917 // (2) make 2 network requests: each unique 918 Set<String> interfaces = new HashSet<>(); 919 boolean first = true; 920 for (int i = 0; i < numberNdp - 1; ++i) { 921 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 922 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 923 peerDiscoveryMac[5] = (byte) (peerDiscoveryMac[5] + i); 924 peerDataPathMac[5] = (byte) (peerDataPathMac[5] + i); 925 926 byte[] pmk = new byte[32]; 927 pmk[0] = (byte) i; 928 929 NetworkRequest nr = getDirectNetworkRequest(clientId + i, 930 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk, 931 null, i); 932 933 Message reqNetworkMsg = Message.obtain(); 934 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 935 reqNetworkMsg.obj = nr; 936 reqNetworkMsg.arg1 = 0; 937 messenger.send(reqNetworkMsg); 938 mMockLooper.dispatchAll(); 939 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 940 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB); 941 942 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), 943 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 944 ifNameCaptor.capture(), eq(pmk), eq(null), eq(true), any(), any()); 945 interfaces.add(ifNameCaptor.getValue()); 946 947 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId + i); 948 mDut.onDataPathConfirmNotification(ndpId + i, peerDataPathMac, true, 0, null, null); 949 mMockLooper.dispatchAll(); 950 if (first) { 951 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 952 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 953 first = false; 954 } 955 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 956 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 957 eq(true), anyLong()); 958 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 959 WifiAwareNetworkInfo netInfo = 960 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 961 .getTransportInfo(); 962 assertArrayEquals(MacAddress.fromBytes( 963 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 964 netInfo.getPeerIpv6Addr().getAddress()); 965 assertEquals(0, netInfo.getPort()); // uninitialized -> 0 966 assertEquals(-1, netInfo.getTransportProtocol()); // uninitialized -> -1 967 assertEquals(i + 1, mDut.mDataPathMgr.getNumOfNdps()); 968 } 969 970 // verify that two request all using the same interface 971 assertEquals("Number of unique interface names", numNdis, interfaces.size()); 972 973 974 // make the 3rd network request which has the same peer as the first one. 975 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 976 977 byte[] pmk = new byte[32]; 978 pmk[0] = (byte) 2; 979 980 NetworkRequest nr = getDirectNetworkRequest(clientId + 2, 981 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, pmk, 982 null, 2); 983 984 Message reqNetworkMsg = Message.obtain(); 985 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 986 reqNetworkMsg.obj = nr; 987 reqNetworkMsg.arg1 = 0; 988 messenger.send(reqNetworkMsg); 989 mMockLooper.dispatchAll(); 990 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 991 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB); 992 993 // It should be reject as interface already has a request to this peer. 994 verifyRequestDeclaredUnfullfillable(nr); 995 996 verifyNoMoreInteractions(mMockNative, mMockCallback, mMockSessionCallback, 997 mAwareMetricsMock, mMockNetdWrapper); 998 } 999 1000 /* 1001 * Initiator tests 1002 */ 1003 1004 /** 1005 * Validate the success flow of the Initiator: using session network specifier with a non-null 1006 * PMK. 1007 */ 1008 @Test testDataPathInitiatorMacPmkSuccess()1009 public void testDataPathInitiatorMacPmkSuccess() throws Exception { 1010 testDataPathInitiatorUtility(false, true, true, false, true, false); 1011 } 1012 1013 /** 1014 * Validate the success flow of the Initiator: using a direct network specifier with a non-null 1015 * peer mac and non-null PMK. 1016 */ 1017 @Test testDataPathInitiatorDirectMacPmkSuccess()1018 public void testDataPathInitiatorDirectMacPmkSuccess() throws Exception { 1019 testDataPathInitiatorUtility(true, true, true, false, true, false); 1020 } 1021 1022 1023 /** 1024 * Validate the fail flow of the Initiator: use a session network specifier with a non-null 1025 * PMK, but don't get a confirmation. 1026 */ 1027 @Test testDataPathInitiatorNoConfirmationTimeoutFail()1028 public void testDataPathInitiatorNoConfirmationTimeoutFail() throws Exception { 1029 testDataPathInitiatorUtility(false, true, true, false, false, false); 1030 } 1031 1032 /** 1033 * Validate the fail flow of the Initiator: use a session network specifier with a non-null 1034 * Passphrase, but get an immediate failure 1035 */ 1036 @Test testDataPathInitiatorNoConfirmationHalFail()1037 public void testDataPathInitiatorNoConfirmationHalFail() throws Exception { 1038 testDataPathInitiatorUtility(false, true, false, true, true, true); 1039 } 1040 1041 /** 1042 * Verify that an TLV configuration with large port/transport-protocol work correctly. 1043 */ 1044 @Test testDataPathInitiatorNetInfoLargeValuesExp1()1045 public void testDataPathInitiatorNetInfoLargeValuesExp1() throws Exception { 1046 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1047 String linkLocalIpv6Address = MacAddress.fromBytes( 1048 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1049 1050 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1051 buildTlv((1 << 16) - 1, (1 << 8) - 1, true), (1 << 16) - 1, (1 << 8) - 1, 1052 linkLocalIpv6Address, 0); 1053 } 1054 1055 /** 1056 * Verify that an TLV configuration with large port/transport-protocol work correctly. 1057 */ 1058 @Test testDataPathInitiatorNetInfoLargeValuesExp2()1059 public void testDataPathInitiatorNetInfoLargeValuesExp2() throws Exception { 1060 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1061 String linkLocalIpv6Address = MacAddress.fromBytes( 1062 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1063 1064 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1065 buildTlv(1 << 15, 1 << 7, true), 1 << 15, 1 << 7, linkLocalIpv6Address, 0); 1066 } 1067 1068 /** 1069 * Verify that an TLV configuration with large port/transport-protocol work correctly. 1070 */ 1071 @Test testDataPathInitiatorNetInfoLargeValuesExp3()1072 public void testDataPathInitiatorNetInfoLargeValuesExp3() throws Exception { 1073 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1074 String linkLocalIpv6Address = MacAddress.fromBytes( 1075 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1076 1077 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1078 buildTlv((1 << 15) - 1, (1 << 7) - 1, true), (1 << 15) - 1, (1 << 7) - 1, 1079 linkLocalIpv6Address, 0); 1080 } 1081 1082 /** 1083 * Verify that an TLV configuration with an IPv6 override works correctly. 1084 */ 1085 @Test testDataPathInitiatorNetInfoIpv6Override()1086 public void testDataPathInitiatorNetInfoIpv6Override() throws Exception { 1087 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1088 final byte[] testVector = 1089 new byte[]{0x00, 0x08, 0x00, 0x00, (byte) 0xb3, (byte) 0xe1, (byte) 0xff, 1090 (byte) 0xfe, 0x7a, 0x2f, (byte) 0xa2}; 1091 1092 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1093 testVector, 0, -1, "fe80::b3:e1ff:fe7a:2fa2", 0); 1094 } 1095 1096 /** 1097 * Verify that retrying address validation a 'small' number of times results in successful 1098 * NDP setup. 1099 */ 1100 @Test testDataPathInitiatorAddressValidationRetrySuccess()1101 public void testDataPathInitiatorAddressValidationRetrySuccess() throws Exception { 1102 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1103 String linkLocalIpv6Address = MacAddress.fromBytes( 1104 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1105 1106 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1107 null, 0, -1, linkLocalIpv6Address, 1108 WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS 1109 / WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS - 1); 1110 } 1111 1112 /** 1113 * Verify that retrying address validation a 'large' number of times results in failure. 1114 */ 1115 @Test testDataPathInitiatorAddressValidationRetryFail()1116 public void testDataPathInitiatorAddressValidationRetryFail() throws Exception { 1117 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1118 String linkLocalIpv6Address = MacAddress.fromBytes( 1119 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1120 1121 testDataPathInitiatorUtilityMore(false, true, true, false, true, false, peerDataPathMac, 1122 null, 0, -1, linkLocalIpv6Address, 1123 WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS 1124 / WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS + 10); 1125 } 1126 1127 /** 1128 * Validate the fail flow of a mis-configured request: Publisher as Initiator 1129 */ 1130 @Test testDataPathInitiatorOnPublisherError()1131 public void testDataPathInitiatorOnPublisherError() throws Exception { 1132 testDataPathInitiatorResponderMismatchUtility(true); 1133 } 1134 1135 /** 1136 * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious 1137 * attacker (i.e. mismatched to its requested client's UID). 1138 */ 1139 @Test testDataPathInitiatorUidSetIncorrectlyError()1140 public void testDataPathInitiatorUidSetIncorrectlyError() throws Exception { 1141 testDataPathInitiatorResponderInvalidUidUtility(false); 1142 } 1143 1144 /** 1145 * Validate the fail flow of an Initiator (subscriber) with its package namee set as a malicious 1146 * attacker (i.e. mismatched to its requested client's package name). 1147 */ 1148 @Test testDataPathInitiatorPackageNameSetIncorrectlyError()1149 public void testDataPathInitiatorPackageNameSetIncorrectlyError() throws Exception { 1150 testDataPathInitiatorResponderInvalidPackageNameUtility(false); 1151 } 1152 1153 /* 1154 * Responder tests 1155 */ 1156 1157 /** 1158 * Validate the success flow of the Responder: using session network specifier with a 1159 * PMK. 1160 */ 1161 @Test testDataPathResonderMacPmkSuccess()1162 public void testDataPathResonderMacPmkSuccess() throws Exception { 1163 testDataPathResponderUtility(false, true, true, false, true); 1164 } 1165 1166 /** 1167 * Validate the success flow of the Responder: using session network specifier with a 1168 * Passphrase. 1169 */ 1170 @Test testDataPathResonderMacPassphraseSuccess()1171 public void testDataPathResonderMacPassphraseSuccess() throws Exception { 1172 testDataPathResponderUtility(false, true, false, false, true); 1173 } 1174 1175 /** 1176 * Validate the success flow of the Responder: using session network specifier with a 1177 * Passphrase and no peer ID (i.e. 0). 1178 */ 1179 @Test testDataPathResonderMacPassphraseNoPeerIdSuccess()1180 public void testDataPathResonderMacPassphraseNoPeerIdSuccess() throws Exception { 1181 testDataPathResponderUtility(false, false, false, true, true); 1182 } 1183 1184 /** 1185 * Validate the success flow of the Responder: using session network specifier with a null 1186 * PMK/Passphrase and no peer ID (i.e. 0). 1187 */ 1188 @Test testDataPathResonderMacOpenNoPeerIdNoPmkPassphraseSuccess()1189 public void testDataPathResonderMacOpenNoPeerIdNoPmkPassphraseSuccess() throws Exception { 1190 testDataPathResponderUtility(false, false, false, false, true); 1191 } 1192 1193 /** 1194 * Validate the success flow of the Responder: using a direct network specifier with a non-null 1195 * peer mac and non-null PMK. 1196 */ 1197 @Test testDataPathResonderDirectMacPmkSuccess()1198 public void testDataPathResonderDirectMacPmkSuccess() throws Exception { 1199 testDataPathResponderUtility(true, true, true, false, true); 1200 } 1201 1202 /** 1203 * Validate the success flow of the Responder: using a direct network specifier with a non-null 1204 * peer mac and null PMK/Passphrase. 1205 */ 1206 @Test testDataPathResonderDirectMacNoPmkPassphraseSuccess()1207 public void testDataPathResonderDirectMacNoPmkPassphraseSuccess() throws Exception { 1208 testDataPathResponderUtility(true, true, false, false, true); 1209 } 1210 1211 /** 1212 * Validate the success flow of the Responder: using a direct network specifier with a null peer 1213 * mac and non-null Passphrase. 1214 */ 1215 @Test testDataPathResonderDirectNoMacPassphraseSuccess()1216 public void testDataPathResonderDirectNoMacPassphraseSuccess() throws Exception { 1217 testDataPathResponderUtility(true, false, false, true, true); 1218 } 1219 1220 /** 1221 * Validate the success flow of the Responder: using a direct network specifier with a null peer 1222 * mac and null Pmk/Passphrase. 1223 */ 1224 @Test testDataPathResonderDirectNoMacNoPmkPassphraseSuccess()1225 public void testDataPathResonderDirectNoMacNoPmkPassphraseSuccess() throws Exception { 1226 testDataPathResponderUtility(true, false, false, false, true); 1227 } 1228 1229 /** 1230 * Validate the fail flow of the Responder: use a session network specifier with a non-null 1231 * PMK, but don't get a confirmation. 1232 */ 1233 @Test testDataPathResponderNoConfirmationTimeoutFail()1234 public void testDataPathResponderNoConfirmationTimeoutFail() throws Exception { 1235 testDataPathResponderUtility(false, true, true, false, false); 1236 } 1237 1238 /** 1239 * Validate the fail flow of a mis-configured request: Subscriber as Responder 1240 */ 1241 @Test testDataPathResponderOnSubscriberError()1242 public void testDataPathResponderOnSubscriberError() throws Exception { 1243 testDataPathInitiatorResponderMismatchUtility(false); 1244 } 1245 1246 /** 1247 * Validate the fail flow of an Initiator (subscriber) with its UID set as a malicious 1248 * attacker (i.e. mismatched to its requested client's UID). 1249 */ 1250 @Test testDataPathResponderUidSetIncorrectlyError()1251 public void testDataPathResponderUidSetIncorrectlyError() throws Exception { 1252 testDataPathInitiatorResponderInvalidUidUtility(true); 1253 } 1254 1255 1256 /** 1257 * Validate the fail flow of an Initiator (subscriber) with its package name set as a malicious 1258 * attacker (i.e. mismatched to its requested client's package name). 1259 */ 1260 @Test testDataPathResponderPackageNameSetIncorrectlyError()1261 public void testDataPathResponderPackageNameSetIncorrectlyError() throws Exception { 1262 testDataPathInitiatorResponderInvalidPackageNameUtility(true); 1263 } 1264 1265 /** 1266 * Validate the TLV generation based on a test vector manually generated from spec. 1267 */ 1268 @Test testTlvGenerationTestVectorPortTransportProtocol()1269 public void testTlvGenerationTestVectorPortTransportProtocol() { 1270 int port = 7000; 1271 int transportProtocol = 6; 1272 1273 byte[] tlvData = WifiAwareDataPathStateManager.NetworkInformationData.buildTlv(port, 1274 transportProtocol); 1275 byte[] testVector = 1276 new byte[]{0x01, 0x0d, 0x00, 0x50, 0x6f, (byte) 0x9a, 0x02, 0x00, 0x02, 0x00, 0x58, 1277 0x1b, 0x01, 0x01, 0x00, 0x06}; 1278 1279 assertArrayEquals(testVector, tlvData); 1280 } 1281 1282 /** 1283 * Validate the TLV parsing based on a test vector of the port + transport protocol manually 1284 * generated from spec. 1285 */ 1286 @Test testTlvParsingTestVectorPortTransportProtocol()1287 public void testTlvParsingTestVectorPortTransportProtocol() { 1288 int port = 7000; 1289 int transportProtocol = 6; 1290 1291 byte[] testVector = 1292 new byte[]{0x01, 0x0d, 0x00, 0x50, 0x6f, (byte) 0x9a, 0x02, 0x00, 0x02, 0x00, 0x58, 1293 0x1b, 0x01, 0x01, 0x00, 0x06}; 1294 1295 WifiAwareDataPathStateManager.NetworkInformationData.ParsedResults parsed = 1296 WifiAwareDataPathStateManager.NetworkInformationData.parseTlv(testVector); 1297 assertEquals(port, (int) parsed.port); 1298 assertEquals(transportProtocol, (int) parsed.transportProtocol); 1299 } 1300 1301 /* 1302 * Utilities 1303 */ 1304 testDataPathInitiatorResponderMismatchUtility(boolean doPublish)1305 private void testDataPathInitiatorResponderMismatchUtility(boolean doPublish) throws Exception { 1306 final int clientId = 123; 1307 final byte pubSubId = 55; 1308 final int ndpId = 2; 1309 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 1310 final int requestorId = 1341234; 1311 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 1312 1313 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 1314 InOrder inOrderM = inOrder(mAwareMetricsMock); 1315 1316 // (0) initialize 1317 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 1318 peerDiscoveryMac, inOrder, inOrderM, doPublish); 1319 1320 // (1) request network 1321 NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk, 1322 null, doPublish, 0); 1323 1324 // corrupt the network specifier: reverse the role (so it's mis-matched) 1325 WifiAwareNetworkSpecifier ns = 1326 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier(); 1327 ns = new WifiAwareNetworkSpecifier( 1328 ns.type, 1329 1 - ns.role, // corruption hack 1330 ns.clientId, 1331 ns.sessionId, 1332 ns.peerId, 1333 ns.peerMac, 1334 ns.pmk, 1335 ns.passphrase, 1336 0, 1337 0); 1338 nr.networkCapabilities.setNetworkSpecifier(ns); 1339 nr.networkCapabilities.setRequestorUid(Process.myUid()); 1340 nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME); 1341 1342 Message reqNetworkMsg = Message.obtain(); 1343 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 1344 reqNetworkMsg.obj = nr; 1345 reqNetworkMsg.arg1 = 0; 1346 res.mMessenger.send(reqNetworkMsg); 1347 mMockLooper.dispatchAll(); 1348 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 1349 1350 // consequences of failure: 1351 // Responder (publisher): responds with a rejection to any data-path requests 1352 // Initiator (subscribe): doesn't initiate (i.e. no HAL requests) 1353 verifyRequestDeclaredUnfullfillable(nr); 1354 if (doPublish) { 1355 // (2) get request & respond 1356 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 1357 mMockLooper.dispatchAll(); 1358 inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false), 1359 eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any()); 1360 } 1361 1362 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 1363 } 1364 testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish)1365 private void testDataPathInitiatorResponderInvalidUidUtility(boolean doPublish) 1366 throws Exception { 1367 final int clientId = 123; 1368 final byte pubSubId = 56; 1369 final int ndpId = 2; 1370 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 1371 final int requestorId = 1341234; 1372 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 1373 1374 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 1375 InOrder inOrderM = inOrder(mAwareMetricsMock); 1376 1377 // (0) initialize 1378 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 1379 peerDiscoveryMac, inOrder, inOrderM, doPublish); 1380 1381 // (1) create network request 1382 NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk, 1383 null, doPublish, 0); 1384 1385 // (2) corrupt request's UID 1386 WifiAwareNetworkSpecifier ns = 1387 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier(); 1388 ns = new WifiAwareNetworkSpecifier( 1389 ns.type, 1390 ns.role, 1391 ns.clientId, 1392 ns.sessionId, 1393 ns.peerId, 1394 ns.peerMac, 1395 ns.pmk, 1396 ns.passphrase, 1397 0, 1398 0); 1399 nr.networkCapabilities.setNetworkSpecifier(ns); 1400 nr.networkCapabilities.setRequestorUid(0 + 1); // corruption hack 1401 nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME); 1402 1403 // (3) request network 1404 Message reqNetworkMsg = Message.obtain(); 1405 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 1406 reqNetworkMsg.obj = nr; 1407 reqNetworkMsg.arg1 = 0; 1408 res.mMessenger.send(reqNetworkMsg); 1409 mMockLooper.dispatchAll(); 1410 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 1411 1412 1413 // consequences of failure: 1414 // Responder (publisher): responds with a rejection to any data-path requests 1415 // Initiator (subscribe): doesn't initiate (i.e. no HAL requests) 1416 verifyRequestDeclaredUnfullfillable(nr); 1417 if (doPublish) { 1418 // (2) get request & respond 1419 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 1420 mMockLooper.dispatchAll(); 1421 inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false), 1422 eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any()); 1423 } 1424 1425 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 1426 } 1427 testDataPathInitiatorResponderInvalidPackageNameUtility(boolean doPublish)1428 private void testDataPathInitiatorResponderInvalidPackageNameUtility(boolean doPublish) 1429 throws Exception { 1430 final int clientId = 123; 1431 final byte pubSubId = 56; 1432 final int ndpId = 2; 1433 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 1434 final int requestorId = 1341234; 1435 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 1436 1437 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 1438 InOrder inOrderM = inOrder(mAwareMetricsMock); 1439 1440 // (0) initialize 1441 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 1442 peerDiscoveryMac, inOrder, inOrderM, doPublish); 1443 1444 // (1) create network request 1445 NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, res.mPeerHandle, pmk, 1446 null, doPublish, 0); 1447 1448 // (2) corrupt request's UID 1449 WifiAwareNetworkSpecifier ns = 1450 (WifiAwareNetworkSpecifier) nr.networkCapabilities.getNetworkSpecifier(); 1451 ns = new WifiAwareNetworkSpecifier( 1452 ns.type, 1453 ns.role, 1454 ns.clientId, 1455 ns.sessionId, 1456 ns.peerId, 1457 ns.peerMac, 1458 ns.pmk, 1459 ns.passphrase, 1460 0, 1461 0); 1462 nr.networkCapabilities.setNetworkSpecifier(ns); 1463 nr.networkCapabilities.setRequestorUid(Process.myUid()); // corruption hack 1464 nr.networkCapabilities.setRequestorPackageName(TEST_PACKAGE_NAME + "h"); // corruption hack 1465 1466 // (3) request network 1467 Message reqNetworkMsg = Message.obtain(); 1468 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 1469 reqNetworkMsg.obj = nr; 1470 reqNetworkMsg.arg1 = 0; 1471 res.mMessenger.send(reqNetworkMsg); 1472 mMockLooper.dispatchAll(); 1473 inOrderM.verify(mAwareMetricsMock, never()).recordNdpRequestType(anyInt()); 1474 1475 // consequences of failure: 1476 // Responder (publisher): responds with a rejection to any data-path requests 1477 // Initiator (subscribe): doesn't initiate (i.e. no HAL requests) 1478 verifyRequestDeclaredUnfullfillable(nr); 1479 if (doPublish) { 1480 // (2) get request & respond 1481 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 1482 mMockLooper.dispatchAll(); 1483 inOrder.verify(mMockNative).respondToDataPathRequest(anyShort(), eq(false), 1484 eq(ndpId), eq(""), eq(null), eq(null), eq(null), anyBoolean(), any()); 1485 } 1486 1487 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 1488 } 1489 testDataPathInitiatorUtility(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation, boolean immediateHalFailure)1490 private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac, 1491 boolean providePmk, boolean providePassphrase, boolean getConfirmation, 1492 boolean immediateHalFailure) throws Exception { 1493 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1494 String linkLocalIpv6Address = MacAddress.fromBytes( 1495 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getHostAddress(); 1496 1497 testDataPathInitiatorUtilityMore(useDirect, provideMac, providePmk, providePassphrase, 1498 getConfirmation, immediateHalFailure, peerDataPathMac, null, 0, -1, 1499 linkLocalIpv6Address, 0); 1500 } 1501 testDataPathInitiatorUtilityMore(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation, boolean immediateHalFailure, byte[] peerDataPathMac, byte[] peerToken, int port, int transportProtocol, String ipv6Address, int numAddrValidationRetries)1502 private void testDataPathInitiatorUtilityMore(boolean useDirect, boolean provideMac, 1503 boolean providePmk, boolean providePassphrase, boolean getConfirmation, 1504 boolean immediateHalFailure, byte[] peerDataPathMac, byte[] peerToken, int port, 1505 int transportProtocol, String ipv6Address, int numAddrValidationRetries) 1506 throws Exception { 1507 final int clientId = 123; 1508 final byte pubSubId = 58; 1509 final int requestorId = 1341234; 1510 final int ndpId = 2; 1511 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 1512 final String passphrase = "some passphrase"; 1513 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 1514 1515 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = 1516 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class); 1517 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 1518 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 1519 mMockNetdWrapper, mMockNetworkInterface); 1520 InOrder inOrderM = inOrder(mAwareMetricsMock); 1521 WifiAwareNetworkAgent networkAgent = null; 1522 1523 if (!providePmk) { 1524 when(mPermissionsWrapperMock.getUidPermission( 1525 eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn( 1526 PackageManager.PERMISSION_DENIED); 1527 } 1528 1529 if (immediateHalFailure) { 1530 when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(), any(), 1531 any(), any(), any(), anyBoolean(), any(), any())).thenReturn(false); 1532 1533 } 1534 1535 // (0) initialize 1536 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 1537 peerDiscoveryMac, inOrder, inOrderM, false); 1538 1539 // (1) request network 1540 NetworkRequest nr; 1541 if (useDirect) { 1542 nr = getDirectNetworkRequest(clientId, 1543 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, 1544 provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null, 1545 providePassphrase ? passphrase : null, 0); 1546 } else { 1547 nr = getSessionNetworkRequest(clientId, res.mSessionId, 1548 provideMac ? res.mPeerHandle : null, providePmk ? pmk : null, 1549 providePassphrase ? passphrase : null, false, 0); 1550 } 1551 1552 Message reqNetworkMsg = Message.obtain(); 1553 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 1554 reqNetworkMsg.obj = nr; 1555 reqNetworkMsg.arg1 = 0; 1556 res.mMessenger.send(reqNetworkMsg); 1557 mMockLooper.dispatchAll(); 1558 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 1559 inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), 1560 eq(useDirect ? 0 : requestorId), 1561 eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), 1562 eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null), 1563 eq(providePassphrase ? passphrase : null), eq(useDirect), any(), any()); 1564 if (immediateHalFailure) { 1565 // short-circuit the rest of this test 1566 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE), 1567 eq(useDirect), anyLong()); 1568 verifyRequestDeclaredUnfullfillable(nr); 1569 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock); 1570 return; 1571 } 1572 1573 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId); 1574 mMockLooper.dispatchAll(); 1575 1576 // (2) get confirmation OR timeout 1577 boolean timeout = false; 1578 if (getConfirmation) { 1579 int numConfigureAgentPropertiesFail = 0; 1580 if (numAddrValidationRetries > 0) { 1581 when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(false); 1582 when(mMockNetworkInterface.configureAgentProperties(any(), any(), any())) 1583 .thenReturn(false); 1584 // First retry will be ConfigureAgentProperties failure. 1585 numConfigureAgentPropertiesFail = 1; 1586 } 1587 when(mClock.getElapsedSinceBootMillis()).thenReturn(0L); 1588 1589 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, peerToken, null); 1590 mMockLooper.dispatchAll(); 1591 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 1592 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 1593 inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(), any()); 1594 if (numAddrValidationRetries <= 0) { 1595 inOrder.verify(mMockNetworkInterface).isAddressUsable(any()); 1596 } 1597 for (int i = 0; i < numAddrValidationRetries; ++i) { 1598 if (i == numConfigureAgentPropertiesFail) { 1599 when(mMockNetworkInterface.configureAgentProperties(any(), any(), any())) 1600 .thenReturn(true); 1601 } 1602 if (i == numAddrValidationRetries - 1) { 1603 when(mMockNetworkInterface.isAddressUsable(any())).thenReturn(true); 1604 } 1605 long currentTime = (i + 1L) 1606 * WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS; 1607 when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTime); 1608 mMockLooper.moveTimeForward( 1609 WifiAwareDataPathStateManager.ADDRESS_VALIDATION_RETRY_INTERVAL_MS + 1); 1610 mMockLooper.dispatchAll(); 1611 inOrder.verify(mMockNetworkInterface).configureAgentProperties(any(), any(), any()); 1612 if (i < numConfigureAgentPropertiesFail) { 1613 continue; 1614 } 1615 inOrder.verify(mMockNetworkInterface).isAddressUsable(any()); 1616 if (currentTime > WifiAwareDataPathStateManager.ADDRESS_VALIDATION_TIMEOUT_MS) { 1617 timeout = true; 1618 break; 1619 } 1620 } 1621 if (timeout) { 1622 verifyRequestDeclaredUnfullfillable(nr); 1623 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 1624 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 1625 } else { 1626 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 1627 networkAgent = agentCaptor.getValue(); 1628 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 1629 eq(useDirect), anyLong()); 1630 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 1631 WifiAwareNetworkInfo netInfo = 1632 (WifiAwareNetworkInfo) networkAgent.mDataPathCapabilities 1633 .getTransportInfo(); 1634 assertEquals(ipv6Address, netInfo.getPeerIpv6Addr().getHostAddress()); 1635 assertEquals(port, netInfo.getPort()); 1636 assertEquals(transportProtocol, netInfo.getTransportProtocol()); 1637 assertEquals(1, mDut.mDataPathMgr.getNumOfNdps()); 1638 mDut.onDataPathScheduleUpdateNotification(peerDiscoveryMac, new ArrayList<>(ndpId), 1639 Collections.emptyList()); 1640 mMockLooper.dispatchAll(); 1641 } 1642 } else { 1643 assertTrue(mAlarmManager.dispatch( 1644 WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG)); 1645 mMockLooper.dispatchAll(); 1646 verifyRequestDeclaredUnfullfillable(nr); 1647 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 1648 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 1649 mMockLooper.dispatchAll(); 1650 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.INTERNAL_FAILURE), 1651 eq(useDirect), anyLong()); 1652 } 1653 1654 // (3) end data-path (unless didn't get confirmation) 1655 if (getConfirmation && !timeout) { 1656 Message endNetworkReqMsg = Message.obtain(); 1657 endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 1658 endNetworkReqMsg.obj = nr; 1659 res.mMessenger.send(endNetworkReqMsg); 1660 1661 networkAgent.onNetworkUnwanted(); 1662 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 1663 mDut.onDataPathEndNotification(ndpId); 1664 mMockLooper.dispatchAll(); 1665 1666 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 1667 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString()); 1668 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 1669 } 1670 1671 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper, 1672 mMockNetworkInterface); 1673 } 1674 testDataPathResponderUtility(boolean useDirect, boolean provideMac, boolean providePmk, boolean providePassphrase, boolean getConfirmation)1675 private void testDataPathResponderUtility(boolean useDirect, boolean provideMac, 1676 boolean providePmk, boolean providePassphrase, boolean getConfirmation) 1677 throws Exception { 1678 final int clientId = 123; 1679 final byte pubSubId = 60; 1680 final int requestorId = 1341234; 1681 final int ndpId = 2; 1682 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 1683 final String passphrase = "some passphrase"; 1684 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 1685 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 1686 1687 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = 1688 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class); 1689 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 1690 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, 1691 mMockNetdWrapper, mMockNetworkInterface); 1692 InOrder inOrderM = inOrder(mAwareMetricsMock); 1693 1694 if (providePmk) { 1695 when(mPermissionsWrapperMock.getUidPermission( 1696 eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn( 1697 PackageManager.PERMISSION_GRANTED); 1698 } 1699 1700 // (0) initialize 1701 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 1702 peerDiscoveryMac, inOrder, inOrderM, true); 1703 1704 // (1) request network 1705 NetworkRequest nr; 1706 if (useDirect) { 1707 nr = getDirectNetworkRequest(clientId, 1708 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, 1709 provideMac ? peerDiscoveryMac : null, providePmk ? pmk : null, 1710 providePassphrase ? passphrase : null, 0); 1711 } else { 1712 nr = getSessionNetworkRequest(clientId, res.mSessionId, 1713 provideMac ? res.mPeerHandle : null, providePmk ? pmk : null, 1714 providePassphrase ? passphrase : null, true, 0); 1715 } 1716 1717 Message reqNetworkMsg = Message.obtain(); 1718 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 1719 reqNetworkMsg.obj = nr; 1720 reqNetworkMsg.arg1 = 0; 1721 res.mMessenger.send(reqNetworkMsg); 1722 mMockLooper.dispatchAll(); 1723 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 1724 1725 // (2) get request & respond (if legacy) 1726 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 1727 mMockLooper.dispatchAll(); 1728 inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true), 1729 eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null), 1730 eq(providePassphrase ? passphrase : null), eq(null), eq(useDirect), any()); 1731 mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0); 1732 mMockLooper.dispatchAll(); 1733 1734 // (3) get confirmation OR timeout 1735 if (getConfirmation) { 1736 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null); 1737 mMockLooper.dispatchAll(); 1738 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 1739 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 1740 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 1741 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 1742 eq(useDirect), anyLong()); 1743 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 1744 WifiAwareNetworkInfo netInfo = 1745 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 1746 .getTransportInfo(); 1747 assertArrayEquals(MacAddress.fromBytes( 1748 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 1749 netInfo.getPeerIpv6Addr().getAddress()); 1750 assertEquals(0, netInfo.getPort()); 1751 assertEquals(-1, netInfo.getTransportProtocol()); 1752 assertEquals(1, mDut.mDataPathMgr.getNumOfNdps()); 1753 } else { 1754 assertTrue(mAlarmManager.dispatch( 1755 WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG)); 1756 mMockLooper.dispatchAll(); 1757 verifyRequestDeclaredUnfullfillable(nr); 1758 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 1759 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 1760 mMockLooper.dispatchAll(); 1761 inOrderM.verify(mAwareMetricsMock).recordNdpStatus( 1762 eq(NanStatusType.INTERNAL_FAILURE), eq(useDirect), anyLong()); 1763 } 1764 1765 // (4) end data-path (unless didn't get confirmation) 1766 if (getConfirmation) { 1767 Message endNetworkMsg = Message.obtain(); 1768 endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 1769 endNetworkMsg.obj = nr; 1770 res.mMessenger.send(endNetworkMsg); 1771 1772 agentCaptor.getValue().onNetworkUnwanted(); 1773 1774 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 1775 mDut.onDataPathEndNotification(ndpId); 1776 mMockLooper.dispatchAll(); 1777 1778 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 1779 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString()); 1780 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 1781 } 1782 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 1783 } 1784 getSessionNetworkRequest(int clientId, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId)1785 private NetworkRequest getSessionNetworkRequest(int clientId, int sessionId, 1786 PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId) 1787 throws Exception { 1788 return getSessionNetworkRequestMore(clientId, sessionId, peerHandle, pmk, passphrase, 1789 doPublish, requestId, 0, -1); 1790 } 1791 getSessionNetworkRequestMore(int clientId, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId, int port, int transportProtocol)1792 private NetworkRequest getSessionNetworkRequestMore(int clientId, int sessionId, 1793 PeerHandle peerHandle, byte[] pmk, String passphrase, boolean doPublish, int requestId, 1794 int port, int transportProtocol) 1795 throws Exception { 1796 final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class); 1797 final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService); 1798 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 1799 final PublishConfig publishConfig = new PublishConfig.Builder().build(); 1800 final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); 1801 1802 ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass( 1803 WifiAwareSession.class); 1804 ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor 1805 .forClass(IWifiAwareEventCallback.class); 1806 ArgumentCaptor<IWifiAwareDiscoverySessionCallback> sessionProxyCallback = ArgumentCaptor 1807 .forClass(IWifiAwareDiscoverySessionCallback.class); 1808 ArgumentCaptor<DiscoverySession> discoverySession = ArgumentCaptor 1809 .forClass(DiscoverySession.class); 1810 1811 AttachCallback mockCallback = mock(AttachCallback.class); 1812 DiscoverySessionCallback mockSessionCallback = mock( 1813 DiscoverySessionCallback.class); 1814 1815 InOrder inOrderS = inOrder(mockAwareService, mockCallback, mockSessionCallback); 1816 1817 mgr.attach(mMockLooperHandler, configRequest, mockCallback, null); 1818 inOrderS.verify(mockAwareService).connect(any(), any(), any(), 1819 clientProxyCallback.capture(), eq(configRequest), eq(false)); 1820 IWifiAwareEventCallback iwaec = clientProxyCallback.getValue(); 1821 iwaec.onConnectSuccess(clientId); 1822 mMockLooper.dispatchAll(); 1823 inOrderS.verify(mockCallback).onAttached(sessionCaptor.capture()); 1824 if (doPublish) { 1825 sessionCaptor.getValue().publish(publishConfig, mockSessionCallback, 1826 mMockLooperHandler); 1827 inOrderS.verify(mockAwareService).publish(any(), any(), eq(clientId), eq(publishConfig), 1828 sessionProxyCallback.capture()); 1829 } else { 1830 sessionCaptor.getValue().subscribe(subscribeConfig, mockSessionCallback, 1831 mMockLooperHandler); 1832 inOrderS.verify(mockAwareService).subscribe(any(), any(), eq(clientId), 1833 eq(subscribeConfig), sessionProxyCallback.capture()); 1834 } 1835 sessionProxyCallback.getValue().onSessionStarted(sessionId); 1836 mMockLooper.dispatchAll(); 1837 if (doPublish) { 1838 inOrderS.verify(mockSessionCallback).onPublishStarted( 1839 (PublishDiscoverySession) discoverySession.capture()); 1840 } else { 1841 inOrderS.verify(mockSessionCallback).onSubscribeStarted( 1842 (SubscribeDiscoverySession) discoverySession.capture()); 1843 } 1844 1845 NetworkSpecifier ns; 1846 if (pmk == null && passphrase == null) { 1847 ns = createNetworkSpecifier(clientId, 1848 doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER 1849 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId, 1850 peerHandle, null, null, port, transportProtocol); 1851 } else if (passphrase == null) { 1852 ns = createNetworkSpecifier(clientId, 1853 doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER 1854 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId, 1855 peerHandle, pmk, null, port, transportProtocol); 1856 } else { 1857 ns = createNetworkSpecifier(clientId, 1858 doPublish ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER 1859 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, sessionId, 1860 peerHandle, null, passphrase, port, transportProtocol); 1861 } 1862 1863 NetworkCapabilities nc = new NetworkCapabilities(); 1864 nc.clearAll(); 1865 nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); 1866 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability( 1867 NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1868 nc.setNetworkSpecifier(ns); 1869 nc.setLinkUpstreamBandwidthKbps(1); 1870 nc.setLinkDownstreamBandwidthKbps(1); 1871 nc.setSignalStrength(1); 1872 nc.setRequestorUid(Process.myUid()); 1873 nc.setRequestorPackageName(TEST_PACKAGE_NAME); 1874 1875 return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST); 1876 } 1877 getDirectNetworkRequest(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int requestId)1878 private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer, 1879 byte[] pmk, String passphrase, int requestId) throws Exception { 1880 return getDirectNetworkRequestMore(clientId, role, peer, pmk, passphrase, requestId, 0, -1); 1881 } 1882 getDirectNetworkRequestMore(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int requestId, int port, int transportProtocol)1883 private NetworkRequest getDirectNetworkRequestMore(int clientId, int role, byte[] peer, 1884 byte[] pmk, String passphrase, int requestId, int port, int transportProtocol) 1885 throws Exception { 1886 final IWifiAwareManager mockAwareService = mock(IWifiAwareManager.class); 1887 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 1888 final WifiAwareManager mgr = new WifiAwareManager(mMockContext, mockAwareService); 1889 1890 ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass( 1891 WifiAwareSession.class); 1892 ArgumentCaptor<IWifiAwareEventCallback> clientProxyCallback = ArgumentCaptor 1893 .forClass(IWifiAwareEventCallback.class); 1894 1895 AttachCallback mockCallback = mock(AttachCallback.class); 1896 1897 mgr.attach(mMockLooperHandler, configRequest, mockCallback, null); 1898 verify(mockAwareService).connect(any(), any(), any(), 1899 clientProxyCallback.capture(), eq(configRequest), eq(false)); 1900 clientProxyCallback.getValue().onConnectSuccess(clientId); 1901 mMockLooper.dispatchAll(); 1902 verify(mockCallback).onAttached(sessionCaptor.capture()); 1903 1904 NetworkSpecifier ns; 1905 if (pmk == null && passphrase == null) { 1906 ns = createNetworkSpecifier(clientId, role, peer, null, null, port, transportProtocol); 1907 } else if (passphrase == null) { 1908 ns = createNetworkSpecifier(clientId, role, peer, pmk, null, port, transportProtocol); 1909 } else { 1910 ns = createNetworkSpecifier(clientId, role, peer, null, passphrase, port, 1911 transportProtocol); 1912 } 1913 NetworkCapabilities nc = new NetworkCapabilities(); 1914 nc.clearAll(); 1915 nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); 1916 nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) 1917 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) 1918 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING) 1919 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 1920 nc.setNetworkSpecifier(ns); 1921 nc.setLinkUpstreamBandwidthKbps(1); 1922 nc.setLinkDownstreamBandwidthKbps(1); 1923 nc.setSignalStrength(1); 1924 nc.setRequestorUid(Process.myUid()); 1925 nc.setRequestorPackageName(TEST_PACKAGE_NAME); 1926 1927 return new NetworkRequest(nc, 0, requestId, NetworkRequest.Type.REQUEST); 1928 } 1929 initDataPathEndPoint(boolean isFirstIteration, int clientId, byte pubSubId, int requestorId, byte[] peerDiscoveryMac, InOrder inOrder, InOrder inOrderM, boolean doPublish)1930 private DataPathEndPointInfo initDataPathEndPoint(boolean isFirstIteration, int clientId, 1931 byte pubSubId, int requestorId, byte[] peerDiscoveryMac, InOrder inOrder, 1932 InOrder inOrderM, boolean doPublish) 1933 throws Exception { 1934 final String someMsg = "some arbitrary message from peer"; 1935 final PublishConfig publishConfig = new PublishConfig.Builder().build(); 1936 final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); 1937 1938 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 1939 ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class); 1940 ArgumentCaptor<Integer> peerIdCaptor = ArgumentCaptor.forClass(Integer.class); 1941 1942 Messenger messenger = initOobDataPathEndPoint(isFirstIteration, 1, clientId, inOrder, 1943 inOrderM); 1944 1945 if (doPublish) { 1946 mDut.publish(clientId, publishConfig, mMockSessionCallback); 1947 } else { 1948 mDut.subscribe(clientId, subscribeConfig, mMockSessionCallback); 1949 } 1950 mMockLooper.dispatchAll(); 1951 if (doPublish) { 1952 inOrder.verify(mMockNative).publish(transactionId.capture(), eq((byte) 0), 1953 eq(publishConfig)); 1954 } else { 1955 inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0), 1956 eq(subscribeConfig)); 1957 } 1958 mDut.onSessionConfigSuccessResponse(transactionId.getValue(), doPublish, pubSubId); 1959 mMockLooper.dispatchAll(); 1960 inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture()); 1961 inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(Process.myUid()), any()); 1962 inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(Process.myUid(), 1963 NanStatusType.SUCCESS, doPublish); 1964 1965 mDut.onMessageReceivedNotification(pubSubId, requestorId, peerDiscoveryMac, 1966 someMsg.getBytes()); 1967 mMockLooper.dispatchAll(); 1968 inOrder.verify(mMockSessionCallback).onMessageReceived(peerIdCaptor.capture(), 1969 eq(someMsg.getBytes())); 1970 1971 return new DataPathEndPointInfo(sessionId.getValue(), peerIdCaptor.getValue(), 1972 isFirstIteration ? messenger : null); 1973 } 1974 initOobDataPathEndPoint(boolean startUpSequence, int maxNdiInterfaces, int clientId, InOrder inOrder, InOrder inOrderM)1975 private Messenger initOobDataPathEndPoint(boolean startUpSequence, 1976 int maxNdiInterfaces, int clientId, InOrder inOrder, InOrder inOrderM) 1977 throws Exception { 1978 final int pid = 2000; 1979 final ConfigRequest configRequest = new ConfigRequest.Builder().build(); 1980 1981 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 1982 ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); 1983 ArgumentCaptor<NetworkProvider> networkProviderCaptor = 1984 ArgumentCaptor.forClass(NetworkProvider.class); 1985 ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class); 1986 1987 Capabilities capabilities = new Capabilities(); 1988 capabilities.maxNdiInterfaces = maxNdiInterfaces; 1989 1990 if (startUpSequence) { 1991 // (0) start/registrations 1992 inOrder.verify(mMockCm).registerNetworkProvider(networkProviderCaptor.capture()); 1993 collector.checkThat("factory name", "WIFI_AWARE_FACTORY", 1994 equalTo(networkProviderCaptor.getValue().getName())); 1995 1996 // (1) get capabilities 1997 mDut.queryCapabilities(); 1998 mMockLooper.dispatchAll(); 1999 inOrder.verify(mMockNative).getCapabilities(transactionId.capture()); 2000 mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities); 2001 mMockLooper.dispatchAll(); 2002 2003 // (2) enable usage 2004 mDut.enableUsage(); 2005 mMockLooper.dispatchAll(); 2006 inOrderM.verify(mAwareMetricsMock).recordEnableUsage(); 2007 } 2008 2009 // (3) create client 2010 mDut.connect(clientId, Process.myUid(), pid, TEST_PACKAGE_NAME, TEST_FEATURE_ID, 2011 mMockCallback, configRequest, false); 2012 mMockLooper.dispatchAll(); 2013 2014 if (startUpSequence) { 2015 inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), 2016 eq(configRequest), eq(false), eq(true), eq(true), 2017 eq(false), eq(false), eq(false)); 2018 mDut.onConfigSuccessResponse(transactionId.getValue()); 2019 mMockLooper.dispatchAll(); 2020 } 2021 2022 inOrder.verify(mMockCallback).onConnectSuccess(clientId); 2023 inOrderM.verify(mAwareMetricsMock).recordAttachSession(eq(Process.myUid()), eq(false), 2024 any()); 2025 2026 if (startUpSequence) { 2027 for (int i = 0; i < maxNdiInterfaces; ++i) { 2028 inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), 2029 strCaptor.capture()); 2030 collector.checkThat("interface created -- " + i, sAwareInterfacePrefix + i, 2031 equalTo(strCaptor.getValue())); 2032 mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); 2033 mMockLooper.dispatchAll(); 2034 } 2035 Messenger messenger = networkProviderCaptor.getValue().getMessenger(); 2036 return messenger; 2037 } 2038 2039 return null; 2040 } 2041 2042 /** 2043 * Copy of DiscoverySession.createNetworkSpecifier - but without any checks! Allows creating 2044 * network requests which may not be valid (e.g. for the API level). 2045 */ createNetworkSpecifier(int clientId, int role, int sessionId, PeerHandle peerHandle, byte[] pmk, String passphrase, int port, int transportProtocol)2046 public NetworkSpecifier createNetworkSpecifier(int clientId, int role, int sessionId, 2047 PeerHandle peerHandle, byte[] pmk, String passphrase, int port, int transportProtocol) { 2048 return new WifiAwareNetworkSpecifier( 2049 (peerHandle == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER 2050 : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB, 2051 role, 2052 clientId, 2053 sessionId, 2054 peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID 2055 null, // peerMac (not used in this method) 2056 pmk, 2057 passphrase, 2058 port, 2059 transportProtocol); 2060 } 2061 2062 /** 2063 * Copy of WifiAwareSession.createNetworkSpecifier - but without any checks! Allows creating 2064 * network requests which may not be valid (e.g. for the API level). 2065 */ createNetworkSpecifier(int clientId, int role, byte[] peer, byte[] pmk, String passphrase, int port, int transportProtocol)2066 private NetworkSpecifier createNetworkSpecifier(int clientId, int role, byte[] peer, byte[] pmk, 2067 String passphrase, int port, int transportProtocol) { 2068 return new WifiAwareNetworkSpecifier( 2069 (peer == null) ? WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER 2070 : WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB, 2071 role, 2072 clientId, 2073 0, // 0 is an invalid session ID 2074 0, // 0 is an invalid peer ID 2075 peer, 2076 pmk, 2077 passphrase, 2078 port, 2079 transportProtocol); 2080 } 2081 2082 private static class DataPathEndPointInfo { 2083 int mSessionId; 2084 PeerHandle mPeerHandle; 2085 Messenger mMessenger; 2086 DataPathEndPointInfo(int sessionId, int peerId, Messenger messenger)2087 DataPathEndPointInfo(int sessionId, int peerId, Messenger messenger) { 2088 mSessionId = sessionId; 2089 mPeerHandle = new PeerHandle(peerId); 2090 mMessenger = messenger; 2091 } 2092 } 2093 2094 /** 2095 * Verify that declareNetworkRequestUnfulfillable was called. 2096 */ verifyRequestDeclaredUnfullfillable(NetworkRequest request)2097 private void verifyRequestDeclaredUnfullfillable(NetworkRequest request) throws Exception { 2098 mMockLooper.dispatchAll(); 2099 verify(mMockCm, atLeastOnce()).declareNetworkRequestUnfulfillable(any()); 2100 } 2101 2102 // copy of the method in WifiAwareDataPathStateManager - but without error checking (so we can 2103 // construct invalid TLVs for testing). buildTlv(int port, int transportProtocol, boolean includeGarbageTlv)2104 private static byte[] buildTlv(int port, int transportProtocol, boolean includeGarbageTlv) { 2105 if (port == 0 && transportProtocol == -1) { 2106 return null; 2107 } 2108 2109 TlvBufferUtils.TlvConstructor tlvc = new TlvBufferUtils.TlvConstructor(1, 2); 2110 tlvc.setByteOrder(ByteOrder.LITTLE_ENDIAN); 2111 tlvc.allocate(30); // safe size for now 2112 2113 tlvc.putRawByteArray(WifiAwareDataPathStateManager.NetworkInformationData.WFA_OUI); 2114 tlvc.putRawByte((byte) WifiAwareDataPathStateManager.NetworkInformationData 2115 .GENERIC_SERVICE_PROTOCOL_TYPE); 2116 2117 if (port != 0) { 2118 tlvc.putShort(WifiAwareDataPathStateManager.NetworkInformationData.SUB_TYPE_PORT, 2119 (short) port); 2120 } 2121 if (transportProtocol != -1) { 2122 tlvc.putByte(WifiAwareDataPathStateManager.NetworkInformationData 2123 .SUB_TYPE_TRANSPORT_PROTOCOL, (byte) transportProtocol); 2124 } 2125 if (includeGarbageTlv) { 2126 tlvc.putShort(55, (short) -1298); 2127 } 2128 2129 byte[] subTypes = tlvc.getArray(); 2130 2131 tlvc.allocate(30); 2132 tlvc.putByteArray(WifiAwareDataPathStateManager.NetworkInformationData.SERVICE_INFO_TYPE, 2133 subTypes); 2134 if (includeGarbageTlv) { 2135 tlvc.putInt(78, 44); 2136 } 2137 2138 return tlvc.getArray(); 2139 } 2140 2141 @Test testAcceptRequestWhenAwareNotReadyWillReleaseRequest()2142 public void testAcceptRequestWhenAwareNotReadyWillReleaseRequest() throws Exception { 2143 final int clientId = 123; 2144 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 2145 ArgumentCaptor<NetworkProvider> networkProviderCaptor = 2146 ArgumentCaptor.forClass(NetworkProvider.class); 2147 verify(mMockCm).registerNetworkProvider(networkProviderCaptor.capture()); 2148 NetworkProvider awareProvider = networkProviderCaptor.getValue(); 2149 collector.checkThat("factory name", "WIFI_AWARE_FACTORY", 2150 equalTo(awareProvider.getName())); 2151 NetworkRequest networkRequest = getDirectNetworkRequest(clientId, 2152 WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, 2153 null, 1); 2154 // Aware usage is not enabled, should declare unfullfillable. 2155 awareProvider.onNetworkRequested(networkRequest, 0, awareProvider.getProviderId()); 2156 verifyRequestDeclaredUnfullfillable(networkRequest); 2157 reset(mMockCm); 2158 // Aware usage is enabled but interface not ready, should declare unfullfillable. 2159 mDut.enableUsage(); 2160 mMockLooper.dispatchAll(); 2161 awareProvider.onNetworkRequested(networkRequest, 0, awareProvider.getProviderId()); 2162 verifyRequestDeclaredUnfullfillable(networkRequest); 2163 } testDataPathAcceptsAnyResponderWithMultipleInitiator(boolean providePmk, boolean providePassphrase, boolean failureOnFirst)2164 private void testDataPathAcceptsAnyResponderWithMultipleInitiator(boolean providePmk, 2165 boolean providePassphrase, boolean failureOnFirst) 2166 throws Exception { 2167 final int clientId = 123; 2168 final byte pubSubId = 60; 2169 final int requestorId = 1341234; 2170 final byte[] pmk = "01234567890123456789012345678901".getBytes(); 2171 final String passphrase = "some passphrase"; 2172 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 2173 final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); 2174 int indexOfFailure = failureOnFirst ? 0 : 1; 2175 int ndpAttemptsCount = 4; 2176 int ndpId = 2; 2177 List<Integer> successNdpIds = new ArrayList<>(); 2178 2179 2180 ArgumentCaptor<WifiAwareNetworkAgent> agentCaptor = 2181 ArgumentCaptor.forClass(WifiAwareNetworkAgent.class); 2182 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 2183 InOrder inOrder = inOrder(mMockNative, mMockCallback, mMockSessionCallback, 2184 mMockNetdWrapper, mMockNetworkInterface, mMockCm); 2185 InOrder inOrderM = inOrder(mAwareMetricsMock); 2186 2187 if (providePmk) { 2188 when(mPermissionsWrapperMock.getUidPermission( 2189 eq(Manifest.permission.NETWORK_STACK), eq(Process.myUid()))).thenReturn( 2190 PackageManager.PERMISSION_GRANTED); 2191 } 2192 2193 // (0) initialize 2194 DataPathEndPointInfo res = initDataPathEndPoint(true, clientId, pubSubId, requestorId, 2195 peerDiscoveryMac, inOrder, inOrderM, true); 2196 2197 // (1) request network 2198 NetworkRequest nr = getSessionNetworkRequest(clientId, res.mSessionId, 2199 null, providePmk ? pmk : null, 2200 providePassphrase ? passphrase : null, true, 0); 2201 2202 Message reqNetworkMsg = Message.obtain(); 2203 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 2204 reqNetworkMsg.obj = nr; 2205 reqNetworkMsg.arg1 = 0; 2206 res.mMessenger.send(reqNetworkMsg); 2207 mMockLooper.dispatchAll(); 2208 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType( 2209 WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER); 2210 boolean firstSuccess = true; 2211 2212 for (int i = 0; i < ndpAttemptsCount; i++) { 2213 // (2) get request & respond 2214 peerDataPathMac[5] += i; 2215 mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, null); 2216 mMockLooper.dispatchAll(); 2217 inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true), 2218 eq(ndpId), eq(sAwareInterfacePrefix + "0"), eq(providePmk ? pmk : null), 2219 eq(providePassphrase ? passphrase : null), eq(null), eq(false), any()); 2220 mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0); 2221 mMockLooper.dispatchAll(); 2222 2223 // (3) get confirmation OR timeout 2224 if (i != indexOfFailure) { 2225 successNdpIds.add(ndpId); 2226 mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null, null); 2227 mMockLooper.dispatchAll(); 2228 if (firstSuccess) { 2229 inOrder.verify(mMockNetdWrapper).setInterfaceUp(anyString()); 2230 inOrder.verify(mMockNetdWrapper).enableIpv6(anyString()); 2231 inOrder.verify(mMockNetworkInterface).setConnected(agentCaptor.capture()); 2232 WifiAwareNetworkInfo netInfo = 2233 (WifiAwareNetworkInfo) agentCaptor.getValue().mDataPathCapabilities 2234 .getTransportInfo(); 2235 assertArrayEquals(MacAddress.fromBytes( 2236 peerDataPathMac).getLinkLocalIpv6FromEui48Mac().getAddress(), 2237 netInfo.getPeerIpv6Addr().getAddress()); 2238 assertEquals(0, netInfo.getPort()); 2239 assertEquals(-1, netInfo.getTransportProtocol()); 2240 assertEquals(1, mDut.mDataPathMgr.getNumOfNdps()); 2241 } 2242 inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), 2243 eq(false), anyLong()); 2244 inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any(), any()); 2245 assertEquals(successNdpIds.size(), mDut.mDataPathMgr.getNumOfNdps()); 2246 2247 firstSuccess = false; 2248 } else { 2249 assertTrue(mAlarmManager.dispatch( 2250 WifiAwareStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG)); 2251 mMockLooper.dispatchAll(); 2252 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); 2253 inOrderM.verify(mAwareMetricsMock).recordNdpStatus( 2254 eq(NanStatusType.INTERNAL_FAILURE), eq(false), anyLong()); 2255 mDut.onDataPathEndNotification(ndpId); 2256 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 2257 verify(mMockCm, never()).declareNetworkRequestUnfulfillable(any()); 2258 } 2259 ndpId++; 2260 } 2261 2262 // (4) one of the NDP is terminated by the other side 2263 int endNdpId = successNdpIds.remove(0); 2264 mDut.onDataPathEndNotification(endNdpId); 2265 mMockLooper.dispatchAll(); 2266 2267 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 2268 assertEquals(successNdpIds.size(), mDut.mDataPathMgr.getNumOfNdps()); 2269 2270 2271 // (5) end data-path (unless didn't get confirmation) 2272 Message endNetworkMsg = Message.obtain(); 2273 endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; 2274 endNetworkMsg.obj = nr; 2275 res.mMessenger.send(endNetworkMsg); 2276 agentCaptor.getValue().onNetworkUnwanted(); 2277 2278 for (int successNdpId : successNdpIds) { 2279 mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); 2280 mDut.onDataPathEndNotification(successNdpId); 2281 mMockLooper.dispatchAll(); 2282 inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(successNdpId)); 2283 inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); 2284 } 2285 inOrder.verify(mMockNetdWrapper).setInterfaceDown(anyString()); 2286 verifyNoMoreInteractions(mMockNative, mAwareMetricsMock, mMockNetdWrapper); 2287 } 2288 2289 @Test testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFirstRequest()2290 public void testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFirstRequest() 2291 throws Exception { 2292 testDataPathAcceptsAnyResponderWithMultipleInitiator(false, true, true); 2293 } 2294 2295 @Test testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFollowingRequest()2296 public void testAcceptAnyResponderWithMultipleInitiatorRequestWithTimeOutAtFollowingRequest() 2297 throws Exception { 2298 testDataPathAcceptsAnyResponderWithMultipleInitiator(false, true, false); 2299 } 2300 2301 /** 2302 * Validate when multiple request present on a device, request from peer can match to the right 2303 * accepts any peer request when no peer specific request matches. 2304 */ 2305 @Test testAcceptsAnyRequestMatchesCorrectlyWhenMultipleRequestPresent()2306 public void testAcceptsAnyRequestMatchesCorrectlyWhenMultipleRequestPresent() throws Exception { 2307 final int clientId = 123; 2308 final byte pubId = 1; 2309 final byte subId = -128; 2310 final int requestorId = 1341234; 2311 final String passphrase = "SomeSecurePassword"; 2312 final String passphrase1 = "SomeSecurePassword1"; 2313 final int ndpId = 1; 2314 final int ndpId2 = 2; 2315 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 2316 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 2317 ArgumentCaptor<String> interfaceName1 = ArgumentCaptor.forClass(String.class); 2318 ArgumentCaptor<String> interfaceName2 = ArgumentCaptor.forClass(String.class); 2319 2320 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 2321 InOrder inOrderM = inOrder(mAwareMetricsMock); 2322 2323 Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM); 2324 2325 // (0) initialize Publish 2326 DataPathEndPointInfo pubRes = initDataPathEndPoint(false, clientId, pubId, requestorId, 2327 peerDiscoveryMac, inOrder, inOrderM, true); 2328 2329 // (1) request responder network 2330 NetworkRequest pubNr = getSessionNetworkRequest(clientId, pubRes.mSessionId, null, 2331 null, passphrase, true, requestorId); 2332 2333 Message reqNetworkMsg = Message.obtain(); 2334 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 2335 reqNetworkMsg.obj = pubNr; 2336 reqNetworkMsg.arg1 = 0; 2337 messenger.send(reqNetworkMsg); 2338 mMockLooper.dispatchAll(); 2339 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 2340 2341 // (2) initialize Subscribe 2342 DataPathEndPointInfo subRes = initDataPathEndPoint(false, clientId, subId, requestorId, 2343 peerDiscoveryMac, inOrder, inOrderM, false); 2344 2345 // (3) request initiator network 2346 NetworkRequest subNr = getSessionNetworkRequest(clientId, subRes.mSessionId, 2347 subRes.mPeerHandle, null, passphrase1, false, requestorId); 2348 2349 Message subReqNetworkMsg = Message.obtain(); 2350 subReqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 2351 subReqNetworkMsg.obj = subNr; 2352 subReqNetworkMsg.arg1 = 0; 2353 messenger.send(subReqNetworkMsg); 2354 mMockLooper.dispatchAll(); 2355 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 2356 2357 // (4) Initiator request succeed 2358 verify(mMockNative).initiateDataPath(transactionId.capture(), anyInt(), anyInt(), anyInt(), 2359 any(), interfaceName1.capture(), any(), anyString(), anyBoolean(), any(), any()); 2360 mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId); 2361 2362 // (5) provide a request from peer 2363 mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac, ndpId2, null); 2364 mMockLooper.dispatchAll(); 2365 2366 // (6) make sure framework respond with the right accepts any peer request. 2367 verify(mMockNative).respondToDataPathRequest(anyShort(), eq(true), eq(ndpId2), 2368 interfaceName2.capture(), eq(null), eq(passphrase), any(), anyBoolean(), any()); 2369 2370 assertNotEquals(interfaceName1.getValue(), interfaceName2.getValue()); 2371 } 2372 2373 /** 2374 * Validate when both peer specific and accepts any peer requests are on the device, framework 2375 * will response to the matched peer with peer specific request. Other peers with accepts any 2376 * request. 2377 */ 2378 @Test testPeerSpecificRequestMatchesCorrectlyWhenAcceptsAnyRequestExist()2379 public void testPeerSpecificRequestMatchesCorrectlyWhenAcceptsAnyRequestExist() 2380 throws Exception { 2381 final int clientId = 123; 2382 final byte pubId = 1; 2383 final int requestorId = 1341234; 2384 final String passphrase = "SomeSecurePassword"; 2385 final String passphrase1 = "SomeSecurePassword1"; 2386 final int ndpId = 1; 2387 final int ndpId2 = 2; 2388 final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); 2389 final byte[] peerDiscoveryMac1 = HexEncoding.decode("000102030406".toCharArray(), false); 2390 ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); 2391 ArgumentCaptor<String> interfaceName1 = ArgumentCaptor.forClass(String.class); 2392 ArgumentCaptor<String> interfaceName2 = ArgumentCaptor.forClass(String.class); 2393 2394 InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback); 2395 InOrder inOrderM = inOrder(mAwareMetricsMock); 2396 2397 Messenger messenger = initOobDataPathEndPoint(true, 2, clientId, inOrder, inOrderM); 2398 2399 // (0) initialize Publish 2400 DataPathEndPointInfo pubRes = initDataPathEndPoint(false, clientId, pubId, requestorId, 2401 peerDiscoveryMac, inOrder, inOrderM, true); 2402 2403 // (1) request accepts any responder network 2404 NetworkRequest pubNr = getSessionNetworkRequest(clientId, pubRes.mSessionId, null, 2405 null, passphrase, true, requestorId); 2406 2407 Message reqNetworkMsg = Message.obtain(); 2408 reqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 2409 reqNetworkMsg.obj = pubNr; 2410 reqNetworkMsg.arg1 = 0; 2411 messenger.send(reqNetworkMsg); 2412 mMockLooper.dispatchAll(); 2413 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 2414 2415 // (2) request peer specific responder network 2416 NetworkRequest subNr = getSessionNetworkRequest(clientId, pubRes.mSessionId, 2417 pubRes.mPeerHandle, null, passphrase1, true, requestorId); 2418 2419 Message subReqNetworkMsg = Message.obtain(); 2420 subReqNetworkMsg.what = NetworkProvider.CMD_REQUEST_NETWORK; 2421 subReqNetworkMsg.obj = subNr; 2422 subReqNetworkMsg.arg1 = 0; 2423 messenger.send(subReqNetworkMsg); 2424 mMockLooper.dispatchAll(); 2425 inOrderM.verify(mAwareMetricsMock).recordNdpRequestType(anyInt()); 2426 2427 // (3) provide a request from specified peer 2428 mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac, ndpId, null); 2429 mMockLooper.dispatchAll(); 2430 2431 // (4) make sure framework respond with the peer specific request. 2432 verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true), eq(ndpId), 2433 interfaceName1.capture(), eq(null), eq(passphrase1), any(), anyBoolean(), any()); 2434 mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0); 2435 mMockLooper.dispatchAll(); 2436 2437 // (5) provide a request from a not specified peer. 2438 mDut.onDataPathRequestNotification(pubId, peerDiscoveryMac1, ndpId2, null); 2439 mMockLooper.dispatchAll(); 2440 2441 // (6) make sure framework respond with the right accepts any peer request. 2442 verify(mMockNative).respondToDataPathRequest(anyShort(), eq(true), eq(ndpId2), 2443 interfaceName2.capture(), eq(null), eq(passphrase), any(), anyBoolean(), any()); 2444 2445 assertNotEquals(interfaceName1.getValue(), interfaceName2.getValue()); 2446 } 2447 } 2448