1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi.p2p; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.net.wifi.CoexUnsafeChannel; 22 import android.net.wifi.ScanResult; 23 import android.net.wifi.p2p.WifiP2pConfig; 24 import android.net.wifi.p2p.WifiP2pDiscoveryConfig; 25 import android.net.wifi.p2p.WifiP2pExtListenParams; 26 import android.net.wifi.p2p.WifiP2pGroup; 27 import android.net.wifi.p2p.WifiP2pGroupList; 28 import android.net.wifi.p2p.WifiP2pManager; 29 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; 30 import android.util.Log; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.server.wifi.WifiGlobals; 34 import com.android.server.wifi.WifiInjector; 35 import com.android.server.wifi.WifiNative; 36 37 import java.util.List; 38 import java.util.Set; 39 40 public class SupplicantP2pIfaceHal { 41 private static final String TAG = "SupplicantP2pIfaceHal"; 42 private final Object mLock = new Object(); 43 private static boolean sVerboseLoggingEnabled = true; 44 private static boolean sHalVerboseLoggingEnabled = true; 45 private final WifiP2pMonitor mMonitor; 46 private final WifiGlobals mWifiGlobals; 47 private final WifiInjector mWifiInjector; 48 49 // HAL interface object - might be implemented by HIDL or AIDL 50 private ISupplicantP2pIfaceHal mP2pIfaceHal; 51 SupplicantP2pIfaceHal(WifiP2pMonitor monitor, WifiGlobals wifiGlobals, WifiInjector wifiInjector)52 public SupplicantP2pIfaceHal(WifiP2pMonitor monitor, WifiGlobals wifiGlobals, 53 WifiInjector wifiInjector) { 54 mMonitor = monitor; 55 mWifiGlobals = wifiGlobals; 56 mWifiInjector = wifiInjector; 57 mP2pIfaceHal = createP2pIfaceHalMockable(); 58 if (mP2pIfaceHal == null) { 59 Log.wtf(TAG, "Failed to get internal ISupplicantP2pIfaceHal instance."); 60 } 61 } 62 63 /** 64 * Enable verbose logging for all sub modules. 65 */ enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)66 public static void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) { 67 sVerboseLoggingEnabled = verboseEnabled; 68 sHalVerboseLoggingEnabled = halVerboseEnabled; 69 SupplicantP2pIfaceHalHidlImpl.enableVerboseLogging(verboseEnabled, halVerboseEnabled); 70 SupplicantP2pIfaceHalAidlImpl.enableVerboseLogging(verboseEnabled, halVerboseEnabled); 71 } 72 73 /** 74 * Set the debug log level for wpa_supplicant 75 * 76 * @param turnOnVerbose Whether to turn on verbose logging or not. 77 * @return true if request is sent successfully, false otherwise. 78 */ setLogLevel(boolean turnOnVerbose)79 public boolean setLogLevel(boolean turnOnVerbose) { 80 synchronized (mLock) { 81 String methodStr = "setLogLevel"; 82 if (mP2pIfaceHal == null) { 83 return handleNullHal(methodStr); 84 } 85 return mP2pIfaceHal.setLogLevel(turnOnVerbose, 86 mWifiGlobals.getShowKeyVerboseLoggingModeEnabled()); 87 } 88 } 89 90 /** 91 * Initialize the P2P Iface HAL. Creates the internal ISupplicantP2pIfaceHal 92 * object and calls its initialize method. 93 * 94 * @return true if the initialization succeeded 95 */ initialize()96 public boolean initialize() { 97 synchronized (mLock) { 98 if (sVerboseLoggingEnabled) { 99 Log.i(TAG, "Initializing SupplicantP2pIfaceHal."); 100 } 101 if (mP2pIfaceHal == null) { 102 Log.wtf(TAG, "Internal ISupplicantP2pIfaceHal instance does not exist."); 103 return false; 104 } 105 if (!mP2pIfaceHal.initialize()) { 106 Log.e(TAG, "Failed to init ISupplicantP2pIfaceHal, stopping startup."); 107 return false; 108 } 109 setLogLevel(sHalVerboseLoggingEnabled); 110 return true; 111 } 112 } 113 114 /** 115 * Wrapper function to create the ISupplicantP2pIfaceHal object. 116 * Created to be mockable in unit tests. 117 */ 118 @VisibleForTesting createP2pIfaceHalMockable()119 protected ISupplicantP2pIfaceHal createP2pIfaceHalMockable() { 120 synchronized (mLock) { 121 // Prefer AIDL implementation if service is declared. 122 if (SupplicantP2pIfaceHalAidlImpl.serviceDeclared()) { 123 Log.i(TAG, "Initializing SupplicantP2pIfaceHal using AIDL implementation."); 124 return new SupplicantP2pIfaceHalAidlImpl(mMonitor, mWifiInjector); 125 126 } else if (SupplicantP2pIfaceHalHidlImpl.serviceDeclared()) { 127 Log.i(TAG, "Initializing SupplicantP2pIfaceHal using HIDL implementation."); 128 return new SupplicantP2pIfaceHalHidlImpl(mMonitor); 129 } 130 Log.e(TAG, "No HIDL or AIDL service available for SupplicantP2pIfaceHal."); 131 return null; 132 } 133 } 134 135 /** 136 * Setup the P2P iface. 137 * 138 * @param ifaceName Name of the interface. 139 * @return true on success, false otherwise. 140 */ setupIface(@onNull String ifaceName)141 public boolean setupIface(@NonNull String ifaceName) { 142 synchronized (mLock) { 143 String methodStr = "setupIface"; 144 if (mP2pIfaceHal == null) { 145 return handleNullHal(methodStr); 146 } 147 return mP2pIfaceHal.setupIface(ifaceName); 148 } 149 } 150 151 /** 152 * Teardown the P2P interface. 153 * 154 * @param ifaceName Name of the interface. 155 * @return true on success, false otherwise. 156 */ teardownIface(@onNull String ifaceName)157 public boolean teardownIface(@NonNull String ifaceName) { 158 synchronized (mLock) { 159 String methodStr = "teardownIface"; 160 if (mP2pIfaceHal == null) { 161 return handleNullHal(methodStr); 162 } 163 return mP2pIfaceHal.teardownIface(ifaceName); 164 } 165 } 166 167 /** 168 * Signals whether initialization started successfully. 169 */ isInitializationStarted()170 public boolean isInitializationStarted() { 171 synchronized (mLock) { 172 String methodStr = "isInitializationStarted"; 173 if (mP2pIfaceHal == null) { 174 return handleNullHal(methodStr); 175 } 176 return mP2pIfaceHal.isInitializationStarted(); 177 } 178 } 179 180 /** 181 * Signals whether Initialization completed successfully. Only necessary for testing, is not 182 * needed to guard calls etc. 183 */ isInitializationComplete()184 public boolean isInitializationComplete() { 185 synchronized (mLock) { 186 String methodStr = "isInitializationComplete"; 187 if (mP2pIfaceHal == null) { 188 return handleNullHal(methodStr); 189 } 190 return mP2pIfaceHal.isInitializationComplete(); 191 } 192 } 193 194 /** 195 * Initiate a P2P service discovery with a (optional) timeout. 196 * 197 * @param timeout Max time to be spent is performing discovery. 198 * Set to 0 to indefinitely continue discovery until an explicit 199 * |stopFind| is sent. 200 * @return boolean value indicating whether operation was successful. 201 */ find(int timeout)202 public boolean find(int timeout) { 203 synchronized (mLock) { 204 String methodStr = "find"; 205 if (mP2pIfaceHal == null) { 206 return handleNullHal(methodStr); 207 } 208 return mP2pIfaceHal.find(timeout); 209 } 210 } 211 212 /** 213 * Initiate a P2P device discovery with a scan type, a (optional) frequency, and a (optional) 214 * timeout. 215 * 216 * @param type indicates what channels to scan. 217 * Valid values are {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} for doing full P2P scan, 218 * {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL} for scanning social channels, 219 * {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ} for scanning a specified frequency. 220 * @param freq is the frequency to be scanned. 221 * The possible values are: 222 * <ul> 223 * <li> A valid frequency for {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ}</li> 224 * <li> {@link WifiP2pManager#WIFI_P2P_SCAN_FREQ_UNSPECIFIED} for 225 * {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} and 226 * {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL}</li> 227 * </ul> 228 * @param timeout Max time to be spent is performing discovery. 229 * Set to 0 to indefinitely continue discovery until an explicit 230 * |stopFind| is sent. 231 * @return boolean value indicating whether operation was successful. 232 */ find(@ifiP2pManager.WifiP2pScanType int type, int freq, int timeout)233 public boolean find(@WifiP2pManager.WifiP2pScanType int type, int freq, int timeout) { 234 synchronized (mLock) { 235 String methodStr = "find"; 236 if (mP2pIfaceHal == null) { 237 return handleNullHal(methodStr); 238 } 239 return mP2pIfaceHal.find(type, freq, timeout); 240 } 241 } 242 243 /** 244 * Initiate P2P device discovery with config params. 245 * 246 * See comments for {@link ISupplicantP2pIfaceHal#findWithParams(WifiP2pDiscoveryConfig, int)}. 247 */ findWithParams(WifiP2pDiscoveryConfig config, int timeout)248 public boolean findWithParams(WifiP2pDiscoveryConfig config, int timeout) { 249 synchronized (mLock) { 250 String methodStr = "findWithParams"; 251 if (mP2pIfaceHal == null) { 252 return handleNullHal(methodStr); 253 } 254 return mP2pIfaceHal.findWithParams(config, timeout); 255 } 256 } 257 258 /** 259 * Stop an ongoing P2P service discovery. 260 * 261 * @return boolean value indicating whether operation was successful. 262 */ stopFind()263 public boolean stopFind() { 264 synchronized (mLock) { 265 String methodStr = "stopFind"; 266 if (mP2pIfaceHal == null) { 267 return handleNullHal(methodStr); 268 } 269 return mP2pIfaceHal.stopFind(); 270 } 271 } 272 273 /** 274 * Flush P2P peer table and state. 275 * 276 * @return boolean value indicating whether operation was successful. 277 */ flush()278 public boolean flush() { 279 synchronized (mLock) { 280 String methodStr = "flush"; 281 if (mP2pIfaceHal == null) { 282 return handleNullHal(methodStr); 283 } 284 return mP2pIfaceHal.flush(); 285 } 286 } 287 288 /** 289 * This command can be used to flush all services from the 290 * device. 291 * 292 * @return boolean value indicating whether operation was successful. 293 */ serviceFlush()294 public boolean serviceFlush() { 295 synchronized (mLock) { 296 String methodStr = "serviceFlush"; 297 if (mP2pIfaceHal == null) { 298 return handleNullHal(methodStr); 299 } 300 return mP2pIfaceHal.serviceFlush(); 301 } 302 } 303 304 /** 305 * Turn on/off power save mode for the interface. 306 * 307 * @param groupIfName Group interface name to use. 308 * @param enable Indicate if power save is to be turned on/off. 309 * 310 * @return boolean value indicating whether operation was successful. 311 */ setPowerSave(String groupIfName, boolean enable)312 public boolean setPowerSave(String groupIfName, boolean enable) { 313 synchronized (mLock) { 314 String methodStr = "setPowerSave"; 315 if (mP2pIfaceHal == null) { 316 return handleNullHal(methodStr); 317 } 318 return mP2pIfaceHal.setPowerSave(groupIfName, enable); 319 } 320 } 321 322 /** 323 * Set the Maximum idle time in seconds for P2P groups. 324 * This value controls how long a P2P group is maintained after there 325 * is no other members in the group. As a group owner, this means no 326 * associated stations in the group. As a P2P client, this means no 327 * group owner seen in scan results. 328 * 329 * @param groupIfName Group interface name to use. 330 * @param timeoutInSec Timeout value in seconds. 331 * 332 * @return boolean value indicating whether operation was successful. 333 */ setGroupIdle(String groupIfName, int timeoutInSec)334 public boolean setGroupIdle(String groupIfName, int timeoutInSec) { 335 synchronized (mLock) { 336 String methodStr = "setGroupIdle"; 337 if (mP2pIfaceHal == null) { 338 return handleNullHal(methodStr); 339 } 340 return mP2pIfaceHal.setGroupIdle(groupIfName, timeoutInSec); 341 } 342 } 343 344 /** 345 * Set the postfix to be used for P2P SSID's. 346 * 347 * @param postfix String to be appended to SSID. 348 * 349 * @return boolean value indicating whether operation was successful. 350 */ setSsidPostfix(String postfix)351 public boolean setSsidPostfix(String postfix) { 352 synchronized (mLock) { 353 String methodStr = "setSsidPostfix"; 354 if (mP2pIfaceHal == null) { 355 return handleNullHal(methodStr); 356 } 357 return mP2pIfaceHal.setSsidPostfix(postfix); 358 } 359 } 360 361 /** 362 * Start P2P group formation with a discovered P2P peer. This includes 363 * optional group owner negotiation, group interface setup, provisioning, 364 * and establishing data connection. 365 * 366 * @param config Configuration to use to connect to remote device. 367 * @param joinExistingGroup Indicates that this is a command to join an 368 * existing group as a client. It skips the group owner negotiation 369 * part. This must send a Provision Discovery Request message to the 370 * target group owner before associating for WPS provisioning. 371 * 372 * @return String containing generated pin, if selected provision method 373 * uses PIN. 374 */ connect(WifiP2pConfig config, boolean joinExistingGroup)375 public String connect(WifiP2pConfig config, boolean joinExistingGroup) { 376 synchronized (mLock) { 377 String methodStr = "connect"; 378 if (mP2pIfaceHal == null) { 379 handleNullHal(methodStr); 380 return null; 381 } 382 return mP2pIfaceHal.connect(config, joinExistingGroup); 383 } 384 } 385 386 /** 387 * Cancel an ongoing P2P group formation and joining-a-group related 388 * operation. This operation unauthorizes the specific peer device (if any 389 * had been authorized to start group formation), stops P2P find (if in 390 * progress), stops pending operations for join-a-group, and removes the 391 * P2P group interface (if one was used) that is in the WPS provisioning 392 * step. If the WPS provisioning step has been completed, the group is not 393 * terminated. 394 * 395 * @return boolean value indicating whether operation was successful. 396 */ cancelConnect()397 public boolean cancelConnect() { 398 synchronized (mLock) { 399 String methodStr = "cancelConnect"; 400 if (mP2pIfaceHal == null) { 401 return handleNullHal(methodStr); 402 } 403 return mP2pIfaceHal.cancelConnect(); 404 } 405 } 406 407 /** 408 * Send P2P provision discovery request to the specified peer. The 409 * parameters for this command are the P2P device address of the peer and the 410 * desired configuration method. 411 * 412 * @param config Config class describing peer setup. 413 * 414 * @return boolean value indicating whether operation was successful. 415 */ provisionDiscovery(WifiP2pConfig config)416 public boolean provisionDiscovery(WifiP2pConfig config) { 417 synchronized (mLock) { 418 String methodStr = "provisionDiscovery"; 419 if (mP2pIfaceHal == null) { 420 return handleNullHal(methodStr); 421 } 422 return mP2pIfaceHal.provisionDiscovery(config); 423 } 424 } 425 426 /** 427 * Invite a device to a persistent group. 428 * If the peer device is the group owner of the persistent group, the peer 429 * parameter is not needed. Otherwise it is used to specify which 430 * device to invite. |goDeviceAddress| parameter may be used to override 431 * the group owner device address for Invitation Request should it not be 432 * known for some reason (this should not be needed in most cases). 433 * 434 * @param group Group object to use. 435 * @param peerAddress MAC address of the device to invite. 436 * 437 * @return boolean value indicating whether operation was successful. 438 */ invite(WifiP2pGroup group, String peerAddress)439 public boolean invite(WifiP2pGroup group, String peerAddress) { 440 synchronized (mLock) { 441 String methodStr = "invite"; 442 if (mP2pIfaceHal == null) { 443 return handleNullHal(methodStr); 444 } 445 return mP2pIfaceHal.invite(group, peerAddress); 446 } 447 } 448 449 /** 450 * Reject connection attempt from a peer (specified with a device 451 * address). This is a mechanism to reject a pending group owner negotiation 452 * with a peer and request to automatically block any further connection or 453 * discovery of the peer. 454 * 455 * @param peerAddress MAC address of the device to reject. 456 * 457 * @return boolean value indicating whether operation was successful. 458 */ reject(String peerAddress)459 public boolean reject(String peerAddress) { 460 synchronized (mLock) { 461 String methodStr = "reject"; 462 if (mP2pIfaceHal == null) { 463 return handleNullHal(methodStr); 464 } 465 return mP2pIfaceHal.reject(peerAddress); 466 } 467 } 468 469 /** 470 * Gets the MAC address of the device. 471 * 472 * @return MAC address of the device. 473 */ getDeviceAddress()474 public String getDeviceAddress() { 475 synchronized (mLock) { 476 String methodStr = "getDeviceAddress"; 477 if (mP2pIfaceHal == null) { 478 handleNullHal(methodStr); 479 return null; 480 } 481 return mP2pIfaceHal.getDeviceAddress(); 482 } 483 } 484 485 /** 486 * Gets the operational SSID of the device. 487 * 488 * @param address MAC address of the peer. 489 * 490 * @return SSID of the device. 491 */ getSsid(String address)492 public String getSsid(String address) { 493 synchronized (mLock) { 494 String methodStr = "getSsid"; 495 if (mP2pIfaceHal == null) { 496 handleNullHal(methodStr); 497 return null; 498 } 499 return mP2pIfaceHal.getSsid(address); 500 } 501 } 502 503 /** 504 * Reinvoke a device from a persistent group. 505 * 506 * @param networkId Used to specify the persistent group. 507 * @param peerAddress MAC address of the device to reinvoke. 508 * 509 * @return true, if operation was successful. 510 */ reinvoke(int networkId, String peerAddress)511 public boolean reinvoke(int networkId, String peerAddress) { 512 synchronized (mLock) { 513 String methodStr = "reinvoke"; 514 if (mP2pIfaceHal == null) { 515 return handleNullHal(methodStr); 516 } 517 return mP2pIfaceHal.reinvoke(networkId, peerAddress); 518 } 519 } 520 521 /** 522 * Set up a P2P group owner manually (i.e., without group owner 523 * negotiation with a specific peer). This is also known as autonomous 524 * group owner. 525 * 526 * @param networkId Used to specify the restart of a persistent group. 527 * @param isPersistent Used to request a persistent group to be formed. 528 * 529 * @return true, if operation was successful. 530 */ groupAdd(int networkId, boolean isPersistent)531 public boolean groupAdd(int networkId, boolean isPersistent) { 532 synchronized (mLock) { 533 String methodStr = "groupAdd"; 534 if (mP2pIfaceHal == null) { 535 return handleNullHal(methodStr); 536 } 537 return mP2pIfaceHal.groupAdd(networkId, isPersistent); 538 } 539 } 540 541 /** 542 * Set up a P2P group owner manually. 543 * This is a helper method that invokes groupAdd(networkId, isPersistent) internally. 544 * 545 * @param isPersistent Used to request a persistent group to be formed. 546 * 547 * @return true, if operation was successful. 548 */ groupAdd(boolean isPersistent)549 public boolean groupAdd(boolean isPersistent) { 550 synchronized (mLock) { 551 // Supplicant expects networkId to be -1 if not supplied. 552 return groupAdd(-1, isPersistent); 553 } 554 } 555 556 /** 557 * Set up a P2P group as Group Owner or join a group with a configuration. 558 * 559 * @param networkName SSID of the group to be formed 560 * @param passphrase passphrase of the group to be formed 561 * @param isPersistent Used to request a persistent group to be formed. 562 * @param freq prefered frequencty or band of the group to be formed 563 * @param peerAddress peerAddress Group Owner MAC address, only applied for Group Client. 564 * If the MAC is "00:00:00:00:00:00", the device will try to find a peer 565 * whose SSID matches ssid. 566 * @param join join a group or create a group 567 * 568 * @return true, if operation was successful. 569 */ groupAdd(String networkName, String passphrase, boolean isPersistent, int freq, String peerAddress, boolean join)570 public boolean groupAdd(String networkName, String passphrase, 571 boolean isPersistent, int freq, String peerAddress, boolean join) { 572 synchronized (mLock) { 573 String methodStr = "groupAdd"; 574 if (mP2pIfaceHal == null) { 575 return handleNullHal(methodStr); 576 } 577 return mP2pIfaceHal.groupAdd(networkName, passphrase, 578 isPersistent, freq, peerAddress, join); 579 } 580 } 581 582 /** 583 * Terminate a P2P group. If a new virtual network interface was used for 584 * the group, it must also be removed. The network interface name of the 585 * group interface is used as a parameter for this command. 586 * 587 * @param groupName Group interface name to use. 588 * 589 * @return true, if operation was successful. 590 */ groupRemove(String groupName)591 public boolean groupRemove(String groupName) { 592 synchronized (mLock) { 593 String methodStr = "groupRemove"; 594 if (mP2pIfaceHal == null) { 595 return handleNullHal(methodStr); 596 } 597 return mP2pIfaceHal.groupRemove(groupName); 598 } 599 } 600 601 /** 602 * Gets the capability of the group which the device is a 603 * member of. 604 * 605 * @param peerAddress MAC address of the peer. 606 * 607 * @return combination of |GroupCapabilityMask| values. 608 */ getGroupCapability(String peerAddress)609 public int getGroupCapability(String peerAddress) { 610 synchronized (mLock) { 611 String methodStr = "getGroupCapability"; 612 if (mP2pIfaceHal == null) { 613 handleNullHal(methodStr); 614 return -1; 615 } 616 return mP2pIfaceHal.getGroupCapability(peerAddress); 617 } 618 } 619 620 /** 621 * Configure Extended Listen Timing. See comments for 622 * {@link ISupplicantP2pIfaceHal#configureExtListen(boolean, int, int, WifiP2pExtListenParams)} 623 * 624 * @return true, if operation was successful. 625 */ configureExtListen(boolean enable, int periodInMillis, int intervalInMillis, @Nullable WifiP2pExtListenParams extListenParams)626 public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis, 627 @Nullable WifiP2pExtListenParams extListenParams) { 628 synchronized (mLock) { 629 String methodStr = "configureExtListen"; 630 if (mP2pIfaceHal == null) { 631 return handleNullHal(methodStr); 632 } 633 return mP2pIfaceHal.configureExtListen( 634 enable, periodInMillis, intervalInMillis, extListenParams); 635 } 636 } 637 638 /** 639 * Set P2P Listen channel. 640 * 641 * @param listenChannel Wifi channel. eg, 1, 6, 11. 642 * 643 * @return true, if operation was successful. 644 */ setListenChannel(int listenChannel)645 public boolean setListenChannel(int listenChannel) { 646 synchronized (mLock) { 647 String methodStr = "setListenChannel"; 648 if (mP2pIfaceHal == null) { 649 return handleNullHal(methodStr); 650 } 651 return mP2pIfaceHal.setListenChannel(listenChannel); 652 } 653 } 654 655 /** 656 * Set P2P operating channel. 657 * 658 * @param operatingChannel the desired operating channel. 659 * @param unsafeChannels channels which p2p cannot use. 660 * 661 * @return true, if operation was successful. 662 */ setOperatingChannel(int operatingChannel, @NonNull List<CoexUnsafeChannel> unsafeChannels)663 public boolean setOperatingChannel(int operatingChannel, 664 @NonNull List<CoexUnsafeChannel> unsafeChannels) { 665 synchronized (mLock) { 666 String methodStr = "setOperatingChannel"; 667 if (mP2pIfaceHal == null) { 668 return handleNullHal(methodStr); 669 } 670 return mP2pIfaceHal.setOperatingChannel(operatingChannel, unsafeChannels); 671 } 672 } 673 674 /** 675 * This command can be used to add a upnp/bonjour service. 676 * 677 * @param servInfo List of service queries. 678 * 679 * @return true, if operation was successful. 680 */ serviceAdd(WifiP2pServiceInfo servInfo)681 public boolean serviceAdd(WifiP2pServiceInfo servInfo) { 682 synchronized (mLock) { 683 String methodStr = "serviceAdd"; 684 if (mP2pIfaceHal == null) { 685 return handleNullHal(methodStr); 686 } 687 return mP2pIfaceHal.serviceAdd(servInfo); 688 } 689 } 690 691 /** 692 * This command can be used to remove a upnp/bonjour service. 693 * 694 * @param servInfo List of service queries. 695 * 696 * @return true, if operation was successful. 697 */ serviceRemove(WifiP2pServiceInfo servInfo)698 public boolean serviceRemove(WifiP2pServiceInfo servInfo) { 699 synchronized (mLock) { 700 String methodStr = "serviceRemove"; 701 if (mP2pIfaceHal == null) { 702 return handleNullHal(methodStr); 703 } 704 return mP2pIfaceHal.serviceRemove(servInfo); 705 } 706 } 707 708 /** 709 * Schedule a P2P service discovery request. The parameters for this command 710 * are the device address of the peer device (or 00:00:00:00:00:00 for 711 * wildcard query that is sent to every discovered P2P peer that supports 712 * service discovery) and P2P Service Query TLV(s) as hexdump. 713 * 714 * @param peerAddress MAC address of the device to discover. 715 * @param query Hex dump of the query data. 716 * @return identifier Identifier for the request. Can be used to cancel the 717 * request. 718 */ requestServiceDiscovery(String peerAddress, String query)719 public String requestServiceDiscovery(String peerAddress, String query) { 720 synchronized (mLock) { 721 String methodStr = "requestServiceDiscovery"; 722 if (mP2pIfaceHal == null) { 723 handleNullHal(methodStr); 724 return null; 725 } 726 return mP2pIfaceHal.requestServiceDiscovery(peerAddress, query); 727 } 728 } 729 730 /** 731 * Cancel a previous service discovery request. 732 * 733 * @param identifier Identifier for the request to cancel. 734 * @return true, if operation was successful. 735 */ cancelServiceDiscovery(String identifier)736 public boolean cancelServiceDiscovery(String identifier) { 737 synchronized (mLock) { 738 String methodStr = "cancelServiceDiscovery"; 739 if (mP2pIfaceHal == null) { 740 return handleNullHal(methodStr); 741 } 742 return mP2pIfaceHal.cancelServiceDiscovery(identifier); 743 } 744 } 745 746 /** 747 * Send driver command to set Miracast mode. 748 * 749 * @param mode Mode of Miracast. 750 * @return true, if operation was successful. 751 */ setMiracastMode(int mode)752 public boolean setMiracastMode(int mode) { 753 synchronized (mLock) { 754 String methodStr = "setMiracastMode"; 755 if (mP2pIfaceHal == null) { 756 return handleNullHal(methodStr); 757 } 758 return mP2pIfaceHal.setMiracastMode(mode); 759 } 760 } 761 762 /** 763 * Initiate WPS Push Button setup. 764 * The PBC operation requires that a button is also pressed at the 765 * AP/Registrar at about the same time (2 minute window). 766 * 767 * @param groupIfName Group interface name to use. 768 * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard. 769 * @return true, if operation was successful. 770 */ startWpsPbc(String groupIfName, String bssid)771 public boolean startWpsPbc(String groupIfName, String bssid) { 772 synchronized (mLock) { 773 String methodStr = "startWpsPbc"; 774 if (mP2pIfaceHal == null) { 775 return handleNullHal(methodStr); 776 } 777 return mP2pIfaceHal.startWpsPbc(groupIfName, bssid); 778 } 779 } 780 781 /** 782 * Initiate WPS Pin Keypad setup. 783 * 784 * @param groupIfName Group interface name to use. 785 * @param pin 8 digit pin to be used. 786 * @return true, if operation was successful. 787 */ startWpsPinKeypad(String groupIfName, String pin)788 public boolean startWpsPinKeypad(String groupIfName, String pin) { 789 synchronized (mLock) { 790 String methodStr = "startWpsPinKeypad"; 791 if (mP2pIfaceHal == null) { 792 return handleNullHal(methodStr); 793 } 794 return mP2pIfaceHal.startWpsPinKeypad(groupIfName, pin); 795 } 796 } 797 798 /** 799 * Initiate WPS Pin Display setup. 800 * 801 * @param groupIfName Group interface name to use. 802 * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard. 803 * @return generated pin if operation was successful, null otherwise. 804 */ startWpsPinDisplay(String groupIfName, String bssid)805 public String startWpsPinDisplay(String groupIfName, String bssid) { 806 synchronized (mLock) { 807 String methodStr = "startWpsPinDisplay"; 808 if (mP2pIfaceHal == null) { 809 handleNullHal(methodStr); 810 return null; 811 } 812 return mP2pIfaceHal.startWpsPinDisplay(groupIfName, bssid); 813 } 814 } 815 816 /** 817 * Cancel any ongoing WPS operations. 818 * 819 * @param groupIfName Group interface name to use. 820 * @return true, if operation was successful. 821 */ cancelWps(String groupIfName)822 public boolean cancelWps(String groupIfName) { 823 synchronized (mLock) { 824 String methodStr = "cancelWps"; 825 if (mP2pIfaceHal == null) { 826 return handleNullHal(methodStr); 827 } 828 return mP2pIfaceHal.cancelWps(groupIfName); 829 } 830 } 831 832 /** 833 * Enable/Disable Wifi Display. 834 * 835 * @param enable true to enable, false to disable. 836 * @return true, if operation was successful. 837 */ enableWfd(boolean enable)838 public boolean enableWfd(boolean enable) { 839 synchronized (mLock) { 840 String methodStr = "enableWfd"; 841 if (mP2pIfaceHal == null) { 842 return handleNullHal(methodStr); 843 } 844 return mP2pIfaceHal.enableWfd(enable); 845 } 846 } 847 848 /** 849 * Set Wifi Display device info. 850 * 851 * @param info WFD device info as described in section 5.1.2 of WFD technical 852 * specification v1.0.0. 853 * @return true, if operation was successful. 854 */ setWfdDeviceInfo(String info)855 public boolean setWfdDeviceInfo(String info) { 856 synchronized (mLock) { 857 String methodStr = "setWfdDeviceInfo"; 858 if (mP2pIfaceHal == null) { 859 return handleNullHal(methodStr); 860 } 861 return mP2pIfaceHal.setWfdDeviceInfo(info); 862 } 863 } 864 865 /** 866 * Remove network with provided id. 867 * 868 * @param networkId Id of the network to lookup. 869 * @return true, if operation was successful. 870 */ removeNetwork(int networkId)871 public boolean removeNetwork(int networkId) { 872 synchronized (mLock) { 873 String methodStr = "removeNetwork"; 874 if (mP2pIfaceHal == null) { 875 return handleNullHal(methodStr); 876 } 877 return mP2pIfaceHal.removeNetwork(networkId); 878 } 879 } 880 881 /** 882 * Get the persistent group list from wpa_supplicant's p2p mgmt interface 883 * 884 * @param groups WifiP2pGroupList to store persistent groups in 885 * @return true, if list has been modified. 886 */ loadGroups(WifiP2pGroupList groups)887 public boolean loadGroups(WifiP2pGroupList groups) { 888 synchronized (mLock) { 889 String methodStr = "loadGroups"; 890 if (mP2pIfaceHal == null) { 891 return handleNullHal(methodStr); 892 } 893 return mP2pIfaceHal.loadGroups(groups); 894 } 895 } 896 897 /** 898 * Set WPS device name. 899 * 900 * @param name String to be set. 901 * @return true if request is sent successfully, false otherwise. 902 */ setWpsDeviceName(String name)903 public boolean setWpsDeviceName(String name) { 904 synchronized (mLock) { 905 String methodStr = "setWpsDeviceName"; 906 if (mP2pIfaceHal == null) { 907 return handleNullHal(methodStr); 908 } 909 return mP2pIfaceHal.setWpsDeviceName(name); 910 } 911 } 912 913 /** 914 * Set WPS device type. 915 * 916 * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg> 917 * @return true if request is sent successfully, false otherwise. 918 */ setWpsDeviceType(String typeStr)919 public boolean setWpsDeviceType(String typeStr) { 920 synchronized (mLock) { 921 String methodStr = "setWpsDeviceType"; 922 if (mP2pIfaceHal == null) { 923 return handleNullHal(methodStr); 924 } 925 return mP2pIfaceHal.setWpsDeviceType(typeStr); 926 } 927 } 928 929 /** 930 * Set WPS config methods 931 * 932 * @param configMethodsStr List of config methods. 933 * @return true if request is sent successfully, false otherwise. 934 */ setWpsConfigMethods(String configMethodsStr)935 public boolean setWpsConfigMethods(String configMethodsStr) { 936 synchronized (mLock) { 937 String methodStr = "setWpsConfigMethods"; 938 if (mP2pIfaceHal == null) { 939 return handleNullHal(methodStr); 940 } 941 return mP2pIfaceHal.setWpsConfigMethods(configMethodsStr); 942 } 943 } 944 945 /** 946 * Get NFC handover request message. 947 * 948 * @return select message if created successfully, null otherwise. 949 */ getNfcHandoverRequest()950 public String getNfcHandoverRequest() { 951 synchronized (mLock) { 952 String methodStr = "getNfcHandoverRequest"; 953 if (mP2pIfaceHal == null) { 954 handleNullHal(methodStr); 955 return null; 956 } 957 return mP2pIfaceHal.getNfcHandoverRequest(); 958 } 959 } 960 961 /** 962 * Get NFC handover select message. 963 * 964 * @return select message if created successfully, null otherwise. 965 */ getNfcHandoverSelect()966 public String getNfcHandoverSelect() { 967 synchronized (mLock) { 968 String methodStr = "getNfcHandoverSelect"; 969 if (mP2pIfaceHal == null) { 970 handleNullHal(methodStr); 971 return null; 972 } 973 return mP2pIfaceHal.getNfcHandoverSelect(); 974 } 975 } 976 977 /** 978 * Report NFC handover select message. 979 * 980 * @return true if reported successfully, false otherwise. 981 */ initiatorReportNfcHandover(String selectMessage)982 public boolean initiatorReportNfcHandover(String selectMessage) { 983 synchronized (mLock) { 984 String methodStr = "initiatorReportNfcHandover"; 985 if (mP2pIfaceHal == null) { 986 return handleNullHal(methodStr); 987 } 988 return mP2pIfaceHal.initiatorReportNfcHandover(selectMessage); 989 } 990 } 991 992 /** 993 * Report NFC handover request message. 994 * 995 * @return true if reported successfully, false otherwise. 996 */ responderReportNfcHandover(String requestMessage)997 public boolean responderReportNfcHandover(String requestMessage) { 998 synchronized (mLock) { 999 String methodStr = "responderReportNfcHandover"; 1000 if (mP2pIfaceHal == null) { 1001 return handleNullHal(methodStr); 1002 } 1003 return mP2pIfaceHal.responderReportNfcHandover(requestMessage); 1004 } 1005 } 1006 1007 /** 1008 * Set the client list for the provided network. 1009 * 1010 * @param networkId Id of the network. 1011 * @param clientListStr Space separated list of clients. 1012 * @return true, if operation was successful. 1013 */ setClientList(int networkId, String clientListStr)1014 public boolean setClientList(int networkId, String clientListStr) { 1015 synchronized (mLock) { 1016 String methodStr = "setClientList"; 1017 if (mP2pIfaceHal == null) { 1018 return handleNullHal(methodStr); 1019 } 1020 return mP2pIfaceHal.setClientList(networkId, clientListStr); 1021 } 1022 } 1023 1024 /** 1025 * Set the client list for the provided network. 1026 * 1027 * @param networkId Id of the network. 1028 * @return Space separated list of clients if successful, null otherwise. 1029 */ getClientList(int networkId)1030 public String getClientList(int networkId) { 1031 synchronized (mLock) { 1032 String methodStr = "getClientList"; 1033 if (mP2pIfaceHal == null) { 1034 handleNullHal(methodStr); 1035 return null; 1036 } 1037 return mP2pIfaceHal.getClientList(networkId); 1038 } 1039 } 1040 1041 /** 1042 * Persist the current configurations to disk. 1043 * 1044 * @return true, if operation was successful. 1045 */ saveConfig()1046 public boolean saveConfig() { 1047 synchronized (mLock) { 1048 String methodStr = "saveConfig"; 1049 if (mP2pIfaceHal == null) { 1050 return handleNullHal(methodStr); 1051 } 1052 return mP2pIfaceHal.saveConfig(); 1053 } 1054 } 1055 1056 /** 1057 * Enable/Disable P2P MAC randomization. 1058 * 1059 * @param enable true to enable, false to disable. 1060 * @return true, if operation was successful. 1061 */ setMacRandomization(boolean enable)1062 public boolean setMacRandomization(boolean enable) { 1063 synchronized (mLock) { 1064 String methodStr = "setMacRandomization"; 1065 if (mP2pIfaceHal == null) { 1066 return handleNullHal(methodStr); 1067 } 1068 return mP2pIfaceHal.setMacRandomization(enable); 1069 } 1070 } 1071 1072 /** 1073 * Set Wifi Display R2 device info. 1074 * 1075 * @param info WFD R2 device info as described in section 5.1.12 of WFD technical 1076 * specification v2.1. 1077 * @return true, if operation was successful. 1078 */ setWfdR2DeviceInfo(String info)1079 public boolean setWfdR2DeviceInfo(String info) { 1080 synchronized (mLock) { 1081 String methodStr = "setWfdR2DeviceInfo"; 1082 if (mP2pIfaceHal == null) { 1083 return handleNullHal(methodStr); 1084 } 1085 return mP2pIfaceHal.setWfdR2DeviceInfo(info); 1086 } 1087 } 1088 1089 /** 1090 * Remove the client with the MAC address from the group. 1091 * 1092 * @param peerAddress Mac address of the client. 1093 * @param isLegacyClient Indicate if client is a legacy client or not. 1094 * @return true if success 1095 */ removeClient(String peerAddress, boolean isLegacyClient)1096 public boolean removeClient(String peerAddress, boolean isLegacyClient) { 1097 synchronized (mLock) { 1098 String methodStr = "removeClient"; 1099 if (mP2pIfaceHal == null) { 1100 return handleNullHal(methodStr); 1101 } 1102 return mP2pIfaceHal.removeClient(peerAddress, isLegacyClient); 1103 } 1104 } 1105 1106 /** 1107 * Set vendor-specific information elements to wpa_supplicant. 1108 * 1109 * @param vendorElements The list of vendor-specific information elements. 1110 * 1111 * @return boolean The value indicating whether operation was successful. 1112 */ setVendorElements(Set<ScanResult.InformationElement> vendorElements)1113 public boolean setVendorElements(Set<ScanResult.InformationElement> vendorElements) { 1114 synchronized (mLock) { 1115 String methodStr = "setVendorElements"; 1116 if (mP2pIfaceHal == null) { 1117 return handleNullHal(methodStr); 1118 } 1119 return mP2pIfaceHal.setVendorElements(vendorElements); 1120 } 1121 } 1122 1123 /** 1124 * Get the supported features. 1125 * 1126 * @return bitmask defined by WifiP2pManager.FEATURE_* 1127 */ getSupportedFeatures()1128 public long getSupportedFeatures() { 1129 if (mP2pIfaceHal instanceof SupplicantP2pIfaceHalHidlImpl) return 0L; 1130 return ((SupplicantP2pIfaceHalAidlImpl) mP2pIfaceHal).getSupportedFeatures(); 1131 } 1132 handleNullHal(String methodStr)1133 private boolean handleNullHal(String methodStr) { 1134 Log.e(TAG, "Cannot call " + methodStr + " because HAL object is null."); 1135 return false; 1136 } 1137 1138 /** 1139 * Configure the IP addresses in supplicant for P2P GO to provide the IP address to 1140 * client in EAPOL handshake. Refer Wi-Fi P2P Technical Specification v1.7 - Section 4.2.8 1141 * IP Address Allocation in EAPOL-Key Frames (4-Way Handshake) for more details. 1142 * The IP addresses are IPV4 addresses and higher-order address bytes are in the 1143 * lower-order int bytes (e.g. 1.2.3.4 is represented as 0x04030201) 1144 * 1145 * @param ipAddressGo The P2P Group Owner IP address. 1146 * @param ipAddressMask The P2P Group owner subnet mask. 1147 * @param ipAddressStart The starting address in the IP address pool. 1148 * @param ipAddressEnd The ending address in the IP address pool. 1149 * @return boolean value indicating whether operation was successful. 1150 */ configureEapolIpAddressAllocationParams(int ipAddressGo, int ipAddressMask, int ipAddressStart, int ipAddressEnd)1151 public boolean configureEapolIpAddressAllocationParams(int ipAddressGo, int ipAddressMask, 1152 int ipAddressStart, int ipAddressEnd) { 1153 synchronized (mLock) { 1154 String methodStr = "configureEapolIpAddressAllocationParams"; 1155 if (mP2pIfaceHal == null) { 1156 return handleNullHal(methodStr); 1157 } 1158 return mP2pIfaceHal.configureEapolIpAddressAllocationParams(ipAddressGo, ipAddressMask, 1159 ipAddressStart, ipAddressEnd); 1160 } 1161 } 1162 1163 /** 1164 * Terminate the supplicant daemon & wait for its death. 1165 */ terminate()1166 public void terminate() { 1167 synchronized (mLock) { 1168 String methodStr = "terminate"; 1169 if (mP2pIfaceHal == null) { 1170 handleNullHal(methodStr); 1171 return; 1172 } 1173 mP2pIfaceHal.terminate(); 1174 } 1175 } 1176 1177 /** 1178 * Registers a death notification for supplicant. 1179 * @return Returns true on success. 1180 */ registerDeathHandler(@onNull WifiNative.SupplicantDeathEventHandler handler)1181 public boolean registerDeathHandler(@NonNull WifiNative.SupplicantDeathEventHandler handler) { 1182 synchronized (mLock) { 1183 String methodStr = "registerDeathHandler"; 1184 if (mP2pIfaceHal == null) { 1185 return handleNullHal(methodStr); 1186 } 1187 return mP2pIfaceHal.registerDeathHandler(handler); 1188 } 1189 } 1190 1191 /** 1192 * Deregisters a death notification for supplicant. 1193 * @return Returns true on success. 1194 */ deregisterDeathHandler()1195 public boolean deregisterDeathHandler() { 1196 synchronized (mLock) { 1197 String methodStr = "deregisterDeathHandler"; 1198 if (mP2pIfaceHal == null) { 1199 return handleNullHal(methodStr); 1200 } 1201 return mP2pIfaceHal.deregisterDeathHandler(); 1202 } 1203 } 1204 } 1205