179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski/*
279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * Copyright (C) 2016 The Android Open Source Project
379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *
479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * Licensed under the Apache License, Version 2.0 (the "License");
579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * you may not use this file except in compliance with the License.
679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * You may obtain a copy of the License at
779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *
879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *      http://www.apache.org/licenses/LICENSE-2.0
979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *
1079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * Unless required by applicable law or agreed to in writing, software
1179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * distributed under the License is distributed on an "AS IS" BASIS,
1279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * See the License for the specific language governing permissions and
1479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * limitations under the License.
1579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski */
1679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
17163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Piuspackage com.android.server.wifi.p2p;
1879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
1979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
2079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
21eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
2279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIface;
2361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIfaceCallback;
24eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantP2pNetwork;
2579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.IfaceType;
2679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
2779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
28163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
2979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hidl.manager.V1_0.IServiceManager;
3079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hidl.manager.V1_0.IServiceNotification;
3179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.WpsInfo;
3279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pConfig;
33eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.net.wifi.p2p.WifiP2pDevice;
3479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pGroup;
35eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.net.wifi.p2p.WifiP2pGroupList;
3661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pManager;
3779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
38f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Piusimport android.os.HwRemoteBinder;
3979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.os.RemoteException;
4096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport android.text.TextUtils;
4179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.util.Log;
4279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
43eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport com.android.internal.util.ArrayUtils;
4461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowskiimport com.android.server.wifi.util.NativeUtil;
4561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
4696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.nio.ByteBuffer;
4796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.nio.ByteOrder;
4879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport java.util.ArrayList;
492a1078dc3729bab248bbd28c8336749481e045cfRoshan Piusimport java.util.Arrays;
50eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport java.util.List;
5196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.util.regex.Matcher;
5296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.util.regex.Pattern;
532a1078dc3729bab248bbd28c8336749481e045cfRoshan Piusimport java.util.stream.Collectors;
54eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
5579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski/**
5679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * Native calls sending requests to the P2P Hals, and callbacks for receiving P2P events
5779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *
5879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * {@hide}
5979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski */
6079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskipublic class SupplicantP2pIfaceHal {
6179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final boolean DBG = true;
6279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final String TAG = "SupplicantP2pIfaceHal";
6379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final int RESULT_NOT_VALID = -1;
6479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
653af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius    private static final int DEFAULT_OPERATING_CLASS = 81;
6696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
6796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Regex pattern for extracting the wps device type bytes.
6896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
6996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
7096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
7196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
7279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
73f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private Object mLock = new Object();
74f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
7579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    // Supplicant HAL HIDL interface objects
7679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private IServiceManager mIServiceManager = null;
7779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicant mISupplicant = null;
7879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicantIface mHidlSupplicantIface = null;
7979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicantP2pIface mISupplicantP2pIface = null;
801c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
811c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
821c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
831c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
841c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (DBG) {
851c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
861c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
871c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
881c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantP2pIface()) {
891c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
901c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
911c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
921c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
931c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
941c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
951c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
961c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
97f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
98f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
99f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
100f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
101f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
102f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
103f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
104f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
105f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mSupplicantDeathRecipient =
106f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
107f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "ISupplicant/ISupplicantStaIface died: cookie=" + cookie);
108f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
109f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
110f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
111f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
11279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
113163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    private final WifiP2pMonitor mMonitor;
114d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private SupplicantP2pIfaceCallback mCallback = null;
115d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
116163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    public SupplicantP2pIfaceHal(WifiP2pMonitor monitor) {
117d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor = monitor;
118d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
119d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
12060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToServiceManagerDeath() {
12160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mIServiceManager == null) return false;
12260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
123f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mIServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) {
12460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
12560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
12660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                mIServiceManager = null; // Will need to register a new ServiceNotification
12760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
12860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
12960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
13060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "IServiceManager.linkToDeath exception", e);
13160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
13260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
13360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
13460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
13560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
13679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /**
13779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * Registers a service notification for the ISupplicant service, which triggers intialization of
13861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the ISupplicantP2pIface
13979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * @return true if the service notification was successfully registered
14079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
14179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    public boolean initialize() {
14279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback.");
14379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
14479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (mIServiceManager != null) {
14579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.i(TAG, "Supplicant HAL already initialized.");
14679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                // Already have an IServiceManager and serviceNotification registered, don't
14779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                // don't register another.
14879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return true;
14979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
15079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicant = null;
15179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = null;
15279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
15379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mIServiceManager = getServiceManagerMockable();
15479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                if (mIServiceManager == null) {
15579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    Log.e(TAG, "Failed to get HIDL Service Manager");
15679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
15779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
15860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                if (!linkToServiceManagerDeath()) {
15979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
16079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
16179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
16279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                   exists */
1631c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!mIServiceManager.registerForNotifications(
1641c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
16579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    Log.e(TAG, "Failed to register for notifications to "
16679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                            + ISupplicant.kInterfaceName);
16779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    mIServiceManager = null; // Will need to register a new ServiceNotification
16879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
16979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
170d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
171d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                // Successful completion by the end of the 'try' block. This will prevent reporting
172d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                // proper initialization after exception is caught.
173d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                return true;
17479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
17579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
17679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        + e);
17779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                supplicantServiceDiedHandler();
17879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
179d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return false;
18079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
18179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
18279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
18360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToSupplicantDeath() {
18460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mISupplicant == null) return false;
18560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
186f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, 0)) {
18760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
18860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
18960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
19060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
19160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
19260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "ISupplicant.linkToDeath exception", e);
19360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
19460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
19560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
19660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
19760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
19879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private boolean initSupplicantService() {
19979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
20079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
20179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mISupplicant = getSupplicantMockable();
20279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
20379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "ISupplicant.getService exception: " + e);
20479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
20579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
20679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (mISupplicant == null) {
20779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
20879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
20979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
21060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            if (!linkToSupplicantDeath()) {
21160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
21260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
21360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
21460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
21560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
21660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
21760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToSupplicantP2pIfaceDeath() {
21860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mISupplicantP2pIface == null) return false;
21960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
220f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicantP2pIface.linkToDeath(mSupplicantDeathRecipient, 0)) {
22160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicantP2pIface");
22260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
22360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
22460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
22560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
22660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "ISupplicantP2pIface.linkToDeath exception", e);
22760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
22879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
22979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return true;
23079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
23179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
23279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private boolean initSupplicantP2pIface() {
23379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
23479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            /** List all supplicant Ifaces */
23579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList();
23679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
23779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mISupplicant.listInterfaces((SupplicantStatus status,
23879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
23979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    if (status.code != SupplicantStatusCode.SUCCESS) {
24079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
24179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        return;
24279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    }
24379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    supplicantIfaces.addAll(ifaces);
24479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                });
24579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
24679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
24779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
24879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
24979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (supplicantIfaces.size() == 0) {
25079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
25179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
25279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
25379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            SupplicantResult<ISupplicantIface> supplicantIface =
25479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    new SupplicantResult("getInterface()");
25579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
25679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                if (ifaceInfo.type == IfaceType.P2P) {
25779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    try {
25879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        mISupplicant.getInterface(ifaceInfo,
25979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                (SupplicantStatus status, ISupplicantIface iface) -> {
26079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                if (status.code != SupplicantStatusCode.SUCCESS) {
26179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
26279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                    return;
26379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                }
26479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                supplicantIface.setResult(status, iface);
26579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                            });
26679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    } catch (RemoteException e) {
26779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
26879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        return false;
26979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    }
27079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    break;
27179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
27279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
27379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
27479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (supplicantIface.getResult() == null) {
27579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "initSupplicantP2pIface got null iface");
27679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
27779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
27879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = getP2pIfaceMockable(supplicantIface.getResult());
27960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            if (!linkToSupplicantP2pIfaceDeath()) {
28060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
28160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
282d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
28379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
284d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (mISupplicantP2pIface != null && mMonitor != null) {
285d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // TODO(ender): Get rid of hard-coded interface name, which is
286d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // assumed to be the group interface name in several other classes
287d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // ("p2p0" should probably become getName()).
288d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mCallback = new SupplicantP2pIfaceCallback("p2p0", mMonitor);
289d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            if (!registerCallback(mCallback)) {
290d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                Log.e(TAG, "Callback registration failed. Initialization incomplete.");
291d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                return false;
292d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            }
29379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
294d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
295d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        return true;
29679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
29779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
29879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private void supplicantServiceDiedHandler() {
29979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
30079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicant = null;
30179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = null;
30279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
30379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
30479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
30524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
30624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
30724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
30824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
30924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
31024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
31124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
31224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
31324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
31461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Signals whether Initialization completed successfully. Only necessary for testing, is not
31561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * needed to guard calls etc.
31624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
31724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationComplete() {
31824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mISupplicantP2pIface != null;
31924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
32024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
32179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /**
32279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
32379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
32479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected IServiceManager getServiceManagerMockable() throws RemoteException {
325006eb17e06a7843e3da3bf939833b94e58a5a034Yifan Hong        return IServiceManager.getService();
32679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
32779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
32879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected ISupplicant getSupplicantMockable() throws RemoteException {
32979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return ISupplicant.getService();
33079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
33179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
33279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected ISupplicantP2pIface getP2pIfaceMockable(ISupplicantIface iface) {
33379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return ISupplicantP2pIface.asInterface(iface.asBinder());
33479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
33579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
336eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    protected ISupplicantP2pNetwork getP2pNetworkMockable(ISupplicantNetwork network) {
337eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        return ISupplicantP2pNetwork.asInterface(network.asBinder());
338eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
33979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
34079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected static void logd(String s) {
34179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        if (DBG) Log.d(TAG, s);
34279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
34379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
34479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected static void logCompletion(String operation, SupplicantStatus status) {
34561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        if (status == null) {
34661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Log.w(TAG, operation + " failed: no status code returned.");
34761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        } else if (status.code == SupplicantStatusCode.SUCCESS) {
34879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logd(operation + " completed successfully.");
34979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        } else {
35079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            Log.w(TAG, operation + " failed: " + status.code + " (" + status.debugMessage + ")");
35179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
35279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
35379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
35479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
35561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
35661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Returns false if SupplicantP2pIface is null, and logs failure to call methodStr
35761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
35861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private boolean checkSupplicantP2pIfaceAndLogFailure(String method) {
35961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        if (mISupplicantP2pIface == null) {
36061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Log.e(TAG, "Can't call " + method + ": ISupplicantP2pIface is null");
36161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
36261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
36361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        return true;
36461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
36561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
36661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private int wpsInfoToConfigMethod(int info) {
36761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        switch (info) {
36861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.PBC:
36961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.PBC;
37061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
37161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.DISPLAY:
37261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.DISPLAY;
37361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
37461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.KEYPAD:
37561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.LABEL:
37661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.KEYPAD;
37761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
37861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            default:
37961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Unsupported WPS provision method: " + info);
38061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
38161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
38261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
38361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
38461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
38561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Retrieves the name of the network interface.
38679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     *
38761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return name Name of the network interface, e.g., wlan0
38879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
38961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getName() {
39061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
39161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getName")) return null;
39261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult("getName()");
39379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
39461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
39561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getName(
39661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String name) -> {
39761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, name);
39861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
39961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
40061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
40161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
40261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
40361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
40479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
40561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
40679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
40761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
40861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
40961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Register for callbacks from this interface.
41061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
41161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * These callbacks are invoked for events that are specific to this interface.
41261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Registration of multiple callback objects is supported. These objects must
41361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * be automatically deleted when the corresponding client process is dead or
41461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * if this interface is removed.
41561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
416163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param receiver An instance of the |ISupplicantP2pIfaceCallback| HIDL
41761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        interface object.
41861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
41961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
42061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean registerCallback(ISupplicantP2pIfaceCallback receiver) {
42161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
42261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("registerCallback")) return false;
42361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("registerCallback()");
42461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
42561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.registerCallback(receiver));
42661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
42761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
42861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
42961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
43061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
43161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
43261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
43361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
43461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
43561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
43661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate a P2P service discovery with a (optional) timeout.
43761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
43896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param timeout Max time to be spent is peforming discovery.
43961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        Set to 0 to indefinely continue discovery untill and explicit
44061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        |stopFind| is sent.
44161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
44261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
44361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean find(int timeout) {
44461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
44561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("find")) return false;
44661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
44761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (timeout < 0) {
44861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid timeout value: " + timeout);
44961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
45061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
45161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("find(" + timeout + ")");
45261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
45361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.find(timeout));
45461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
45561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
45661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
45761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
45861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
45961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
46061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
46161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
46261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
46361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
46461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Stop an ongoing P2P service discovery.
46561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
46661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
46761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
46861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean stopFind() {
46961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
47061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("stopFind")) return false;
47161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("stopFind()");
47261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
47361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.stopFind());
47461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
47561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
47661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
47761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
47861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
47961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
48061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
48161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
48261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
48361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
48461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Flush P2P peer table and state.
48561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
48661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
48761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
48861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean flush() {
48961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
49061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("flush")) return false;
49161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("flush()");
49261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
49361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.flush());
49461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
49561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
49661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
49761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
49861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
49961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
50061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
50161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
50261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
50361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
50461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to flush all services from the
50561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * device.
50661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
50761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
50861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
50961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceFlush() {
51061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
51161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceFlush")) return false;
51261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("serviceFlush()");
51361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
51461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.flushServices());
51561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
51661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
51761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
51861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
51961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
52061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
52161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
52261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
52361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
52461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
52561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Turn on/off power save mode for the interface.
52661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
52761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
52861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable Indicate if power save is to be turned on/off.
52961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
53061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
53161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
53261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setPowerSave(String groupIfName, boolean enable) {
53361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
53461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setPowerSave")) return false;
53561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
53661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setPowerSave(" + groupIfName + ", " + enable + ")");
53761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
53861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setPowerSave(groupIfName, enable));
53961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
54061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
54161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
54261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
54361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
54461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
54561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
54661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
54761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
54861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
54961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set the Maximum idle time in seconds for P2P groups.
55061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This value controls how long a P2P group is maintained after there
55161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * is no other members in the group. As a group owner, this means no
55261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * associated stations in the group. As a P2P client, this means no
55361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group owner seen in scan results.
55461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
55561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
55661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param timeoutInSec Timeout value in seconds.
55761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
55861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
55961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
56061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setGroupIdle(String groupIfName, int timeoutInSec) {
56161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
56261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setGroupIdle")) return false;
56361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Basic checking here. Leave actual parameter validation to supplicant.
56461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (timeoutInSec < 0) {
56561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid group timeout value " + timeoutInSec);
56661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
56761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
56861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
56961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
570163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                    "setGroupIdle(" + groupIfName + ", " + timeoutInSec + ")");
57161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
57261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setGroupIdle(groupIfName, timeoutInSec));
57361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
57461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
57561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
57661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
57761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
57861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
57961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
58061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
58161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
58261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
58361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set the postfix to be used for P2P SSID's.
58461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
58561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param postfix String to be appended to SSID.
58661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
58761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
58861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
58961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setSsidPostfix(String postfix) {
59061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
59161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setSsidPostfix")) return false;
59261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Basic checking here. Leave actual parameter validation to supplicant.
59361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (postfix == null) {
59461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid SSID postfix value (null).");
59561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
59661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
59761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
59861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("setSsidPostfix(" + postfix + ")");
59961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
60061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setSsidPostfix(
60161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        NativeUtil.decodeSsid("\"" + postfix + "\"")));
60261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
60361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
60461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
60545a984619e338090981499e4823e0177649e3c28Roshan Pius            } catch (IllegalArgumentException e) {
60661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not decode SSID.", e);
60761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
60861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
60961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
61061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
61161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
61261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
61361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
61461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
61561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
61661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Start P2P group formation with a discovered P2P peer. This includes
61761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * optional group owner negotiation, group interface setup, provisioning,
61861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * and establishing data connection.
61961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
62061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param config Configuration to use to connect to remote device.
62161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param joinExistingGroup Indicates that this is a command to join an
62261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        existing group as a client. It skips the group owner negotiation
62361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        part. This must send a Provision Discovery Request message to the
62461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        target group owner before associating for WPS provisioning.
62561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
62661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return String containing generated pin, if selected provision method
62761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        uses PIN.
62861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
62961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String connect(WifiP2pConfig config, boolean joinExistingGroup) {
63096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (config == null) return null;
63161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
63261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setSsidPostfix")) return null;
63361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
63461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config == null) {
63561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not connect: null config.");
63661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
63761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
63861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
63961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config.deviceAddress == null) {
64061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse null mac address.");
64161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
64261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
64361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
6447395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius            if (config.wps.setup == WpsInfo.PBC && !TextUtils.isEmpty(config.wps.pin)) {
6457395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius                Log.e(TAG, "Expected empty pin for PBC.");
6467395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius                return null;
6477395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius            }
6487395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius
64961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] peerAddress = null;
65061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
65161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                peerAddress = NativeUtil.macAddressToByteArray(config.deviceAddress);
65261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
65361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
65461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
65561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
65661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
65761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int provisionMethod = wpsInfoToConfigMethod(config.wps.setup);
65861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (provisionMethod == RESULT_NOT_VALID) {
65961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid WPS config method: " + config.wps.setup);
66061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
66161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
66261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // NOTE: preSelectedPin cannot be null, otherwise hal would crash.
6637395d73fb33a6ad5e234f8fc2832810ec8109af9Roshan Pius            String preSelectedPin = TextUtils.isEmpty(config.wps.pin) ? "" : config.wps.pin;
66461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            boolean persistent = (config.netId == WifiP2pGroup.PERSISTENT_NET_ID);
66561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
66661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int goIntent = 0;
66761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!joinExistingGroup) {
66861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                int groupOwnerIntent = config.groupOwnerIntent;
66961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
67061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
67161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
672d303ba3891c4ebd2bc0ea8f3125a7358cf1d9018Tomonori Nanbu                goIntent = groupOwnerIntent;
67361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
67461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
67561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult(
67661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "connect(" + config.deviceAddress + ")");
67761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
67861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.connect(
67961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        peerAddress, provisionMethod, preSelectedPin, joinExistingGroup,
68061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        persistent, goIntent,
68161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String generatedPin) -> {
68261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, generatedPin);
68361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
68461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
68561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
68661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
68761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
68861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
68961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
69061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
69161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
69261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
69361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel an ongoing P2P group formation and joining-a-group related
69461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * operation. This operation unauthorizes the specific peer device (if any
69561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * had been authorized to start group formation), stops P2P find (if in
69661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * progress), stops pending operations for join-a-group, and removes the
69761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * P2P group interface (if one was used) that is in the WPS provisioning
69861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * step. If the WPS provisioning step has been completed, the group is not
69961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * terminated.
70061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
70161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
70261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
70361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelConnect() {
70461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
70561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelConnect")) return false;
70661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("cancelConnect()");
70761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
70861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelConnect());
70961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
71061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
71161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
71261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
71361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
71461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
71561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
71661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
71761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
71861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
71961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Send P2P provision discovery request to the specified peer. The
72061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * parameters for this command are the P2P device address of the peer and the
72161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * desired configuration method.
72261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
72361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param config Config class describing peer setup.
72461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
72561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
72661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
72761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean provisionDiscovery(WifiP2pConfig config) {
72896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (config == null) return false;
72961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
73061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("provisionDiscovery")) return false;
73161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
73261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int targetMethod = wpsInfoToConfigMethod(config.wps.setup);
7335a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            if (targetMethod == RESULT_NOT_VALID) {
73461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Unrecognized WPS configuration method: " + config.wps.setup);
73561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
73661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
7375a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            if (targetMethod == ISupplicantP2pIface.WpsProvisionMethod.DISPLAY) {
7385a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne                // We are doing display, so provision discovery is keypad.
7395a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne                targetMethod = ISupplicantP2pIface.WpsProvisionMethod.KEYPAD;
7405a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            } else if (targetMethod == ISupplicantP2pIface.WpsProvisionMethod.KEYPAD) {
7415a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne                // We are doing keypad, so provision discovery is display.
7425a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne                targetMethod = ISupplicantP2pIface.WpsProvisionMethod.DISPLAY;
7435a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            }
74461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
74561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config.deviceAddress == null) {
74661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse null mac address.");
74761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
74861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
74961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
75061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
75161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(config.deviceAddress);
75261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
75361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
75461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
75561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
75661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
75761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
75861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "provisionDiscovery(" + config.deviceAddress + ", " + config.wps.setup + ")");
75961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
76061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.provisionDiscovery(macAddress, targetMethod));
76161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
76261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
76361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
76461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
76561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
76661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
76761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
76861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
76961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
77061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
77161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
77261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Invite a device to a persistent group.
77361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If the peer device is the group owner of the persistent group, the peer
77461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * parameter is not needed. Otherwise it is used to specify which
77561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * device to invite. |goDeviceAddress| parameter may be used to override
77661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the group owner device address for Invitation Request should it not be
77761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * known for some reason (this should not be needed in most cases).
77861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
77996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param group Group object to use.
78061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to invite.
78161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
78261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
78361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
78461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean invite(WifiP2pGroup group, String peerAddress) {
78596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(peerAddress)) return false;
78661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
78761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("invite")) return false;
78861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group == null) {
78961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot invite to null group.");
79061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
79161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
79261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
79361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group.getOwner() == null) {
79461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot invite to group with null owner.");
79561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
79661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
79761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
79861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group.getOwner().deviceAddress == null) {
79961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group owner has no mac address.");
80061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
80161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
80261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
80361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] ownerMacAddress = null;
80461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
80561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                ownerMacAddress = NativeUtil.macAddressToByteArray(group.getOwner().deviceAddress);
80661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
80761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group owner mac address parse error.", e);
80861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
80961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
81061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
81161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
81261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
81361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
81461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
81561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
81661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] peerMacAddress;
81761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
81861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                peerMacAddress = NativeUtil.macAddressToByteArray(peerAddress);
81961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
82061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Peer mac address parse error.", e);
82161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
82261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
82361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
82461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
825163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                    "invite(" + group.getInterface() + ", " + group.getOwner().deviceAddress
826163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                            + ", " + peerAddress + ")");
82761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
82861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.invite(
82961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        group.getInterface(), ownerMacAddress, peerMacAddress));
83061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
83161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
83261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
83361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
83461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
83561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
83661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
83761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
83861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
83961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
84061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Reject connection attempt from a peer (specified with a device
84161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * address). This is a mechanism to reject a pending group owner negotiation
84261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * with a peer and request to automatically block any further connection or
84361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * discovery of the peer.
84461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
84561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to reject.
84661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
84761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
84861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
84961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean reject(String peerAddress) {
85061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
85161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("reject")) return false;
85261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
85361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
85461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse rejected peer's mac address.");
85561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
85661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
85761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
85861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
85961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
86061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
86161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
86261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
86361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
86461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
86561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result =
86661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("reject(" + peerAddress + ")");
86761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
86861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.reject(macAddress));
86961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
87061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
87161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
87261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
87361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
87461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
87561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
87661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
87761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
87861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
87961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
88061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the MAC address of the device.
88161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
88261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return MAC address of the device.
88361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
88461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getDeviceAddress() {
88561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
88661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getDeviceAddress")) return null;
88761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult("getDeviceAddress()");
88861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
88961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getDeviceAddress((SupplicantStatus status, byte[] address) -> {
89061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    String parsedAddress = null;
89161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    try {
89261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        parsedAddress = NativeUtil.macAddressFromByteArray(address);
89361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } catch (Exception e) {
89461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        Log.e(TAG, "Could not process reported address.", e);
89561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
89661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    result.setResult(status, parsedAddress);
89761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                });
89861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
89961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
90061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
90161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
90261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
90361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
90461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
90561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
90661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
90761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
90861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
90961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
91061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the operational SSID of the device.
91161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
91296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param address MAC address of the peer.
91361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
91461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return SSID of the device.
91561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
91661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getSsid(String address) {
91761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
91861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getSsid")) return null;
91961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
92061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (address == null) {
92161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
92261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
92361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
92461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
92561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
92661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(address);
92761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
92861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse mac address.", e);
92961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
93061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
93161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
93261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result =
93361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("getSsid(" + address + ")");
93461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
93561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getSsid(
93661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, (SupplicantStatus status, ArrayList<Byte> ssid) -> {
93761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            String ssidString = null;
93861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            if (ssid != null) {
93961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                try {
94061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    ssidString = NativeUtil.encodeSsid(ssid);
94161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                } catch (Exception e) {
94261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    Log.e(TAG, "Could not encode SSID.", e);
94361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                }
94461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
94561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, ssidString);
94661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
94761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
94861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
94961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
95061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
95161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
95261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
95361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
95461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
95561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
95661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
95761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
95861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
95961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Reinvoke a device from a persistent group.
96061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
96161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param networkId Used to specify the persistent group.
96261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to reinvoke.
96361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
96461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
96561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
96661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean reinvoke(int networkId, String peerAddress) {
96796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(peerAddress) || networkId < 0) return false;
96861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
96961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("reinvoke")) return false;
97061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
97161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
97261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
97361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
97461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
97561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
97661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
97761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
97861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse mac address.", e);
97961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
98061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
98161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
98261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
98361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "reinvoke(" + networkId + ", " + peerAddress + ")");
98461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
98561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.reinvoke(networkId, macAddress));
98661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
98761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
98861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
98961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
99061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
99161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
99261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
99361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
99461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
99561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
99661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
99761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set up a P2P group owner manually (i.e., without group owner
99861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * negotiation with a specific peer). This is also known as autonomous
99961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group owner.
100061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
100161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param networkId Used to specify the restart of a persistent group.
100261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param isPersistent Used to request a persistent group to be formed.
100361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
100461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
100561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
100661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupAdd(int networkId, boolean isPersistent) {
100761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
100861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("groupAdd")) return false;
100961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result =
101061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("groupAdd(" + networkId + ", " + isPersistent + ")");
101161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
101261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.addGroup(isPersistent, networkId));
101361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
101461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
101561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
101661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
101761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
101861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
101961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
102061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
102161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
102261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set up a P2P group owner manually.
102361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This is a helper method that invokes groupAdd(networkId, isPersistent) internally.
102461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
102561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param isPersistent Used to request a persistent group to be formed.
102661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
102761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
102861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
102961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupAdd(boolean isPersistent) {
103061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        // Supplicant expects networkId to be -1 if not supplied.
103161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        return groupAdd(-1, isPersistent);
103261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
103361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
103461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
103561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
103661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Terminate a P2P group. If a new virtual network interface was used for
103761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the group, it must also be removed. The network interface name of the
103861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group interface is used as a parameter for this command.
103961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
104096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param groupName Group interface name to use.
104161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
104261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
104361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
104461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupRemove(String groupName) {
104596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupName)) return false;
104661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
104761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("groupRemove")) return false;
104861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("groupRemove(" + groupName + ")");
104961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
105061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.removeGroup(groupName));
105161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
105261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
105361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
105461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
105561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
105661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
105761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
105861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
105961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
106061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
106161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the capability of the group which the device is a
106261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * member of.
106361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
106461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the peer.
106561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
106661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return combination of |GroupCapabilityMask| values.
106761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
106861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public int getGroupCapability(String peerAddress) {
106961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
107061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getGroupCapability")) {
107161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
107261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
107361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
107461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
107561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
107661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
107761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
107861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
107961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
108061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
108161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
108261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse group address.", e);
108361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
108461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
108561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
108661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Integer> capability = new SupplicantResult(
108761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "getGroupCapability(" + peerAddress + ")");
108861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
108961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getGroupCapability(
109061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, (SupplicantStatus status, int cap) -> {
109161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            capability.setResult(status, cap);
109261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
109361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
109461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
109561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
109661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
109761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
109861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!capability.isSuccess()) {
109961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
110061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
110161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
110261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return capability.getResult();
110361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
110461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
110561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
110661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
110761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
110861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Configure Extended Listen Timing.
110961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
111061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If enabled, listen state must be entered every |intervalInMillis| for at
111161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * least |periodInMillis|. Both values have acceptable range of 1-65535
111261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * (with interval obviously having to be larger than or equal to duration).
111361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If the P2P module is not idle at the time the Extended Listen Timing
111461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * timeout occurs, the Listen State operation must be skipped.
111561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
111661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable Enables or disables listening.
111761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param periodInMillis Period in milliseconds.
111861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param intervalInMillis Interval in milliseconds.
111961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
112061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
112161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
112261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
112396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (enable && intervalInMillis < periodInMillis) {
112496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return false;
112596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
112661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
112761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("configureExtListen")) return false;
112861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
112961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // If listening is disabled, wpa supplicant expects zeroes.
113061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!enable) {
113161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                periodInMillis = 0;
113261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                intervalInMillis = 0;
113361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
113461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
113561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Verify that the integers are not negative. Leave actual parameter validation to
113661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // supplicant.
113761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (periodInMillis < 0 || intervalInMillis < 0) {
1138163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                Log.e(TAG, "Invalid parameters supplied to configureExtListen: " + periodInMillis
1139163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                        + ", " + intervalInMillis);
114061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
114161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
114261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
114361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
114461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "configureExtListen(" + periodInMillis + ", " + intervalInMillis + ")");
114561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
114661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(
114761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        mISupplicantP2pIface.configureExtListen(periodInMillis, intervalInMillis));
114861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
114961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
115061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
115161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
115261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
115361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
115461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
115561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
115661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
115761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
115861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
11593af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius     * Set P2P Listen channel and operating chanel.
116061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
11613af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius     * @param listenChannel Wifi channel. eg, 1, 6, 11.
11623af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius     * @param operatingChannel Wifi channel. eg, 1, 6, 11.
116361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
116461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
116561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
11663af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius    public boolean setListenChannel(int listenChannel, int operatingChannel) {
116761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
116861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setListenChannel")) return false;
11693af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius
11703af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius            if (listenChannel >= 1 && listenChannel <= 11) {
11713af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                SupplicantResult<Void> result = new SupplicantResult(
11723af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                        "setListenChannel(" + listenChannel + ", " + DEFAULT_OPERATING_CLASS + ")");
11733af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                try {
11743af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    result.setResult(mISupplicantP2pIface.setListenChannel(
11753af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                            listenChannel, DEFAULT_OPERATING_CLASS));
11763af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                } catch (RemoteException e) {
11773af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
11783af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    supplicantServiceDiedHandler();
11793af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                }
11803af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                if (!result.isSuccess()) {
11813af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    return false;
11823af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                }
11833af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius            } else if (listenChannel != 0) {
11843af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                // listenChannel == 0 does not set any listen channel.
118561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
118661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
118761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
11883af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius            if (operatingChannel >= 0 && operatingChannel <= 165) {
11893af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                ArrayList<ISupplicantP2pIface.FreqRange> ranges = new ArrayList<>();
11903af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                // operatingChannel == 0 enables all freqs.
11913af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                if (operatingChannel >= 1 && operatingChannel <= 165) {
11923af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    int freq = (operatingChannel <= 14 ? 2407 : 5000) + operatingChannel * 5;
11933af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    ISupplicantP2pIface.FreqRange range1 =  new ISupplicantP2pIface.FreqRange();
11943af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    range1.min = 1000;
11953af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    range1.max = freq - 5;
11963af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    ISupplicantP2pIface.FreqRange range2 =  new ISupplicantP2pIface.FreqRange();
11973af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    range2.min = freq + 5;
11983af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    range2.max = 6000;
11993af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    ranges.add(range1);
12003af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    ranges.add(range2);
12013af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                }
12023af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                SupplicantResult<Void> result = new SupplicantResult(
12033af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                        "setDisallowedFrequencies(" + ranges + ")");
12043af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                try {
12053af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    result.setResult(mISupplicantP2pIface.setDisallowedFrequencies(ranges));
12063af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                } catch (RemoteException e) {
12073af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
12083af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                    supplicantServiceDiedHandler();
12093af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                }
12103af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius                return result.isSuccess();
121161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
12123af7d54afce3e72a8ccf037dd8e4fa30c8ccf878Roshan Pius            return false;
121361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
121461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
121561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
121661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
121761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
121861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to add a upnp/bonjour service.
121961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
122096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param servInfo List of service queries.
122161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
122261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
122361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
122461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceAdd(WifiP2pServiceInfo servInfo) {
122561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
122661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceAdd")) return false;
122761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
122861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (servInfo == null) {
122961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Null service info passed.");
123061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
123161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
123261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
123361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            for (String s : servInfo.getSupplicantQueryList()) {
123461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (s == null) {
123561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Invalid service description (null).");
123661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
123761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
123861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
123961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                String[] data = s.split(" ");
124061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (data.length < 3) {
124161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Service specification invalid: " + s);
124261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
124361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
124461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
124561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                SupplicantResult<Void> result = null;
124661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
124761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    if ("upnp".equals(data[0])) {
124861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        int version = 0;
124961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        try {
1250748932d87b7084ae33f7eb6453e30076b0e20524Glen Kuhne                            version = Integer.parseInt(data[1], 16);
125161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        } catch (NumberFormatException e) {
125261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            Log.e(TAG, "UPnP Service specification invalid: " + s, e);
125361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            return false;
125461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
125561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
125661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result = new SupplicantResult(
125761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                "addUpnpService(" + data[1] + ", " + data[2] + ")");
125861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result.setResult(mISupplicantP2pIface.addUpnpService(version, data[2]));
125961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else if ("bonjour".equals(data[0])) {
126061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        if (data[1] != null && data[2] != null) {
126161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> request = null;
126261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> response = null;
126361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            try {
126461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                request = NativeUtil.byteArrayToArrayList(
126561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                        NativeUtil.hexStringToByteArray(data[1]));
126661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                response = NativeUtil.byteArrayToArrayList(
126761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                        NativeUtil.hexStringToByteArray(data[2]));
126861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            } catch (Exception e) {
126961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                Log.e(TAG, "Invalid bonjour service description.");
127061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                return false;
127161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
127261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result = new SupplicantResult(
127361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    "addBonjourService(" + data[1] + ", " + data[2] + ")");
127461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(
127561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    mISupplicantP2pIface.addBonjourService(request, response));
127661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
127761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else {
127861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        return false;
127961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
128061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (RemoteException e) {
128161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
128261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    supplicantServiceDiedHandler();
128361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
128461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
128561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (result == null || !result.isSuccess()) return false;
128661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
128761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
128861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return true;
128961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
129061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
129161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
129261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
129361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
129461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to remove a upnp/bonjour service.
129561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
129696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param servInfo List of service queries.
129761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
129861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
129961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
130061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceRemove(WifiP2pServiceInfo servInfo) {
130161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
130261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceRemove")) return false;
130361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
130461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (servInfo == null) {
130561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Null service info passed.");
130661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
130761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
130861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
130961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            for (String s : servInfo.getSupplicantQueryList()) {
131061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (s == null) {
131161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Invalid service description (null).");
131261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
131361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
131461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
131561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                String[] data = s.split(" ");
131661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (data.length < 3) {
131761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Service specification invalid: " + s);
131861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
131961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
132061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
132161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                SupplicantResult<Void> result = null;
132261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
132361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    if ("upnp".equals(data[0])) {
132461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        int version = 0;
132561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        try {
1326748932d87b7084ae33f7eb6453e30076b0e20524Glen Kuhne                            version = Integer.parseInt(data[1], 16);
132761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        } catch (NumberFormatException e) {
132861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            Log.e(TAG, "UPnP Service specification invalid: " + s, e);
132961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            return false;
133061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
133161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result = new SupplicantResult(
133261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                "removeUpnpService(" + data[1] + ", " + data[2] + ")");
133361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result.setResult(mISupplicantP2pIface.removeUpnpService(version, data[2]));
133461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else if ("bonjour".equals(data[0])) {
133561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        if (data[1] != null) {
133661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> request = null;
133761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            try {
133861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                request = NativeUtil.byteArrayToArrayList(
133961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    NativeUtil.hexStringToByteArray(data[1]));
134061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            } catch (Exception e) {
134161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                Log.e(TAG, "Invalid bonjour service description.");
134261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                return false;
134361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
134461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result = new SupplicantResult("removeBonjourService(" + data[1] + ")");
134561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(mISupplicantP2pIface.removeBonjourService(request));
134661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
134761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else {
134861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        Log.e(TAG, "Unknown / unsupported P2P service requested: " + data[0]);
134961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        return false;
135061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
135161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (RemoteException e) {
135261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
135361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    supplicantServiceDiedHandler();
135461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
135561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
135661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (result == null || !result.isSuccess()) return false;
135761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
135861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
135961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return true;
136061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
136161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
136261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
136361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
136461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
136561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Schedule a P2P service discovery request. The parameters for this command
136661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * are the device address of the peer device (or 00:00:00:00:00:00 for
136761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * wildcard query that is sent to every discovered P2P peer that supports
136861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * service discovery) and P2P Service Query TLV(s) as hexdump.
136961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
137061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to discover.
137161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param query Hex dump of the query data.
137261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return identifier Identifier for the request. Can be used to cancel the
137361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *         request.
137461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
137561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String requestServiceDiscovery(String peerAddress, String query) {
137661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
137761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("requestServiceDiscovery")) return null;
137861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
137961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
138061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
138161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
138261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
138361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
138461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
138561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
138661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
138761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not process peer MAC address.", e);
138861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
138961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
139061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
139161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (query == null) {
139261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse service discovery query: " + query);
139361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
139461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
139561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            ArrayList<Byte> binQuery = null;
139661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
139761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                binQuery = NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(query));
139861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
139961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse service query.", e);
140061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
140161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
140261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
140361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Long> result = new SupplicantResult(
140461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "requestServiceDiscovery(" + peerAddress + ", " + query + ")");
140561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
140661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.requestServiceDiscovery(
140761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, binQuery,
140861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, long identifier) -> {
140961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, new Long(identifier));
141061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
141161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
141261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
141361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
141461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
141561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
141661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Long value = result.getResult();
141761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (value == null) return null;
141861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return value.toString();
141961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
142061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
142161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
142261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
142361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
142461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel a previous service discovery request.
142561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
142661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param identifier Identifier for the request to cancel.
142761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
142861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
142961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelServiceDiscovery(String identifier) {
143061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
143161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelServiceDiscovery")) return false;
143261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (identifier == null) {
143361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "cancelServiceDiscovery requires a valid tag.");
143461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
143561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
143661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1437cb90e9415a66b9328d5e091317262151e83be823Glen Kuhne            long id = 0;
143861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
1439cb90e9415a66b9328d5e091317262151e83be823Glen Kuhne                id = Long.parseLong(identifier);
144061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (NumberFormatException e) {
144161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Service discovery identifier invalid: " + identifier, e);
144261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
144361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
144461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
144561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
144661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "cancelServiceDiscovery(" + identifier + ")");
144761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
144861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelServiceDiscovery(id));
144961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
145061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
145161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
145261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
145361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
145461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
145561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
145661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
145761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
145861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
145961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
146061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Send driver command to set Miracast mode.
146161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
146261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param mode Mode of Miracast.
146361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
146461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
146561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setMiracastMode(int mode) {
146661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
146761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setMiracastMode")) return false;
146861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte targetMode = ISupplicantP2pIface.MiracastMode.DISABLED;
146961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
147061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            switch (mode) {
147161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                case WifiP2pManager.MIRACAST_SOURCE:
147261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    targetMode = ISupplicantP2pIface.MiracastMode.SOURCE;
147361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    break;
147461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
147561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                case WifiP2pManager.MIRACAST_SINK:
147661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    targetMode = ISupplicantP2pIface.MiracastMode.SINK;
147761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    break;
147861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
147961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
148061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
148161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setMiracastMode(" + mode + ")");
148261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
148361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setMiracastMode(targetMode));
148461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
148561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
148661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
148761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
148861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
148961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
149061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
149161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
149261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
149361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
149461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
149561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Push Button setup.
149661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * The PBC operation requires that a button is also pressed at the
149761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * AP/Registrar at about the same time (2 minute window).
149861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
149961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
1500d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard.
150161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
150261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
150361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean startWpsPbc(String groupIfName, String bssid) {
1504b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne        if (TextUtils.isEmpty(groupIfName)) {
1505b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            Log.e(TAG, "Group name required when requesting WPS PBC. Got (" + groupIfName + ")");
1506b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            return false;
1507b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne        }
150861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
150961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPbc")) return false;
151061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Null values should be fine, since bssid can be empty.
151161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
1512b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            try {
1513b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                macAddress = NativeUtil.macAddressToByteArray(bssid);
1514b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            } catch (Exception e) {
1515b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                Log.e(TAG, "Could not parse BSSID.", e);
1516b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                return false;
151761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
151861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
151961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
152061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPbc(" + groupIfName + ", " + bssid + ")");
152161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
152261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.startWpsPbc(groupIfName, macAddress));
152361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
152461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
152561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
152661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
152761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
152861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
152961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
153061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
153161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
153261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
153361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
153461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Pin Keypad setup.
153561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
153661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
153761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param pin 8 digit pin to be used.
153861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
153961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
154061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean startWpsPinKeypad(String groupIfName, String pin) {
154196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(pin)) return false;
154261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
154361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinKeypad")) return false;
154461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
154561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
154661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
154761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
154861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (pin == null) {
154961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "PIN required when requesting WPS KEYPAD.");
155061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
155161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
155261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
155361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
155461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPinKeypad(" + groupIfName + ", " + pin + ")");
155561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
155661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.startWpsPinKeypad(groupIfName, pin));
155761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
155861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
155961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
156061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
156161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
156261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
156361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
156461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
156561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
156661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
156761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
156861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Pin Display setup.
156961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
157061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
1571d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssid BSSID of the AP. Use empty bssid to indicate wildcard.
1572b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return generated pin if operation was successful, null otherwise.
157361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
157461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String startWpsPinDisplay(String groupIfName, String bssid) {
1575d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius        if (TextUtils.isEmpty(groupIfName)) return null;
157661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
157761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinDisplay")) return null;
157861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
157961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
158061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
158161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
158261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
158361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Null values should be fine, since bssid can be empty.
158461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
1585b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            try {
1586b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                macAddress = NativeUtil.macAddressToByteArray(bssid);
1587b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne            } catch (Exception e) {
1588b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                Log.e(TAG, "Could not parse BSSID.", e);
1589b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                return null;
159061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
159161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
159261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult(
159361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPinDisplay(" + groupIfName + ", " + bssid + ")");
159461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
159561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.startWpsPinDisplay(
159661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        groupIfName, macAddress,
159761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String generatedPin) -> {
159861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, generatedPin);
159961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
160061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
160161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
160261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
160361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
160461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
160561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
160661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
160761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
160861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
160961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
161061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
161161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel any ongoing WPS operations.
161261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
161361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
161461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
161561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
161661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelWps(String groupIfName) {
161761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
161861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelWps")) return false;
161961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
162061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
162161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
162261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
162361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
162461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
162561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "cancelWps(" + groupIfName + ")");
162661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
162761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelWps(groupIfName));
162861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
162961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
163061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
163161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
163261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
163461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
163561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
163661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
163961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Enable/Disable Wifi Display.
164061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
164161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable true to enable, false to disable.
164261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
164361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
164461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean enableWfd(boolean enable) {
164561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
164661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("enableWfd")) return false;
164761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
164861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
164961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "enableWfd(" + enable + ")");
165061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
165161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.enableWfd(enable));
165261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
165361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
165461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
165561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
165661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
165761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
165861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
165961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
166061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
166161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
166261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
166361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set Wifi Display device info.
166461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
166561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param info WFD device info as described in section 5.1.2 of WFD technical
166661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        specification v1.0.0.
166761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
166861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
166961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setWfdDeviceInfo(String info) {
167061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
167161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setWfdDeviceInfo")) return false;
167261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
167361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (info == null) {
167461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse null WFD info string.");
167561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
167661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
167761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] wfdInfo = null;
167861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
167961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                wfdInfo = NativeUtil.hexStringToByteArray(info);
168061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
168161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse WFD Device Info string.");
168261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
168361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
168461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
168561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
168661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setWfdDeviceInfo(" + info + ")");
168761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
168861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setWfdDeviceInfo(wfdInfo));
168961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
169061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
169161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
169261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
169361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
169461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
169561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
169661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
169761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1698eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
169996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Remove network with provided id.
170096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
170196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param networkId Id of the network to lookup.
170296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true, if operation was successful.
170396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
170496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean removeNetwork(int networkId) {
170596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
170696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("removeNetwork")) return false;
170796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
170896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
170996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "removeNetwork(" + networkId + ")");
171096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
171196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.removeNetwork(networkId));
171296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
171396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
171496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
171596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
171696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
171796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
171896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
171996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
172096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
172196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
1722eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * List the networks saved in wpa_supplicant.
1723eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1724eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return List of network ids.
1725eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1726eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    private List<Integer> listNetworks() {
1727eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1728eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("listNetworks")) return null;
1729eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult("listNetworks()");
1730eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            try {
1731eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                mISupplicantP2pIface.listNetworks(
1732eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        (SupplicantStatus status, ArrayList<Integer> networkIds) -> {
1733eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            result.setResult(status, networkIds);
1734eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        });
1735eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            } catch (RemoteException e) {
1736eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1737eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                supplicantServiceDiedHandler();
1738eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1739eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            return result.getResult();
1740eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1741eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
174261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1743eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
1744eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * Get the supplicant P2p network object for the specified network ID.
1745eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1746eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @param networkId Id of the network to lookup.
1747eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return ISupplicantP2pNetwork instance on success, null on failure.
1748eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1749eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    private ISupplicantP2pNetwork getNetwork(int networkId) {
1750eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1751eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNetwork")) return null;
1752eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            SupplicantResult<ISupplicantNetwork> result =
1753eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    new SupplicantResult("getNetwork(" + networkId + ")");
1754eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            try {
1755eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                mISupplicantP2pIface.getNetwork(
1756eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        networkId,
1757eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        (SupplicantStatus status, ISupplicantNetwork network) -> {
1758eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            result.setResult(status, network);
1759eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        });
1760eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            } catch (RemoteException e) {
1761eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1762eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                supplicantServiceDiedHandler();
1763eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1764eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (result.getResult() == null) {
1765eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "getNetwork got null network");
1766eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                return null;
1767eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1768eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            return getP2pNetworkMockable(result.getResult());
1769eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1770eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
177161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1772eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
1773b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne     * Get the persistent group list from wpa_supplicant's p2p mgmt interface
1774eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1775b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne     * @param groups WifiP2pGroupList to store persistent groups in
1776eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return true, if list has been modified.
1777eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1778eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    public boolean loadGroups(WifiP2pGroupList groups) {
1779eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1780eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("loadGroups")) return false;
1781eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            List<Integer> networkIds = listNetworks();
1782eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (networkIds == null || networkIds.isEmpty()) {
1783eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                return false;
1784eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1785eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            for (Integer networkId : networkIds) {
1786eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                ISupplicantP2pNetwork network = getNetwork(networkId);
1787eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (network == null) {
1788eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "Failed to retrieve network object for " + networkId);
1789eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    continue;
1790eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1791eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<Boolean> resultIsCurrent =
1792eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("isCurrent(" + networkId + ")");
1793eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1794eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.isCurrent(
1795eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, boolean isCurrent) -> {
1796eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultIsCurrent.setResult(status, isCurrent);
1797eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1798eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1799eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1800eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1801eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1802b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                /** Skip the current network, if we're somehow getting networks from the p2p GO
1803b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                    interface, instead of p2p mgmt interface*/
1804b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                if (!resultIsCurrent.isSuccess() || resultIsCurrent.getResult()) {
1805b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                    Log.i(TAG, "Skipping current network");
1806eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    continue;
1807eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1808eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1809eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                WifiP2pGroup group = new WifiP2pGroup();
1810eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                group.setNetworkId(networkId);
1811eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1812eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                // Now get the ssid, bssid and other flags for this network.
1813eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<ArrayList> resultSsid =
1814eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("getSsid(" + networkId + ")");
1815eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1816eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.getSsid(
1817eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, ArrayList<Byte> ssid) -> {
1818eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultSsid.setResult(status, ssid);
1819eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1820eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1821eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1822eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1823eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1824eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultSsid.isSuccess() && resultSsid.getResult() != null
1825eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        && !resultSsid.getResult().isEmpty()) {
1826b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                    group.setNetworkName(NativeUtil.removeEnclosingQuotes(
1827b8adfb745a2c1540db40af204f7de9b1a815071fGlen Kuhne                            NativeUtil.encodeSsid(resultSsid.getResult())));
1828eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
182961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1830eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<byte[]> resultBssid =
1831eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("getBssid(" + networkId + ")");
1832eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1833eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.getBssid(
1834eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, byte[] bssid) -> {
1835eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultBssid.setResult(status, bssid);
1836eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1837eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1838eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1839eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1840eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1841eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultBssid.isSuccess() && !ArrayUtils.isEmpty(resultBssid.getResult())) {
1842eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    WifiP2pDevice device = new WifiP2pDevice();
1843eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    device.deviceAddress =
1844eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            NativeUtil.macAddressFromByteArray(resultBssid.getResult());
1845eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    group.setOwner(device);
1846eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1847eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1848eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<Boolean> resultIsGo =
1849eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("isGo(" + networkId + ")");
1850eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1851eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.isGo(
1852eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, boolean isGo) -> {
1853eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultIsGo.setResult(status, isGo);
1854eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1855eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1856eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1857eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1858eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1859eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultIsGo.isSuccess()) {
1860eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    group.setIsGroupOwner(resultIsGo.getResult());
1861eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1862eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                groups.add(group);
1863eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1864eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1865eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        return true;
1866eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
186761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
186896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
186996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Set WPS device name.
187096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
187196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param name String to be set.
187296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if request is sent successfully, false otherwise.
187396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
187496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean setWpsDeviceName(String name) {
187596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (name == null) {
187696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return false;
187796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
187896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
187996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceName")) return false;
188096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
188196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "setWpsDeviceName(" + name + ")");
188296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
188396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.setWpsDeviceName(name));
188496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
188596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
188696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
188796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
188896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
188996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
189096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
189196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
189296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
189396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Set WPS device type.
189496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
189596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
189696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if request is sent successfully, false otherwise.
189796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
189896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean setWpsDeviceType(String typeStr) {
189945a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
190045a984619e338090981499e4823e0177649e3c28Roshan Pius            Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
190145a984619e338090981499e4823e0177649e3c28Roshan Pius            if (!match.find() || match.groupCount() != 3) {
190245a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Malformed WPS device type " + typeStr);
190345a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
190496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
190545a984619e338090981499e4823e0177649e3c28Roshan Pius            short categ = Short.parseShort(match.group(1));
190645a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
190745a984619e338090981499e4823e0177649e3c28Roshan Pius            short subCateg = Short.parseShort(match.group(3));
190845a984619e338090981499e4823e0177649e3c28Roshan Pius
190945a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] bytes = new byte[8];
191045a984619e338090981499e4823e0177649e3c28Roshan Pius            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
191145a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(categ);
191245a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.put(oui);
191345a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(subCateg);
191445a984619e338090981499e4823e0177649e3c28Roshan Pius            synchronized (mLock) {
191545a984619e338090981499e4823e0177649e3c28Roshan Pius                if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceType")) return false;
191645a984619e338090981499e4823e0177649e3c28Roshan Pius                SupplicantResult<Void> result = new SupplicantResult(
191745a984619e338090981499e4823e0177649e3c28Roshan Pius                        "setWpsDeviceType(" + typeStr + ")");
191845a984619e338090981499e4823e0177649e3c28Roshan Pius                try {
191945a984619e338090981499e4823e0177649e3c28Roshan Pius                    result.setResult(mISupplicantP2pIface.setWpsDeviceType(bytes));
192045a984619e338090981499e4823e0177649e3c28Roshan Pius                } catch (RemoteException e) {
192145a984619e338090981499e4823e0177649e3c28Roshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
192245a984619e338090981499e4823e0177649e3c28Roshan Pius                    supplicantServiceDiedHandler();
192345a984619e338090981499e4823e0177649e3c28Roshan Pius                }
192445a984619e338090981499e4823e0177649e3c28Roshan Pius                return result.isSuccess();
192545a984619e338090981499e4823e0177649e3c28Roshan Pius            }
192645a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
192745a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + typeStr, e);
192845a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
192996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
193096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
193196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
193296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
1933163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * Set WPS config methods
1934163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     *
1935163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param configMethodsStr List of config methods.
1936163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @return true if request is sent successfully, false otherwise.
1937163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     */
1938163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
1939163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        synchronized (mLock) {
1940163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("setWpsConfigMethods")) return false;
1941163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            SupplicantResult<Void> result =
1942163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                    new SupplicantResult("setWpsConfigMethods(" + configMethodsStr + ")");
1943163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            short configMethodsMask = 0;
1944163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            String[] configMethodsStrArr = configMethodsStr.split("\\s+");
1945163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            for (int i = 0; i < configMethodsStrArr.length; i++) {
1946163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
1947163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            }
1948163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            try {
1949163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                result.setResult(mISupplicantP2pIface.setWpsConfigMethods(configMethodsMask));
1950163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            } catch (RemoteException e) {
1951163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1952163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                supplicantServiceDiedHandler();
1953163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            }
1954163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            return result.isSuccess();
1955163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        }
1956163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    }
1957163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius
1958163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    /**
195996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Get NFC handover request message.
196096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
196196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return select message if created successfully, null otherwise.
196296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
196396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public String getNfcHandoverRequest() {
196496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
196596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverRequest")) return null;
196696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult(
196796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "getNfcHandoverRequest()");
196896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
196996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                mISupplicantP2pIface.createNfcHandoverRequestMessage(
197096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        (SupplicantStatus status, ArrayList<Byte> message) -> {
197196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            result.setResult(status, message);
197296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        });
197396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
197496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
197596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
197696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
197796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!result.isSuccess()) {
197896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                return null;
197996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
198096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
198196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return NativeUtil.hexStringFromByteArray(
198296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    NativeUtil.byteArrayFromArrayList(result.getResult()));
198396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
198496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
198596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
198696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
198796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Get NFC handover select message.
198896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
198996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return select message if created successfully, null otherwise.
199096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
199196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public String getNfcHandoverSelect() {
199296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
199396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverSelect")) return null;
199496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult(
199596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "getNfcHandoverSelect()");
199696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
199796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                mISupplicantP2pIface.createNfcHandoverSelectMessage(
199896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        (SupplicantStatus status, ArrayList<Byte> message) -> {
199996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            result.setResult(status, message);
200096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        });
200196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
200296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
200396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
200496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
200596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!result.isSuccess()) {
200696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                return null;
200796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
200896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
200996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return NativeUtil.hexStringFromByteArray(
201096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    NativeUtil.byteArrayFromArrayList(result.getResult()));
201196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
201296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
201396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
201496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
201596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Report NFC handover select message.
201696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
201796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if reported successfully, false otherwise.
201896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
201996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean initiatorReportNfcHandover(String selectMessage) {
202096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (selectMessage == null) return false;
202196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
202296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("initiatorReportNfcHandover")) return false;
202396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
202496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "initiatorReportNfcHandover(" + selectMessage + ")");
202596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
202696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.reportNfcHandoverInitiation(
202796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
202896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            selectMessage))));
202996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
203096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
203196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
203245a984619e338090981499e4823e0177649e3c28Roshan Pius            } catch (IllegalArgumentException e) {
203345a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Illegal argument " + selectMessage, e);
203445a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
203596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
203696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
203796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
203896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
203996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
204096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
204196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Report NFC handover request message.
204296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
204396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if reported successfully, false otherwise.
204496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
204596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean responderReportNfcHandover(String requestMessage) {
204696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (requestMessage == null) return false;
204796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
204896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("responderReportNfcHandover")) return false;
204996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
205096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "responderReportNfcHandover(" + requestMessage + ")");
205196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
205296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.reportNfcHandoverResponse(
205396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
205496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            requestMessage))));
205596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
205696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
205796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
205845a984619e338090981499e4823e0177649e3c28Roshan Pius            } catch (IllegalArgumentException e) {
205945a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Illegal argument " + requestMessage, e);
206045a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
206196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
206296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
206396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
206496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
20652a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius
20662a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    /**
20672a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * Set the client list for the provided network.
20682a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     *
20692a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @param networkId Id of the network.
20702a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @param clientListStr Space separated list of clients.
20712a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @return true, if operation was successful.
20722a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     */
20732a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    public boolean setClientList(int networkId, String clientListStr) {
20742a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        synchronized (mLock) {
20752a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("setClientList")) return false;
20762a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (TextUtils.isEmpty(clientListStr)) {
20772a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "Invalid client list");
20782a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                return false;
20792a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
20802a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            ISupplicantP2pNetwork network = getNetwork(networkId);
20812a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (network == null) {
20822a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "Invalid network id ");
20832a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                return false;
20842a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
20852a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
20862a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                    "setClientList(" + networkId + ", " + clientListStr + ")");
20872a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            try {
208845a984619e338090981499e4823e0177649e3c28Roshan Pius                ArrayList<byte[]> clients = new ArrayList<>();
208945a984619e338090981499e4823e0177649e3c28Roshan Pius                for (String clientStr : Arrays.asList(clientListStr.split("\\s+"))) {
209045a984619e338090981499e4823e0177649e3c28Roshan Pius                    clients.add(NativeUtil.macAddressToByteArray(clientStr));
209145a984619e338090981499e4823e0177649e3c28Roshan Pius                }
20922a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                result.setResult(network.setClientList(clients));
20932a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            } catch (RemoteException e) {
20942a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
20952a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                supplicantServiceDiedHandler();
209645a984619e338090981499e4823e0177649e3c28Roshan Pius            } catch (IllegalArgumentException e) {
209745a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Illegal argument " + clientListStr, e);
209845a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
20992a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
21002a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            return result.isSuccess();
21012a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        }
21022a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    }
21032a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius
21042a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    /**
21052a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * Set the client list for the provided network.
21062a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     *
21072a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @param networkId Id of the network.
21082a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @return  Space separated list of clients if successfull, null otherwise.
21092a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     */
21102a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    public String getClientList(int networkId) {
21112a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        synchronized (mLock) {
21122a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getClientList")) return null;
21132a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            ISupplicantP2pNetwork network = getNetwork(networkId);
21142a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (network == null) {
21152a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "Invalid network id ");
21162a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                return null;
21172a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
21182a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult(
21192a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                    "getClientList(" + networkId + ")");
21202a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            try {
21212a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                network.getClientList(
21222a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        (SupplicantStatus status, ArrayList<byte[]> clients) -> {
21232a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                            result.setResult(status, clients);
21242a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        });
21252a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            } catch (RemoteException e) {
21262a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
21272a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                supplicantServiceDiedHandler();
21282a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
21292a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (!result.isSuccess()) {
21302a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                return null;
21312a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
21322a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            ArrayList<byte[]> clients = result.getResult();
21332a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            return clients.stream()
21342a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                    .map(NativeUtil::macAddressFromByteArray)
21352a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                    .collect(Collectors.joining(" "));
21362a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        }
21372a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    }
21382a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius
21392a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    /**
21402a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * Persist the current configurations to disk.
21412a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     *
21422a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     * @return true, if operation was successful.
21432a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius     */
21442a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    public boolean saveConfig() {
21452a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        synchronized (mLock) {
21462a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("saveConfig")) return false;
21472a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            SupplicantResult<Void> result = new SupplicantResult("saveConfig()");
21482a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            try {
21492a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                result.setResult(mISupplicantP2pIface.saveConfig());
21502a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            } catch (RemoteException e) {
21512a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
21522a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                supplicantServiceDiedHandler();
21532a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            }
21542a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius            return result.isSuccess();
21552a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius        }
21562a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius    }
21572a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius
2158163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    /**
2159163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * Converts the Wps config method string to the equivalent enum value.
2160163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     */
2161163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
2162163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        switch (configMethod) {
2163163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "usba":
2164163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.USBA;
2165163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "ethernet":
2166163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.ETHERNET;
2167163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "label":
2168163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.LABEL;
2169163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "display":
2170163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.DISPLAY;
2171163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "int_nfc_token":
2172163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
2173163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "ext_nfc_token":
2174163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
2175163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "nfc_interface":
2176163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.NFC_INTERFACE;
2177163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "push_button":
2178163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.PUSHBUTTON;
2179163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "keypad":
2180163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.KEYPAD;
2181163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "virtual_push_button":
2182163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
2183163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "physical_push_button":
2184163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
2185163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "p2ps":
2186163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.P2PS;
2187163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "virtual_display":
2188163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
2189163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            case "physical_display":
2190163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                return WpsConfigMethods.PHY_DISPLAY;
2191163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius            default:
2192163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                throw new IllegalArgumentException(
2193163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                        "Invalid WPS config method: " + configMethod);
2194163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        }
2195163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    }
2196163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius
219761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /** Container class allowing propagation of status and/or value
219861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * from callbacks.
219961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
220061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Primary purpose is to allow callback lambdas to provide results
220161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * to parent methods.
220261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
220361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private static class SupplicantResult<E> {
220461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private String mMethodName;
220561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private SupplicantStatus mStatus;
220661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private E mValue;
220761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
2208163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        SupplicantResult(String methodName) {
220961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mMethodName = methodName;
221061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mStatus = null;
221161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mValue = null;
221261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logd("entering " + mMethodName);
221361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
221461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
221561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        public void setResult(SupplicantStatus status, E value) {
221661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logCompletion(mMethodName, status);
221761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logd("leaving " + mMethodName + " with result = " + value);
221879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mStatus = status;
221979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mValue = value;
222079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
222179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
222279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public void setResult(SupplicantStatus status) {
222379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logCompletion(mMethodName, status);
222479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logd("leaving " + mMethodName);
222579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mStatus = status;
222679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
222779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
222879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public boolean isSuccess() {
222979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            return (mStatus != null && mStatus.code == SupplicantStatusCode.SUCCESS);
223079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
223179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
223279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public E getResult() {
223379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            return (isSuccess() ? mValue : null);
223479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
223579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
223679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski}
2237