SupplicantP2pIfaceHal.java revision b8b3fb8228a1f90106bad8c59ce006b81ef7921c
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
1779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskipackage com.android.server.wifi;
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;
2879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hidl.manager.V1_0.IServiceManager;
2979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.hidl.manager.V1_0.IServiceNotification;
3079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.WpsInfo;
3179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pConfig;
32eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.net.wifi.p2p.WifiP2pDevice;
3379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pGroup;
34eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport android.net.wifi.p2p.WifiP2pGroupList;
3561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pManager;
3679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
37f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Piusimport android.os.HwRemoteBinder;
3879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.os.RemoteException;
3996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport android.text.TextUtils;
4079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport android.util.Log;
4179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
42eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport com.android.internal.util.ArrayUtils;
4361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowskiimport com.android.server.wifi.util.NativeUtil;
4461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
4596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.nio.ByteBuffer;
4696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.nio.ByteOrder;
4779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskiimport java.util.ArrayList;
48eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Piusimport java.util.List;
4996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.util.regex.Matcher;
5096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Piusimport java.util.regex.Pattern;
51eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
5279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski/**
5379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * Native calls sending requests to the P2P Hals, and callbacks for receiving P2P events
5479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski *
5579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski * {@hide}
5679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski */
5779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowskipublic class SupplicantP2pIfaceHal {
5879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final boolean DBG = true;
5979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final String TAG = "SupplicantP2pIfaceHal";
6079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final int RESULT_NOT_VALID = -1;
6179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private static final int DEFAULT_GROUP_OWNER_INTENT = 6;
6296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
6396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Regex pattern for extracting the wps device type bytes.
6496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
6596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
6696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
6796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
6879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
69f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private Object mLock = new Object();
70f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
7179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    // Supplicant HAL HIDL interface objects
7279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private IServiceManager mIServiceManager = null;
7379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicant mISupplicant = null;
7479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicantIface mHidlSupplicantIface = null;
7579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private ISupplicantP2pIface mISupplicantP2pIface = null;
761c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
771c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
781c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
791c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
801c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (DBG) {
811c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
821c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
831c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
841c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantP2pIface()) {
851c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
861c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
871c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
881c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
891c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
901c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
911c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
921c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
93f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
94f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
95f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
96f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
97f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
98f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
99f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
100f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
101f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mSupplicantDeathRecipient =
102f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
103f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "ISupplicant/ISupplicantStaIface died: cookie=" + cookie);
104f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
105f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
106f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
107f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
10879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
109d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private final WifiMonitor mMonitor;
110d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private SupplicantP2pIfaceCallback mCallback = null;
111d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
112d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public SupplicantP2pIfaceHal(WifiMonitor monitor) {
113d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor = monitor;
114d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
115d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
11660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToServiceManagerDeath() {
11760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mIServiceManager == null) return false;
11860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
119f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mIServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) {
12060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
12160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
12260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                mIServiceManager = null; // Will need to register a new ServiceNotification
12360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
12460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
12560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
12660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "IServiceManager.linkToDeath exception", e);
12760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
12860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
12960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
13060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
13160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
13279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /**
13379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * Registers a service notification for the ISupplicant service, which triggers intialization of
13461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the ISupplicantP2pIface
13579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * @return true if the service notification was successfully registered
13679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
13779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    public boolean initialize() {
13879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback.");
13979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
14079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (mIServiceManager != null) {
14179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.i(TAG, "Supplicant HAL already initialized.");
14279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                // Already have an IServiceManager and serviceNotification registered, don't
14379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                // don't register another.
14479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return true;
14579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
14679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicant = null;
14779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = null;
14879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
14979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mIServiceManager = getServiceManagerMockable();
15079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                if (mIServiceManager == null) {
15179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    Log.e(TAG, "Failed to get HIDL Service Manager");
15279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
15379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
15460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                if (!linkToServiceManagerDeath()) {
15579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
15679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
15779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
15879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                   exists */
1591c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!mIServiceManager.registerForNotifications(
1601c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
16179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    Log.e(TAG, "Failed to register for notifications to "
16279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                            + ISupplicant.kInterfaceName);
16379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    mIServiceManager = null; // Will need to register a new ServiceNotification
16479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    return false;
16579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
166d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
167d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                // Successful completion by the end of the 'try' block. This will prevent reporting
168d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                // proper initialization after exception is caught.
169d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                return true;
17079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
17179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
17279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        + e);
17379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                supplicantServiceDiedHandler();
17479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
175d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return false;
17679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
17779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
17879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
17960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToSupplicantDeath() {
18060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mISupplicant == null) return false;
18160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
182f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, 0)) {
18360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
18460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
18560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
18660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
18760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
18860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "ISupplicant.linkToDeath exception", e);
18960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
19060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
19160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
19260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
19360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
19479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private boolean initSupplicantService() {
19579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
19679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
19779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mISupplicant = getSupplicantMockable();
19879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
19979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "ISupplicant.getService exception: " + e);
20079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
20179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
20279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (mISupplicant == null) {
20379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
20479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
20579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
20660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            if (!linkToSupplicantDeath()) {
20760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
20860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
20960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        }
21060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        return true;
21160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    }
21260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius
21360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius    private boolean linkToSupplicantP2pIfaceDeath() {
21460ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        if (mISupplicantP2pIface == null) return false;
21560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        try {
216f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicantP2pIface.linkToDeath(mSupplicantDeathRecipient, 0)) {
21760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicantP2pIface");
21860ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                supplicantServiceDiedHandler();
21960ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
22060ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
22160ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius        } catch (RemoteException e) {
22260ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            Log.e(TAG, "ISupplicantP2pIface.linkToDeath exception", e);
22360ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            return false;
22479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
22579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return true;
22679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
22779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
22879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private boolean initSupplicantP2pIface() {
22979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
23079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            /** List all supplicant Ifaces */
23179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList();
23279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            try {
23379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                mISupplicant.listInterfaces((SupplicantStatus status,
23479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
23579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    if (status.code != SupplicantStatusCode.SUCCESS) {
23679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
23779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        return;
23879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    }
23979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    supplicantIfaces.addAll(ifaces);
24079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                });
24179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            } catch (RemoteException e) {
24279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
24379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
24479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
24579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (supplicantIfaces.size() == 0) {
24679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
24779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
24879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
24979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            SupplicantResult<ISupplicantIface> supplicantIface =
25079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    new SupplicantResult("getInterface()");
25179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
25279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                if (ifaceInfo.type == IfaceType.P2P) {
25379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    try {
25479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        mISupplicant.getInterface(ifaceInfo,
25579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                (SupplicantStatus status, ISupplicantIface iface) -> {
25679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                if (status.code != SupplicantStatusCode.SUCCESS) {
25779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
25879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                    return;
25979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                }
26079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                                supplicantIface.setResult(status, iface);
26179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                            });
26279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    } catch (RemoteException e) {
26379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
26479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                        return false;
26579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    }
26679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                    break;
26779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                }
26879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
26979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
27079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            if (supplicantIface.getResult() == null) {
27179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                Log.e(TAG, "initSupplicantP2pIface got null iface");
27279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski                return false;
27379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            }
27479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = getP2pIfaceMockable(supplicantIface.getResult());
27560ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            if (!linkToSupplicantP2pIfaceDeath()) {
27660ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius                return false;
27760ef62896e60b41a36a73f4a58d1281084b7181aRoshan Pius            }
278d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
27979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
280d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (mISupplicantP2pIface != null && mMonitor != null) {
281d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // TODO(ender): Get rid of hard-coded interface name, which is
282d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // assumed to be the group interface name in several other classes
283d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            // ("p2p0" should probably become getName()).
284d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mCallback = new SupplicantP2pIfaceCallback("p2p0", mMonitor);
285d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            if (!registerCallback(mCallback)) {
286d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                Log.e(TAG, "Callback registration failed. Initialization incomplete.");
287d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                return false;
288d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            }
28979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
290d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
291d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        return true;
29279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
29379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
29479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    private void supplicantServiceDiedHandler() {
29579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        synchronized (mLock) {
29679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicant = null;
29779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mISupplicantP2pIface = null;
29879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
29979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
30079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
30124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
30224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
30324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
30424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
30524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
30624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
30724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
30824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
30924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
31061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Signals whether Initialization completed successfully. Only necessary for testing, is not
31161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * needed to guard calls etc.
31224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
31324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationComplete() {
31424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mISupplicantP2pIface != null;
31524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
31624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
31779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    /**
31879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
31979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
32079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected IServiceManager getServiceManagerMockable() throws RemoteException {
321006eb17e06a7843e3da3bf939833b94e58a5a034Yifan Hong        return IServiceManager.getService();
32279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
32379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
32479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected ISupplicant getSupplicantMockable() throws RemoteException {
32579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return ISupplicant.getService();
32679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
32779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
32879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected ISupplicantP2pIface getP2pIfaceMockable(ISupplicantIface iface) {
32979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        return ISupplicantP2pIface.asInterface(iface.asBinder());
33079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
33179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
332eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    protected ISupplicantP2pNetwork getP2pNetworkMockable(ISupplicantNetwork network) {
333eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        return ISupplicantP2pNetwork.asInterface(network.asBinder());
334eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
33579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
33679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected static void logd(String s) {
33779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        if (DBG) Log.d(TAG, s);
33879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
33979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
34079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    protected static void logCompletion(String operation, SupplicantStatus status) {
34161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        if (status == null) {
34261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Log.w(TAG, operation + " failed: no status code returned.");
34361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        } else if (status.code == SupplicantStatusCode.SUCCESS) {
34479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logd(operation + " completed successfully.");
34579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        } else {
34679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            Log.w(TAG, operation + " failed: " + status.code + " (" + status.debugMessage + ")");
34779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
34879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
34979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
35079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
35161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
35261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Returns false if SupplicantP2pIface is null, and logs failure to call methodStr
35361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
35461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private boolean checkSupplicantP2pIfaceAndLogFailure(String method) {
35561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        if (mISupplicantP2pIface == null) {
35661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Log.e(TAG, "Can't call " + method + ": ISupplicantP2pIface is null");
35761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
35861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
35961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        return true;
36061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
36161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
36261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private int wpsInfoToConfigMethod(int info) {
36361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        switch (info) {
36461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.PBC:
36561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.PBC;
36661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
36761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.DISPLAY:
36861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.DISPLAY;
36961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
37061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.KEYPAD:
37161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            case WpsInfo.LABEL:
37261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return ISupplicantP2pIface.WpsProvisionMethod.KEYPAD;
37361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
37461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            default:
37561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Unsupported WPS provision method: " + info);
37661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
37761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
37861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
37961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
38061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
38161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Retrieves the name of the network interface.
38279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     *
38361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return name Name of the network interface, e.g., wlan0
38479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski     */
38561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getName() {
38661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
38761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getName")) return null;
38861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult("getName()");
38979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
39061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
39161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getName(
39261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String name) -> {
39361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, name);
39461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
39561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
39661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
39761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
39861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
39961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
40079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
40161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
40279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
40361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
40461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
40561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Register for callbacks from this interface.
40661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
40761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * These callbacks are invoked for events that are specific to this interface.
40861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Registration of multiple callback objects is supported. These objects must
40961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * be automatically deleted when the corresponding client process is dead or
41061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * if this interface is removed.
41161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
41261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param callback An instance of the |ISupplicantP2pIfaceCallback| HIDL
41361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        interface object.
41461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
41561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
41661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean registerCallback(ISupplicantP2pIfaceCallback receiver) {
41761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
41861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("registerCallback")) return false;
41961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("registerCallback()");
42061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
42161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.registerCallback(receiver));
42261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
42361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
42461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
42561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
42661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
42761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
42861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
42961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
43061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
43161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
43261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate a P2P service discovery with a (optional) timeout.
43361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
43496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param timeout Max time to be spent is peforming discovery.
43561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        Set to 0 to indefinely continue discovery untill and explicit
43661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        |stopFind| is sent.
43761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
43861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
43961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean find(int timeout) {
44061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
44161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("find")) return false;
44261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
44361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (timeout < 0) {
44461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid timeout value: " + timeout);
44561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
44661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
44761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("find(" + timeout + ")");
44861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
44961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.find(timeout));
45061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
45161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
45261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
45361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
45461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
45561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
45661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
45761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
45861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
45961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
46061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Stop an ongoing P2P service discovery.
46161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
46261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
46361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
46461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean stopFind() {
46561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
46661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("stopFind")) return false;
46761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("stopFind()");
46861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
46961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.stopFind());
47061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
47161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
47261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
47361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
47461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
47561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
47661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
47761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
47861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
47961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
48061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Flush P2P peer table and state.
48161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
48261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
48361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
48461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean flush() {
48561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
48661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("flush")) return false;
48761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("flush()");
48861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
48961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.flush());
49061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
49161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
49261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
49361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
49461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
49561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
49661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
49761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
49861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
49961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
50061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to flush all services from the
50161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * device.
50261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
50361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
50461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
50561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceFlush() {
50661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
50761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceFlush")) return false;
50861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("serviceFlush()");
50961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
51061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.flushServices());
51161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
51261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
51361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
51461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
51561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
51661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
51761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
51861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
51961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
52061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
52161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Turn on/off power save mode for the interface.
52261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
52361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
52461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable Indicate if power save is to be turned on/off.
52561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
52661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
52761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
52861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setPowerSave(String groupIfName, boolean enable) {
52961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
53061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setPowerSave")) return false;
53161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
53261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setPowerSave(" + groupIfName + ", " + enable + ")");
53361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
53461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setPowerSave(groupIfName, enable));
53561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
53661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
53761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
53861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
53961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
54061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
54161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
54261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
54361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
54461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
54561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set the Maximum idle time in seconds for P2P groups.
54661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This value controls how long a P2P group is maintained after there
54761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * is no other members in the group. As a group owner, this means no
54861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * associated stations in the group. As a P2P client, this means no
54961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group owner seen in scan results.
55061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
55161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
55261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param timeoutInSec Timeout value in seconds.
55361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
55461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
55561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
55661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setGroupIdle(String groupIfName, int timeoutInSec) {
55761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
55861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setGroupIdle")) return false;
55961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Basic checking here. Leave actual parameter validation to supplicant.
56061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (timeoutInSec < 0) {
56161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid group timeout value " + timeoutInSec);
56261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
56361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
56461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
56561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
56661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setGroupIdle(" + groupIfName + ", " + timeoutInSec+ ")");
56761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
56861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setGroupIdle(groupIfName, timeoutInSec));
56961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
57061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
57161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
57261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
57361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
57461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
57561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
57661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
57761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
57861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
57961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set the postfix to be used for P2P SSID's.
58061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
58161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param postfix String to be appended to SSID.
58261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
58361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
58461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
58561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setSsidPostfix(String postfix) {
58661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
58761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setSsidPostfix")) return false;
58861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Basic checking here. Leave actual parameter validation to supplicant.
58961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (postfix == null) {
59061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid SSID postfix value (null).");
59161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
59261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
59361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
59461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("setSsidPostfix(" + postfix + ")");
59561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
59661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setSsidPostfix(
59761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        NativeUtil.decodeSsid("\"" + postfix + "\"")));
59861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
59961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
60061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
60161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
60261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not decode SSID.", e);
60361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
60461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
60561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
60661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
60761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
60861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
60961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
61061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
61161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
61261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Start P2P group formation with a discovered P2P peer. This includes
61361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * optional group owner negotiation, group interface setup, provisioning,
61461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * and establishing data connection.
61561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
61661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param config Configuration to use to connect to remote device.
61761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param joinExistingGroup Indicates that this is a command to join an
61861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        existing group as a client. It skips the group owner negotiation
61961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        part. This must send a Provision Discovery Request message to the
62061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        target group owner before associating for WPS provisioning.
62161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
62261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return String containing generated pin, if selected provision method
62361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        uses PIN.
62461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
62561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String connect(WifiP2pConfig config, boolean joinExistingGroup) {
62696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (config == null) return null;
62761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
62861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setSsidPostfix")) return null;
62961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
63061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config == null) {
63161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not connect: null config.");
63261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
63361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
63461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
63561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config.deviceAddress == null) {
63661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse null mac address.");
63761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
63861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
63961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
64061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] peerAddress = null;
64161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
64261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                peerAddress = NativeUtil.macAddressToByteArray(config.deviceAddress);
64361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
64461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
64561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
64661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
64761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
64861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int provisionMethod = wpsInfoToConfigMethod(config.wps.setup);
64961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (provisionMethod == RESULT_NOT_VALID) {
65061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid WPS config method: " + config.wps.setup);
65161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
65261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
65361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
65461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // NOTE: preSelectedPin cannot be null, otherwise hal would crash.
65561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            String preSelectedPin = "";
65661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (provisionMethod == ISupplicantP2pIface.WpsProvisionMethod.DISPLAY) {
65761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                preSelectedPin = config.wps.pin;
65861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (preSelectedPin == null) {
65961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "PIN must be supplied when provision method is DISPLAY.");
66061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return null;
66161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
66261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
66361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
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                }
67261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
67361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
67461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult(
67561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "connect(" + config.deviceAddress + ")");
67661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
67761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.connect(
67861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        peerAddress, provisionMethod, preSelectedPin, joinExistingGroup,
67961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        persistent, goIntent,
68061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String generatedPin) -> {
68161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, generatedPin);
68261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
68361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
68461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
68561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
68661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
68761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
68861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
68961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
69061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
69161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
69261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel an ongoing P2P group formation and joining-a-group related
69361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * operation. This operation unauthorizes the specific peer device (if any
69461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * had been authorized to start group formation), stops P2P find (if in
69561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * progress), stops pending operations for join-a-group, and removes the
69661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * P2P group interface (if one was used) that is in the WPS provisioning
69761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * step. If the WPS provisioning step has been completed, the group is not
69861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * terminated.
69961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
70061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
70161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
70261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelConnect() {
70361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
70461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelConnect")) return false;
70561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("cancelConnect()");
70661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
70761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelConnect());
70861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
70961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
71061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
71161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
71261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
71361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
71461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
71561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
71661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
71761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
71861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Send P2P provision discovery request to the specified peer. The
71961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * parameters for this command are the P2P device address of the peer and the
72061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * desired configuration method.
72161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
72261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param config Config class describing peer setup.
72361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
72461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
72561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
72661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean provisionDiscovery(WifiP2pConfig config) {
72796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (config == null) return false;
72861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
72961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("provisionDiscovery")) return false;
73061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
73161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int targetMethod = wpsInfoToConfigMethod(config.wps.setup);
73261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (targetMethod == -1) {
73361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Unrecognized WPS configuration method: " + config.wps.setup);
73461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
73561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
73661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
73761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (config.deviceAddress == null) {
73861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse null mac address.");
73961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
74061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
74161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
74261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
74361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(config.deviceAddress);
74461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
74561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
74661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
74761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
74861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
74961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
75061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "provisionDiscovery(" + config.deviceAddress + ", " + config.wps.setup + ")");
75161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
75261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.provisionDiscovery(macAddress, targetMethod));
75361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
75461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
75561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
75661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
75761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
75861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
75961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
76061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
76161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
76261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
76361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
76461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Invite a device to a persistent group.
76561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If the peer device is the group owner of the persistent group, the peer
76661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * parameter is not needed. Otherwise it is used to specify which
76761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * device to invite. |goDeviceAddress| parameter may be used to override
76861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the group owner device address for Invitation Request should it not be
76961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * known for some reason (this should not be needed in most cases).
77061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
77196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param group Group object to use.
77261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to invite.
77361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
77461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
77561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
77661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean invite(WifiP2pGroup group, String peerAddress) {
77796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(peerAddress)) return false;
77861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
77961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("invite")) return false;
78061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group == null) {
78161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot invite to null group.");
78261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
78361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
78461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
78561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group.getOwner() == null) {
78661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot invite to group with null owner.");
78761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
78861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
78961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
79061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (group.getOwner().deviceAddress == null) {
79161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group owner has no mac address.");
79261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
79361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
79461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
79561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] ownerMacAddress = null;
79661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
79761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                ownerMacAddress = NativeUtil.macAddressToByteArray(group.getOwner().deviceAddress);
79861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
79961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group owner mac address parse error.", e);
80061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
80161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
80261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
80361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
80461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
80561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
80661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
80761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
80861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] peerMacAddress;
80961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
81061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                peerMacAddress = NativeUtil.macAddressToByteArray(peerAddress);
81161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
81261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Peer mac address parse error.", e);
81361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
81461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
81561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
81661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
81761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "invite(" + group.getInterface() + ", " +
81861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    group.getOwner().deviceAddress + ", " + peerAddress + ")");
81961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
82061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.invite(
82161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        group.getInterface(), ownerMacAddress, peerMacAddress));
82261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
82361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
82461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
82561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
82661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
82761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
82861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
82961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
83061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
83161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
83261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Reject connection attempt from a peer (specified with a device
83361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * address). This is a mechanism to reject a pending group owner negotiation
83461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * with a peer and request to automatically block any further connection or
83561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * discovery of the peer.
83661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
83761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to reject.
83861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
83961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return boolean value indicating whether operation was successful.
84061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
84161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean reject(String peerAddress) {
84261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
84361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("reject")) return false;
84461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
84561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
84661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse rejected peer's mac address.");
84761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
84861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
84961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
85061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
85161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
85261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
85361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse peer mac address.", e);
85461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
85561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
85661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
85761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result =
85861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("reject(" + peerAddress + ")");
85961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
86061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.reject(macAddress));
86161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
86261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
86361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
86461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
86561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
86661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
86761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
86861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
86961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
87061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
87161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
87261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the MAC address of the device.
87361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
87461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return MAC address of the device.
87561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
87661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getDeviceAddress() {
87761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
87861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getDeviceAddress")) return null;
87961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult("getDeviceAddress()");
88061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
88161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getDeviceAddress((SupplicantStatus status, byte[] address) -> {
88261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    String parsedAddress = null;
88361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    try {
88461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        parsedAddress = NativeUtil.macAddressFromByteArray(address);
88561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } catch (Exception e) {
88661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        Log.e(TAG, "Could not process reported address.", e);
88761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
88861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    result.setResult(status, parsedAddress);
88961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                });
89061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
89161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
89261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
89361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
89461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
89561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
89661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
89761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
89861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
89961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
90061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
90161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
90261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the operational SSID of the device.
90361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
90496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param address MAC address of the peer.
90561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
90661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return SSID of the device.
90761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
90861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String getSsid(String address) {
90961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
91061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getSsid")) return null;
91161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
91261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (address == null) {
91361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
91461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
91561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
91661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
91761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
91861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(address);
91961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
92061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse mac address.", e);
92161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
92261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
92361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
92461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result =
92561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("getSsid(" + address + ")");
92661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
92761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getSsid(
92861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, (SupplicantStatus status, ArrayList<Byte> ssid) -> {
92961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            String ssidString = null;
93061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            if (ssid != null) {
93161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                try {
93261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    ssidString = NativeUtil.encodeSsid(ssid);
93361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                } catch (Exception e) {
93461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    Log.e(TAG, "Could not encode SSID.", e);
93561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                }
93661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
93761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, ssidString);
93861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
93961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
94061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
94161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
94261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
94361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
94461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
94561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
94661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
94761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
94861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
94961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
95061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
95161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Reinvoke a device from a persistent group.
95261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
95361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param networkId Used to specify the persistent group.
95461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to reinvoke.
95561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
95661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
95761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
95861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean reinvoke(int networkId, String peerAddress) {
95996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(peerAddress) || networkId < 0) return false;
96061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
96161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("reinvoke")) return false;
96261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
96361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
96461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
96561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
96661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
96761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
96861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
96961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
97061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse mac address.", e);
97161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
97261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
97361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
97461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
97561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "reinvoke(" + networkId + ", " + peerAddress + ")");
97661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
97761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.reinvoke(networkId, macAddress));
97861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
97961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
98061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
98161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
98261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
98361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
98461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
98561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
98661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
98761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
98861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
98961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set up a P2P group owner manually (i.e., without group owner
99061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * negotiation with a specific peer). This is also known as autonomous
99161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group owner.
99261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
99361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param networkId Used to specify the restart of a persistent group.
99461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param isPersistent Used to request a persistent group to be formed.
99561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
99661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
99761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
99861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupAdd(int networkId, boolean isPersistent) {
99961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
100061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("groupAdd")) return false;
100161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result =
100261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    new SupplicantResult("groupAdd(" + networkId + ", " + isPersistent + ")");
100361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
100461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.addGroup(isPersistent, networkId));
100561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
100661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
100761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
100861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
100961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
101061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
101161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
101261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
101361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
101461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set up a P2P group owner manually.
101561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This is a helper method that invokes groupAdd(networkId, isPersistent) internally.
101661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
101761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param isPersistent Used to request a persistent group to be formed.
101861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
101961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
102061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
102161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupAdd(boolean isPersistent) {
102261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        // Supplicant expects networkId to be -1 if not supplied.
102361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        return groupAdd(-1, isPersistent);
102461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
102561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
102661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
102761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
102861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Terminate a P2P group. If a new virtual network interface was used for
102961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * the group, it must also be removed. The network interface name of the
103061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * group interface is used as a parameter for this command.
103161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
103296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param groupName Group interface name to use.
103361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
103461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
103561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
103661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean groupRemove(String groupName) {
103796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupName)) return false;
103861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
103961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("groupRemove")) return false;
104061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult("groupRemove(" + groupName + ")");
104161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
104261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.removeGroup(groupName));
104361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
104461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
104561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
104661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
104761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
104861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
104961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
105061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
105161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
105261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
105361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Gets the capability of the group which the device is a
105461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * member of.
105561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
105661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the peer.
105761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
105861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return combination of |GroupCapabilityMask| values.
105961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
106061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public int getGroupCapability(String peerAddress) {
106161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
106261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("getGroupCapability")) {
106361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
106461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
106561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
106661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
106761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
106861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
106961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
107061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
107161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
107261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
107361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
107461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse group address.", e);
107561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
107661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
107761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
107861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Integer> capability = new SupplicantResult(
107961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "getGroupCapability(" + peerAddress + ")");
108061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
108161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.getGroupCapability(
108261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, (SupplicantStatus status, int cap) -> {
108361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            capability.setResult(status, cap);
108461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
108561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
108661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
108761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
108861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
108961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
109061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!capability.isSuccess()) {
109161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return RESULT_NOT_VALID;
109261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
109361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
109461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return capability.getResult();
109561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
109661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
109761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
109861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
109961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
110061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Configure Extended Listen Timing.
110161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
110261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If enabled, listen state must be entered every |intervalInMillis| for at
110361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * least |periodInMillis|. Both values have acceptable range of 1-65535
110461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * (with interval obviously having to be larger than or equal to duration).
110561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * If the P2P module is not idle at the time the Extended Listen Timing
110661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * timeout occurs, the Listen State operation must be skipped.
110761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
110861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable Enables or disables listening.
110961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param periodInMillis Period in milliseconds.
111061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param intervalInMillis Interval in milliseconds.
111161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
111261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
111361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
111461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean configureExtListen(boolean enable, int periodInMillis, int intervalInMillis) {
111596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (enable && intervalInMillis < periodInMillis) {
111696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return false;
111796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
111861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
111961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("configureExtListen")) return false;
112061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
112161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // If listening is disabled, wpa supplicant expects zeroes.
112261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!enable) {
112361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                periodInMillis = 0;
112461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                intervalInMillis = 0;
112561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
112661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
112761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Verify that the integers are not negative. Leave actual parameter validation to
112861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // supplicant.
112961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (periodInMillis < 0 || intervalInMillis < 0) {
113061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid parameters supplied to configureExtListen: " +
113161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        periodInMillis + ", " + intervalInMillis);
113261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
113361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
113461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
113561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
113661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "configureExtListen(" + periodInMillis + ", " + intervalInMillis + ")");
113761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
113861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(
113961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        mISupplicantP2pIface.configureExtListen(periodInMillis, intervalInMillis));
114061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
114161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
114261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
114361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
114461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
114561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
114661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
114761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
114861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
114961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
115061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
115161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set P2P Listen channel.
115261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
115361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * When specifying a social channel on the 2.4 GHz band (1/6/11) there is no
115461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * need to specify the operating class since it defaults to 81. When
115561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * specifying a social channel on the 60 GHz band (2), specify the 60 GHz
115661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * operating class (180).
115761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
115861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param channel Wifi channel. eg, 1, 6, 11.
115961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param operatingClass Operating Class indicates the channel set of the AP
116061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        indicated by this BSSID
116161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
116261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
116361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
116461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setListenChannel(int channel, int operatingClass) {
116561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
116661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setListenChannel")) return false;
116761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Verify that the integers are not negative. Leave actual parameter validation to
116861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // supplicant.
116961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (channel < 0 || operatingClass < 0) {
117061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Invalid values supplied to setListenChannel: " +
117161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        channel + ", " + operatingClass);
117261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
117361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
117461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
117561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
117661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setListenChannel(" + channel + ", " + operatingClass + ")");
117761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
117861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setListenChannel(channel, operatingClass));
117961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
118061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
118161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
118261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
118361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
118461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
118561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
118661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
118761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
118861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
118961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to add a upnp/bonjour service.
119061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
119196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param servInfo List of service queries.
119261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
119361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
119461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
119561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceAdd(WifiP2pServiceInfo servInfo) {
119661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
119761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceAdd")) return false;
119861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
119961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (servInfo == null) {
120061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Null service info passed.");
120161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
120261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
120361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
120461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            for (String s : servInfo.getSupplicantQueryList()) {
120561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (s == null) {
120661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Invalid service description (null).");
120761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
120861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
120961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
121061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                String[] data = s.split(" ");
121161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (data.length < 3) {
121261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Service specification invalid: " + s);
121361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
121461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
121561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
121661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                SupplicantResult<Void> result = null;
121761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
121861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    if ("upnp".equals(data[0])) {
121961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        int version = 0;
122061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        try {
122161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            version = Integer.parseInt(data[1]);
122261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        } catch (NumberFormatException e) {
122361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            Log.e(TAG, "UPnP Service specification invalid: " + s, e);
122461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            return false;
122561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
122661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
122761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result = new SupplicantResult(
122861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                "addUpnpService(" + data[1] + ", " + data[2] + ")");
122961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result.setResult(mISupplicantP2pIface.addUpnpService(version, data[2]));
123061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else if ("bonjour".equals(data[0])) {
123161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        if (data[1] != null && data[2] != null) {
123261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> request = null;
123361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> response = null;
123461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            try {
123561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                request = NativeUtil.byteArrayToArrayList(
123661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                        NativeUtil.hexStringToByteArray(data[1]));
123761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                response = NativeUtil.byteArrayToArrayList(
123861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                        NativeUtil.hexStringToByteArray(data[2]));
123961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            } catch (Exception e) {
124061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                Log.e(TAG, "Invalid bonjour service description.");
124161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                return false;
124261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
124361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result = new SupplicantResult(
124461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    "addBonjourService(" + data[1] + ", " + data[2] + ")");
124561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(
124661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    mISupplicantP2pIface.addBonjourService(request, response));
124761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
124861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else {
124961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        return false;
125061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
125161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (RemoteException e) {
125261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
125361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    supplicantServiceDiedHandler();
125461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
125561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
125661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (result == null || !result.isSuccess()) return false;
125761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
125861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
125961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return true;
126061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
126161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
126261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
126361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
126461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
126561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * This command can be used to remove a upnp/bonjour service.
126661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
126796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param servInfo List of service queries.
126861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
126961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
127061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
127161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean serviceRemove(WifiP2pServiceInfo servInfo) {
127261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
127361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("serviceRemove")) return false;
127461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
127561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (servInfo == null) {
127661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Null service info passed.");
127761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
127861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
127961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
128061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            for (String s : servInfo.getSupplicantQueryList()) {
128161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (s == null) {
128261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Invalid service description (null).");
128361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
128461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
128561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
128661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                String[] data = s.split(" ");
128761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (data.length < 3) {
128861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Service specification invalid: " + s);
128961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
129061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
129161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
129261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                SupplicantResult<Void> result = null;
129361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
129461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    if ("upnp".equals(data[0])) {
129561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        int version = 0;
129661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        try {
129761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            version = Integer.parseInt(data[1]);
129861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        } catch (NumberFormatException e) {
129961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            Log.e(TAG, "UPnP Service specification invalid: " + s, e);
130061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            return false;
130161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
130261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result = new SupplicantResult(
130361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                "removeUpnpService(" + data[1] + ", " + data[2] + ")");
130461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        result.setResult(mISupplicantP2pIface.removeUpnpService(version, data[2]));
130561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else if ("bonjour".equals(data[0])) {
130661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        if (data[1] != null) {
130761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            ArrayList<Byte> request = null;
130861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            try {
130961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                request = NativeUtil.byteArrayToArrayList(
131061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                    NativeUtil.hexStringToByteArray(data[1]));
131161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            } catch (Exception e) {
131261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                Log.e(TAG, "Invalid bonjour service description.");
131361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                                return false;
131461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            }
131561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result = new SupplicantResult("removeBonjourService(" + data[1] + ")");
131661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(mISupplicantP2pIface.removeBonjourService(request));
131761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        }
131861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    } else {
131961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        Log.e(TAG, "Unknown / unsupported P2P service requested: " + data[0]);
132061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        return false;
132161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    }
132261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (RemoteException e) {
132361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
132461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    supplicantServiceDiedHandler();
132561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
132661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
132761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                if (result == null || !result.isSuccess()) return false;
132861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
132961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
133061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return true;
133161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
133261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
133361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
133461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
133561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
133661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Schedule a P2P service discovery request. The parameters for this command
133761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * are the device address of the peer device (or 00:00:00:00:00:00 for
133861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * wildcard query that is sent to every discovered P2P peer that supports
133961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * service discovery) and P2P Service Query TLV(s) as hexdump.
134061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
134161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param peerAddress MAC address of the device to discover.
134261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param query Hex dump of the query data.
134361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return identifier Identifier for the request. Can be used to cancel the
134461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *         request.
134561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
134661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String requestServiceDiscovery(String peerAddress, String query) {
134761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
134861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("requestServiceDiscovery")) return null;
134961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
135061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (peerAddress == null) {
135161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse peer mac address.");
135261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
135361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
135461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
135561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
135661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                macAddress = NativeUtil.macAddressToByteArray(peerAddress);
135761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
135861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not process peer MAC address.", e);
135961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
136061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
136161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
136261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (query == null) {
136361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse service discovery query: " + query);
136461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
136561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
136661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            ArrayList<Byte> binQuery = null;
136761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
136861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                binQuery = NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(query));
136961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
137061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse service query.", e);
137161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
137261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
137361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
137461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Long> result = new SupplicantResult(
137561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "requestServiceDiscovery(" + peerAddress + ", " + query + ")");
137661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
137761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.requestServiceDiscovery(
137861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        macAddress, binQuery,
137961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, long identifier) -> {
138061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, new Long(identifier));
138161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
138261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
138361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
138461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
138561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
138661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
138761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            Long value = result.getResult();
138861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (value == null) return null;
138961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return value.toString();
139061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
139161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
139261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
139361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
139461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
139561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel a previous service discovery request.
139661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
139761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param identifier Identifier for the request to cancel.
139861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
139961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
140061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelServiceDiscovery(String identifier) {
140161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
140261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelServiceDiscovery")) return false;
140361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (identifier == null) {
140461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "cancelServiceDiscovery requires a valid tag.");
140561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
140661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
140761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
140861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            int id = 0;
140961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
141061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                id = Integer.parseInt(identifier);
141161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (NumberFormatException e) {
141261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Service discovery identifier invalid: " + identifier, e);
141361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
141461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
141561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
141661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
141761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "cancelServiceDiscovery(" + identifier + ")");
141861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
141961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelServiceDiscovery(id));
142061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
142161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
142261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
142361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
142461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
142561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
142661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
142761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
142861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
142961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
143061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
143161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Send driver command to set Miracast mode.
143261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
143361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param mode Mode of Miracast.
143461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
143561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
143661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setMiracastMode(int mode) {
143761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
143861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setMiracastMode")) return false;
143961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte targetMode = ISupplicantP2pIface.MiracastMode.DISABLED;
144061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
144161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            switch (mode) {
144261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                case WifiP2pManager.MIRACAST_SOURCE:
144361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    targetMode = ISupplicantP2pIface.MiracastMode.SOURCE;
144461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    break;
144561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
144661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                case WifiP2pManager.MIRACAST_SINK:
144761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    targetMode = ISupplicantP2pIface.MiracastMode.SINK;
144861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    break;
144961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
145061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
145161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
145261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setMiracastMode(" + mode + ")");
145361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
145461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setMiracastMode(targetMode));
145561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
145661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
145761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
145861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
145961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
146061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
146161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
146261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
146361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
146461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
146561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
146661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Push Button setup.
146761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * The PBC operation requires that a button is also pressed at the
146861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * AP/Registrar at about the same time (2 minute window).
146961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
147061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
147161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
147261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
147361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
147461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean startWpsPbc(String groupIfName, String bssid) {
147596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(bssid)) return false;
147661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
147761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPbc")) return false;
147861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
147961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS PBC.");
148061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
148161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
148261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
148361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Null values should be fine, since bssid can be empty.
148461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
148561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (bssid != null) {
148661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
148761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    macAddress = NativeUtil.macAddressToByteArray(bssid);
148861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (Exception e) {
148961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Could not parse BSSID.", e);
149061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return false;
149161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
149261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
149361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
149461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
149561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPbc(" + groupIfName + ", " + bssid + ")");
149661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
149761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.startWpsPbc(groupIfName, macAddress));
149861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
149961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
150061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
150161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
150261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
150361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
150461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
150561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
150661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
150761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
150861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
150961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Pin Keypad setup.
151061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
151161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
151261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param pin 8 digit pin to be used.
151361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
151461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
151561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean startWpsPinKeypad(String groupIfName, String pin) {
151696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(pin)) return false;
151761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
151861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinKeypad")) return false;
151961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
152061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
152161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
152261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
152361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (pin == null) {
152461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "PIN required when requesting WPS KEYPAD.");
152561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
152661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
152761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
152861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
152961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPinKeypad(" + groupIfName + ", " + pin + ")");
153061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
153161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.startWpsPinKeypad(groupIfName, pin));
153261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
153361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
153461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
153561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
153661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
153761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
153861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
153961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
154061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
154161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
154261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
154361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Initiate WPS Pin Display setup.
154461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
154561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
154661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
1547b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return generated pin if operation was successful, null otherwise.
154861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
154961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public String startWpsPinDisplay(String groupIfName, String bssid) {
155096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (TextUtils.isEmpty(groupIfName) || TextUtils.isEmpty(bssid)) return null;
155161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
155261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("startWpsPinDisplay")) return null;
155361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
155461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
155561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return null;
155661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
155761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
155861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            // Null values should be fine, since bssid can be empty.
155961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] macAddress = null;
156061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (bssid != null) {
156161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                try {
156261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    macAddress = NativeUtil.macAddressToByteArray(bssid);
156361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                } catch (Exception e) {
156461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    Log.e(TAG, "Could not parse BSSID.", e);
156561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    return null;
156661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                }
156761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
156861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
156961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<String> result = new SupplicantResult(
157061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "startWpsPinDisplay(" + groupIfName + ", " + bssid + ")");
157161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
157261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                mISupplicantP2pIface.startWpsPinDisplay(
157361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        groupIfName, macAddress,
157461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        (SupplicantStatus status, String generatedPin) -> {
157561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                            result.setResult(status, generatedPin);
157661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                        });
157761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
157861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
157961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
158061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
158161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
158261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.getResult();
158361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
158461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
158561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
158661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
158761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
158861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Cancel any ongoing WPS operations.
158961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
159061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param groupIfName Group interface name to use.
159161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
159261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
159361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean cancelWps(String groupIfName) {
159461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
159561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("cancelWps")) return false;
159661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (groupIfName == null) {
159761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Group name required when requesting WPS KEYPAD.");
159861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
159961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
160061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
160161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
160261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "cancelWps(" + groupIfName + ")");
160361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
160461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.cancelWps(groupIfName));
160561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
160661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
160761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
160861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
160961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
161061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
161161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
161261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
161361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
161461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
161561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
161661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Enable/Disable Wifi Display.
161761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
161861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param enable true to enable, false to disable.
161961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
162061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
162161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean enableWfd(boolean enable) {
162261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
162361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("enableWfd")) return false;
162461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
162561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
162661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "enableWfd(" + enable + ")");
162761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
162861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.enableWfd(enable));
162961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
163061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
163161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
163261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
163361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
163561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
163661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
163761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
163961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /**
164061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Set Wifi Display device info.
164161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
164261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @param info WFD device info as described in section 5.1.2 of WFD technical
164361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *        specification v1.0.0.
164461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * @return true, if operation was successful.
164561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
164661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    public boolean setWfdDeviceInfo(String info) {
164761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        synchronized (mLock) {
164861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (!checkSupplicantP2pIfaceAndLogFailure("setWfdDeviceInfo")) return false;
164961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
165061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            if (info == null) {
165161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Cannot parse null WFD info string.");
165261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
165361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
165461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            byte[] wfdInfo = null;
165561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
165661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                wfdInfo = NativeUtil.hexStringToByteArray(info);
165761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (Exception e) {
165861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "Could not parse WFD Device Info string.");
165961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                return false;
166061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
166161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
166261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            SupplicantResult<Void> result = new SupplicantResult(
166361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                    "setWfdDeviceInfo(" + info + ")");
166461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            try {
166561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                result.setResult(mISupplicantP2pIface.setWfdDeviceInfo(wfdInfo));
166661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            } catch (RemoteException e) {
166761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
166861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski                supplicantServiceDiedHandler();
166961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            }
167061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
167161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return result.isSuccess();
167261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
167361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    }
167461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1675eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
167696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Remove network with provided id.
167796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
167896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param networkId Id of the network to lookup.
167996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true, if operation was successful.
168096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
168196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean removeNetwork(int networkId) {
168296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
168396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("removeNetwork")) return false;
168496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
168596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
168696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "removeNetwork(" + networkId + ")");
168796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
168896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.removeNetwork(networkId));
168996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
169096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
169196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
169296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
169396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
169496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
169596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
169696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
169796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
169896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
1699eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * List the networks saved in wpa_supplicant.
1700eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1701eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return List of network ids.
1702eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1703eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    private List<Integer> listNetworks() {
1704eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1705eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("listNetworks")) return null;
1706eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult("listNetworks()");
1707eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            try {
1708eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                mISupplicantP2pIface.listNetworks(
1709eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        (SupplicantStatus status, ArrayList<Integer> networkIds) -> {
1710eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            result.setResult(status, networkIds);
1711eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        });
1712eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            } catch (RemoteException e) {
1713eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1714eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                supplicantServiceDiedHandler();
1715eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1716eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            return result.getResult();
1717eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1718eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
171961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1720eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
1721eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * Get the supplicant P2p network object for the specified network ID.
1722eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1723eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @param networkId Id of the network to lookup.
1724eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return ISupplicantP2pNetwork instance on success, null on failure.
1725eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1726eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    private ISupplicantP2pNetwork getNetwork(int networkId) {
1727eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1728eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNetwork")) return null;
1729eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            SupplicantResult<ISupplicantNetwork> result =
1730eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    new SupplicantResult("getNetwork(" + networkId + ")");
1731eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            try {
1732eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                mISupplicantP2pIface.getNetwork(
1733eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        networkId,
1734eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        (SupplicantStatus status, ISupplicantNetwork network) -> {
1735eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            result.setResult(status, network);
1736eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        });
1737eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            } catch (RemoteException e) {
1738eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1739eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                supplicantServiceDiedHandler();
1740eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1741eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (result.getResult() == null) {
1742eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                Log.e(TAG, "getNetwork got null network");
1743eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                return null;
1744eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1745eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            return getP2pNetworkMockable(result.getResult());
1746eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1747eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
174861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1749eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    /**
1750eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * Populate list of available networks or update existing list.
1751eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     *
1752eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     * @return true, if list has been modified.
1753eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius     */
1754eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    public boolean loadGroups(WifiP2pGroupList groups) {
1755eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        synchronized (mLock) {
1756eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("loadGroups")) return false;
1757eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            List<Integer> networkIds = listNetworks();
1758eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            if (networkIds == null || networkIds.isEmpty()) {
1759eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                return false;
1760eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1761eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            for (Integer networkId : networkIds) {
1762eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                ISupplicantP2pNetwork network = getNetwork(networkId);
1763eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (network == null) {
1764eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "Failed to retrieve network object for " + networkId);
1765eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    continue;
1766eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1767eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<Boolean> resultIsCurrent =
1768eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("isCurrent(" + networkId + ")");
1769eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1770eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.isCurrent(
1771eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, boolean isCurrent) -> {
1772eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultIsCurrent.setResult(status, isCurrent);
1773eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1774eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1775eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1776eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1777eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1778eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (!resultIsCurrent.isSuccess() || !resultIsCurrent.getResult()) {
1779eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.i(TAG, "Skipping non current network");
1780eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    continue;
1781eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1782eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1783eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                WifiP2pGroup group = new WifiP2pGroup();
1784eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                group.setNetworkId(networkId);
1785eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1786eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                // Now get the ssid, bssid and other flags for this network.
1787eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<ArrayList> resultSsid =
1788eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("getSsid(" + networkId + ")");
1789eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1790eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.getSsid(
1791eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, ArrayList<Byte> ssid) -> {
1792eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultSsid.setResult(status, ssid);
1793eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1794eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1795eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1796eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1797eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1798eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultSsid.isSuccess() && resultSsid.getResult() != null
1799eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        && !resultSsid.getResult().isEmpty()) {
1800eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    group.setNetworkName(NativeUtil.encodeSsid(resultSsid.getResult()));
1801eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
180261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
1803eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<byte[]> resultBssid =
1804eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("getBssid(" + networkId + ")");
1805eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1806eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.getBssid(
1807eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, byte[] bssid) -> {
1808eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultBssid.setResult(status, bssid);
1809eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1810eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1811eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1812eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1813eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1814eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultBssid.isSuccess() && !ArrayUtils.isEmpty(resultBssid.getResult())) {
1815eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    WifiP2pDevice device = new WifiP2pDevice();
1816eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    device.deviceAddress =
1817eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            NativeUtil.macAddressFromByteArray(resultBssid.getResult());
1818eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    group.setOwner(device);
1819eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1820eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius
1821eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                SupplicantResult<Boolean> resultIsGo =
1822eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                        new SupplicantResult("isGo(" + networkId + ")");
1823eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                try {
1824eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    network.isGo(
1825eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            (SupplicantStatus status, boolean isGo) -> {
1826eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                                resultIsGo.setResult(status, isGo);
1827eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                            });
1828eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                } catch (RemoteException e) {
1829eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    Log.e(TAG, "ISupplicantP2pIface exception: " + e);
1830eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    supplicantServiceDiedHandler();
1831eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1832eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                if (resultIsGo.isSuccess()) {
1833eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                    group.setIsGroupOwner(resultIsGo.getResult());
1834eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                }
1835eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius                groups.add(group);
1836eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius            }
1837eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        }
1838eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius        return true;
1839eed5100c0a64dc8d12651226bb9fd2fad4b2891bRoshan Pius    }
184061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
184196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
184296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Set WPS device name.
184396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
184496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param name String to be set.
184596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if request is sent successfully, false otherwise.
184696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
184796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean setWpsDeviceName(String name) {
184896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (name == null) {
184996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return false;
185096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
185196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
185296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceName")) return false;
185396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
185496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "setWpsDeviceName(" + name + ")");
185596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
185696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.setWpsDeviceName(name));
185796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
185896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
185996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
186096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
186196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
186296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
186396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
186496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
186596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
186696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Set WPS device type.
186796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
186896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
186996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if request is sent successfully, false otherwise.
187096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
187196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean setWpsDeviceType(String typeStr) {
187296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
187396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (!match.find() || match.groupCount() != 3) {
187496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            Log.e(TAG, "Malformed WPS device type " + typeStr);
187596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return false;
187696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
187796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        short categ = Short.parseShort(match.group(1));
187896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
187996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        short subCateg = Short.parseShort(match.group(3));
188096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
188196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        byte[] bytes = new byte[8];
188296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
188396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        byteBuffer.putShort(categ);
188496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        byteBuffer.put(oui);
188596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        byteBuffer.putShort(subCateg);
188696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
188796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("setWpsDeviceType")) return false;
188896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
188996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "setWpsDeviceType(" + typeStr + ")");
189096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
189196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.setWpsDeviceType(bytes));
189296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
189396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
189496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
189596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
189696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
189796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
189896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
189996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
190096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
190196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Get NFC handover request message.
190296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
190396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return select message if created successfully, null otherwise.
190496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
190596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public String getNfcHandoverRequest() {
190696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
190796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverRequest")) return null;
190896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult(
190996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "getNfcHandoverRequest()");
191096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
191196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                mISupplicantP2pIface.createNfcHandoverRequestMessage(
191296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        (SupplicantStatus status, ArrayList<Byte> message) -> {
191396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            result.setResult(status, message);
191496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        });
191596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
191696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
191796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
191896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
191996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!result.isSuccess()) {
192096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                return null;
192196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
192296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
192396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return NativeUtil.hexStringFromByteArray(
192496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    NativeUtil.byteArrayFromArrayList(result.getResult()));
192596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
192696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
192796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
192896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
192996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Get NFC handover select message.
193096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
193196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return select message if created successfully, null otherwise.
193296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
193396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public String getNfcHandoverSelect() {
193496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
193596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("getNfcHandoverSelect")) return null;
193696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<ArrayList> result = new SupplicantResult(
193796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "getNfcHandoverSelect()");
193896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
193996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                mISupplicantP2pIface.createNfcHandoverSelectMessage(
194096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        (SupplicantStatus status, ArrayList<Byte> message) -> {
194196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            result.setResult(status, message);
194296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        });
194396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
194496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
194596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
194696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
194796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!result.isSuccess()) {
194896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                return null;
194996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
195096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
195196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return NativeUtil.hexStringFromByteArray(
195296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    NativeUtil.byteArrayFromArrayList(result.getResult()));
195396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
195496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
195596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
195696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
195796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Report NFC handover select message.
195896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
195996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if reported successfully, false otherwise.
196096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
196196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean initiatorReportNfcHandover(String selectMessage) {
196296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (selectMessage == null) return false;
196396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
196496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("initiatorReportNfcHandover")) return false;
196596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
196696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "initiatorReportNfcHandover(" + selectMessage + ")");
196796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
196896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.reportNfcHandoverInitiation(
196996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
197096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            selectMessage))));
197196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
197296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
197396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
197496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
197596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
197696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
197796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
197896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius
197996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    /**
198096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * Report NFC handover request message.
198196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     *
198296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     * @return true if reported successfully, false otherwise.
198396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius     */
198496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    public boolean responderReportNfcHandover(String requestMessage) {
198596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        if (requestMessage == null) return false;
198696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        synchronized (mLock) {
198796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            if (!checkSupplicantP2pIfaceAndLogFailure("responderReportNfcHandover")) return false;
198896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            SupplicantResult<Void> result = new SupplicantResult(
198996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                    "responderReportNfcHandover(" + requestMessage + ")");
199096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            try {
199196c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                result.setResult(mISupplicantP2pIface.reportNfcHandoverResponse(
199296c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                        NativeUtil.byteArrayToArrayList(NativeUtil.hexStringToByteArray(
199396c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                            requestMessage))));
199496c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            } catch (RemoteException e) {
199596c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                Log.e(TAG, "ISupplicantP2pIface exception: " + e);
199696c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius                supplicantServiceDiedHandler();
199796c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            }
199896c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius            return result.isSuccess();
199996c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius        }
200096c464e93515cda4326ca93ecf8a90c9ab551b7fRoshan Pius    }
200161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    /** Container class allowing propagation of status and/or value
200261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * from callbacks.
200361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     *
200461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * Primary purpose is to allow callback lambdas to provide results
200561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     * to parent methods.
200661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski     */
200761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski    private static class SupplicantResult<E> {
200861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private String mMethodName;
200961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private SupplicantStatus mStatus;
201061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        private E mValue;
201161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
201261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        public SupplicantResult(String methodName) {
201361233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mMethodName = methodName;
201461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mStatus = null;
201561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            mValue = null;
201661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logd("entering " + mMethodName);
201761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
201861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski
201961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        public void setResult(SupplicantStatus status, E value) {
202061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logCompletion(mMethodName, status);
202161233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            logd("leaving " + mMethodName + " with result = " + value);
202279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mStatus = status;
202379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mValue = value;
202479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
202579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
202679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public void setResult(SupplicantStatus status) {
202779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logCompletion(mMethodName, status);
202879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            logd("leaving " + mMethodName);
202979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            mStatus = status;
203079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
203179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
203279d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public boolean isSuccess() {
203379d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            return (mStatus != null && mStatus.code == SupplicantStatusCode.SUCCESS);
203479d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
203579d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski
203679d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        public E getResult() {
203779d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski            return (isSuccess() ? mValue : null);
203879d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        }
203979d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski    }
204079d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski}
2041