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