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