1 /* 2 * Copyright (C) 2022 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.hal; 18 19 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128; 20 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_256; 21 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128; 22 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_256; 23 24 import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_AKM_SAE; 25 import static com.android.server.wifi.aware.WifiAwareStateManager.NAN_PAIRING_REQUEST_TYPE_SETUP; 26 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.hardware.wifi.NanBandIndex; 30 import android.hardware.wifi.NanBandSpecificConfig; 31 import android.hardware.wifi.NanBootstrappingRequest; 32 import android.hardware.wifi.NanBootstrappingResponse; 33 import android.hardware.wifi.NanCipherSuiteType; 34 import android.hardware.wifi.NanConfigRequest; 35 import android.hardware.wifi.NanConfigRequestSupplemental; 36 import android.hardware.wifi.NanDataPathSecurityConfig; 37 import android.hardware.wifi.NanDataPathSecurityType; 38 import android.hardware.wifi.NanDebugConfig; 39 import android.hardware.wifi.NanDiscoveryCommonConfig; 40 import android.hardware.wifi.NanEnableRequest; 41 import android.hardware.wifi.NanInitiateDataPathRequest; 42 import android.hardware.wifi.NanMatchAlg; 43 import android.hardware.wifi.NanPairingAkm; 44 import android.hardware.wifi.NanPairingConfig; 45 import android.hardware.wifi.NanPairingRequest; 46 import android.hardware.wifi.NanPairingRequestType; 47 import android.hardware.wifi.NanPairingSecurityConfig; 48 import android.hardware.wifi.NanPairingSecurityType; 49 import android.hardware.wifi.NanPublishRequest; 50 import android.hardware.wifi.NanRangingIndication; 51 import android.hardware.wifi.NanRespondToDataPathIndicationRequest; 52 import android.hardware.wifi.NanRespondToPairingIndicationRequest; 53 import android.hardware.wifi.NanSubscribeRequest; 54 import android.hardware.wifi.NanTransmitFollowupRequest; 55 import android.hardware.wifi.NanTxType; 56 import android.net.MacAddress; 57 import android.net.wifi.aware.AwarePairingConfig; 58 import android.net.wifi.aware.ConfigRequest; 59 import android.net.wifi.aware.PublishConfig; 60 import android.net.wifi.aware.SubscribeConfig; 61 import android.net.wifi.aware.WifiAwareDataPathSecurityConfig; 62 import android.os.RemoteException; 63 import android.os.ServiceSpecificException; 64 import android.util.Log; 65 66 import com.android.modules.utils.build.SdkLevel; 67 import com.android.server.wifi.aware.Capabilities; 68 import com.android.server.wifi.util.HalAidlUtil; 69 70 import java.nio.charset.StandardCharsets; 71 72 /** 73 * AIDL implementation of the IWifiNanIface interface. 74 */ 75 public class WifiNanIfaceAidlImpl implements IWifiNanIface { 76 private static final String TAG = "WifiNanIfaceAidlImpl"; 77 private android.hardware.wifi.IWifiNanIface mWifiNanIface; 78 private String mIfaceName; 79 private final Object mLock = new Object(); 80 private final WifiNanIfaceCallbackAidlImpl mHalCallback; 81 private WifiNanIface.Callback mFrameworkCallback; 82 WifiNanIfaceAidlImpl(@onNull android.hardware.wifi.IWifiNanIface nanIface)83 public WifiNanIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiNanIface nanIface) { 84 mWifiNanIface = nanIface; 85 mHalCallback = new WifiNanIfaceCallbackAidlImpl(this); 86 } 87 88 /** 89 * Enable verbose logging. 90 */ 91 @Override enableVerboseLogging(boolean verbose)92 public void enableVerboseLogging(boolean verbose) { 93 synchronized (mLock) { 94 if (mHalCallback != null) { 95 mHalCallback.enableVerboseLogging(verbose); 96 } 97 } 98 } 99 getFrameworkCallback()100 protected WifiNanIface.Callback getFrameworkCallback() { 101 return mFrameworkCallback; 102 } 103 104 /** 105 * See comments for {@link IWifiNanIface#registerFrameworkCallback(WifiNanIface.Callback)} 106 */ 107 @Override registerFrameworkCallback(WifiNanIface.Callback callback)108 public boolean registerFrameworkCallback(WifiNanIface.Callback callback) { 109 final String methodStr = "registerFrameworkCallback"; 110 synchronized (mLock) { 111 if (!checkIfaceAndLogFailure(methodStr)) return false; 112 if (mFrameworkCallback != null) { 113 Log.e(TAG, "Framework callback is already registered"); 114 return false; 115 } else if (callback == null) { 116 Log.e(TAG, "Cannot register a null framework callback"); 117 return false; 118 } 119 120 try { 121 mWifiNanIface.registerEventCallback(mHalCallback); 122 mFrameworkCallback = callback; 123 return true; 124 } catch (RemoteException e) { 125 handleRemoteException(e, methodStr); 126 } catch (ServiceSpecificException e) { 127 handleServiceSpecificException(e, methodStr); 128 } 129 return false; 130 } 131 } 132 133 /** 134 * See comments for {@link IWifiNanIface#getName()} 135 */ 136 @Override 137 @Nullable getName()138 public String getName() { 139 final String methodStr = "getName"; 140 synchronized (mLock) { 141 if (!checkIfaceAndLogFailure(methodStr)) return null; 142 if (mIfaceName != null) return mIfaceName; 143 try { 144 mIfaceName = mWifiNanIface.getName(); 145 return mIfaceName; 146 } catch (RemoteException e) { 147 handleRemoteException(e, methodStr); 148 } catch (ServiceSpecificException e) { 149 handleServiceSpecificException(e, methodStr); 150 } 151 return null; 152 } 153 } 154 155 /** 156 * See comments for {@link IWifiNanIface#getCapabilities(short)} 157 */ 158 @Override getCapabilities(short transactionId)159 public boolean getCapabilities(short transactionId) { 160 final String methodStr = "getCapabilities"; 161 synchronized (mLock) { 162 try { 163 if (!checkIfaceAndLogFailure(methodStr)) return false; 164 mWifiNanIface.getCapabilitiesRequest((char) transactionId); 165 return true; 166 } catch (RemoteException e) { 167 handleRemoteException(e, methodStr); 168 } catch (ServiceSpecificException e) { 169 handleServiceSpecificException(e, methodStr); 170 } 171 return false; 172 } 173 } 174 175 /** 176 * See comments for {@link IWifiNanIface#enableAndConfigure(short, ConfigRequest, boolean, 177 * boolean, boolean, boolean, int, int, int, WifiNanIface.PowerParameters)} 178 */ 179 @Override enableAndConfigure(short transactionId, ConfigRequest configRequest, boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled, boolean isInstantCommunicationEnabled, int instantModeChannel, int clusterId, int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters)180 public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest, 181 boolean notifyIdentityChange, boolean initialConfiguration, boolean rangingEnabled, 182 boolean isInstantCommunicationEnabled, int instantModeChannel, int clusterId, 183 int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) { 184 final String methodStr = "enableAndConfigure"; 185 try { 186 if (!checkIfaceAndLogFailure(methodStr)) return false; 187 NanConfigRequestSupplemental supplemental = createNanConfigRequestSupplemental( 188 rangingEnabled, isInstantCommunicationEnabled, instantModeChannel, clusterId); 189 if (initialConfiguration) { 190 NanEnableRequest req = createNanEnableRequest( 191 configRequest, notifyIdentityChange, supplemental, 192 macAddressRandomizationIntervalSec, powerParameters); 193 mWifiNanIface.enableRequest((char) transactionId, req, supplemental); 194 } else { 195 NanConfigRequest req = createNanConfigRequest( 196 configRequest, notifyIdentityChange, supplemental, 197 macAddressRandomizationIntervalSec, powerParameters); 198 mWifiNanIface.configRequest((char) transactionId, req, supplemental); 199 } 200 return true; 201 } catch (RemoteException e) { 202 handleRemoteException(e, methodStr); 203 } catch (ServiceSpecificException e) { 204 handleServiceSpecificException(e, methodStr); 205 } 206 return false; 207 } 208 209 /** 210 * See comments for {@link IWifiNanIface#disable(short)} 211 */ 212 @Override disable(short transactionId)213 public boolean disable(short transactionId) { 214 final String methodStr = "disable"; 215 synchronized (mLock) { 216 try { 217 if (!checkIfaceAndLogFailure(methodStr)) return false; 218 mWifiNanIface.disableRequest((char) transactionId); 219 return true; 220 } catch (RemoteException e) { 221 handleRemoteException(e, methodStr); 222 } catch (ServiceSpecificException e) { 223 handleServiceSpecificException(e, methodStr); 224 } 225 return false; 226 } 227 } 228 229 /** 230 * See comments for {@link IWifiNanIface#publish(short, byte, PublishConfig, byte[])} 231 */ 232 @Override publish(short transactionId, byte publishId, PublishConfig publishConfig, byte[] nanIdentityKey)233 public boolean publish(short transactionId, byte publishId, PublishConfig publishConfig, 234 byte[] nanIdentityKey) { 235 final String methodStr = "publish"; 236 synchronized (mLock) { 237 try { 238 if (!checkIfaceAndLogFailure(methodStr)) return false; 239 NanPublishRequest req = createNanPublishRequest(publishId, publishConfig, 240 nanIdentityKey); 241 mWifiNanIface.startPublishRequest((char) transactionId, req); 242 return true; 243 } catch (RemoteException e) { 244 handleRemoteException(e, methodStr); 245 } catch (ServiceSpecificException e) { 246 handleServiceSpecificException(e, methodStr); 247 } 248 return false; 249 } 250 } 251 252 /** 253 * See comments for {@link IWifiNanIface#subscribe(short, byte, SubscribeConfig, byte[])} 254 */ 255 @Override subscribe(short transactionId, byte subscribeId, SubscribeConfig subscribeConfig, byte[] nanIdentityKey)256 public boolean subscribe(short transactionId, byte subscribeId, 257 SubscribeConfig subscribeConfig, 258 byte[] nanIdentityKey) { 259 final String methodStr = "subscribe"; 260 synchronized (mLock) { 261 try { 262 if (!checkIfaceAndLogFailure(methodStr)) return false; 263 NanSubscribeRequest req = createNanSubscribeRequest(subscribeId, subscribeConfig, 264 nanIdentityKey); 265 mWifiNanIface.startSubscribeRequest((char) transactionId, req); 266 return true; 267 } catch (RemoteException e) { 268 handleRemoteException(e, methodStr); 269 } catch (ServiceSpecificException e) { 270 handleServiceSpecificException(e, methodStr); 271 } 272 return false; 273 } 274 } 275 276 /** 277 * See comments for {@link IWifiNanIface#sendMessage(short, byte, int, MacAddress, byte[])} 278 */ 279 @Override sendMessage(short transactionId, byte pubSubId, int requesterInstanceId, MacAddress dest, byte[] message)280 public boolean sendMessage(short transactionId, byte pubSubId, int requesterInstanceId, 281 MacAddress dest, byte[] message) { 282 final String methodStr = "sendMessage"; 283 synchronized (mLock) { 284 try { 285 if (!checkIfaceAndLogFailure(methodStr)) return false; 286 NanTransmitFollowupRequest req = createNanTransmitFollowupRequest( 287 pubSubId, requesterInstanceId, dest, message); 288 mWifiNanIface.transmitFollowupRequest((char) transactionId, req); 289 return true; 290 } catch (RemoteException e) { 291 handleRemoteException(e, methodStr); 292 } catch (ServiceSpecificException e) { 293 handleServiceSpecificException(e, methodStr); 294 } 295 return false; 296 } 297 } 298 299 /** 300 * See comments for {@link IWifiNanIface#stopPublish(short, byte)} 301 */ 302 @Override stopPublish(short transactionId, byte pubSubId)303 public boolean stopPublish(short transactionId, byte pubSubId) { 304 final String methodStr = "stopPublish"; 305 synchronized (mLock) { 306 try { 307 if (!checkIfaceAndLogFailure(methodStr)) return false; 308 mWifiNanIface.stopPublishRequest((char) transactionId, pubSubId); 309 return true; 310 } catch (RemoteException e) { 311 handleRemoteException(e, methodStr); 312 } catch (ServiceSpecificException e) { 313 handleServiceSpecificException(e, methodStr); 314 } 315 return false; 316 } 317 } 318 319 /** 320 * See comments for {@link IWifiNanIface#stopSubscribe(short, byte)} 321 */ 322 @Override stopSubscribe(short transactionId, byte pubSubId)323 public boolean stopSubscribe(short transactionId, byte pubSubId) { 324 final String methodStr = "stopSubscribe"; 325 synchronized (mLock) { 326 try { 327 if (!checkIfaceAndLogFailure(methodStr)) return false; 328 mWifiNanIface.stopSubscribeRequest((char) transactionId, pubSubId); 329 return true; 330 } catch (RemoteException e) { 331 handleRemoteException(e, methodStr); 332 } catch (ServiceSpecificException e) { 333 handleServiceSpecificException(e, methodStr); 334 } 335 return false; 336 } 337 } 338 339 /** 340 * See comments for {@link IWifiNanIface#createAwareNetworkInterface(short, String)} 341 */ 342 @Override createAwareNetworkInterface(short transactionId, String interfaceName)343 public boolean createAwareNetworkInterface(short transactionId, String interfaceName) { 344 final String methodStr = "createAwareNetworkInterface"; 345 synchronized (mLock) { 346 try { 347 if (!checkIfaceAndLogFailure(methodStr)) return false; 348 mWifiNanIface.createDataInterfaceRequest((char) transactionId, interfaceName); 349 return true; 350 } catch (RemoteException e) { 351 handleRemoteException(e, methodStr); 352 } catch (ServiceSpecificException e) { 353 handleServiceSpecificException(e, methodStr); 354 } 355 return false; 356 } 357 } 358 359 /** 360 * See comments for {@link IWifiNanIface#deleteAwareNetworkInterface(short, String)} 361 */ 362 @Override deleteAwareNetworkInterface(short transactionId, String interfaceName)363 public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) { 364 final String methodStr = "deleteAwareNetworkInterface"; 365 synchronized (mLock) { 366 try { 367 if (!checkIfaceAndLogFailure(methodStr)) return false; 368 mWifiNanIface.deleteDataInterfaceRequest((char) transactionId, interfaceName); 369 return true; 370 } catch (RemoteException e) { 371 handleRemoteException(e, methodStr); 372 } catch (ServiceSpecificException e) { 373 handleServiceSpecificException(e, methodStr); 374 } 375 return false; 376 } 377 } 378 379 /** 380 * See comments for 381 * {@link IWifiNanIface#initiateDataPath(short, int, int, int, MacAddress, String, boolean, byte[], Capabilities, WifiAwareDataPathSecurityConfig, byte)} 382 */ 383 @Override initiateDataPath(short transactionId, int peerId, int channelRequestType, int channel, MacAddress peer, String interfaceName, boolean isOutOfBand, byte[] appInfo, Capabilities capabilities, WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId)384 public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType, 385 int channel, MacAddress peer, String interfaceName, 386 boolean isOutOfBand, byte[] appInfo, Capabilities capabilities, 387 WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId) { 388 final String methodStr = "initiateDataPath"; 389 synchronized (mLock) { 390 try { 391 if (!checkIfaceAndLogFailure(methodStr)) return false; 392 NanInitiateDataPathRequest req = createNanInitiateDataPathRequest( 393 peerId, channelRequestType, channel, peer, interfaceName, isOutOfBand, 394 appInfo, securityConfig, pubSubId); 395 mWifiNanIface.initiateDataPathRequest((char) transactionId, req); 396 return true; 397 } catch (RemoteException e) { 398 handleRemoteException(e, methodStr); 399 } catch (ServiceSpecificException e) { 400 handleServiceSpecificException(e, methodStr); 401 } 402 return false; 403 } 404 } 405 406 /** 407 * See comments for 408 * {@link IWifiNanIface#respondToDataPathRequest(short, boolean, int, String, byte[], boolean, Capabilities, WifiAwareDataPathSecurityConfig, byte)} 409 */ 410 @Override respondToDataPathRequest(short transactionId, boolean accept, int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand, Capabilities capabilities, WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId)411 public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId, 412 String interfaceName, byte[] appInfo, boolean isOutOfBand, Capabilities capabilities, 413 WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId) { 414 final String methodStr = "respondToDataPathRequest"; 415 synchronized (mLock) { 416 try { 417 if (!checkIfaceAndLogFailure(methodStr)) return false; 418 NanRespondToDataPathIndicationRequest req = 419 createNanRespondToDataPathIndicationRequest( 420 accept, ndpId, interfaceName, appInfo, isOutOfBand, 421 securityConfig, pubSubId); 422 mWifiNanIface.respondToDataPathIndicationRequest((char) transactionId, req); 423 return true; 424 } catch (RemoteException e) { 425 handleRemoteException(e, methodStr); 426 } catch (ServiceSpecificException e) { 427 handleServiceSpecificException(e, methodStr); 428 } 429 return false; 430 } 431 } 432 433 /** 434 * See comments for {@link IWifiNanIface#endDataPath(short, int)} 435 */ 436 @Override endDataPath(short transactionId, int ndpId)437 public boolean endDataPath(short transactionId, int ndpId) { 438 final String methodStr = "endDataPath"; 439 synchronized (mLock) { 440 try { 441 if (!checkIfaceAndLogFailure(methodStr)) return false; 442 mWifiNanIface.terminateDataPathRequest((char) transactionId, ndpId); 443 return true; 444 } catch (RemoteException e) { 445 handleRemoteException(e, methodStr); 446 } catch (ServiceSpecificException e) { 447 handleServiceSpecificException(e, methodStr); 448 } 449 return false; 450 } 451 } 452 453 @Override respondToPairingRequest(short transactionId, int pairingId, boolean accept, byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm, int cipherSuite)454 public boolean respondToPairingRequest(short transactionId, int pairingId, boolean accept, 455 byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, 456 String password, int akm, int cipherSuite) { 457 String methodStr = "respondToPairingRequest"; 458 NanRespondToPairingIndicationRequest request = createNanPairingResponse(pairingId, accept, 459 pairingIdentityKey, enablePairingCache, requestType, pmk, password, akm, 460 cipherSuite); 461 synchronized (mLock) { 462 try { 463 if (!checkIfaceAndLogFailure(methodStr)) return false; 464 mWifiNanIface.respondToPairingIndicationRequest((char) transactionId, request); 465 return true; 466 } catch (RemoteException e) { 467 handleRemoteException(e, methodStr); 468 } catch (ServiceSpecificException e) { 469 handleServiceSpecificException(e, methodStr); 470 } 471 return false; 472 } 473 } 474 475 @Override initiateNanPairingRequest(short transactionId, int peerId, MacAddress peer, byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm, int cipherSuite)476 public boolean initiateNanPairingRequest(short transactionId, int peerId, MacAddress peer, 477 byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, 478 String password, int akm, int cipherSuite) { 479 String methodStr = "initiateNanPairingRequest"; 480 NanPairingRequest nanPairingRequest = createNanPairingRequest(peerId, peer, 481 pairingIdentityKey, enablePairingCache, requestType, pmk, password, akm, 482 cipherSuite); 483 synchronized (mLock) { 484 try { 485 if (!checkIfaceAndLogFailure(methodStr)) return false; 486 mWifiNanIface.initiatePairingRequest((char) transactionId, nanPairingRequest); 487 return true; 488 } catch (RemoteException e) { 489 handleRemoteException(e, methodStr); 490 } catch (ServiceSpecificException e) { 491 handleServiceSpecificException(e, methodStr); 492 } 493 return false; 494 } 495 } 496 497 @Override endPairing(short transactionId, int pairingId)498 public boolean endPairing(short transactionId, int pairingId) { 499 String methodStr = "endPairing"; 500 synchronized (mLock) { 501 try { 502 if (!checkIfaceAndLogFailure(methodStr)) return false; 503 mWifiNanIface.terminatePairingRequest((char) transactionId, pairingId); 504 return true; 505 } catch (RemoteException e) { 506 handleRemoteException(e, methodStr); 507 } catch (ServiceSpecificException e) { 508 handleServiceSpecificException(e, methodStr); 509 } 510 return false; 511 } 512 } 513 514 @Override initiateNanBootstrappingRequest(short transactionId, int peerId, MacAddress peer, int method, byte[] cookie, byte pubSubId, boolean isComeBack)515 public boolean initiateNanBootstrappingRequest(short transactionId, int peerId, MacAddress peer, 516 int method, byte[] cookie, byte pubSubId, boolean isComeBack) { 517 String methodStr = "initiateNanBootstrappingRequest"; 518 NanBootstrappingRequest request = createNanBootstrappingRequest(peerId, peer, method, 519 cookie, pubSubId, isComeBack); 520 synchronized (mLock) { 521 try { 522 if (!checkIfaceAndLogFailure(methodStr)) return false; 523 mWifiNanIface.initiateBootstrappingRequest((char) transactionId, request); 524 return true; 525 } catch (RemoteException e) { 526 handleRemoteException(e, methodStr); 527 } catch (ServiceSpecificException e) { 528 handleServiceSpecificException(e, methodStr); 529 } 530 return false; 531 } 532 } 533 534 @Override respondToNanBootstrappingRequest(short transactionId, int bootstrappingId, boolean accept, byte pubSubId)535 public boolean respondToNanBootstrappingRequest(short transactionId, int bootstrappingId, 536 boolean accept, byte pubSubId) { 537 String methodStr = "respondToNanBootstrappingRequest"; 538 NanBootstrappingResponse request = createNanBootstrappingResponse(bootstrappingId, accept, 539 pubSubId); 540 synchronized (mLock) { 541 try { 542 if (!checkIfaceAndLogFailure(methodStr)) return false; 543 mWifiNanIface.respondToBootstrappingIndicationRequest((char) transactionId, 544 request); 545 return true; 546 } catch (RemoteException e) { 547 handleRemoteException(e, methodStr); 548 } catch (ServiceSpecificException e) { 549 handleServiceSpecificException(e, methodStr); 550 } 551 return false; 552 } 553 } 554 555 @Override suspend(short transactionId, byte pubSubId)556 public boolean suspend(short transactionId, byte pubSubId) { 557 String methodStr = "suspend"; 558 synchronized (mLock) { 559 try { 560 if (!checkIfaceAndLogFailure(methodStr)) return false; 561 mWifiNanIface.suspendRequest((char) transactionId, pubSubId); 562 return true; 563 } catch (RemoteException e) { 564 handleRemoteException(e, methodStr); 565 } catch (ServiceSpecificException e) { 566 handleServiceSpecificException(e, methodStr); 567 } 568 return false; 569 } 570 } 571 572 @Override resume(short transactionId, byte pubSubId)573 public boolean resume(short transactionId, byte pubSubId) { 574 String methodStr = "resume"; 575 synchronized (mLock) { 576 try { 577 if (!checkIfaceAndLogFailure(methodStr)) return false; 578 mWifiNanIface.resumeRequest((char) transactionId, pubSubId); 579 return true; 580 } catch (RemoteException e) { 581 handleRemoteException(e, methodStr); 582 } catch (ServiceSpecificException e) { 583 handleServiceSpecificException(e, methodStr); 584 } 585 return false; 586 } 587 } 588 589 // Utilities 590 createNanBootstrappingResponse(int bootstrappingId, boolean accept, byte pubSubId)591 private static NanBootstrappingResponse createNanBootstrappingResponse(int bootstrappingId, 592 boolean accept, byte pubSubId) { 593 NanBootstrappingResponse request = new NanBootstrappingResponse(); 594 request.acceptRequest = accept; 595 request.bootstrappingInstanceId = bootstrappingId; 596 request.discoverySessionId = pubSubId; 597 return request; 598 } 599 createNanBootstrappingRequest(int peerId, MacAddress peer, int method, byte[] cookie, byte pubSubId, boolean isComeBack)600 private static NanBootstrappingRequest createNanBootstrappingRequest(int peerId, 601 MacAddress peer, int method, byte[] cookie, byte pubSubId, boolean isComeBack) { 602 NanBootstrappingRequest request = new NanBootstrappingRequest(); 603 request.peerId = peerId; 604 request.peerDiscMacAddr = peer.toByteArray(); 605 request.requestBootstrappingMethod = method; 606 request.cookie = copyArray(cookie); 607 request.discoverySessionId = pubSubId; 608 request.isComeback = isComeBack; 609 return request; 610 } 611 createNanConfigRequestSupplemental( boolean rangingEnabled, boolean isInstantCommunicationEnabled, int instantModeChannel, int clusterId)612 private static NanConfigRequestSupplemental createNanConfigRequestSupplemental( 613 boolean rangingEnabled, boolean isInstantCommunicationEnabled, int instantModeChannel, 614 int clusterId) { 615 NanConfigRequestSupplemental out = new NanConfigRequestSupplemental(); 616 out.discoveryBeaconIntervalMs = 0; 617 out.numberOfSpatialStreamsInDiscovery = 0; 618 out.enableDiscoveryWindowEarlyTermination = false; 619 out.enableRanging = rangingEnabled; 620 out.enableInstantCommunicationMode = isInstantCommunicationEnabled; 621 out.instantModeChannel = instantModeChannel; 622 out.clusterId = clusterId; 623 return out; 624 } 625 createNanBandSpecificConfigs( ConfigRequest configRequest)626 private static NanBandSpecificConfig[] createNanBandSpecificConfigs( 627 ConfigRequest configRequest) { 628 NanBandSpecificConfig config24 = new NanBandSpecificConfig(); 629 config24.rssiClose = 60; 630 config24.rssiMiddle = 70; 631 config24.rssiCloseProximity = 60; 632 config24.dwellTimeMs = 200; 633 config24.scanPeriodSec = 20; 634 if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ] 635 == ConfigRequest.DW_INTERVAL_NOT_INIT) { 636 config24.validDiscoveryWindowIntervalVal = false; 637 } else { 638 config24.validDiscoveryWindowIntervalVal = true; 639 config24.discoveryWindowIntervalVal = 640 (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]; 641 } 642 643 NanBandSpecificConfig config5 = new NanBandSpecificConfig(); 644 config5.rssiClose = 60; 645 config5.rssiMiddle = 75; 646 config5.rssiCloseProximity = 60; 647 config5.dwellTimeMs = 200; 648 config5.scanPeriodSec = 20; 649 if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ] 650 == ConfigRequest.DW_INTERVAL_NOT_INIT) { 651 config5.validDiscoveryWindowIntervalVal = false; 652 } else { 653 config5.validDiscoveryWindowIntervalVal = true; 654 config5.discoveryWindowIntervalVal = 655 (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]; 656 } 657 658 NanBandSpecificConfig config6 = new NanBandSpecificConfig(); 659 config6.rssiClose = 60; 660 config6.rssiMiddle = 75; 661 config6.rssiCloseProximity = 60; 662 config6.dwellTimeMs = 200; 663 config6.scanPeriodSec = 20; 664 if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ] 665 == ConfigRequest.DW_INTERVAL_NOT_INIT) { 666 config6.validDiscoveryWindowIntervalVal = false; 667 } else { 668 config6.validDiscoveryWindowIntervalVal = true; 669 config6.discoveryWindowIntervalVal = 670 (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_6GHZ]; 671 } 672 673 return new NanBandSpecificConfig[]{config24, config5, config6}; 674 } 675 createNanEnableRequest( ConfigRequest configRequest, boolean notifyIdentityChange, NanConfigRequestSupplemental configSupplemental, int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters)676 private static NanEnableRequest createNanEnableRequest( 677 ConfigRequest configRequest, boolean notifyIdentityChange, 678 NanConfigRequestSupplemental configSupplemental, 679 int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) { 680 NanEnableRequest req = new NanEnableRequest(); 681 NanBandSpecificConfig[] nanBandSpecificConfigs = 682 createNanBandSpecificConfigs(configRequest); 683 684 req.operateInBand = new boolean[3]; 685 req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true; 686 req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand; 687 req.operateInBand[NanBandIndex.NAN_BAND_6GHZ] = configRequest.mSupport6gBand; 688 req.hopCountMax = 2; 689 req.configParams = new NanConfigRequest(); 690 req.configParams.masterPref = (byte) configRequest.mMasterPreference; 691 req.configParams.disableDiscoveryAddressChangeIndication = !notifyIdentityChange; 692 req.configParams.disableStartedClusterIndication = !notifyIdentityChange; 693 req.configParams.disableJoinedClusterIndication = !notifyIdentityChange; 694 req.configParams.includePublishServiceIdsInBeacon = true; 695 req.configParams.numberOfPublishServiceIdsInBeacon = 0; 696 req.configParams.includeSubscribeServiceIdsInBeacon = true; 697 req.configParams.numberOfSubscribeServiceIdsInBeacon = 0; 698 req.configParams.rssiWindowSize = 8; 699 req.configParams.macAddressRandomizationIntervalSec = macAddressRandomizationIntervalSec; 700 701 req.configParams.bandSpecificConfig = new NanBandSpecificConfig[3]; 702 req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = 703 nanBandSpecificConfigs[0]; 704 req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = nanBandSpecificConfigs[1]; 705 req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ] = nanBandSpecificConfigs[2]; 706 707 req.debugConfigs = new NanDebugConfig(); 708 req.debugConfigs.validClusterIdVals = true; 709 req.debugConfigs.clusterIdTopRangeVal = (char) configRequest.mClusterHigh; 710 req.debugConfigs.clusterIdBottomRangeVal = (char) configRequest.mClusterLow; 711 req.debugConfigs.validIntfAddrVal = false; 712 req.debugConfigs.intfAddrVal = new byte[6]; 713 req.debugConfigs.validOuiVal = false; 714 req.debugConfigs.ouiVal = 0; 715 req.debugConfigs.validRandomFactorForceVal = false; 716 req.debugConfigs.randomFactorForceVal = 0; 717 req.debugConfigs.validHopCountForceVal = false; 718 req.debugConfigs.hopCountForceVal = 0; 719 req.debugConfigs.validDiscoveryChannelVal = false; 720 req.debugConfigs.discoveryChannelMhzVal = new int[3]; 721 req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0; 722 req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0; 723 req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_6GHZ] = 0; 724 req.debugConfigs.validUseBeaconsInBandVal = false; 725 req.debugConfigs.useBeaconsInBandVal = new boolean[3]; 726 req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true; 727 req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true; 728 req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_6GHZ] = true; 729 req.debugConfigs.validUseSdfInBandVal = false; 730 req.debugConfigs.useSdfInBandVal = new boolean[3]; 731 req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true; 732 req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true; 733 req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_6GHZ] = true; 734 updateConfigForPowerSettings(req.configParams, configSupplemental, powerParameters); 735 updateConfigRequestVendorData(req.configParams, configRequest); 736 return req; 737 } 738 createNanConfigRequest( ConfigRequest configRequest, boolean notifyIdentityChange, NanConfigRequestSupplemental configSupplemental, int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters)739 private static NanConfigRequest createNanConfigRequest( 740 ConfigRequest configRequest, boolean notifyIdentityChange, 741 NanConfigRequestSupplemental configSupplemental, 742 int macAddressRandomizationIntervalSec, WifiNanIface.PowerParameters powerParameters) { 743 NanConfigRequest req = new NanConfigRequest(); 744 NanBandSpecificConfig[] nanBandSpecificConfigs = 745 createNanBandSpecificConfigs(configRequest); 746 747 req.masterPref = (byte) configRequest.mMasterPreference; 748 req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange; 749 req.disableStartedClusterIndication = !notifyIdentityChange; 750 req.disableJoinedClusterIndication = !notifyIdentityChange; 751 req.includePublishServiceIdsInBeacon = true; 752 req.numberOfPublishServiceIdsInBeacon = 0; 753 req.includeSubscribeServiceIdsInBeacon = true; 754 req.numberOfSubscribeServiceIdsInBeacon = 0; 755 req.rssiWindowSize = 8; 756 req.macAddressRandomizationIntervalSec = macAddressRandomizationIntervalSec; 757 758 req.bandSpecificConfig = new NanBandSpecificConfig[3]; 759 req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = nanBandSpecificConfigs[0]; 760 req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = nanBandSpecificConfigs[1]; 761 req.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ] = nanBandSpecificConfigs[2]; 762 updateConfigForPowerSettings(req, configSupplemental, powerParameters); 763 updateConfigRequestVendorData(req, configRequest); 764 return req; 765 } 766 767 /** 768 * Update the NAN configuration to reflect the current power settings 769 */ updateConfigForPowerSettings(NanConfigRequest req, NanConfigRequestSupplemental configSupplemental, WifiNanIface.PowerParameters powerParameters)770 private static void updateConfigForPowerSettings(NanConfigRequest req, 771 NanConfigRequestSupplemental configSupplemental, 772 WifiNanIface.PowerParameters powerParameters) { 773 updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ], 774 powerParameters.discoveryWindow5Ghz); 775 updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ], 776 powerParameters.discoveryWindow24Ghz); 777 updateSingleConfigForPowerSettings(req.bandSpecificConfig[NanBandIndex.NAN_BAND_6GHZ], 778 powerParameters.discoveryWindow6Ghz); 779 780 configSupplemental.discoveryBeaconIntervalMs = powerParameters.discoveryBeaconIntervalMs; 781 configSupplemental.numberOfSpatialStreamsInDiscovery = 782 powerParameters.numberOfSpatialStreamsInDiscovery; 783 configSupplemental.enableDiscoveryWindowEarlyTermination = 784 powerParameters.enableDiscoveryWindowEarlyTermination; 785 } 786 updateSingleConfigForPowerSettings( NanBandSpecificConfig cfg, int override)787 private static void updateSingleConfigForPowerSettings( 788 NanBandSpecificConfig cfg, int override) { 789 if (override != -1) { 790 cfg.validDiscoveryWindowIntervalVal = true; 791 cfg.discoveryWindowIntervalVal = (byte) override; 792 } 793 } 794 updateConfigRequestVendorData( NanConfigRequest halReq, ConfigRequest frameworkReq)795 private static void updateConfigRequestVendorData( 796 NanConfigRequest halReq, ConfigRequest frameworkReq) { 797 if (SdkLevel.isAtLeastV() && WifiHalAidlImpl.isServiceVersionAtLeast(2) 798 && !frameworkReq.getVendorData().isEmpty()) { 799 halReq.vendorData = 800 HalAidlUtil.frameworkToHalOuiKeyedDataList(frameworkReq.getVendorData()); 801 } 802 } 803 createNanPublishRequest( byte publishId, PublishConfig publishConfig, byte[] nik)804 private static NanPublishRequest createNanPublishRequest( 805 byte publishId, PublishConfig publishConfig, byte[] nik) { 806 NanPublishRequest req = new NanPublishRequest(); 807 req.baseConfigs = new NanDiscoveryCommonConfig(); 808 req.baseConfigs.sessionId = publishId; 809 req.baseConfigs.ttlSec = (char) publishConfig.mTtlSec; 810 req.baseConfigs.discoveryWindowPeriod = 1; 811 req.baseConfigs.discoveryCount = 0; 812 req.baseConfigs.serviceName = copyArray(publishConfig.mServiceName); 813 req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_NEVER; 814 if (publishConfig.mServiceSpecificInfo != null 815 && publishConfig.mServiceSpecificInfo.length > 255) { 816 req.baseConfigs.extendedServiceSpecificInfo = 817 copyArray(publishConfig.mServiceSpecificInfo); 818 req.baseConfigs.serviceSpecificInfo = new byte[0]; 819 } else { 820 req.baseConfigs.serviceSpecificInfo = copyArray(publishConfig.mServiceSpecificInfo); 821 req.baseConfigs.extendedServiceSpecificInfo = new byte[0]; 822 } 823 if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED) { 824 req.baseConfigs.txMatchFilter = copyArray(publishConfig.mMatchFilter); 825 req.baseConfigs.rxMatchFilter = new byte[0]; 826 } else { 827 req.baseConfigs.rxMatchFilter = copyArray(publishConfig.mMatchFilter); 828 req.baseConfigs.txMatchFilter = new byte[0]; 829 } 830 req.baseConfigs.useRssiThreshold = false; 831 req.baseConfigs.disableDiscoveryTerminationIndication = 832 !publishConfig.mEnableTerminateNotification; 833 req.baseConfigs.disableMatchExpirationIndication = true; 834 req.baseConfigs.disableFollowupReceivedIndication = false; 835 836 req.autoAcceptDataPathRequests = false; 837 838 req.baseConfigs.rangingRequired = publishConfig.mEnableRanging; 839 840 req.baseConfigs.securityConfig = new NanDataPathSecurityConfig(); 841 req.baseConfigs.securityConfig.pmk = new byte[32]; 842 req.baseConfigs.securityConfig.passphrase = new byte[0]; 843 req.baseConfigs.securityConfig.scid = new byte[16]; 844 req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN; 845 WifiAwareDataPathSecurityConfig securityConfig = publishConfig.getSecurityConfig(); 846 if (securityConfig != null) { 847 req.baseConfigs.securityConfig.cipherType = getHalCipherSuiteType( 848 securityConfig.getCipherSuite()); 849 if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) { 850 req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PMK; 851 req.baseConfigs.securityConfig.pmk = copyArray(securityConfig.getPmk()); 852 } 853 if (securityConfig.getPskPassphrase() != null 854 && securityConfig.getPskPassphrase().length() != 0) { 855 req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE; 856 req.baseConfigs.securityConfig.passphrase = 857 securityConfig.getPskPassphrase().getBytes(); 858 } 859 if (securityConfig.getPmkId() != null && securityConfig.getPmkId().length != 0) { 860 req.baseConfigs.securityConfig.scid = copyArray(securityConfig.getPmkId()); 861 } 862 } 863 864 req.baseConfigs.enableSessionSuspendability = SdkLevel.isAtLeastU() 865 && publishConfig.isSuspendable(); 866 867 req.publishType = publishConfig.mPublishType; 868 req.txType = NanTxType.BROADCAST; 869 req.pairingConfig = createAidlPairingConfig(publishConfig.getPairingConfig()); 870 req.identityKey = copyArray(nik, 16); 871 872 if (SdkLevel.isAtLeastV() && !publishConfig.getVendorData().isEmpty()) { 873 req.vendorData = 874 HalAidlUtil.frameworkToHalOuiKeyedDataList(publishConfig.getVendorData()); 875 } 876 877 return req; 878 } 879 createNanSubscribeRequest( byte subscribeId, SubscribeConfig subscribeConfig, byte[] nik)880 private static NanSubscribeRequest createNanSubscribeRequest( 881 byte subscribeId, SubscribeConfig subscribeConfig, byte[] nik) { 882 NanSubscribeRequest req = new NanSubscribeRequest(); 883 req.baseConfigs = new NanDiscoveryCommonConfig(); 884 req.baseConfigs.sessionId = subscribeId; 885 req.baseConfigs.ttlSec = (char) subscribeConfig.mTtlSec; 886 req.baseConfigs.discoveryWindowPeriod = 1; 887 req.baseConfigs.discoveryCount = 0; 888 req.baseConfigs.serviceName = copyArray(subscribeConfig.mServiceName); 889 req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE; 890 if (subscribeConfig.mServiceSpecificInfo != null 891 && subscribeConfig.mServiceSpecificInfo.length > 255) { 892 req.baseConfigs.extendedServiceSpecificInfo = 893 copyArray(subscribeConfig.mServiceSpecificInfo); 894 req.baseConfigs.serviceSpecificInfo = new byte[0]; 895 } else { 896 req.baseConfigs.serviceSpecificInfo = copyArray(subscribeConfig.mServiceSpecificInfo); 897 req.baseConfigs.extendedServiceSpecificInfo = new byte[0]; 898 } 899 if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE) { 900 req.baseConfigs.txMatchFilter = copyArray(subscribeConfig.mMatchFilter); 901 req.baseConfigs.rxMatchFilter = new byte[0]; 902 } else { 903 req.baseConfigs.rxMatchFilter = copyArray(subscribeConfig.mMatchFilter); 904 req.baseConfigs.txMatchFilter = new byte[0]; 905 } 906 req.baseConfigs.useRssiThreshold = false; 907 req.baseConfigs.disableDiscoveryTerminationIndication = 908 !subscribeConfig.mEnableTerminateNotification; 909 req.baseConfigs.disableMatchExpirationIndication = false; 910 req.baseConfigs.disableFollowupReceivedIndication = false; 911 912 req.baseConfigs.rangingRequired = 913 subscribeConfig.mMinDistanceMmSet || subscribeConfig.mMaxDistanceMmSet; 914 req.baseConfigs.configRangingIndications = 0; 915 if (subscribeConfig.mMinDistanceMmSet) { 916 req.baseConfigs.distanceEgressCm = (char) Math.min( 917 subscribeConfig.mMinDistanceMm / 10, Short.MAX_VALUE); 918 req.baseConfigs.configRangingIndications |= NanRangingIndication.EGRESS_MET_MASK; 919 } 920 if (subscribeConfig.mMaxDistanceMmSet) { 921 req.baseConfigs.distanceIngressCm = (char) Math.min( 922 subscribeConfig.mMaxDistanceMm / 10, Short.MAX_VALUE); 923 req.baseConfigs.configRangingIndications |= NanRangingIndication.INGRESS_MET_MASK; 924 } 925 926 // TODO: configure security 927 req.baseConfigs.securityConfig = new NanDataPathSecurityConfig(); 928 req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN; 929 req.baseConfigs.securityConfig.pmk = new byte[32]; 930 req.baseConfigs.securityConfig.passphrase = new byte[0]; 931 req.baseConfigs.securityConfig.scid = new byte[16]; 932 933 req.baseConfigs.enableSessionSuspendability = SdkLevel.isAtLeastU() 934 && subscribeConfig.isSuspendable(); 935 936 req.subscribeType = subscribeConfig.mSubscribeType; 937 req.pairingConfig = createAidlPairingConfig(subscribeConfig.getPairingConfig()); 938 req.identityKey = copyArray(nik, 16); 939 req.intfAddr = new android.hardware.wifi.MacAddress[0]; 940 941 if (SdkLevel.isAtLeastV() && !subscribeConfig.getVendorData().isEmpty()) { 942 req.vendorData = 943 HalAidlUtil.frameworkToHalOuiKeyedDataList(subscribeConfig.getVendorData()); 944 } 945 946 return req; 947 } 948 createAidlPairingConfig( @ullable AwarePairingConfig pairingConfig)949 private static NanPairingConfig createAidlPairingConfig( 950 @Nullable AwarePairingConfig pairingConfig) { 951 NanPairingConfig config = new NanPairingConfig(); 952 if (pairingConfig == null) { 953 return config; 954 } 955 config.enablePairingCache = pairingConfig.isPairingCacheEnabled(); 956 config.enablePairingSetup = pairingConfig.isPairingSetupEnabled(); 957 config.enablePairingVerification = pairingConfig.isPairingVerificationEnabled(); 958 config.supportedBootstrappingMethods = pairingConfig.getBootstrappingMethods(); 959 return config; 960 } 961 createNanTransmitFollowupRequest( byte pubSubId, int requesterInstanceId, MacAddress dest, byte[] message)962 private static NanTransmitFollowupRequest createNanTransmitFollowupRequest( 963 byte pubSubId, int requesterInstanceId, MacAddress dest, byte[] message) { 964 NanTransmitFollowupRequest req = new NanTransmitFollowupRequest(); 965 req.discoverySessionId = pubSubId; 966 req.peerId = requesterInstanceId; 967 req.addr = dest.toByteArray(); 968 req.isHighPriority = false; 969 req.shouldUseDiscoveryWindow = true; 970 if (message != null && message.length > 255) { 971 req.extendedServiceSpecificInfo = copyArray(message); 972 req.serviceSpecificInfo = new byte[0]; 973 } else { 974 req.serviceSpecificInfo = copyArray(message); 975 req.extendedServiceSpecificInfo = new byte[0]; 976 } 977 req.disableFollowupResultIndication = false; 978 return req; 979 } 980 createNanInitiateDataPathRequest( int peerId, int channelRequestType, int channel, MacAddress peer, String interfaceName, boolean isOutOfBand, byte[] appInfo, WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId)981 private static NanInitiateDataPathRequest createNanInitiateDataPathRequest( 982 int peerId, int channelRequestType, int channel, MacAddress peer, String interfaceName, 983 boolean isOutOfBand, byte[] appInfo, WifiAwareDataPathSecurityConfig securityConfig, 984 byte pubSubId) { 985 NanInitiateDataPathRequest req = new NanInitiateDataPathRequest(); 986 req.peerId = peerId; 987 req.peerDiscMacAddr = peer.toByteArray(); 988 req.channelRequestType = WifiNanIface.NanDataPathChannelCfg.toAidl(channelRequestType); 989 req.serviceNameOutOfBand = new byte[0]; 990 req.channel = channel; 991 req.ifaceName = interfaceName; 992 req.securityConfig = new NanDataPathSecurityConfig(); 993 req.securityConfig.pmk = new byte[32]; 994 req.securityConfig.passphrase = new byte[0]; 995 req.securityConfig.scid = new byte[16]; 996 req.securityConfig.securityType = NanDataPathSecurityType.OPEN; 997 if (securityConfig != null) { 998 req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite()); 999 if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) { 1000 req.securityConfig.securityType = NanDataPathSecurityType.PMK; 1001 req.securityConfig.pmk = copyArray(securityConfig.getPmk()); 1002 req.securityConfig.passphrase = new byte[0]; 1003 } 1004 if (securityConfig.getPskPassphrase() != null 1005 && securityConfig.getPskPassphrase().length() != 0) { 1006 req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE; 1007 req.securityConfig.passphrase = securityConfig.getPskPassphrase().getBytes(); 1008 req.securityConfig.pmk = new byte[32]; 1009 } 1010 req.securityConfig.scid = copyArray(securityConfig.getPmkId(), 16); 1011 } 1012 1013 if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) { 1014 req.serviceNameOutOfBand = WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH 1015 .getBytes(StandardCharsets.UTF_8); 1016 } 1017 req.appInfo = copyArray(appInfo); 1018 req.discoverySessionId = pubSubId; 1019 return req; 1020 } 1021 createNanPairingRequest(int peerId, MacAddress peer, byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm, int cipherSuite)1022 private static NanPairingRequest createNanPairingRequest(int peerId, MacAddress peer, 1023 byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, 1024 String password, int akm, int cipherSuite) { 1025 NanPairingRequest request = new NanPairingRequest(); 1026 request.peerId = peerId; 1027 request.peerDiscMacAddr = peer.toByteArray(); 1028 request.pairingIdentityKey = copyArray(pairingIdentityKey, 16); 1029 request.enablePairingCache = enablePairingCache; 1030 request.requestType = requestType == NAN_PAIRING_REQUEST_TYPE_SETUP 1031 ? NanPairingRequestType.NAN_PAIRING_SETUP 1032 : NanPairingRequestType.NAN_PAIRING_VERIFICATION; 1033 request.securityConfig = new NanPairingSecurityConfig(); 1034 request.securityConfig.pmk = new byte[32]; 1035 request.securityConfig.cipherType = cipherSuite; 1036 request.securityConfig.passphrase = new byte[0]; 1037 if (pmk != null && pmk.length != 0) { 1038 request.securityConfig.securityType = NanPairingSecurityType.PMK; 1039 request.securityConfig.pmk = copyArray(pmk); 1040 request.securityConfig.akm = akm == NAN_PAIRING_AKM_SAE ? NanPairingAkm.SAE 1041 : NanPairingAkm.PASN; 1042 } else if (password != null && password.length() != 0) { 1043 request.securityConfig.securityType = NanPairingSecurityType.PASSPHRASE; 1044 request.securityConfig.passphrase = password.getBytes(); 1045 request.securityConfig.akm = NanPairingAkm.SAE; 1046 } else { 1047 request.securityConfig.securityType = NanPairingSecurityType.OPPORTUNISTIC; 1048 request.securityConfig.akm = NanPairingAkm.PASN; 1049 } 1050 return request; 1051 } 1052 createNanPairingResponse( int pairingInstanceId, boolean accept, byte[] pairingIdentityKey, boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm, int cipherSuite)1053 private static NanRespondToPairingIndicationRequest createNanPairingResponse( 1054 int pairingInstanceId, boolean accept, byte[] pairingIdentityKey, 1055 boolean enablePairingCache, int requestType, byte[] pmk, String password, int akm, 1056 int cipherSuite) { 1057 NanRespondToPairingIndicationRequest request = new NanRespondToPairingIndicationRequest(); 1058 request.pairingInstanceId = pairingInstanceId; 1059 request.acceptRequest = accept; 1060 request.pairingIdentityKey = copyArray(pairingIdentityKey, 16); 1061 request.enablePairingCache = enablePairingCache; 1062 request.requestType = requestType == NAN_PAIRING_REQUEST_TYPE_SETUP 1063 ? NanPairingRequestType.NAN_PAIRING_SETUP 1064 : NanPairingRequestType.NAN_PAIRING_VERIFICATION; 1065 request.securityConfig = new NanPairingSecurityConfig(); 1066 request.securityConfig.pmk = new byte[32]; 1067 request.securityConfig.passphrase = new byte[0]; 1068 request.securityConfig.cipherType = cipherSuite; 1069 if (pmk != null && pmk.length != 0) { 1070 request.securityConfig.securityType = NanPairingSecurityType.PMK; 1071 request.securityConfig.pmk = copyArray(pmk); 1072 request.securityConfig.akm = akm == NAN_PAIRING_AKM_SAE ? NanPairingAkm.SAE 1073 : NanPairingAkm.PASN; 1074 } else if (password != null && password.length() != 0) { 1075 request.securityConfig.securityType = NanPairingSecurityType.PASSPHRASE; 1076 request.securityConfig.passphrase = password.getBytes(); 1077 request.securityConfig.akm = NanPairingAkm.SAE; 1078 } else { 1079 request.securityConfig.securityType = NanPairingSecurityType.OPPORTUNISTIC; 1080 request.securityConfig.akm = NanPairingAkm.PASN; 1081 } 1082 return request; 1083 } 1084 1085 private static NanRespondToDataPathIndicationRequest createNanRespondToDataPathIndicationRequest(boolean accept, int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand, WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId)1086 createNanRespondToDataPathIndicationRequest(boolean accept, int ndpId, 1087 String interfaceName, byte[] appInfo, boolean isOutOfBand, 1088 WifiAwareDataPathSecurityConfig securityConfig, byte pubSubId) { 1089 NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest(); 1090 req.acceptRequest = accept; 1091 req.ndpInstanceId = ndpId; 1092 req.ifaceName = interfaceName; 1093 req.serviceNameOutOfBand = new byte[0]; 1094 req.securityConfig = new NanDataPathSecurityConfig(); 1095 req.securityConfig.pmk = new byte[32]; 1096 req.securityConfig.passphrase = new byte[0]; 1097 req.securityConfig.scid = new byte[16]; 1098 req.securityConfig.securityType = NanDataPathSecurityType.OPEN; 1099 if (securityConfig != null) { 1100 req.securityConfig.cipherType = getHalCipherSuiteType(securityConfig.getCipherSuite()); 1101 if (securityConfig.getPmk() != null && securityConfig.getPmk().length != 0) { 1102 req.securityConfig.securityType = NanDataPathSecurityType.PMK; 1103 req.securityConfig.pmk = copyArray(securityConfig.getPmk()); 1104 } 1105 if (securityConfig.getPskPassphrase() != null 1106 && securityConfig.getPskPassphrase().length() != 0) { 1107 req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE; 1108 req.securityConfig.passphrase = securityConfig.getPskPassphrase().getBytes(); 1109 } 1110 req.securityConfig.scid = copyArray(securityConfig.getPmkId(), 16); 1111 } 1112 1113 if (req.securityConfig.securityType != NanDataPathSecurityType.OPEN && isOutOfBand) { 1114 req.serviceNameOutOfBand = WifiNanIface.SERVICE_NAME_FOR_OOB_DATA_PATH 1115 .getBytes(StandardCharsets.UTF_8); 1116 } 1117 req.appInfo = copyArray(appInfo); 1118 req.discoverySessionId = pubSubId; 1119 return req; 1120 } 1121 getHalCipherSuiteType(int frameworkCipherSuites)1122 private static int getHalCipherSuiteType(int frameworkCipherSuites) { 1123 switch (frameworkCipherSuites) { 1124 case WIFI_AWARE_CIPHER_SUITE_NCS_SK_128: 1125 return NanCipherSuiteType.SHARED_KEY_128_MASK; 1126 case WIFI_AWARE_CIPHER_SUITE_NCS_SK_256: 1127 return NanCipherSuiteType.SHARED_KEY_256_MASK; 1128 case WIFI_AWARE_CIPHER_SUITE_NCS_PK_128: 1129 return NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK; 1130 case WIFI_AWARE_CIPHER_SUITE_NCS_PK_256: 1131 return NanCipherSuiteType.PUBLIC_KEY_2WDH_256_MASK; 1132 } 1133 return NanCipherSuiteType.NONE; 1134 } 1135 copyArray(byte[] source)1136 private static byte[] copyArray(byte[] source) { 1137 return copyArray(source, 0); 1138 } 1139 copyArray(byte[] source, int length)1140 private static byte[] copyArray(byte[] source, int length) { 1141 return source != null && source.length != 0 ? source.clone() : new byte[length]; 1142 } 1143 checkIfaceAndLogFailure(String methodStr)1144 private boolean checkIfaceAndLogFailure(String methodStr) { 1145 if (mWifiNanIface == null) { 1146 Log.e(TAG, "Unable to call " + methodStr + " because iface is null."); 1147 return false; 1148 } 1149 return true; 1150 } 1151 handleRemoteException(RemoteException e, String methodStr)1152 private void handleRemoteException(RemoteException e, String methodStr) { 1153 mWifiNanIface = null; 1154 mIfaceName = null; 1155 Log.e(TAG, methodStr + " failed with remote exception: " + e); 1156 } 1157 handleServiceSpecificException(ServiceSpecificException e, String methodStr)1158 private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) { 1159 Log.e(TAG, methodStr + " failed with service-specific exception: " + e); 1160 } 1161 } 1162