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 android.net.wifi.aware; 18 19 import static android.Manifest.permission.MANAGE_WIFI_NETWORK_SELECTION; 20 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.net.NetworkSpecifier; 27 import android.os.Build; 28 import android.util.CloseGuard; 29 import android.util.Log; 30 31 import androidx.annotation.RequiresApi; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.modules.utils.build.SdkLevel; 35 36 import java.lang.ref.Reference; 37 import java.lang.ref.WeakReference; 38 39 /** 40 * A class representing a single publish or subscribe Aware session. This object 41 * will not be created directly - only its child classes are available: 42 * {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This 43 * class provides functionality common to both publish and subscribe discovery sessions: 44 * <ul> 45 * <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method. 46 * <li>Creating a network-specifier when requesting a Aware connection using 47 * {@link WifiAwareNetworkSpecifier.Builder}. 48 * </ul> 49 * <p> 50 * The {@link #close()} method must be called to destroy discovery sessions once they are 51 * no longer needed. 52 */ 53 public class DiscoverySession implements AutoCloseable { 54 private static final String TAG = "DiscoverySession"; 55 private static final boolean DBG = false; 56 private static final boolean VDBG = false; // STOPSHIP if true 57 58 private static final int MAX_SEND_RETRY_COUNT = 5; 59 60 /** @hide */ 61 protected WeakReference<WifiAwareManager> mMgr; 62 /** @hide */ 63 protected final int mClientId; 64 /** @hide */ 65 protected final int mSessionId; 66 /** @hide */ 67 protected boolean mTerminated = false; 68 69 private final CloseGuard mCloseGuard = new CloseGuard(); 70 71 /** 72 * Return the maximum permitted retry count when sending messages using 73 * {@link #sendMessage(PeerHandle, int, byte[], int)}. 74 * 75 * @return Maximum retry count when sending messages. 76 * 77 * @hide 78 */ getMaxSendRetryCount()79 public static int getMaxSendRetryCount() { 80 return MAX_SEND_RETRY_COUNT; 81 } 82 83 /** @hide */ DiscoverySession(WifiAwareManager manager, int clientId, int sessionId)84 public DiscoverySession(WifiAwareManager manager, int clientId, int sessionId) { 85 if (VDBG) { 86 Log.v(TAG, "New discovery session created: manager=" + manager + ", clientId=" 87 + clientId + ", sessionId=" + sessionId); 88 } 89 90 mMgr = new WeakReference<>(manager); 91 mClientId = clientId; 92 mSessionId = sessionId; 93 94 mCloseGuard.open("close"); 95 } 96 97 /** 98 * Destroy the publish or subscribe session - free any resources, and stop 99 * transmitting packets on-air (for an active session) or listening for 100 * matches (for a passive session). The session may not be used for any 101 * additional operations after its destruction. 102 * <p> 103 * This operation must be done on a session which is no longer needed. Otherwise system 104 * resources will continue to be utilized until the application exits. The only 105 * exception is a session for which we received a termination callback, 106 * {@link DiscoverySessionCallback#onSessionTerminated()}. 107 */ 108 @Override close()109 public void close() { 110 WifiAwareManager mgr = mMgr.get(); 111 if (mgr == null) { 112 Log.w(TAG, "destroy: called post GC on WifiAwareManager"); 113 return; 114 } 115 mgr.terminateSession(mClientId, mSessionId); 116 mTerminated = true; 117 mMgr.clear(); 118 mCloseGuard.close(); 119 Reference.reachabilityFence(this); 120 } 121 122 /** 123 * Sets the status of the session to terminated - i.e. an indication that 124 * already terminated rather than executing a termination. 125 * 126 * @hide 127 */ setTerminated()128 public void setTerminated() { 129 if (mTerminated) { 130 Log.w(TAG, "terminate: already terminated."); 131 return; 132 } 133 134 mTerminated = true; 135 mMgr.clear(); 136 mCloseGuard.close(); 137 } 138 139 /** @hide */ 140 @Override finalize()141 protected void finalize() throws Throwable { 142 try { 143 if (mCloseGuard != null) { 144 mCloseGuard.warnIfOpen(); 145 } 146 147 if (!mTerminated) { 148 close(); 149 } 150 } finally { 151 super.finalize(); 152 } 153 } 154 155 /** 156 * Access the client ID of the Aware session. 157 * 158 * Note: internal visibility for testing. 159 * 160 * @return The internal client ID. 161 * 162 * @hide 163 */ 164 @VisibleForTesting getClientId()165 public int getClientId() { 166 return mClientId; 167 } 168 169 /** 170 * Access the discovery session ID of the Aware session. 171 * 172 * Note: internal visibility for testing. 173 * 174 * @return The internal discovery session ID. 175 * 176 * @hide 177 */ 178 @VisibleForTesting getSessionId()179 public int getSessionId() { 180 return mSessionId; 181 } 182 183 /** 184 * Sends a message to the specified destination. Aware messages are transmitted in the context 185 * of a discovery session - executed subsequent to a publish/subscribe 186 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 187 * byte[], java.util.List)} event. 188 * <p> 189 * Aware messages are not guaranteed delivery. Callbacks on 190 * {@link DiscoverySessionCallback} indicate message was transmitted successfully, 191 * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission 192 * failed (possibly after several retries) - 193 * {@link DiscoverySessionCallback#onMessageSendFailed(int)}. 194 * <p> 195 * The peer will get a callback indicating a message was received using 196 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 197 * byte[])}. 198 * 199 * @param peerHandle The peer's handle for the message. Must be a result of an 200 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 201 * byte[], java.util.List)} or 202 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 203 * byte[])} events. 204 * @param messageId An arbitrary integer used by the caller to identify the message. The same 205 * integer ID will be returned in the callbacks indicating message send success or 206 * failure. The {@code messageId} is not used internally by the Aware service - it 207 * can be arbitrary and non-unique. 208 * @param message The message to be transmitted. 209 * @param retryCount An integer specifying how many additional service-level (as opposed to PHY 210 * or MAC level) retries should be attempted if there is no ACK from the receiver 211 * (note: no retransmissions are attempted in other failure cases). A value of 0 212 * indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}. 213 * 214 * @hide 215 */ sendMessage(@onNull PeerHandle peerHandle, int messageId, @Nullable byte[] message, int retryCount)216 public void sendMessage(@NonNull PeerHandle peerHandle, int messageId, 217 @Nullable byte[] message, int retryCount) { 218 if (mTerminated) { 219 Log.w(TAG, "sendMessage: called on terminated session"); 220 return; 221 } 222 223 WifiAwareManager mgr = mMgr.get(); 224 if (mgr == null) { 225 Log.w(TAG, "sendMessage: called post GC on WifiAwareManager"); 226 return; 227 } 228 229 mgr.sendMessage(mClientId, mSessionId, peerHandle, message, messageId, retryCount); 230 } 231 232 /** 233 * Sends a message to the specified destination. Aware messages are transmitted in the context 234 * of a discovery session - executed subsequent to a publish/subscribe 235 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 236 * byte[], java.util.List)} event. 237 * <p> 238 * Aware messages are not guaranteed delivery. Callbacks on 239 * {@link DiscoverySessionCallback} indicate message was transmitted successfully, 240 * {@link DiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission 241 * failed (possibly after several retries) - 242 * {@link DiscoverySessionCallback#onMessageSendFailed(int)}. 243 * <p> 244 * The peer will get a callback indicating a message was received using 245 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 246 * byte[])}. 247 * 248 * @param peerHandle The peer's handle for the message. Must be a result of an 249 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 250 * byte[], java.util.List)} or 251 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 252 * byte[])} events. 253 * @param messageId An arbitrary integer used by the caller to identify the message. The same 254 * integer ID will be returned in the callbacks indicating message send success or 255 * failure. The {@code messageId} is not used internally by the Aware service - it 256 * can be arbitrary and non-unique. 257 * @param message The message to be transmitted. 258 */ sendMessage(@onNull PeerHandle peerHandle, int messageId, @Nullable byte[] message)259 public void sendMessage(@NonNull PeerHandle peerHandle, int messageId, 260 @Nullable byte[] message) { 261 sendMessage(peerHandle, messageId, message, 0); 262 } 263 264 /** 265 * Initiate a Wi-Fi Aware Pairing setup request to create a pairing with the target peer. 266 * The Aware pairing request should be done in the context of a discovery session - 267 * after a publish/subscribe 268 * {@link DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} event is received. 269 * The peer will get a callback indicating a message was received using 270 * {@link DiscoverySessionCallback#onPairingSetupRequestReceived(PeerHandle, int)}. 271 * When the Aware Pairing setup is finished, both sides will receive 272 * {@link DiscoverySessionCallback#onPairingSetupSucceeded(PeerHandle, String)} 273 * 274 * @param peerHandle The peer's handle for the pairing request. Must be a result of a 275 * {@link 276 * DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} 277 * or 278 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])} 279 * events. 280 * @param peerDeviceAlias The alias of paired device set by caller, will help caller to identify 281 * the paired device. 282 * @param cipherSuite The cipher suite to be used to encrypt the link. 283 * @param password The password used for the pairing setup. If set to empty or null, 284 * opportunistic pairing will be used. 285 */ 286 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) initiatePairingRequest(@onNull PeerHandle peerHandle, @NonNull String peerDeviceAlias, @Characteristics.WifiAwarePairingCipherSuites int cipherSuite, @Nullable String password)287 public void initiatePairingRequest(@NonNull PeerHandle peerHandle, 288 @NonNull String peerDeviceAlias, 289 @Characteristics.WifiAwarePairingCipherSuites int cipherSuite, 290 @Nullable String password) { 291 if (!SdkLevel.isAtLeastU()) { 292 throw new UnsupportedOperationException(); 293 } 294 WifiAwareManager mgr = mMgr.get(); 295 if (mgr == null) { 296 Log.w(TAG, "initiatePairingRequest: called post GC on WifiAwareManager"); 297 return; 298 } 299 mgr.initiateNanPairingSetupRequest(mClientId, mSessionId, peerHandle, password, 300 peerDeviceAlias, cipherSuite); 301 } 302 303 /** 304 * Accept and respond to a Wi-Fi Aware Pairing setup request received from peer. This is the 305 * response to the 306 * {@link DiscoverySessionCallback#onPairingSetupRequestReceived(PeerHandle, int)} 307 * When the Aware Pairing setup is finished, both sides will receive 308 * {@link DiscoverySessionCallback#onPairingSetupSucceeded(PeerHandle, String)} 309 * 310 * @param requestId Id to identify the received pairing session, obtained by 311 * {@link 312 * DiscoverySessionCallback#onPairingSetupRequestReceived(PeerHandle, 313 * int)} 314 * @param peerHandle The peer's handle for the pairing request. Must be a result of a 315 * {@link 316 * DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} 317 * or 318 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])} 319 * events. 320 * @param peerDeviceAlias The alias of paired device set by caller, will help caller to identify 321 * the paired device. 322 * @param cipherSuite The cipher suite to be used to encrypt the link. 323 * @param password The password is used for the pairing setup. If set to empty or null, 324 * opportunistic pairing will be used. 325 */ 326 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) acceptPairingRequest(int requestId, @NonNull PeerHandle peerHandle, @NonNull String peerDeviceAlias, @Characteristics.WifiAwarePairingCipherSuites int cipherSuite, @Nullable String password)327 public void acceptPairingRequest(int requestId, @NonNull PeerHandle peerHandle, 328 @NonNull String peerDeviceAlias, 329 @Characteristics.WifiAwarePairingCipherSuites int cipherSuite, 330 @Nullable String password) { 331 if (!SdkLevel.isAtLeastU()) { 332 throw new UnsupportedOperationException(); 333 } 334 WifiAwareManager mgr = mMgr.get(); 335 if (mgr == null) { 336 Log.w(TAG, "initiatePairingRequest: called post GC on WifiAwareManager"); 337 return; 338 } 339 mgr.responseNanPairingSetupRequest(mClientId, mSessionId, peerHandle, requestId, password, 340 peerDeviceAlias, true, cipherSuite); 341 } 342 343 /** 344 * Reject a Wi-Fi Aware Pairing setup request received from peer. This is the 345 * response to the 346 * {@link DiscoverySessionCallback#onPairingSetupRequestReceived(PeerHandle, int)} 347 * 348 * @param requestId Id to identify the received pairing session, get by 349 * {@link 350 * DiscoverySessionCallback#onPairingSetupRequestReceived(PeerHandle, 351 * int)} 352 * @param peerHandle The peer's handle for the pairing request. Must be a result of a 353 * {@link 354 * DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} 355 * or 356 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])} 357 * events. 358 */ 359 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) rejectPairingRequest(int requestId, @NonNull PeerHandle peerHandle)360 public void rejectPairingRequest(int requestId, @NonNull PeerHandle peerHandle) { 361 if (!SdkLevel.isAtLeastU()) { 362 throw new UnsupportedOperationException(); 363 } 364 WifiAwareManager mgr = mMgr.get(); 365 if (mgr == null) { 366 Log.w(TAG, "initiatePairingRequest: called post GC on WifiAwareManager"); 367 return; 368 } 369 mgr.responseNanPairingSetupRequest(mClientId, mSessionId, peerHandle, requestId, null, 370 null, false, WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128); 371 } 372 373 /** 374 * Initiate a Wi-Fi Aware bootstrapping setup request to create a pairing with the target peer. 375 * The Aware bootstrapping request should be done in the context of a discovery session - 376 * after a publish/subscribe 377 * {@link DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} event is received. 378 * The peer will check if the method can be fulfilled by 379 * {@link AwarePairingConfig.Builder#setBootstrappingMethods(int)} 380 * When the Aware Bootstrapping setup finished, both side will receive 381 * {@link DiscoverySessionCallback#onBootstrappingSucceeded(PeerHandle, int)} 382 * @param peerHandle The peer's handle for the pairing request. Must be a result of an 383 * {@link DiscoverySessionCallback#onServiceDiscovered(ServiceDiscoveryInfo)} or 384 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])} events. 385 * @param method one of the AwarePairingConfig#PAIRING_BOOTSTRAPPING_ values, should be one of 386 * the methods received from {@link ServiceDiscoveryInfo#getPairingConfig()} 387 * {@link AwarePairingConfig#getBootstrappingMethods()} 388 */ 389 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) initiateBootstrappingRequest(@onNull PeerHandle peerHandle, @AwarePairingConfig.BootstrappingMethod int method)390 public void initiateBootstrappingRequest(@NonNull PeerHandle peerHandle, 391 @AwarePairingConfig.BootstrappingMethod int method) { 392 if (!SdkLevel.isAtLeastU()) { 393 throw new UnsupportedOperationException(); 394 } 395 WifiAwareManager mgr = mMgr.get(); 396 if (mgr == null) { 397 Log.w(TAG, "initiatePairingRequest: called post GC on WifiAwareManager"); 398 return; 399 } 400 mgr.initiateBootStrappingSetupRequest(mClientId, mSessionId, peerHandle, method); 401 } 402 403 /** 404 * Put Aware connection into suspension mode to save power. Suspend mode pauses all Wi-Fi Aware 405 * activities for this discovery session including any active NDPs. 406 * <p> 407 * This method would work only for a {@link DiscoverySession} which has been created using 408 * a suspendable {@link PublishConfig} or {@link SubscribeConfig}. 409 * 410 * @see PublishConfig#isSuspendable() 411 * @see SubscribeConfig#isSuspendable() 412 * @hide 413 */ 414 @SystemApi 415 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 416 @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION) suspend()417 public void suspend() { 418 if (mTerminated) { 419 throw new IllegalStateException("Suspend called on a terminated session."); 420 } 421 422 WifiAwareManager mgr = mMgr.get(); 423 if (mgr == null) { 424 throw new IllegalStateException("Failed to get WifiAwareManager."); 425 } 426 427 if (!SdkLevel.isAtLeastU()) { 428 throw new UnsupportedOperationException(); 429 } 430 431 mgr.suspend(mClientId, mSessionId); 432 } 433 434 /** 435 * Wake up Aware connection from suspension mode to transmit data. Resumes all paused 436 * Wi-Fi Aware activities and any associated NDPs to a state before they were suspended. Resume 437 * operation will be faster than recreating the corresponding discovery session and NDPs with 438 * the same benefit of power. 439 * <p> 440 * This method would work only for a {@link DiscoverySession} which has been created using 441 * a suspendable {@link PublishConfig} or {@link SubscribeConfig}. 442 * 443 * @see PublishConfig#isSuspendable() 444 * @see SubscribeConfig#isSuspendable() 445 * @hide 446 */ 447 @SystemApi 448 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 449 @RequiresPermission(MANAGE_WIFI_NETWORK_SELECTION) resume()450 public void resume() { 451 if (mTerminated) { 452 throw new IllegalStateException("Resume called on a terminated session."); 453 } 454 455 WifiAwareManager mgr = mMgr.get(); 456 if (mgr == null) { 457 throw new IllegalStateException("Failed to get WifiAwareManager."); 458 } 459 460 if (!SdkLevel.isAtLeastU()) { 461 throw new UnsupportedOperationException(); 462 } 463 464 mgr.resume(mClientId, mSessionId); 465 } 466 467 /** 468 * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for 469 * an unencrypted WiFi Aware connection (link) to the specified peer. The 470 * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to 471 * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. 472 * <p> 473 * This method should be used when setting up a connection with a peer discovered through Aware 474 * discovery or communication (in such scenarios the MAC address of the peer is shielded by 475 * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other 476 * OOB (out-of-band) mechanism then use the alternative 477 * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the 478 * peer's MAC address. 479 * <p> 480 * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR 481 * and a Publisher is a RESPONDER. 482 * <p> 483 * To set up an encrypted link use the 484 * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} API. 485 * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}. 486 * 487 * @param peerHandle The peer's handle obtained through 488 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)} 489 * or 490 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}. 491 * On a RESPONDER this value is used to gate the acceptance of a connection 492 * request from only that peer. 493 * 494 * @return A {@link NetworkSpecifier} to be used to construct 495 * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to 496 * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest, 497 * android.net.ConnectivityManager.NetworkCallback)} 498 * [or other varieties of that API]. 499 */ 500 @Deprecated createNetworkSpecifierOpen(@onNull PeerHandle peerHandle)501 public NetworkSpecifier createNetworkSpecifierOpen(@NonNull PeerHandle peerHandle) { 502 if (mTerminated) { 503 Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session"); 504 return null; 505 } 506 507 WifiAwareManager mgr = mMgr.get(); 508 if (mgr == null) { 509 Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager"); 510 return null; 511 } 512 513 int role = this instanceof SubscribeDiscoverySession 514 ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR 515 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER; 516 517 return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null, null); 518 } 519 520 /** 521 * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for 522 * an encrypted WiFi Aware connection (link) to the specified peer. The 523 * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to 524 * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. 525 * <p> 526 * This method should be used when setting up a connection with a peer discovered through Aware 527 * discovery or communication (in such scenarios the MAC address of the peer is shielded by 528 * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other 529 * OOB (out-of-band) mechanism then use the alternative 530 * {@link WifiAwareSession#createNetworkSpecifierPassphrase(int, byte[], String)} method - 531 * which uses the peer's MAC address. 532 * <p> 533 * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR 534 * and a Publisher is a RESPONDER. 535 * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}. 536 * 537 * @param peerHandle The peer's handle obtained through 538 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 539 * byte[], java.util.List)} or 540 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 541 * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request 542 * from only that peer. 543 * @param passphrase The passphrase to be used to encrypt the link. The PMK is generated from 544 * the passphrase. Use the 545 * {@link #createNetworkSpecifierOpen(PeerHandle)} API to 546 * specify an open (unencrypted) link. 547 * 548 * @return A {@link NetworkSpecifier} to be used to construct 549 * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to 550 * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest, 551 * android.net.ConnectivityManager.NetworkCallback)} 552 * [or other varieties of that API]. 553 */ 554 @Deprecated createNetworkSpecifierPassphrase( @onNull PeerHandle peerHandle, @NonNull String passphrase)555 public NetworkSpecifier createNetworkSpecifierPassphrase( 556 @NonNull PeerHandle peerHandle, @NonNull String passphrase) { 557 if (!WifiAwareUtils.validatePassphrase(passphrase)) { 558 throw new IllegalArgumentException("Passphrase must meet length requirements"); 559 } 560 561 if (mTerminated) { 562 Log.w(TAG, "createNetworkSpecifierPassphrase: called on terminated session"); 563 return null; 564 } 565 566 WifiAwareManager mgr = mMgr.get(); 567 if (mgr == null) { 568 Log.w(TAG, "createNetworkSpecifierPassphrase: called post GC on WifiAwareManager"); 569 return null; 570 } 571 572 int role = this instanceof SubscribeDiscoverySession 573 ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR 574 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER; 575 576 return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null, 577 passphrase); 578 } 579 580 /** 581 * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} for 582 * an encrypted WiFi Aware connection (link) to the specified peer. The 583 * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to 584 * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. 585 * <p> 586 * This method should be used when setting up a connection with a peer discovered through Aware 587 * discovery or communication (in such scenarios the MAC address of the peer is shielded by 588 * an opaque peer ID handle). If an Aware connection is needed to a peer discovered using other 589 * OOB (out-of-band) mechanism then use the alternative 590 * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses 591 * the peer's MAC address. 592 * <p> 593 * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR 594 * and a Publisher is a RESPONDER. 595 * @deprecated Use the replacement {@link WifiAwareNetworkSpecifier.Builder}. 596 * 597 * @param peerHandle The peer's handle obtained through 598 * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, 599 * byte[], java.util.List)} or 600 * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, 601 * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request 602 * from only that peer. 603 * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for 604 * encrypting the data-path. Use the 605 * {@link #createNetworkSpecifierPassphrase(PeerHandle, String)} to specify a 606 * Passphrase or {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an 607 * open (unencrypted) link. 608 * 609 * @return A {@link NetworkSpecifier} to be used to construct 610 * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} to pass to 611 * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest, 612 * android.net.ConnectivityManager.NetworkCallback)} 613 * [or other varieties of that API]. 614 * 615 * @hide 616 */ 617 @Deprecated 618 @SystemApi createNetworkSpecifierPmk(@onNull PeerHandle peerHandle, @NonNull byte[] pmk)619 public NetworkSpecifier createNetworkSpecifierPmk(@NonNull PeerHandle peerHandle, 620 @NonNull byte[] pmk) { 621 if (!WifiAwareUtils.validatePmk(pmk)) { 622 throw new IllegalArgumentException("PMK must 32 bytes"); 623 } 624 625 if (mTerminated) { 626 Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session"); 627 return null; 628 } 629 630 WifiAwareManager mgr = mMgr.get(); 631 if (mgr == null) { 632 Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager"); 633 return null; 634 } 635 636 int role = this instanceof SubscribeDiscoverySession 637 ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR 638 : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER; 639 640 return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk, null); 641 } 642 } 643