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