• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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