1 /* 2 * Copyright (C) 2008 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 static com.android.server.wifi.HalDeviceManager.HDM_CREATE_IFACE_P2P; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.net.wifi.CoexUnsafeChannel; 24 import android.net.wifi.ScanResult; 25 import android.net.wifi.nl80211.WifiNl80211Manager; 26 import android.net.wifi.p2p.WifiP2pConfig; 27 import android.net.wifi.p2p.WifiP2pGroup; 28 import android.net.wifi.p2p.WifiP2pGroupList; 29 import android.net.wifi.p2p.WifiP2pManager; 30 import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; 31 import android.os.Handler; 32 import android.os.WorkSource; 33 import android.text.TextUtils; 34 import android.util.Log; 35 36 import com.android.server.wifi.HalDeviceManager; 37 import com.android.server.wifi.PropertyService; 38 import com.android.server.wifi.WifiMetrics; 39 import com.android.server.wifi.WifiNative; 40 import com.android.server.wifi.WifiVendorHal; 41 42 import java.util.HashSet; 43 import java.util.List; 44 import java.util.Set; 45 46 /** 47 * Native calls for bring up/shut down of the supplicant daemon and for 48 * sending requests to the supplicant daemon 49 */ 50 public class WifiP2pNative { 51 private static final String TAG = "WifiP2pNative"; 52 private boolean mVerboseLoggingEnabled = false; 53 private final SupplicantP2pIfaceHal mSupplicantP2pIfaceHal; 54 private final WifiNative mWifiNative; 55 private final WifiMetrics mWifiMetrics; 56 private final WifiNl80211Manager mWifiNl80211Manager; 57 private final HalDeviceManager mHalDeviceManager; 58 private final PropertyService mPropertyService; 59 private final WifiVendorHal mWifiVendorHal; 60 private String mP2pIfaceName; 61 private InterfaceDestroyedListenerInternal mInterfaceDestroyedListener; 62 63 64 // Internal callback registered to HalDeviceManager. 65 private class InterfaceDestroyedListenerInternal implements 66 HalDeviceManager.InterfaceDestroyedListener { 67 private final HalDeviceManager.InterfaceDestroyedListener mExternalListener; 68 private boolean mValid; 69 InterfaceDestroyedListenerInternal( HalDeviceManager.InterfaceDestroyedListener externalListener)70 InterfaceDestroyedListenerInternal( 71 HalDeviceManager.InterfaceDestroyedListener externalListener) { 72 mExternalListener = externalListener; 73 mValid = true; 74 } 75 teardownAndInvalidate(@ullable String ifaceName)76 public void teardownAndInvalidate(@Nullable String ifaceName) { 77 if (!TextUtils.isEmpty(ifaceName)) { 78 mSupplicantP2pIfaceHal.teardownIface(ifaceName); 79 } 80 mP2pIfaceName = null; 81 mValid = false; 82 } 83 84 @Override onDestroyed(String ifaceName)85 public void onDestroyed(String ifaceName) { 86 Log.d(TAG, "P2P InterfaceDestroyedListener " + ifaceName); 87 if (!mValid) { 88 Log.d(TAG, "Ignoring stale interface destroyed listener"); 89 return; 90 } 91 teardownAndInvalidate(ifaceName); 92 mExternalListener.onDestroyed(ifaceName); 93 } 94 } 95 WifiP2pNative( WifiNl80211Manager wifiNl80211Manager, WifiNative wifiNative, WifiMetrics wifiMetrics, WifiVendorHal wifiVendorHal, SupplicantP2pIfaceHal p2pIfaceHal, HalDeviceManager halDeviceManager, PropertyService propertyService)96 public WifiP2pNative( 97 WifiNl80211Manager wifiNl80211Manager, 98 WifiNative wifiNative, 99 WifiMetrics wifiMetrics, 100 WifiVendorHal wifiVendorHal, 101 SupplicantP2pIfaceHal p2pIfaceHal, 102 HalDeviceManager halDeviceManager, 103 PropertyService propertyService) { 104 mWifiNative = wifiNative; 105 mWifiMetrics = wifiMetrics; 106 mWifiNl80211Manager = wifiNl80211Manager; 107 mWifiVendorHal = wifiVendorHal; 108 mSupplicantP2pIfaceHal = p2pIfaceHal; 109 mHalDeviceManager = halDeviceManager; 110 mPropertyService = propertyService; 111 } 112 113 /** 114 * Enable verbose logging for all sub modules. 115 */ enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)116 public void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) { 117 mVerboseLoggingEnabled = verboseEnabled; 118 SupplicantP2pIfaceHal.enableVerboseLogging(verboseEnabled, halVerboseEnabled); 119 } 120 121 private static final int CONNECT_TO_SUPPLICANT_SAMPLING_INTERVAL_MS = 100; 122 private static final int CONNECT_TO_SUPPLICANT_MAX_SAMPLES = 50; 123 /** 124 * This method is called to wait for establishing connection to wpa_supplicant. 125 * 126 * @return true if connection is established, false otherwise. 127 */ waitForSupplicantConnection()128 private boolean waitForSupplicantConnection() { 129 // Start initialization if not already started. 130 if (!mSupplicantP2pIfaceHal.isInitializationStarted() 131 && !mSupplicantP2pIfaceHal.initialize()) { 132 return false; 133 } 134 int connectTries = 0; 135 while (connectTries++ < CONNECT_TO_SUPPLICANT_MAX_SAMPLES) { 136 // Check if the initialization is complete. 137 if (mSupplicantP2pIfaceHal.isInitializationComplete()) { 138 return true; 139 } 140 try { 141 Thread.sleep(CONNECT_TO_SUPPLICANT_SAMPLING_INTERVAL_MS); 142 } catch (InterruptedException ignore) { 143 } 144 } 145 return false; 146 } 147 148 /** 149 * Close supplicant connection. 150 */ closeSupplicantConnection()151 public void closeSupplicantConnection() { 152 // Nothing to do for HAL. 153 } 154 155 /** 156 * Returns whether HAL is supported on this device or not. 157 */ isHalInterfaceSupported()158 public boolean isHalInterfaceSupported() { 159 return mHalDeviceManager.isSupported(); 160 } 161 162 private static final String P2P_IFACE_NAME = "p2p0"; 163 private static final String P2P_INTERFACE_PROPERTY = "wifi.direct.interface"; 164 165 /** 166 * Helper function to handle creation of P2P iface. 167 * For devices which do not the support the HAL, this will bypass HalDeviceManager & 168 * teardown any existing iface. 169 */ createP2pIface(Handler handler, WorkSource requestorWs)170 private String createP2pIface(Handler handler, WorkSource requestorWs) { 171 if (mHalDeviceManager.isSupported()) { 172 mP2pIfaceName = mHalDeviceManager.createP2pIface( 173 mInterfaceDestroyedListener, handler, requestorWs); 174 if (mP2pIfaceName == null) { 175 Log.e(TAG, "Failed to create P2p iface in HalDeviceManager"); 176 return null; 177 } 178 return mP2pIfaceName; 179 } else { 180 Log.i(TAG, "Vendor Hal is not supported, ignoring createP2pIface."); 181 return mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); 182 } 183 } 184 185 /** 186 * Setup Interface for P2p mode. 187 * 188 * @param destroyedListener Listener to be invoked when the interface is destroyed. 189 * @param handler Handler to be used for invoking the destroyedListener. 190 * @param requestorWs Worksource to attribute the request to. 191 */ setupInterface( @ullable HalDeviceManager.InterfaceDestroyedListener destroyedListener, @NonNull Handler handler, @NonNull WorkSource requestorWs)192 public String setupInterface( 193 @Nullable HalDeviceManager.InterfaceDestroyedListener destroyedListener, 194 @NonNull Handler handler, @NonNull WorkSource requestorWs) { 195 Log.d(TAG, "Setup P2P interface"); 196 if (mP2pIfaceName == null) { 197 mInterfaceDestroyedListener = (null == destroyedListener) 198 ? null 199 : new InterfaceDestroyedListenerInternal(destroyedListener); 200 String ifaceName = createP2pIface(handler, requestorWs); 201 if (ifaceName == null) { 202 Log.e(TAG, "Failed to create P2p iface"); 203 if (mHalDeviceManager.isItPossibleToCreateIface(HDM_CREATE_IFACE_P2P, 204 requestorWs)) { 205 mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToHal(); 206 } 207 return null; 208 } 209 if (!waitForSupplicantConnection()) { 210 Log.e(TAG, "Failed to connect to supplicant"); 211 teardownInterface(); 212 mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); 213 return null; 214 } 215 if (!mSupplicantP2pIfaceHal.setupIface(ifaceName)) { 216 Log.e(TAG, "Failed to setup P2p iface in supplicant"); 217 teardownInterface(); 218 mWifiMetrics.incrementNumSetupP2pInterfaceFailureDueToSupplicant(); 219 return null; 220 } 221 Log.i(TAG, "P2P interface setup completed"); 222 return ifaceName; 223 } else { 224 Log.i(TAG, "P2P interface already exists"); 225 return mHalDeviceManager.isSupported() 226 ? mP2pIfaceName 227 : mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); 228 } 229 } 230 231 /** 232 * Teardown P2p interface. 233 */ teardownInterface()234 public void teardownInterface() { 235 Log.d(TAG, "Teardown P2P interface"); 236 if (mHalDeviceManager.isSupported()) { 237 if (mP2pIfaceName != null) { 238 mHalDeviceManager.removeP2pIface(mP2pIfaceName); 239 if (null != mInterfaceDestroyedListener) { 240 mInterfaceDestroyedListener.teardownAndInvalidate(mP2pIfaceName); 241 } 242 Log.i(TAG, "P2P interface teardown completed"); 243 } 244 } else { 245 Log.i(TAG, "HAL is not supported. Destroy listener for the interface."); 246 String ifaceName = mPropertyService.getString(P2P_INTERFACE_PROPERTY, P2P_IFACE_NAME); 247 if (null != mInterfaceDestroyedListener) { 248 mInterfaceDestroyedListener.teardownAndInvalidate(ifaceName); 249 } 250 } 251 } 252 253 /** 254 * Replace requestorWs in-place when iface is already enabled. 255 */ replaceRequestorWs(WorkSource requestorWs)256 public boolean replaceRequestorWs(WorkSource requestorWs) { 257 if (mHalDeviceManager.isSupported()) { 258 if (mP2pIfaceName == null) return false; 259 return mHalDeviceManager.replaceRequestorWsForP2pIface(mP2pIfaceName, requestorWs); 260 } else { 261 Log.i(TAG, "HAL is not supported. Ignore replace requestorWs"); 262 return true; 263 } 264 } 265 266 /** 267 * Get the supported features. 268 * 269 * The features can be retrieved regardless of whether the P2P interface is up. 270 * 271 * Note that the feature set may be incomplete if Supplicant has not been started 272 * on the device yet. 273 * 274 * @return bitmask defined by WifiP2pManager.FEATURE_* 275 */ getSupportedFeatures()276 public long getSupportedFeatures() { 277 return mSupplicantP2pIfaceHal.getSupportedFeatures(); 278 } 279 280 /** 281 * Set WPS device name. 282 * 283 * @param name String to be set. 284 * @return true if request is sent successfully, false otherwise. 285 */ setDeviceName(String name)286 public boolean setDeviceName(String name) { 287 return mSupplicantP2pIfaceHal.setWpsDeviceName(name); 288 } 289 290 /** 291 * Populate list of available networks or update existing list. 292 * 293 * @return true, if list has been modified. 294 */ p2pListNetworks(WifiP2pGroupList groups)295 public boolean p2pListNetworks(WifiP2pGroupList groups) { 296 return mSupplicantP2pIfaceHal.loadGroups(groups); 297 } 298 299 /** 300 * Initiate WPS Push Button setup. 301 * The PBC operation requires that a button is also pressed at the 302 * AP/Registrar at about the same time (2 minute window). 303 * 304 * @param iface Group interface name to use. 305 * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard. 306 * @return true, if operation was successful. 307 */ startWpsPbc(String iface, String bssid)308 public boolean startWpsPbc(String iface, String bssid) { 309 return mSupplicantP2pIfaceHal.startWpsPbc(iface, bssid); 310 } 311 312 /** 313 * Initiate WPS Pin Keypad setup. 314 * 315 * @param iface Group interface name to use. 316 * @param pin 8 digit pin to be used. 317 * @return true, if operation was successful. 318 */ startWpsPinKeypad(String iface, String pin)319 public boolean startWpsPinKeypad(String iface, String pin) { 320 return mSupplicantP2pIfaceHal.startWpsPinKeypad(iface, pin); 321 } 322 323 /** 324 * Initiate WPS Pin Display setup. 325 * 326 * @param iface Group interface name to use. 327 * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard. 328 * @return generated pin if operation was successful, null otherwise. 329 */ startWpsPinDisplay(String iface, String bssid)330 public String startWpsPinDisplay(String iface, String bssid) { 331 return mSupplicantP2pIfaceHal.startWpsPinDisplay(iface, bssid); 332 } 333 334 /** 335 * Remove network with provided id. 336 * 337 * @param netId Id of the network to lookup. 338 * @return true, if operation was successful. 339 */ removeP2pNetwork(int netId)340 public boolean removeP2pNetwork(int netId) { 341 return mSupplicantP2pIfaceHal.removeNetwork(netId); 342 } 343 344 /** 345 * Set WPS device type. 346 * 347 * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg> 348 * @return true if request is sent successfully, false otherwise. 349 */ setP2pDeviceType(String type)350 public boolean setP2pDeviceType(String type) { 351 return mSupplicantP2pIfaceHal.setWpsDeviceType(type); 352 } 353 354 /** 355 * Set WPS config methods 356 * 357 * @param cfg List of config methods. 358 * @return true if request is sent successfully, false otherwise. 359 */ setConfigMethods(String cfg)360 public boolean setConfigMethods(String cfg) { 361 return mSupplicantP2pIfaceHal.setWpsConfigMethods(cfg); 362 } 363 364 /** 365 * Set the postfix to be used for P2P SSID's. 366 * 367 * @param postfix String to be appended to SSID. 368 * 369 * @return boolean value indicating whether operation was successful. 370 */ setP2pSsidPostfix(String postfix)371 public boolean setP2pSsidPostfix(String postfix) { 372 return mSupplicantP2pIfaceHal.setSsidPostfix(postfix); 373 } 374 375 /** 376 * Set the Maximum idle time in seconds for P2P groups. 377 * This value controls how long a P2P group is maintained after there 378 * is no other members in the group. As a group owner, this means no 379 * associated stations in the group. As a P2P client, this means no 380 * group owner seen in scan results. 381 * 382 * @param iface Group interface name to use. 383 * @param time Timeout value in seconds. 384 * 385 * @return boolean value indicating whether operation was successful. 386 */ setP2pGroupIdle(String iface, int time)387 public boolean setP2pGroupIdle(String iface, int time) { 388 return mSupplicantP2pIfaceHal.setGroupIdle(iface, time); 389 } 390 391 /** 392 * Turn on/off power save mode for the interface. 393 * 394 * @param iface Group interface name to use. 395 * @param enabled Indicate if power save is to be turned on/off. 396 * 397 * @return boolean value indicating whether operation was successful. 398 */ setP2pPowerSave(String iface, boolean enabled)399 public boolean setP2pPowerSave(String iface, boolean enabled) { 400 return mSupplicantP2pIfaceHal.setPowerSave(iface, enabled); 401 } 402 403 /** 404 * Enable/Disable Wifi Display. 405 * 406 * @param enable true to enable, false to disable. 407 * @return true, if operation was successful. 408 */ setWfdEnable(boolean enable)409 public boolean setWfdEnable(boolean enable) { 410 return mSupplicantP2pIfaceHal.enableWfd(enable); 411 } 412 413 /** 414 * Set Wifi Display device info. 415 * 416 * @param hex WFD device info as described in section 5.1.2 of WFD technical 417 * specification v1.0.0. 418 * @return true, if operation was successful. 419 */ setWfdDeviceInfo(String hex)420 public boolean setWfdDeviceInfo(String hex) { 421 return mSupplicantP2pIfaceHal.setWfdDeviceInfo(hex); 422 } 423 424 /** 425 * Initiate a P2P service discovery indefinitely. 426 * Will trigger {@link WifiP2pMonitor#P2P_DEVICE_FOUND_EVENT} on finding devices. 427 * 428 * @return boolean value indicating whether operation was successful. 429 */ p2pFind()430 public boolean p2pFind() { 431 return p2pFind(0); 432 } 433 434 /** 435 * Initiate a P2P service discovery with a (optional) timeout. 436 * 437 * @param timeout The maximum amount of time to be spent in performing discovery. 438 * Set to 0 to indefinitely continue discovery until an explicit 439 * |stopFind| is sent. 440 * @return boolean value indicating whether operation was successful. 441 */ p2pFind(int timeout)442 public boolean p2pFind(int timeout) { 443 return mSupplicantP2pIfaceHal.find(timeout); 444 } 445 446 /** 447 * Initiate a P2P device discovery with a scan type, a (optional) frequency, and a (optional) 448 * timeout. 449 * 450 * @param type indicates what channels to scan. 451 * Valid values are {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} for doing full P2P scan, 452 * {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL} for scanning social channels, 453 * {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ} for scanning a specified frequency. 454 * @param freq is the frequency to be scanned. 455 * The possible values are: 456 * <ul> 457 * <li> A valid frequency for {@link WifiP2pManager#WIFI_P2P_SCAN_SINGLE_FREQ}</li> 458 * <li> {@link WifiP2pManager#WIFI_P2P_SCAN_FREQ_UNSPECIFIED} for 459 * {@link WifiP2pManager#WIFI_P2P_SCAN_FULL} and 460 * {@link WifiP2pManager#WIFI_P2P_SCAN_SOCIAL}</li> 461 * </ul> 462 * @param timeout The maximum amount of time to be spent in performing discovery. 463 * Set to 0 to indefinitely continue discovery until an explicit 464 * |stopFind| is sent. 465 * @return boolean value indicating whether operation was successful. 466 */ p2pFind(@ifiP2pManager.WifiP2pScanType int type, int freq, int timeout)467 public boolean p2pFind(@WifiP2pManager.WifiP2pScanType int type, int freq, int timeout) { 468 return mSupplicantP2pIfaceHal.find(type, freq, timeout); 469 } 470 471 /** 472 * Stop an ongoing P2P service discovery. 473 * 474 * @return boolean value indicating whether operation was successful. 475 */ p2pStopFind()476 public boolean p2pStopFind() { 477 return mSupplicantP2pIfaceHal.stopFind(); 478 } 479 480 /** 481 * Configure Extended Listen Timing. 482 * 483 * If enabled, listen state must be entered every |intervalInMillis| for at 484 * least |periodInMillis|. Both values have acceptable range of 1-65535 485 * (with interval obviously having to be larger than or equal to duration). 486 * If the P2P module is not idle at the time the Extended Listen Timing 487 * timeout occurs, the Listen State operation must be skipped. 488 * 489 * @param enable Enables or disables listening. 490 * @param period Period in milliseconds. 491 * @param interval Interval in milliseconds. 492 * 493 * @return true, if operation was successful. 494 */ p2pExtListen(boolean enable, int period, int interval)495 public boolean p2pExtListen(boolean enable, int period, int interval) { 496 return mSupplicantP2pIfaceHal.configureExtListen(enable, period, interval); 497 } 498 499 /** 500 * Set P2P Listen channel. 501 * 502 * When specifying a social channel on the 2.4 GHz band (1/6/11) there is no 503 * need to specify the operating class since it defaults to 81. When 504 * specifying a social channel on the 60 GHz band (2), specify the 60 GHz 505 * operating class (180). 506 * 507 * @param lc Wifi channel. eg, 1, 6, 11. 508 * 509 * @return true, if operation was successful. 510 */ p2pSetListenChannel(int lc)511 public boolean p2pSetListenChannel(int lc) { 512 return mSupplicantP2pIfaceHal.setListenChannel(lc); 513 } 514 515 /** 516 * Set P2P operating channel. 517 * 518 * @param oc Wifi channel, eg, 1, 6, 11. 519 * @param unsafeChannels channels are not allowed. 520 * @return true if operation was successful. 521 */ p2pSetOperatingChannel(int oc, @NonNull List<CoexUnsafeChannel> unsafeChannels)522 public boolean p2pSetOperatingChannel(int oc, @NonNull List<CoexUnsafeChannel> unsafeChannels) { 523 if (null == unsafeChannels) { 524 Log.wtf(TAG, "unsafeChannels is null."); 525 return false; 526 } 527 return mSupplicantP2pIfaceHal.setOperatingChannel(oc, unsafeChannels); 528 } 529 530 /** 531 * Flush P2P peer table and state. 532 * 533 * @return boolean value indicating whether operation was successful. 534 */ p2pFlush()535 public boolean p2pFlush() { 536 return mSupplicantP2pIfaceHal.flush(); 537 } 538 539 /** 540 * Start P2P group formation with a discovered P2P peer. This includes 541 * optional group owner negotiation, group interface setup, provisioning, 542 * and establishing data connection. 543 * 544 * @param config Configuration to use to connect to remote device. 545 * @param joinExistingGroup Indicates that this is a command to join an 546 * existing group as a client. It skips the group owner negotiation 547 * part. This must send a Provision Discovery Request message to the 548 * target group owner before associating for WPS provisioning. 549 * 550 * @return String containing generated pin, if selected provision method 551 * uses PIN. 552 */ p2pConnect(WifiP2pConfig config, boolean joinExistingGroup)553 public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) { 554 return mSupplicantP2pIfaceHal.connect(config, joinExistingGroup); 555 } 556 557 /** 558 * Cancel an ongoing P2P group formation and joining-a-group related 559 * operation. This operation unauthorizes the specific peer device (if any 560 * had been authorized to start group formation), stops P2P find (if in 561 * progress), stops pending operations for join-a-group, and removes the 562 * P2P group interface (if one was used) that is in the WPS provisioning 563 * step. If the WPS provisioning step has been completed, the group is not 564 * terminated. 565 * 566 * @return boolean value indicating whether operation was successful. 567 */ p2pCancelConnect()568 public boolean p2pCancelConnect() { 569 return mSupplicantP2pIfaceHal.cancelConnect(); 570 } 571 572 /** 573 * Send P2P provision discovery request to the specified peer. The 574 * parameters for this command are the P2P device address of the peer and the 575 * desired configuration method. 576 * 577 * @param config Config class describing peer setup. 578 * 579 * @return boolean value indicating whether operation was successful. 580 */ p2pProvisionDiscovery(WifiP2pConfig config)581 public boolean p2pProvisionDiscovery(WifiP2pConfig config) { 582 return mSupplicantP2pIfaceHal.provisionDiscovery(config); 583 } 584 585 /** 586 * Set up a P2P group owner manually. 587 * This is a helper method that invokes groupAdd(networkId, isPersistent) internally. 588 * 589 * @param persistent Used to request a persistent group to be formed. 590 * 591 * @return true, if operation was successful. 592 */ p2pGroupAdd(boolean persistent)593 public boolean p2pGroupAdd(boolean persistent) { 594 return mSupplicantP2pIfaceHal.groupAdd(persistent); 595 } 596 597 /** 598 * Set up a P2P group owner manually (i.e., without group owner 599 * negotiation with a specific peer). This is also known as autonomous 600 * group owner. 601 * 602 * @param netId Used to specify the restart of a persistent group. 603 * 604 * @return true, if operation was successful. 605 */ p2pGroupAdd(int netId)606 public boolean p2pGroupAdd(int netId) { 607 return mSupplicantP2pIfaceHal.groupAdd(netId, true); 608 } 609 610 /** 611 * Set up a P2P group as Group Owner or join a group with a configuration. 612 * 613 * @param config Used to specify config for setting up a P2P group 614 * 615 * @return true, if operation was successful. 616 */ p2pGroupAdd(WifiP2pConfig config, boolean join)617 public boolean p2pGroupAdd(WifiP2pConfig config, boolean join) { 618 int freq = 0; 619 switch (config.groupOwnerBand) { 620 case WifiP2pConfig.GROUP_OWNER_BAND_2GHZ: 621 freq = 2; 622 break; 623 case WifiP2pConfig.GROUP_OWNER_BAND_5GHZ: 624 freq = 5; 625 break; 626 // treat it as frequency. 627 default: 628 freq = config.groupOwnerBand; 629 } 630 abortWifiRunningScanIfNeeded(join); 631 return mSupplicantP2pIfaceHal.groupAdd( 632 config.networkName, 633 config.passphrase, 634 (config.netId == WifiP2pGroup.NETWORK_ID_PERSISTENT), 635 freq, config.deviceAddress, join); 636 } 637 abortWifiRunningScanIfNeeded(boolean isJoin)638 private void abortWifiRunningScanIfNeeded(boolean isJoin) { 639 if (!isJoin) return; 640 641 Set<String> wifiClientInterfaces = mWifiNative.getClientInterfaceNames(); 642 643 for (String interfaceName: wifiClientInterfaces) { 644 mWifiNl80211Manager.abortScan(interfaceName); 645 } 646 } 647 648 /** 649 * Terminate a P2P group. If a new virtual network interface was used for 650 * the group, it must also be removed. The network interface name of the 651 * group interface is used as a parameter for this command. 652 * 653 * @param iface Group interface name to use. 654 * @return true, if operation was successful. 655 */ p2pGroupRemove(String iface)656 public boolean p2pGroupRemove(String iface) { 657 return mSupplicantP2pIfaceHal.groupRemove(iface); 658 } 659 660 /** 661 * Reject connection attempt from a peer (specified with a device 662 * address). This is a mechanism to reject a pending group owner negotiation 663 * with a peer and request to automatically block any further connection or 664 * discovery of the peer. 665 * 666 * @param deviceAddress MAC address of the device to reject. 667 * 668 * @return boolean value indicating whether operation was successful. 669 */ p2pReject(String deviceAddress)670 public boolean p2pReject(String deviceAddress) { 671 return mSupplicantP2pIfaceHal.reject(deviceAddress); 672 } 673 674 /** 675 * Invite a device to a persistent group. 676 * If the peer device is the group owner of the persistent group, the peer 677 * parameter is not needed. Otherwise it is used to specify which 678 * device to invite. |goDeviceAddress| parameter may be used to override 679 * the group owner device address for Invitation Request should it not be 680 * known for some reason (this should not be needed in most cases). 681 * 682 * @param group Group object to use. 683 * @param deviceAddress MAC address of the device to invite. 684 * 685 * @return boolean value indicating whether operation was successful. 686 */ p2pInvite(WifiP2pGroup group, String deviceAddress)687 public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) { 688 return mSupplicantP2pIfaceHal.invite(group, deviceAddress); 689 } 690 691 /** 692 * Reinvoke a device from a persistent group. 693 * 694 * @param netId Used to specify the persistent group. 695 * @param deviceAddress MAC address of the device to reinvoke. 696 * 697 * @return true, if operation was successful. 698 */ p2pReinvoke(int netId, String deviceAddress)699 public boolean p2pReinvoke(int netId, String deviceAddress) { 700 return mSupplicantP2pIfaceHal.reinvoke(netId, deviceAddress); 701 } 702 703 /** 704 * Gets the operational SSID of the device. 705 * 706 * @param deviceAddress MAC address of the peer. 707 * 708 * @return SSID of the device. 709 */ p2pGetSsid(String deviceAddress)710 public String p2pGetSsid(String deviceAddress) { 711 return mSupplicantP2pIfaceHal.getSsid(deviceAddress); 712 } 713 714 /** 715 * Gets the MAC address of the device. 716 * 717 * @return MAC address of the device. 718 */ p2pGetDeviceAddress()719 public String p2pGetDeviceAddress() { 720 return mSupplicantP2pIfaceHal.getDeviceAddress(); 721 } 722 723 /** 724 * Gets the capability of the group which the device is a 725 * member of. 726 * 727 * @param deviceAddress MAC address of the peer. 728 * 729 * @return combination of |GroupCapabilityMask| values. 730 */ getGroupCapability(String deviceAddress)731 public int getGroupCapability(String deviceAddress) { 732 return mSupplicantP2pIfaceHal.getGroupCapability(deviceAddress); 733 } 734 735 /** 736 * This command can be used to add a upnp/bonjour service. 737 * 738 * @param servInfo List of service queries. 739 * 740 * @return true, if operation was successful. 741 */ p2pServiceAdd(WifiP2pServiceInfo servInfo)742 public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) { 743 return mSupplicantP2pIfaceHal.serviceAdd(servInfo); 744 } 745 746 /** 747 * This command can be used to remove a upnp/bonjour service. 748 * 749 * @param servInfo List of service queries. 750 * 751 * @return true, if operation was successful. 752 */ p2pServiceDel(WifiP2pServiceInfo servInfo)753 public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) { 754 return mSupplicantP2pIfaceHal.serviceRemove(servInfo); 755 } 756 757 /** 758 * This command can be used to flush all services from the 759 * device. 760 * 761 * @return boolean value indicating whether operation was successful. 762 */ p2pServiceFlush()763 public boolean p2pServiceFlush() { 764 return mSupplicantP2pIfaceHal.serviceFlush(); 765 } 766 767 /** 768 * Schedule a P2P service discovery request. The parameters for this command 769 * are the device address of the peer device (or 00:00:00:00:00:00 for 770 * wildcard query that is sent to every discovered P2P peer that supports 771 * service discovery) and P2P Service Query TLV(s) as hexdump. 772 * 773 * @param addr MAC address of the device to discover. 774 * @param query Hex dump of the query data. 775 * @return identifier Identifier for the request. Can be used to cancel the 776 * request. 777 */ p2pServDiscReq(String addr, String query)778 public String p2pServDiscReq(String addr, String query) { 779 return mSupplicantP2pIfaceHal.requestServiceDiscovery(addr, query); 780 } 781 782 /** 783 * Cancel a previous service discovery request. 784 * 785 * @param id Identifier for the request to cancel. 786 * @return true, if operation was successful. 787 */ p2pServDiscCancelReq(String id)788 public boolean p2pServDiscCancelReq(String id) { 789 return mSupplicantP2pIfaceHal.cancelServiceDiscovery(id); 790 } 791 792 /** 793 * Send driver command to set Miracast mode. 794 * 795 * @param mode Mode of Miracast. 796 * 0 = disabled 797 * 1 = operating as source 798 * 2 = operating as sink 799 */ setMiracastMode(int mode)800 public void setMiracastMode(int mode) { 801 mSupplicantP2pIfaceHal.setMiracastMode(mode); 802 } 803 804 /** 805 * Get NFC handover request message. 806 * 807 * @return select message if created successfully, null otherwise. 808 */ getNfcHandoverRequest()809 public String getNfcHandoverRequest() { 810 return mSupplicantP2pIfaceHal.getNfcHandoverRequest(); 811 } 812 813 /** 814 * Get NFC handover select message. 815 * 816 * @return select message if created successfully, null otherwise. 817 */ getNfcHandoverSelect()818 public String getNfcHandoverSelect() { 819 return mSupplicantP2pIfaceHal.getNfcHandoverSelect(); 820 } 821 822 /** 823 * Report NFC handover select message. 824 * 825 * @return true if reported successfully, false otherwise. 826 */ initiatorReportNfcHandover(String selectMessage)827 public boolean initiatorReportNfcHandover(String selectMessage) { 828 return mSupplicantP2pIfaceHal.initiatorReportNfcHandover(selectMessage); 829 } 830 831 /** 832 * Report NFC handover request message. 833 * 834 * @return true if reported successfully, false otherwise. 835 */ responderReportNfcHandover(String requestMessage)836 public boolean responderReportNfcHandover(String requestMessage) { 837 return mSupplicantP2pIfaceHal.responderReportNfcHandover(requestMessage); 838 } 839 840 /** 841 * Set the client list for the provided network. 842 * 843 * @param netId Id of the network. 844 * @return Space separated list of clients if successfull, null otherwise. 845 */ getP2pClientList(int netId)846 public String getP2pClientList(int netId) { 847 return mSupplicantP2pIfaceHal.getClientList(netId); 848 } 849 850 /** 851 * Set the client list for the provided network. 852 * 853 * @param netId Id of the network. 854 * @param list Space separated list of clients. 855 * @return true, if operation was successful. 856 */ setP2pClientList(int netId, String list)857 public boolean setP2pClientList(int netId, String list) { 858 return mSupplicantP2pIfaceHal.setClientList(netId, list); 859 } 860 861 /** 862 * Save the current configuration to p2p_supplicant.conf. 863 * 864 * @return true on success, false otherwise. 865 */ saveConfig()866 public boolean saveConfig() { 867 return mSupplicantP2pIfaceHal.saveConfig(); 868 } 869 870 /** 871 * Enable/Disable MAC randomization. 872 * 873 * @param enable true to enable, false to disable. 874 * @return true, if operation was successful. 875 */ setMacRandomization(boolean enable)876 public boolean setMacRandomization(boolean enable) { 877 return mSupplicantP2pIfaceHal.setMacRandomization(enable); 878 } 879 880 /** 881 * Set Wifi Display R2 device info. 882 * 883 * @param hex WFD device info as described in section 5.1.12 of WFD technical 884 * specification v2.1.0. 885 * @return true, if operation was successful. 886 */ setWfdR2DeviceInfo(String hex)887 public boolean setWfdR2DeviceInfo(String hex) { 888 return mSupplicantP2pIfaceHal.setWfdR2DeviceInfo(hex); 889 } 890 891 /** 892 * Remove the client with the MAC address from the group. 893 * 894 * @param peerAddress Mac address of the client. 895 * @return true if success 896 */ removeClient(String peerAddress)897 public boolean removeClient(String peerAddress) { 898 // The client is deemed as a P2P client, not a legacy client, hence the false. 899 return mSupplicantP2pIfaceHal.removeClient(peerAddress, false); 900 } 901 902 /** 903 * Set vendor-specific information elements to the native service. 904 * 905 * @param vendorElements the vendor opaque data. 906 * @return true, if operation was successful. 907 */ setVendorElements(Set<ScanResult.InformationElement> vendorElements)908 public boolean setVendorElements(Set<ScanResult.InformationElement> vendorElements) { 909 return mSupplicantP2pIfaceHal.setVendorElements(vendorElements); 910 } 911 912 /** 913 * Remove vendor-specific information elements from the native service. 914 */ removeVendorElements()915 public boolean removeVendorElements() { 916 return mSupplicantP2pIfaceHal.setVendorElements( 917 new HashSet<ScanResult.InformationElement>()); 918 } 919 920 /** Indicate whether or not 5GHz/6GHz DBS is supported. */ is5g6gDbsSupported()921 public boolean is5g6gDbsSupported() { 922 if (mP2pIfaceName == null) return false; 923 if (!mHalDeviceManager.isSupported()) return false; 924 return mHalDeviceManager.is5g6gDbsSupportedOnP2pIface(mP2pIfaceName); 925 } 926 927 /** 928 * Configure the IP addresses in supplicant for P2P GO to provide the IP address to 929 * client in EAPOL handshake. Refer Wi-Fi P2P Technical Specification v1.7 - Section 4.2.8 930 * IP Address Allocation in EAPOL-Key Frames (4-Way Handshake) for more details. 931 * The IP addresses are IPV4 addresses and higher-order address bytes are in the 932 * lower-order int bytes (e.g. 1.2.3.4 is represented as 0x04030201) 933 * 934 * @param ipAddressGo The P2P Group Owner IP address. 935 * @param ipAddressMask The P2P Group owner subnet mask. 936 * @param ipAddressStart The starting address in the IP address pool. 937 * @param ipAddressEnd The ending address in the IP address pool. 938 * @return boolean value indicating whether operation was successful. 939 */ configureEapolIpAddressAllocationParams(int ipAddressGo, int ipAddressMask, int ipAddressStart, int ipAddressEnd)940 public boolean configureEapolIpAddressAllocationParams(int ipAddressGo, int ipAddressMask, 941 int ipAddressStart, int ipAddressEnd) { 942 return mSupplicantP2pIfaceHal.configureEapolIpAddressAllocationParams(ipAddressGo, 943 ipAddressMask, ipAddressStart, ipAddressEnd); 944 } 945 } 946