SupplicantStaIfaceHal.java revision 1c353f3fca322aab2fff5369a55876a91a112775
1240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/*
298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Copyright (C) 2017 The Android Open Source Project
3240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
4240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
5240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * you may not use this file except in compliance with the License.
6240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * You may obtain a copy of the License at
7240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
8240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
9240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
10240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Unless required by applicable law or agreed to in writing, software
11240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
12240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * See the License for the specific language governing permissions and
14240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * limitations under the License.
15240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
16240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhnepackage com.android.server.wifi;
17240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork;
195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName;
205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability;
215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm;
225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium;
235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName;
245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSConnCapability;
255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSFriendlyName;
265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
29c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Piusimport android.content.Context;
30240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
3296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
33240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
34c224fb554deca894818490c9416ff35d18a79d76Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
3596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
36240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
40240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
41240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
42f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
4382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.SupplicantState;
4466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
4582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.WifiSsid;
46240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
47240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
48f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
4996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
505a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.AnqpEvent;
515a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.IconEvent;
525a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.WnmData;
535a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPElement;
545a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPParser;
555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.Constants;
56d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
57240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.io.IOException;
595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.nio.BufferUnderflowException;
605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteBuffer;
615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteOrder;
62240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
63f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
64f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
65f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Matcher;
675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Pattern;
68d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
69240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
70240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
71240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
72240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
73b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
74b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
7598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private static final String SERVICE_MANAGER_NAME = "manager";
765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
83511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean mVerboseLoggingEnabled = false;
8498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private IServiceManager mIServiceManager = null;
8598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
8698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
8798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
88b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
891c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
901c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
911c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
921c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
931c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (mVerboseLoggingEnabled) {
941c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
951c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
961c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
971c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantStaIface()) {
981c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
991c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
1001c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
1011c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
1021c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1031c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
1041c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
1051c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
10603fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
1077c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
1087c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
1097c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
1105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius    private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
111240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private final Object mLock = new Object();
112c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
113c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
1147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
115c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
116c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
117c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
118b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        mISupplicantStaIfaceCallback = new SupplicantStaIfaceHalCallback();
1198c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
121240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
122511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * Enable/Disable verbose logging.
123511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     *
124511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * @param enable true to enable, false to disable.
125511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     */
126511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    void enableVerboseLogging(boolean enable) {
127511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        mVerboseLoggingEnabled = enable;
128511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    }
129511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius
130ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToServiceManagerDeath() {
131ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mIServiceManager == null) return false;
132ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
133ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!mIServiceManager.linkToDeath(cookie -> {
134ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
135ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                synchronized (mLock) {
136ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                    supplicantServiceDiedHandler();
137ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
138ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                }
139ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }, 0)) {
140ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
141ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
142ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                mIServiceManager = null; // Will need to register a new ServiceNotification
143ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
144ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
145ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
146ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "IServiceManager.linkToDeath exception", e);
147ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
148ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
149ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
150ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
151ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
152511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    /**
15398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
15498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
156240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
158511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (mVerboseLoggingEnabled) Log.i(TAG, "Registering ISupplicant service ready callback.");
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
16098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
16198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
16298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
16398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
16498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
16598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
16698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
16898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
16998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
173ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                if (!linkToServiceManagerDeath()) {
174240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
176240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
177240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
1781c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!mIServiceManager.registerForNotifications(
1791c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
181240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
18298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
186240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
18898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
190240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
192240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
194ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantDeath() {
195ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicant == null) return false;
196ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
197ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!mISupplicant.linkToDeath(cookie -> {
198ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.w(TAG, "ISupplicant died: cookie=" + cookie);
199ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                synchronized (mLock) {
200ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                    supplicantServiceDiedHandler();
201ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                }
202ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }, 0)) {
203ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
204ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
205ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
206ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
207ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
208ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicant.linkToDeath exception", e);
209ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
210ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
211ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
212ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
213ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
21498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
215240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
216240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
21798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
218240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
219240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
220240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
221240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
22298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
223240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
224240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
225240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
226ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantDeath()) {
227ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
228ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
229ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
230ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
231ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
232ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
233ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantStaIfaceDeath() {
234ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicantStaIface == null) return false;
235ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
236ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!mISupplicantStaIface.linkToDeath(cookie -> {
237ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.w(TAG, "ISupplicantStaIface died: cookie=" + cookie);
238ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                synchronized (mLock) {
239ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                    supplicantServiceDiedHandler();
240ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                }
241ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }, 0)) {
242ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicantStaIface");
243ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
244ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
245ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
246ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
247ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicantStaIface.linkToDeath exception", e);
248ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
249240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
250240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
251240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
252240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
25398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
254240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
255240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
256240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
257240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
25898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
259240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
260240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
261240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
262240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
263240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
264240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
265240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
266240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
267240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
26898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
269240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
270240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
271240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
27298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
273240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
274240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
27503fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
276240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
27798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
278240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
27998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
280240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
281240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
282240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
283240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
284240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
285240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
286240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
287240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
288240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
28998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
290240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
29103fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
292240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
293240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
294240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
29598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
29698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
297240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
298240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
29998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
30003fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
301ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantStaIfaceDeath()) {
302ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
303ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
304b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            if (!registerCallback(mISupplicantStaIfaceCallback)) {
305c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
306c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
307240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
308240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
309240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
310240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
31198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
312240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
31398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
31498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
3155317e7c11c99d5cc8417c65cc73cf548f8f52b87Roshan Pius            mWifiMonitor.broadcastSupplicantDisconnectionEvent(mIfaceName);
316240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
317240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
318240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
31998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
32024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
32124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
32224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
32324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
32424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
32524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
32624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
32724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
32898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
32998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
33098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
3318c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3328c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
3338c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
33498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
3358c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
33698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
33798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return IServiceManager.getService(SERVICE_MANAGER_NAME);
33898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
33998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
34198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
34298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
34398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
34598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
3468c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3478c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
34896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
3497c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
350d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
35166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
35266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
35366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
354d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
35566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
35666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
35766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
35866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
35966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
36066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
36166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
36266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
36366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
36466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
365f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        if (!network.saveWifiConfiguration(config)) {
36666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
367f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            if (!removeAllNetworks()) {
368f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius                loge("Failed to remove all networks on failure.");
369f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            }
37066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
37166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
372f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        return network;
37366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
37466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
37566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
3767c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
3777c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
3787c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
3797c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
3807c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
3817c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
3827c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
383d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
3847c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3857c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
3867c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
38766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
388d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
3897c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
3907c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
391d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
39266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
39366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
39466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
39566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
39666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
39766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
39866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
39966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4017c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = addNetwork(config);
4027c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
403d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
40466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4067c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
407d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
40866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4107c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
4117c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
4127c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
4137c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
4147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
4157c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
4167c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
4177c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
4187c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
4197c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
4207c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
4217c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
4227c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
4237c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
4247c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
4257c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
4267c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
4277c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
4287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
4297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
4307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return connectToNetwork(config, false);
4317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4327c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
4337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
4347c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
4357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
4367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4377c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4387c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
4397c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
4407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4417c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
44266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
44366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
44466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
44566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
446f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
447f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
448f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
449f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
450f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
451f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
452f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
453f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
454f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
455f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
456f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
457f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
458f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
459f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
460f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
461f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
462f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
463f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
464f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
465f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
466f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
467f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
468f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (!network.loadWifiConfiguration(config, networkExtra)) {
469f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId);
470f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
471f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
472f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
473f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
474f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
475f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
476f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
477f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
478f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
479f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
480f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
481f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
482f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
483f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
484f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
485f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
486f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
487f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
488f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
489f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
49066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
49166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
49266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
49366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
49466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
49566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
49666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
49766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
49866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
49966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
50066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
50166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
50266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
50366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
50466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
50566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
50666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
50766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
50866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
50966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
5100a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
5110a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5120a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
5130a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
5140a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5150a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
5160a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return false;
5170a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.setBssid(bssidStr);
5180a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5190a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5200a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5210a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
5220a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5230a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
5240a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5250a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
5260a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return null;
5270a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.getWpsNfcConfigurationToken();
5280a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5290a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5300a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5318aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap identity response for the currently configured network.
5328aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5338aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param identityStr String to send.
5348aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5358aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5368aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
5378aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5388aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapIdentityResponse(identityStr);
5398aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5408aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5418aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5428aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth response for the currently configured network.
5438aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5448aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5458aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5468aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5478aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
5488aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5498aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr);
5508aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5518aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5528aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5538aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
5548aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5558aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5568aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5578aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
5588aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5598aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthFailure();
5608aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5618aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5628aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5638aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth response for the currently configured network.
5648aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5658aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5668aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5678aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5688aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
5698aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5708aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr);
5718aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5728aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5738aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5748aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auts response for the currently configured network.
5758aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5768aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5778aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5788aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5798aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
5808aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5818aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr);
5828aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5838aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5848aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5858aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth failure for the currently configured network.
5868aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5878aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5888aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5898aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
5908aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5918aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthFailure();
5928aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5938aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5948aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
595d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
596d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
59796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
59896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
59996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
60096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
60196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
60296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
6033aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
60496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
60596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
60696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6073aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
61196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
612b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
61396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6143aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
615c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
616c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
61796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
61896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
61996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
62096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
62196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
622d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
62396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
62496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
625d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
626d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
62796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
62896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
62996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
63096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
63196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
63296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
63396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
63596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
636b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
641d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
643f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
644f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
645f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
646f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
647f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
648f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
649f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
650c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
651511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        SupplicantStaNetworkHal network =
652511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                new SupplicantStaNetworkHal(iSupplicantStaNetwork, mIfaceName, mContext,
653511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                        mWifiMonitor);
654511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (network != null) {
655511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            network.enableVerboseLogging(mVerboseLoggingEnabled);
656511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        }
657511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        return network;
658f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
659f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
660f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
66196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
66296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
66396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
66596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
66696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
6673aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
66896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
66996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
67096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
67196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6723aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
67396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
67496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
67596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
67696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
677b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
67896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6793aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
680c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
681c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
68296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
68396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
68496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
68596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
68696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
68796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
688c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
689c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
690c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
691c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
692c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
693c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
694c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
695c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
696c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
697b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
698c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
699c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
700c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
701c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
702c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
70396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
70496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
70596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
70696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
70796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
70896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
70996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
7103aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
71196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
71296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
71396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
71496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
7153aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
71696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
71796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
71896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
71996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
720b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
72196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7223aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
72396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
72496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
725d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
7265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
7285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
7305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
7337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
7357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
7387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
740b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
7485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
7505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
7535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
7545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        if (!match.find() || match.groupCount() != 3) {
7555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Log.e(TAG, "Malformed WPS device type " + typeStr);
7565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
7575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
7585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short categ = Short.parseShort(match.group(1));
7595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
7605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short subCateg = Short.parseShort(match.group(3));
7615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] bytes = new byte[8];
7635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
7645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(categ);
7655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.put(oui);
7665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(subCateg);
7675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsDeviceType(bytes);
7685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
7695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
7717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
7737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
7767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
778b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
7865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
7885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
7917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
7937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
7967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
798b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
8065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
8085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
8117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
8137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
8167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
818b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
8265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
8285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
8317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
8337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
8367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
838b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
8465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
8485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
8517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
8537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
8567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
858b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
8665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
8685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
8715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
8725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
8735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
8745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
8755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
8765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
8775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
8785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
8807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
8827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
8857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
887b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8887651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
893d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
894d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
895d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
896d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
897d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
898d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
90296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
90396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
90496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
90596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
906b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
90796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
90896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
90996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
91096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
911d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
912d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
913d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
914d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
915d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
916d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
917d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
92296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
925b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
92796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
92896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
930d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
931d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
932d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
933d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
934d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
935d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
936d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
93796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
93896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
93996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
94096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
94196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
94296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
94396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
944b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
94696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
949d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
950d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
951d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
952d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
953d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
954d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
955d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
956d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
96096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
96196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
96296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
96396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
964b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
96596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
96696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
969d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
970d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
971d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
972d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
973d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
974d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
975d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
976d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
977d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
978d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
979b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
98096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
98196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
98296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
98396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
98496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
98596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
98696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
98796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
988b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
98996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
99096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
993d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
994d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
995d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
996d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
997d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
998d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
999d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1000d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
1001d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
1002d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1003b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
100596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
100696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
100796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
100896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
100996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
101096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
101196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1012b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
101396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
101496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1017d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1018d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1019d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
1020d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1021d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1022d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1023d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
1024d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
1025d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1026d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1027b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
102896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
102996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
103096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
103196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
103296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
103396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
103496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
103596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1036b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
103796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
103896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
103996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
104096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1041d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1042d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1043d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
1044d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1045d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1046d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
1047d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
1048d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1049d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1050d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
1051d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
1052d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
1053d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
1054d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1055d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1056b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
105796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
105896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
105996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
106096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
106196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
106296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
106396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
106496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
106596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
106696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1067b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
106896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
106996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
107096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
107196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1072d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1073d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1074d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
1075d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1076d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1077d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
1078d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1079d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1080d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
1081d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
1082d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1083d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1084b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
108596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
108696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
108796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
108896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
108996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
109096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
109196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
109296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
109396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1094b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
109596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
109696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
109796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
109896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1099d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
110096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
110196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
1102d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
110396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
110496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1105d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
110696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
110796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
110896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
110996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
111096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
111196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
111296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
11133aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1114d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
111596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
111696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
111796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1118b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
111996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
11203aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
112196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
112296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1123d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1124d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1125d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1126d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1127d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1128d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1129d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
113096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
113196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
113296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
113396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
113496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
113596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
113696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1137b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
113896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
113996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
114096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
114196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1142d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1143d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1144d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1145d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1146d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1147d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1148d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
114996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
115096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
115196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
115296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
115396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
115496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
115596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1156b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
115796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
115896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
115996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
116096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1161d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1162d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
1163d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1164d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
1165d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1166d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1167d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1168d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1169d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1170d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1171d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1172d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1173f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean addRxFilter(byte type) {
117496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
117596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
117696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
117796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
117896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
117996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
118096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1181b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
118296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
118396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
118496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
118596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1186d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1187d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1188d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
1189d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1190d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1191d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1192d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1193d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1194f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean removeRxFilter(byte type) {
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
119696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
119796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
119896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
119996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
120096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
120196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1202b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
120396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
120496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
120596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
120696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1207d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1208d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1209d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1210d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1211d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1212d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1213d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1214d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
1215d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
1216d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1217d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1218d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
121996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
122096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
122196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
122296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
122396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
122496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
122596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1226b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
122796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
122896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
122996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
123096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1231d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1232d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1233d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1234d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1235d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1236d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1237d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
123896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
123996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
124096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
124196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
124296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
124396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
124496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
124596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1246b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
124796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
124896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
124996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
125096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1251d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1252d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1253d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1254d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1255d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
12565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1257d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1258d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
125996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
126096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
126196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
126296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
126396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
126496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
126596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1266b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
126796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
126896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
126996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
127096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1271d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1272d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1273d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1274d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1275d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1276d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1277d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1278d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1279d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1280d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1281d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1282b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
128396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
128496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
128596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
128696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
128796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
128896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
128996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
129096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1291b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
129296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
129396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
129496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
129596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
129696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
12975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
12995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
13015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
13025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
13055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
13065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
13107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
13127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
13157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1317b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
13255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
13275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
13305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
13315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
13357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
13377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
13407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1342b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
13505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
13525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
13557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
13577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
13607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1362b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
13705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
13725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
13735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
13755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
13765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
13807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
13827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
13837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
13847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
13867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
13877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
13887651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
13897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
13907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
13917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1392b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
13957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
14005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
14047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
14067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
14097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1411b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
14195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
14215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
14247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
14267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
14297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1431b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
1437cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_EXCESSIVE = ISupplicant.DebugLevel.EXCESSIVE;
1438cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_MSGDUMP = ISupplicant.DebugLevel.MSGDUMP;
1439cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_DEBUG = ISupplicant.DebugLevel.DEBUG;
1440cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_INFO = ISupplicant.DebugLevel.INFO;
1441cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_WARNING = ISupplicant.DebugLevel.WARNING;
1442cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_ERROR = ISupplicant.DebugLevel.ERROR;
1443cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1444cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1445cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param level One of the above {@link #LOG_LEVEL_EXCESSIVE} - {@link #LOG_LEVEL_ERROR} value.
1446cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1447cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1448cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setLogLevel(int level) {
1449cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return setDebugParams(level, false, false);
1450cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1451cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1452cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1453cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1454cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1455cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1456cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1457cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1458cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1459cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1460cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1461cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1462b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1463cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1464cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1465cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1466cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1467cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1468cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1469cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1470cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1471cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1472cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1473cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1474cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1475cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1476cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1477cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1478cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1479cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1480cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1481cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1482cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1483cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1484cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1485cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1486cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1487cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1488cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1489cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1490cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1491cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1492b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1493cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1494cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1495cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1496cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1497cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1498cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1499cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1500cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1501cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1502cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1503cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1504cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1505cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1506cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1507cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1508cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
150996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
151096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
151196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
151296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
151396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
151496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
151596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
151696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
151796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
151896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
151996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
152096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
152196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
152296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
152396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1524511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean checkStatusAndLogFailure(SupplicantStatus status,
152596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
152696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
1527b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: "
1528b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                    + supplicantStatusCodeToString(status.code) + ", " + status.debugMessage);
152996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
1530b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        } else {
1531511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            if (mVerboseLoggingEnabled) {
1532b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded");
1533511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            }
1534b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            return true;
153596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
1536b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    }
1537b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius
1538b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    /**
1539b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     * Helper function to log callbacks.
1540b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     */
1541b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private void logCallback(final String methodStr) {
1542b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        if (mVerboseLoggingEnabled) {
1543b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
1544b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        }
1545b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    }
1546b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1547b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1548b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    private void handleRemoteException(RemoteException e, String methodStr) {
1549b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        supplicantServiceDiedHandler();
1550b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e);
155196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
155296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
155396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
155496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
155596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
155696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
155796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
155896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
155996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
156096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
156196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
156296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
156396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
156496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
156596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
156696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
156796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
156896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
156996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
157096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
157196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
157296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
157396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
157496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
157596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
157696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
157796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
157896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
157996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
158096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
158196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
158296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
158396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
15845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
15855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
15875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
15895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
15905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
15915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
15925f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
15935f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
15945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
15955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
15965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
15975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
15985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
15995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
16005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
16015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
16025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
16035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
16045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
16055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
16065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
16075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
16085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
16095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
16105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
16115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
16125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
16135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
16145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
16155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
16165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
16175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
16185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
16195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
16205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
16215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
16225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
16235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
162482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
162582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
162682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
162782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
162882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
162982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
163082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
163182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
163282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
163382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
163482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
163582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
163682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
163782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
163882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
163982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
164082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
164182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
164282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
164382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
164482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
164582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
164682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
164782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
164882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
164982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
165082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
165182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
165282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
165382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1654240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1655240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1656240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1657240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1658240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1659240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1660240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1661240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1662240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1663240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1664240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
166566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1666c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
16675a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16685a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
16695a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
16705a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
16715a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
16725a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
16735a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16745a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
16755a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
16765a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
16775a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
16785a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
16795a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
16805a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
16815a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
16825a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
16835a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
16845a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
16855a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16865a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16875a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
16885a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16895a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
16905a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
16915a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
16925a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
16935a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
16945a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16955a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
16965a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
16975a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
16985a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
16995a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
17005a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
17015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
17025a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
17035a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
17045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
17055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
17065a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Helper utility to convert the bssid bytes to long.
17075a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
17085a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private Long toLongBssid(byte[] bssidBytes) {
17095a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
17105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return ByteBufferReader.readInteger(
17115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ByteBuffer.wrap(bssidBytes), ByteOrder.BIG_ENDIAN, bssidBytes.length);
17125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (BufferUnderflowException | IllegalArgumentException e) {
17135a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return 0L;
17145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
17155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
17165a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1717c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1718c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1719b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkAdded");
1720c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1721c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1722c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1723c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1724b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkRemoved");
1725c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1726c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1727c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1728c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1729c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
1730b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onStateChanged");
1731b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1732b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
1733b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                WifiSsid wifiSsid =
1734b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
1735b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
1736b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastSupplicantStateChangeEvent(
1737b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
1738b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (newSupplicantState == SupplicantState.ASSOCIATED) {
1739b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastAssociationSuccesfulEvent(mIfaceName, bssidStr);
1740b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else if (newSupplicantState == SupplicantState.COMPLETED) {
1741b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastNetworkConnectionEvent(
1742b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                            mIfaceName, mFrameworkNetworkId, bssidStr);
1743b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
174482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1745c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1746c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1747c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17485a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1749c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1750c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
1751b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAnqpQueryDone");
1752b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1753b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
1754b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
1755b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
1756b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(
1757b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
1758b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
1759b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
1760b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
1761b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
1762b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
1763b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
1764b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
1765b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAnqpDoneEvent(
1766b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, new AnqpEvent(toLongBssid(bssid), elementsMap));
1767b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1768c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1769c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1770c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17715a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1772c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
1773b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20IconQueryDone");
1774b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1775b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastIconDoneEvent(
1776b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
1777b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        new IconEvent(toLongBssid(bssid), fileName, data.size(),
1778b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                NativeUtil.byteArrayFromArrayList(data)));
1779b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1780c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1781c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1782c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17835a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
1784b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20SubscriptionRemediation");
1785b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1786b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1787b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, new WnmData(toLongBssid(bssid), url, osuMethod));
1788b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1789c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1790c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1791c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17925a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
17935a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
1794b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20DeauthImminentNotice");
1795b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1796b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1797b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
1798b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        new WnmData(toLongBssid(bssid), url, reasonCode == WnmData.ESS,
1799b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                reAuthDelayInSec));
1800b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1801c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1802c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1803c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1804c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1805b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onDisconnected");
1806b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1807b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastNetworkDisconnectionEvent(
1808b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
1809b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1810b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1811c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1812c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1813c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1814c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode) {
1815b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAssociationRejected");
1816b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1817b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                // TODO(b/35464954): Need to figure out when to trigger
1818b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                // |WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD|
1819b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode,
1820b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1821b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1822c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1823c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1824c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1825c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1826b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAuthenticationTimeout");
1827b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1828b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1829b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_TIMEOUT);
1830b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1831c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1832c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1833c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1834c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
1835b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onEapFailure");
1836b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1837b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1838b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_EAP_FAILURE);
1839b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1840c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1841c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1842c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1843c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
1844b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventSuccess");
1845b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1846b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
1847b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1848c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1849c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1850c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1851c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
1852b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventFail");
1853b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1854b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (configError == WpsConfigError.MSG_TIMEOUT
1855b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        && errorInd == WpsErrorIndication.NO_ERROR) {
1856b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
1857b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else {
1858b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
1859b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
1860bcf35be52f93d09a3f2ac8d4272a6d66467309b9Roshan Pius            }
1861c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1862c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1863c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1864c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
1865b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventPbcOverlap");
1866b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1867b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
1868b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1869c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1870c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1871c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1872c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
1873b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkStart");
1874c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1875c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1876c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1877c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
1878b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkTimeout");
1879c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1880c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
1881c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
188266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
188366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
188466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
188566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
188666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
188766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
188866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
188966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
189066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
189166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
189266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
1893240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
1894