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