SupplicantStaIfaceHal.java revision 35c9c7f7a2f83d81b8d61da834b3960f5b9ffe19
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;
3535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason;
3696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
39240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
41240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
42240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
43f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
4482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.SupplicantState;
4566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
4682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.WifiSsid;
47f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Piusimport android.os.HwRemoteBinder;
48240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
49913bcdf2c0c37a04735e7401037e729496aae021Roshan Piusimport android.text.TextUtils;
50240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
51f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
5296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
535a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.AnqpEvent;
545a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.IconEvent;
555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.WnmData;
565a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPElement;
575a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPParser;
585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.Constants;
59d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
60240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
615a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.io.IOException;
625a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.nio.BufferUnderflowException;
635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteBuffer;
645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteOrder;
65240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
66f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
67f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
68f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Matcher;
705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Pattern;
71d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
72240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
73240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
74240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
75240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
76b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
77b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
85f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final Object mLock = new Object();
86511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean mVerboseLoggingEnabled = false;
87f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
8898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
89f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private IServiceManager mIServiceManager = null;
9098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
9198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
92b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
931c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
941c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
951c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
961c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
971c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (mVerboseLoggingEnabled) {
981c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
991c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
1001c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1011c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantStaIface()) {
1021c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
1031c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
1041c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
1051c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
1061c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1071c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
1081c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
1091c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
110f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
111f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
112f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
113f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
114f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
115f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
116f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
117f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
118f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mSupplicantDeathRecipient =
119f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
120f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "ISupplicant/ISupplicantStaIface died: cookie=" + cookie);
121f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
122f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
123f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
124f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
125f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
12603fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
1277c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
1287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
1297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
1305a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius    private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
131c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
132c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
1337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
134c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
135c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
136c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
137b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        mISupplicantStaIfaceCallback = new SupplicantStaIfaceHalCallback();
1388c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
139240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
141511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * Enable/Disable verbose logging.
142511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     *
143511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * @param enable true to enable, false to disable.
144511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     */
145511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    void enableVerboseLogging(boolean enable) {
146511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        mVerboseLoggingEnabled = enable;
147511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    }
148511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius
149ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToServiceManagerDeath() {
150ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mIServiceManager == null) return false;
151ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
152f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mIServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) {
153ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
154ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
155ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                mIServiceManager = null; // Will need to register a new ServiceNotification
156ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
157ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
158ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
159ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "IServiceManager.linkToDeath exception", e);
160ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
161ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
162ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
163ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
164ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
165511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    /**
16698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
16798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
168240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
169240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
171511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (mVerboseLoggingEnabled) Log.i(TAG, "Registering ISupplicant service ready callback.");
172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
17398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
17498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
17598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
17698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
17798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
17898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
17998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
18198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
18298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
186ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                if (!linkToServiceManagerDeath()) {
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
190240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
1911c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!mIServiceManager.registerForNotifications(
1921c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
19598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
196240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
197240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
198240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
200240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
20198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
202240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
203240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
204240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
205240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
206240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
207ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantDeath() {
208ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicant == null) return false;
209ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
210f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, 0)) {
211ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
212ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
213ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
214ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
215ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
216ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicant.linkToDeath exception", e);
217ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
218ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
219ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
220ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
221ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
22298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
223240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
224240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
22598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
226240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
227240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
228240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
229240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
23098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
231240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
232240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
233240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
234ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantDeath()) {
235ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
236ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
237ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
238ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
239ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
240ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
241ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantStaIfaceDeath() {
242ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicantStaIface == null) return false;
243ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
244f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicantStaIface.linkToDeath(mSupplicantDeathRecipient, 0)) {
245ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicantStaIface");
246ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
247ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
248ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
249ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
250ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicantStaIface.linkToDeath exception", e);
251ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
252240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
253240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
254240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
255240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
25698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
257240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
258240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
259240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
260240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
26198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
262240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
263240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
264240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
265240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
266240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
267240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
268240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
269240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
270240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
27198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
272240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
273240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
274240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
27598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
276240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
277240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
27803fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
279240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
28098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
281240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
28298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
283240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
284240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
285240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
286240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
287240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
288240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
289240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
290240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
291240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
29298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
293240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
29403fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
295240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
296240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
297240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
29898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
29998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
300240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
301240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
30298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
30303fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
304ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantStaIfaceDeath()) {
305ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
306ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
307b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            if (!registerCallback(mISupplicantStaIfaceCallback)) {
308c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
309c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
310240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
311240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
312240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
313240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
31498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
315240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
31698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
31798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
3185317e7c11c99d5cc8417c65cc73cf548f8f52b87Roshan Pius            mWifiMonitor.broadcastSupplicantDisconnectionEvent(mIfaceName);
319240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
320240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
321240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
32298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
32324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
32424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
32524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
32624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
32724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
32824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
32924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
33024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
33198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
33298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
33398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
3348c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3358c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
3368c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
33798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
3388c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
33998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
340006eb17e06a7843e3da3bf939833b94e58a5a034Yifan Hong        return IServiceManager.getService();
34198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
34298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
34498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
34598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
34698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
34898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
3498c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3508c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
35196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
3527c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
353d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
35466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
35566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
35666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
357d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
35866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
35966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
36066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
36166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
36266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
36366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
36466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
36566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
36666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
36766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
368f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        if (!network.saveWifiConfiguration(config)) {
36966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
370f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            if (!removeAllNetworks()) {
371f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius                loge("Failed to remove all networks on failure.");
372f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            }
37366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
37466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
375f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        return network;
37666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
37766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
37866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
3797c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
3807c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
3817c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
3827c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
3837c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
3847c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
3857c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
386d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
3877c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3887c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
3897c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
39066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
391d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
3927c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
3937c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
394d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
39566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
39666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
39766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
39866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
39966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
40066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
40166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
40266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4047c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = addNetwork(config);
4057c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
406d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
40766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4097c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
410d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
41166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
41266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4137c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
4147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
4157c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
4167c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
4177c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
4187c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
4197c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
4207c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
4217c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
4227c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
4237c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
4247c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
4257c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
4267c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
4277c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
4287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
4297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
4307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
4317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
4327c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
4337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return connectToNetwork(config, false);
4347c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
4367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
4377c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
4387c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
4397c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4417c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
4427c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
4437c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4447c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
44566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
44666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
44766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
44866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
449f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
450f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
451f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
452f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
453f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
454f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
455f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
456f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
457f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
458f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
459f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
460f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
461f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
462f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
463f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
464f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
465f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
466f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
467f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
468f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
469f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
470f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
471a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            boolean loadSuccess = false;
472a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            try {
473a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                loadSuccess = network.loadWifiConfiguration(config, networkExtra);
474a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            } catch (IllegalArgumentException e) {
475a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.wtf(TAG, "Exception while loading config params: " + config, e);
476a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            }
477a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            if (!loadSuccess) {
478a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId
479a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                        + ". Skipping...");
480a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                continue;
481f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
482f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
483f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
484f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
485f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
486f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
487f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
488f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
489f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
490f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
491f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
492f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
493f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
494f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
495f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
496f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
497f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
498f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
499f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
50066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
50166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
50266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
50366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
50466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
50566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
50666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
50766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
50866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
50966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
51066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
51166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
51266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
51366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
51466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
51566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
51666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
51766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
51866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
51966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
5200a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
5210a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5220a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
5230a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
5240a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5250a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
5260a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return false;
5270a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.setBssid(bssidStr);
5280a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5290a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5300a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5310a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
5320a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5330a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
5340a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5350a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
5360a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return null;
5370a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.getWpsNfcConfigurationToken();
5380a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5390a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5400a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5418aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap identity response for the currently configured network.
5428aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5438aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param identityStr String to send.
5448aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5458aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5468aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
5478aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5488aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapIdentityResponse(identityStr);
5498aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5508aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5518aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5528aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth response for the currently configured network.
5538aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5548aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5558aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5568aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5578aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
5588aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5598aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr);
5608aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5618aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5628aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5638aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
5648aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5658aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5668aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5678aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
5688aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5698aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthFailure();
5708aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5718aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5728aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5738aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth response for the currently configured network.
5748aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5758aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5768aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5778aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5788aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
5798aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5808aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr);
5818aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5828aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5838aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5848aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auts response for the currently configured network.
5858aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5868aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5878aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5888aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5898aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
5908aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5918aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr);
5928aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5938aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5948aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5958aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth failure for the currently configured network.
5968aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5978aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5988aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5998aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
6008aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
6018aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthFailure();
6028aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6038aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6048aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
605d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
606d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
60796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
61196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
61296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
6133aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
61496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
61596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
61696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6173aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
61896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
61996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
62096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
62196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
622b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
62396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6243aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
625c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
626c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
62796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
62896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
62996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
63096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
63196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
632d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
63396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
635d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
636d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
64196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
64396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
64496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
64596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
646b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
64796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
64896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
64996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
65096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
651d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
65296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
653f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
654f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
655f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
656f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
657f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
658f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
659f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
660c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
661511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        SupplicantStaNetworkHal network =
662511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                new SupplicantStaNetworkHal(iSupplicantStaNetwork, mIfaceName, mContext,
663511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                        mWifiMonitor);
664511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (network != null) {
665511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            network.enableVerboseLogging(mVerboseLoggingEnabled);
666511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        }
667511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        return network;
668f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
669f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
670f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
67196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
67296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
67396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
67496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
67596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
67696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
6773aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
67896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
67996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
68096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
68196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6823aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
68396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
68496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
68596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
68696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
687b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
68896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6893aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
690c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
691c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
69296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
69396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
69496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
69596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
69696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
69796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
698c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
699c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
700c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
701c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
702c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
703c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
704c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
705c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
706c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
707b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
708c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
709c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
710c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
711c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
712c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
71396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
71496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
71596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
71696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
71796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
71896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
71996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
7203aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
72196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
72296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
72396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
72496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
7253aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
72696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
72796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
72896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
72996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
730b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
73196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7323aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
73396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
73496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
735d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
7365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
7385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
7405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
7437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
7457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
7487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
750b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
7585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
7605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
7635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
7645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        if (!match.find() || match.groupCount() != 3) {
7655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Log.e(TAG, "Malformed WPS device type " + typeStr);
7665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
7675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
7685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short categ = Short.parseShort(match.group(1));
7695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
7705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short subCateg = Short.parseShort(match.group(3));
7715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] bytes = new byte[8];
7735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
7745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(categ);
7755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.put(oui);
7765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(subCateg);
7775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsDeviceType(bytes);
7785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
7795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
7817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
7837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
7867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
788b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
7965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
7985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
8017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
8037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
8067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
808b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
8165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
8185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
8217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
8237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
8267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
828b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
8365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
8385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
8417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
8437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
8467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
848b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
8565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
8585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
8617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
8637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
8667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
868b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
8765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
8785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
8815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
8825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
8835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
8845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
8855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
8865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
8875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
8885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
8907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
8927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
8957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
897b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
9007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
9017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
9027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
903d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
904d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
905d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
906d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
907d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
908d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
90996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
91096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
91196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
91296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
91396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
91496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
91596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
916b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
91796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
921d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
922d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
923d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
924d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
925d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
926d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
927d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
92896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
93096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
93196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
93296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
93396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
93496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
935b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
93696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
93796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
93896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
93996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
940d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
941d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
942d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
943d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
944d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
945d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
946d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
954b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
95596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
95696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
959d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
960d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
961d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
962d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
963d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
964d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
965d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
966d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
96996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
97096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
97196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
97296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
97396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
974b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
97596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
97696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
97796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
97896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
979d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
980d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
981d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
982d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
983d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
984d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
985d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
986d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
987d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
988d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
989b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
99096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
99396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
99496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
998b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
100196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
100296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1003d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1004d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1005d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
1006d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1007d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1008d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1009d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1010d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
1011d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
1012d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1013b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
101496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
101796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
101896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
101996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
102096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
102196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1022b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
102396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
102496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
102596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
102696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1027d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1028d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1029d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
1030d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1031d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1032d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1033d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
1034d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
1035d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1036d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1037b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
103896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
103996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
104096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
104196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
104296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
104396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1046b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
104796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
104896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1051d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1052d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1053d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
1054d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1055d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1056d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
1057d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
1058d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1059d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1060d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
1061d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
1062d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
1063d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
1064d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1065d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1066b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
106796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
106896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
106996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
107096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
107196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
107296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
107396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
107496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
107596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
107696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1077b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
107896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
107996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
108096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
108196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1082d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1083d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1084d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
1085d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1086d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1087d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
1088d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1089d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1090d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
1091d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
1092d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1093d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1094b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
109596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
109696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
109796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
109896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
109996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
110096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
110196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
110296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
110396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1104b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
110596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
110696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
110796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
110896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1109d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
111096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
111196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
1112d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
111396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
111496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1115d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
111696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
111796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
111896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
111996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
112096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
112196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
112296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
11233aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1124d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
112596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
112696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
112796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1128b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
112996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
11303aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
113196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
113296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1133d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1134d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1135d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1136d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1137d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1138d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1139d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
114096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
114196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
114296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
114396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
114496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
114596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
114696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1147b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
114896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
114996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
115096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
115196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1152d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1153d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1154d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1155d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1156d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1157d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1158d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
115996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
116096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
116196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
116296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
116396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
116496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
116596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1166b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
116796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
116896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
116996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
117096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1171d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1172d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
1173d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1174d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
1175d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1176d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1177d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1178d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1179d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1180d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1181d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1182d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1183f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean addRxFilter(byte type) {
118496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
118596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
118696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
118796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
118896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
118996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
119096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1191b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
119296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
119396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
119496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1196d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1197d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1198d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
1199d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1200d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1201d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1202d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1203d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1204f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean removeRxFilter(byte type) {
120596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
120696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
120796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
120896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
120996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
121096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
121196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1212b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
121396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
121496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
121596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
121696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1217d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1218d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1219d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1220d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1221d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1222d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1223d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1224d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
1225d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
1226d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1227d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1228d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
122996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
123096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
123196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
123296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
123396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
123496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
123596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1236b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
123796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
123896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
123996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
124096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1241d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1242d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1243d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1244d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1245d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1246d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1247d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
124896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
124996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
125096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
125196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
125296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
125396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
125496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
125596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1256b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
125796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
125896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
125996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
126096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1261d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1262d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1263d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1264d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1265d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
12665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1267d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1268d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
126996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
127096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
127196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
127296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
127396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
127496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
127596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1276b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
127796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
127896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
127996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
128096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1281d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1282d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1283d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1284d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1285d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1286d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1287d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1288d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1289913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(codeStr)) return false;
1290d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1291d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1292d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1293b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
129496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
129596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
129696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
129796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
129896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
129996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
130096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
130196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1302b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
130396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
130496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
130596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
130696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
130796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
13085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
13105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
13125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
13135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
1316913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(bssidStr) || TextUtils.isEmpty(pin)) return false;
13175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
13185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
13227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
13247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
13277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1329b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
13375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1338d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
13395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
13425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
13435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
13477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
13497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
13527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1354b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
13625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
13645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
1367913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(pin)) return false;
13687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
13707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
13737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1375b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
13835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1384d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
13855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
13865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
13885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
13895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
13937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
13957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
13967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
13977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
13997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
14007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
14017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
14027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
14037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
14047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1405b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
14087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
14135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
14177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
14197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
14227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1424b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
14325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
14345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
14377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
14397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
14427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1444b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14503e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /** See ISupplicant.hal for documentation */
14513e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    public boolean enableAutoReconnect(boolean enable) {
14523e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        synchronized (mLock) {
14533e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            final String methodStr = "enableAutoReconnect";
14543e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
14553e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            try {
14563e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                SupplicantStatus status = mISupplicantStaIface.enableAutoReconnect(enable);
14573e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
14583e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            } catch (RemoteException e) {
14593e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                handleRemoteException(e, methodStr);
14603e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return false;
14613e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            }
14623e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        }
14633e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
14643e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
1465cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_EXCESSIVE = ISupplicant.DebugLevel.EXCESSIVE;
1466cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_MSGDUMP = ISupplicant.DebugLevel.MSGDUMP;
1467cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_DEBUG = ISupplicant.DebugLevel.DEBUG;
1468cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_INFO = ISupplicant.DebugLevel.INFO;
1469cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_WARNING = ISupplicant.DebugLevel.WARNING;
1470cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_ERROR = ISupplicant.DebugLevel.ERROR;
1471cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1472cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1473cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param level One of the above {@link #LOG_LEVEL_EXCESSIVE} - {@link #LOG_LEVEL_ERROR} value.
1474cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1475cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1476cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setLogLevel(int level) {
1477cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return setDebugParams(level, false, false);
1478cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1479cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1480cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1481cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1482cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1483cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1484cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1485cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1486cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1487cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1488cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1489cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1490b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1491cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1492cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1493cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1494cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1495cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1496cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1497cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1498cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1499cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1500cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1501cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1502cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1503cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1504cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1505cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1506cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1507cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1508cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1509cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1510cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1511cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1512cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1513cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1514cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1515cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1516cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1517cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1518cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1519cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1520b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1521cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1522cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1523cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1524cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1525cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1526cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1527cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1528cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1529cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1530cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1531cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1532cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1533cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1534cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1535cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1536cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
153796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
153896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
153996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
154096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
154196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
154296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
154396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
154496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
154596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
154696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
154796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
154896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
154996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
155096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
155196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1552511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean checkStatusAndLogFailure(SupplicantStatus status,
155396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
155496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
1555b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: "
1556b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                    + supplicantStatusCodeToString(status.code) + ", " + status.debugMessage);
155796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
1558b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        } else {
1559511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            if (mVerboseLoggingEnabled) {
1560b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded");
1561511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            }
1562b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            return true;
156396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
1564b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    }
1565b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius
1566b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    /**
1567b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     * Helper function to log callbacks.
1568b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     */
1569b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private void logCallback(final String methodStr) {
1570b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        if (mVerboseLoggingEnabled) {
1571b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
1572b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        }
1573b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    }
1574b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1575b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1576b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    private void handleRemoteException(RemoteException e, String methodStr) {
1577b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        supplicantServiceDiedHandler();
1578b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e);
157996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
158096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
158196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
158296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
158396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
158496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
158596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
158696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
158796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
158896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
158996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
159096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
159196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
159296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
159396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
159496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
159596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
159696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
159796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
159896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
159996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
160096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
160196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
160296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
160396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
160496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
160596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
160696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
160796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
160896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
160996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
161096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
161196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
16125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
16135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
16145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
16155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
16165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
16175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
16185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
16195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
16205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
16215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
16225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
16235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
16245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
16255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
16265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
16275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
16285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
16295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
16305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
16315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
16325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
16335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
16345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
16355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
16365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
16375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
16385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
16395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
16405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
16415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
16425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
16435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
16445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
16455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
16465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
16475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
16485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
16495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
16505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
16515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
165282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
165382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
165482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
165582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
165682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
165782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
165882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
165982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
166082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
166182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
166282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
166382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
166482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
166582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
166682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
166782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
166882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
166982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
167082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
167182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
167282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
167382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
167482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
167582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
167682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
167782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
167882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
167982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
168082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
168182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1682240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1683240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1684240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1685240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1686240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1687240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1688240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1689240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1690240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1691240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1692240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
169366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1694c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
169592e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i
169692e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
169792e43feb3eb54736a28226b588bc087fdda1646eMichael Plass
16985a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16995a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
17005a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
17015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
17025a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
17035a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
17045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
17055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
17065a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
17075a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
17085a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
17095a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
17105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
17115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
17125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
17135a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
17145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
17155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
17165a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
17175a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
17185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
17195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
17205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
17215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
17225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
17235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
17245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
17255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
17265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
17275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
17285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
17295a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
17305a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
17315a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
17325a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
17335a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
17345a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
17355a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1736c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1737c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1738b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkAdded");
1739c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1740c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1741c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1742c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1743b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkRemoved");
1744c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1745c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1746c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1747c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1748c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
1749b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onStateChanged");
1750b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1751b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
1752b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                WifiSsid wifiSsid =
1753b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
1754b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
1755b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastSupplicantStateChangeEvent(
1756b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
175735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (newSupplicantState == SupplicantState.COMPLETED) {
1758b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastNetworkConnectionEvent(
1759b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                            mIfaceName, mFrameworkNetworkId, bssidStr);
1760b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
176192e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
176282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1763c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1764c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1765c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17665a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1767c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1768c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
1769b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAnqpQueryDone");
1770b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1771b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
1772b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
1773b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
1774b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(
1775b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
1776b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
1777b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
1778b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
1779b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
1780b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
1781b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
1782b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
1783b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAnqpDoneEvent(
17842a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName, new AnqpEvent(NativeUtil.macAddressToLong(bssid), elementsMap));
1785b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1786c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1787c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1788c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17895a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1790c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
1791b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20IconQueryDone");
1792b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1793b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastIconDoneEvent(
1794b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
17952a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new IconEvent(NativeUtil.macAddressToLong(bssid), fileName, data.size(),
1796b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                NativeUtil.byteArrayFromArrayList(data)));
1797b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1798c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1799c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1800c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
1802b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20SubscriptionRemediation");
1803b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1804b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
18052a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName,
18062a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url, osuMethod));
1807b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1808c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1809c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1810c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
18125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
1813b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20DeauthImminentNotice");
1814b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1815b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1816b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
18172a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url,
18182a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                                reasonCode == WnmData.ESS, reAuthDelayInSec));
1819b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1820c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1821c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1822c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1823c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1824b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onDisconnected");
1825b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
182692e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mVerboseLoggingEnabled) {
182792e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway
182892e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " locallyGenerated=" + locallyGenerated
182992e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " reasonCode=" + reasonCode);
183092e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
183192e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mStateIsFourway
183292e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                        && (!locallyGenerated || reasonCode != WLAN_REASON_IE_IN_4WAY_DIFFERS)) {
183392e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    mWifiMonitor.broadcastAuthenticationFailureEvent(
183492e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD);
183592e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
1836b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastNetworkDisconnectionEvent(
1837b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
1838b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1839b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1840c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1841c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1842c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18436680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
1844b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAssociationRejected");
1845b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
18466680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius                mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode, timedOut,
1847b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1848b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1849c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1850c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1851c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1852c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1853b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAuthenticationTimeout");
1854b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1855b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1856b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_TIMEOUT);
1857b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1858c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1859c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1860c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
186135c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
186235c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            logCallback("onBssidChanged");
186335c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            synchronized (mLock) {
186435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (reason == BssidChangeReason.ASSOC_START) {
186535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastTargetBssidEvent(
186635c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
186735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                } else if (reason == BssidChangeReason.ASSOC_COMPLETE) {
186835c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastAssociatedBssidEvent(
186935c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
187035c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                }
187135c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            }
187235c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        }
187335c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius
187435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        @Override
1875c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
1876b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onEapFailure");
1877b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1878b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1879b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_EAP_FAILURE);
1880b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1881c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1882c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1883c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1884c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
1885b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventSuccess");
1886b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1887b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
1888b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1889c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1890c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1891c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1892c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
1893b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventFail");
1894b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1895b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (configError == WpsConfigError.MSG_TIMEOUT
1896b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        && errorInd == WpsErrorIndication.NO_ERROR) {
1897b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
1898b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else {
1899b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
1900b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
1901bcf35be52f93d09a3f2ac8d4272a6d66467309b9Roshan Pius            }
1902c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1903c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1904c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1905c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
1906b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventPbcOverlap");
1907b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1908b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
1909b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1910c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1911c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1912c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1913c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
1914b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkStart");
1915c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1916c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1917c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1918c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
1919b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkTimeout");
1920c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1921c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
1922c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
192366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
192466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
192566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
192666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
192766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
192866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
192966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
193066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
193166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
193266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
193366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
1934240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
1935