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