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
29ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wangimport android.annotation.NonNull;
30c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Piusimport android.content.Context;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
32240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
3396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
34240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
35c224fb554deca894818490c9416ff35d18a79d76Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
3635c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason;
3796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
39240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
40240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
42240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
43240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
44f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
4582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.SupplicantState;
4666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
47efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Raoimport android.net.wifi.WifiManager;
4882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.WifiSsid;
49f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Piusimport android.os.HwRemoteBinder;
50240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
51913bcdf2c0c37a04735e7401037e729496aae021Roshan Piusimport android.text.TextUtils;
52240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
53ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wangimport android.util.Pair;
54f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
5596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
565a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.AnqpEvent;
575a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.IconEvent;
585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.WnmData;
595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPElement;
605a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPParser;
615a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.Constants;
62d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
63240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
645a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.io.IOException;
655a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.nio.BufferUnderflowException;
665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteBuffer;
675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteOrder;
68240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
69f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
70f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
71f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Matcher;
735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Pattern;
74d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
75240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
76240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
77240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
78240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
79b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
80b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
88f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final Object mLock = new Object();
89511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean mVerboseLoggingEnabled = false;
90f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
9198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
92f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private IServiceManager mIServiceManager = null;
9398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
9498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
95b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
961c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
971c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
981c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
991c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
1001c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (mVerboseLoggingEnabled) {
1011c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
1021c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
1031c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1041c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantStaIface()) {
1051c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
1061c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
1071c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
1081c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
1091c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1101c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
1111c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
1121c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
113f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
114f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
115f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
116f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
117f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
118f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
119f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
120f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
121f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mSupplicantDeathRecipient =
122f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
123f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "ISupplicant/ISupplicantStaIface died: cookie=" + cookie);
124f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
125f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
126f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
127f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
128f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
12903fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
130ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    private SupplicantStaNetworkHal mCurrentNetworkRemoteHandle;
131ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    private WifiConfiguration mCurrentNetworkLocalConfig;
132c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
133c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
1347c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
135c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
136c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
137c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
138b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        mISupplicantStaIfaceCallback = new SupplicantStaIfaceHalCallback();
1398c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
141240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
142511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * Enable/Disable verbose logging.
143511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     *
144511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * @param enable true to enable, false to disable.
145511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     */
146511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    void enableVerboseLogging(boolean enable) {
147511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        mVerboseLoggingEnabled = enable;
148511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    }
149511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius
150ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToServiceManagerDeath() {
151ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mIServiceManager == null) return false;
152ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
153f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mIServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) {
154ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
155ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
156ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                mIServiceManager = null; // Will need to register a new ServiceNotification
157ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
158ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
159ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
160ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "IServiceManager.linkToDeath exception", e);
161ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
162ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
163ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
164ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
165ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
166511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    /**
16798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
16898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
169240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
172511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (mVerboseLoggingEnabled) Log.i(TAG, "Registering ISupplicant service ready callback.");
173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
17498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
17598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
17698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
17798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
17898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
17998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
18098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
181240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
18298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
18398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
186240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
187ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                if (!linkToServiceManagerDeath()) {
188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
190240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
1921c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!mIServiceManager.registerForNotifications(
1931c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                        ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) {
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
195240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
19698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
197240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
198240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
200240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
201240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
20298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
203240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
204240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
205240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
206240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
207240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
208ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantDeath() {
209ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicant == null) return false;
210ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
211f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, 0)) {
212ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
213ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
214ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
215ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
216ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
217ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicant.linkToDeath exception", e);
218ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
219ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
220ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
221ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
222ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
22398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
224240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
225240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
22698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
227240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
228240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
229240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
230240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
23198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
232240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
233240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
234240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
235ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantDeath()) {
236ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
237ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
238ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        }
239ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        return true;
240ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    }
241ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius
242ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius    private boolean linkToSupplicantStaIfaceDeath() {
243ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        if (mISupplicantStaIface == null) return false;
244ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        try {
245f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            if (!mISupplicantStaIface.linkToDeath(mSupplicantDeathRecipient, 0)) {
246ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                Log.wtf(TAG, "Error on linkToDeath on ISupplicantStaIface");
247ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                supplicantServiceDiedHandler();
248ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
249ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
250ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius        } catch (RemoteException e) {
251ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            Log.e(TAG, "ISupplicantStaIface.linkToDeath exception", e);
252ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            return false;
253240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
254240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
255240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
256240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
257ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    private int getCurrentNetworkId() {
258ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkLocalConfig == null) {
259ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            return WifiConfiguration.INVALID_NETWORK_ID;
260ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        }
261ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkLocalConfig.networkId;
262ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    }
263ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang
26498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
265240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
266240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
267240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
268240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
26998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
270240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
271240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
272240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
273240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
274240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
275240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
276240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
277240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
278240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
27998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
280240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
281240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
282240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
28398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
284240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
285240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
28603fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
287240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
28898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
289240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
29098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
291240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
292240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
293240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
294240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
295240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
296240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
297240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
298240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
299240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
30098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
301240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
30203fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
303240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
304240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
305240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
30698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
30798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
308240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
309240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
31098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
31103fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
312ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantStaIfaceDeath()) {
313ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
314ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
315b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            if (!registerCallback(mISupplicantStaIfaceCallback)) {
316c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
317c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
318240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
319240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
320240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
321240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
32298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
323240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
32498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
32598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
3265317e7c11c99d5cc8417c65cc73cf548f8f52b87Roshan Pius            mWifiMonitor.broadcastSupplicantDisconnectionEvent(mIfaceName);
327240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
328240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
329240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
33098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
33124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
33224250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
33324250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
33424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
33524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
33624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
33724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
33824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
33998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
34098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
34198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
3428c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3438c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
3448c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
34598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
3468c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
34798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
348006eb17e06a7843e3da3bf939833b94e58a5a034Yifan Hong        return IServiceManager.getService();
34998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
35098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
35198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
35298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
35398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
35498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
35598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
35698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
3578c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3588c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
35996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
3607c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
361d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
36266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
363ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang     * @return a Pair object including SupplicantStaNetworkHal and WifiConfiguration objects
364ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang     * for the current network.
36566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
366ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    private Pair<SupplicantStaNetworkHal, WifiConfiguration>
367ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            addNetworkAndSaveConfig(WifiConfiguration config) {
36866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
36966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
37066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
37166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
37266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
37366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
37466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
37566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
37666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
37766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
37845a984619e338090981499e4823e0177649e3c28Roshan Pius        boolean saveSuccess = false;
37945a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
38045a984619e338090981499e4823e0177649e3c28Roshan Pius            saveSuccess = network.saveWifiConfiguration(config);
38145a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
38245a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Exception while saving config params: " + config, e);
38345a984619e338090981499e4823e0177649e3c28Roshan Pius        }
38445a984619e338090981499e4823e0177649e3c28Roshan Pius        if (!saveSuccess) {
38566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
386f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            if (!removeAllNetworks()) {
387f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius                loge("Failed to remove all networks on failure.");
388f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            }
38966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
39066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
391ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return new Pair(network, new WifiConfiguration(config));
39266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
39366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
39466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
3957c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
3967c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
397ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang     * 1. If |config| is different to the current supplicant network, removes all supplicant
398ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang     * networks and saves |config|.
399ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang     * 2. Select the new network in wpa_supplicant.
400d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
4017c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
4027c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
40366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
404ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang    public boolean connectToNetwork(@NonNull WifiConfiguration config) {
405a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang        logd("connectToNetwork " + config.configKey());
406ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (WifiConfigurationUtil.isSameNetwork(config, mCurrentNetworkLocalConfig)) {
407ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            logd("Network is already saved, will not trigger remove and add operation.");
408ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        } else {
409ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            mCurrentNetworkRemoteHandle = null;
410ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            mCurrentNetworkLocalConfig = null;
411ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            if (!removeAllNetworks()) {
412ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                loge("Failed to remove existing networks");
413ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                return false;
414ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            }
415ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            Pair<SupplicantStaNetworkHal, WifiConfiguration> pair = addNetworkAndSaveConfig(config);
416ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            if (pair == null) {
417ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                loge("Failed to add/save network configuration: " + config.configKey());
418ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                return false;
419ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            }
420ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            mCurrentNetworkRemoteHandle = pair.first;
421ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang            mCurrentNetworkLocalConfig = pair.second;
42266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
423ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang
424ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (!mCurrentNetworkRemoteHandle.select()) {
425d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
42666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
42766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
4297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
4307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
4317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
4327c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
4337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
4347c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
4357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
4367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
4377c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
4387c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
4397c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
4407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
4417c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
4427c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
4437c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
444ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (getCurrentNetworkId() != config.networkId) {
4457c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
446ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                    + "Current network ID: " + getCurrentNetworkId());
447a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang            return connectToNetwork(config);
4487c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4497c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
4507c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
451ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (!mCurrentNetworkRemoteHandle.setBssid(bssid)) {
4527c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
4537c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4547c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4557c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
4567c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
4577c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4587c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
45966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
46066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
46166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
46266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
463f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
464f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
465f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
466f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
467f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
468f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
469f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
470f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
471f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
472f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
473f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
474f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
475f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
476f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
477f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
478f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
479f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
480f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
481f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
482f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
483f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
484f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
485a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            boolean loadSuccess = false;
486a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            try {
487a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                loadSuccess = network.loadWifiConfiguration(config, networkExtra);
488a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            } catch (IllegalArgumentException e) {
489a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.wtf(TAG, "Exception while loading config params: " + config, e);
490a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            }
491a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            if (!loadSuccess) {
492a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId
493a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                        + ". Skipping...");
494a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                continue;
495f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
496f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
497f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
498f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
499f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
500f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
501f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
502f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
503f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
504f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
505f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
506f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
507f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
508f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
509f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
510f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
511f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
512f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
513f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
514403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * Remove the request |networkId| from supplicant if it's the current network,
515403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
516403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
517403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
518403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
519403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    public void removeNetworkIfCurrent(int networkId) {
520403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang        synchronized (mLock) {
521403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang            if (getCurrentNetworkId() == networkId) {
522403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang                // Currently we only save 1 network in supplicant.
523403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang                removeAllNetworks();
524403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang            }
525403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang        }
526403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
527403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
528403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /**
52966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
53066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
53166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
53266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
53366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
53466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
53566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
53666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
53766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
53866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
53966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
54066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
54166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
54266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
54366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
54466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
5457b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        // Reset current network info.  Probably not needed once we add support to remove/reset
5467b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        // current network on receiving disconnection event from supplicant (b/32898136).
547ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        mCurrentNetworkLocalConfig = null;
548ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        mCurrentNetworkRemoteHandle = null;
54966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
55066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
55166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
55266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
5530a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
5540a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5550a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
5560a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
5570a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5580a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
559ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
560ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.setBssid(bssidStr);
5610a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5620a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5630a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5640a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
5650a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5660a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
5670a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5680a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
569ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return null;
570ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.getWpsNfcConfigurationToken();
5710a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5720a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5730a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
574a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * Get the eap anonymous identity for the currently configured network.
575a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
576a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
577a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
578a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    public String getCurrentNetworkEapAnonymousIdentity() {
579ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return null;
580ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.fetchEapAnonymousIdentity();
581a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
582a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
583a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
5848aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap identity response for the currently configured network.
5858aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5868aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param identityStr String to send.
5878aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5888aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5898aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
590ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
591ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapIdentityResponse(identityStr);
5928aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5938aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5948aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5958aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth response for the currently configured network.
5968aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5978aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5988aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5998aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6008aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
601ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
602ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapSimGsmAuthResponse(paramsStr);
6038aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6048aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6058aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
6068aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
6078aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6088aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6098aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6108aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
611ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
612ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapSimGsmAuthFailure();
6138aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6148aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6158aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
6168aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth response for the currently configured network.
6178aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6188aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
6198aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6208aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6218aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
622ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
623ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAuthResponse(paramsStr);
6248aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6258aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6268aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
6278aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auts response for the currently configured network.
6288aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6298aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
6308aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6318aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6328aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
633ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
634ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAutsResponse(paramsStr);
6358aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6368aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6378aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
6388aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth failure for the currently configured network.
6398aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6408aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6418aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6428aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
643ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        if (mCurrentNetworkRemoteHandle == null) return false;
644ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang        return mCurrentNetworkRemoteHandle.sendNetworkEapSimUmtsAuthFailure();
6458aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6468aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6478aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
648d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
649d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
65096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
65196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
65296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
65396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
65496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
65596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
6563aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
65796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
65896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
65996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6603aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
66196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
66296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
66396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
665b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
66696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6673aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
668c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
669c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
67096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
67196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
67296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
67396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
67496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
675d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
67696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
67796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
678d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
679d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
68096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
68196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
68296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
68396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
68496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
68596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
68696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
68796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
68896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
689b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
69096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
69196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
69296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
69396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
694d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
69596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
696f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
697f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
698f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
699f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
700f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
701f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
702f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
703c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
704511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        SupplicantStaNetworkHal network =
705511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                new SupplicantStaNetworkHal(iSupplicantStaNetwork, mIfaceName, mContext,
706511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                        mWifiMonitor);
707511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (network != null) {
708511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            network.enableVerboseLogging(mVerboseLoggingEnabled);
709511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        }
710511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        return network;
711f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
712f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
713f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
71496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
71596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
71696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
71796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
71896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
71996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
7203aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
72196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
72296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
72396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
72496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
7253aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
72696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
72796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
72896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
72996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
730b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
73196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7323aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
733c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
734c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
73596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
73696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
73796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
73896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
73996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
74096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
741c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
742c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
743c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
744c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
745c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
746c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
747c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
748c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
749c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
750b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
751c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
752c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
753c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
754c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
755c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
75696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
75796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
75896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
75996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
76096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
76196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
76296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
7633aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
76496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
76596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
76696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
76796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
7683aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
76996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
77096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
77196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
77296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
773b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
77496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7753aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
77696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
77796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
778d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
7795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
7815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
7835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
7867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
7887651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
7917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
793b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
8015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
8035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
80645a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
80745a984619e338090981499e4823e0177649e3c28Roshan Pius            Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
80845a984619e338090981499e4823e0177649e3c28Roshan Pius            if (!match.find() || match.groupCount() != 3) {
80945a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Malformed WPS device type " + typeStr);
81045a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
81145a984619e338090981499e4823e0177649e3c28Roshan Pius            }
81245a984619e338090981499e4823e0177649e3c28Roshan Pius            short categ = Short.parseShort(match.group(1));
81345a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
81445a984619e338090981499e4823e0177649e3c28Roshan Pius            short subCateg = Short.parseShort(match.group(3));
81545a984619e338090981499e4823e0177649e3c28Roshan Pius
81645a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] bytes = new byte[8];
81745a984619e338090981499e4823e0177649e3c28Roshan Pius            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
81845a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(categ);
81945a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.put(oui);
82045a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(subCateg);
82145a984619e338090981499e4823e0177649e3c28Roshan Pius            return setWpsDeviceType(bytes);
82245a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
82345a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + typeStr, e);
8245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
8255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
8265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
8275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
8297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
8317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
8347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
836b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
8445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
8465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
8497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
8517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
8547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
856b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
8645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
8665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
8697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
8717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
8747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
876b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
8845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
8865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
8897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
8917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
8947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
896b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
9007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
9017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
9025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
9035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
9045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
9055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
9065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
9075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
9085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
9097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
9107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
9117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
9127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
9137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
9147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
9157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
916b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
9177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
9187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
9197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
9207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
9217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
9225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
9235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
9245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
9255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
9265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
9275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
9285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
9295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
9305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
9315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
9325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
9335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
9345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
9355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
9365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
9377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
9387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
9397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
9407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
9417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
9427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
9437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
9447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
945b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
9467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
9477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
9487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
9497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
9507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
951d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
952d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
953d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
954d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
955d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
956d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
96096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
96196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
96296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
96396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
964b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
96596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
96696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
969d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
970d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
971d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
972d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
973d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
974d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
975d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
97696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
97796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
97896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
97996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
98096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
98196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
98296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
983b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
98496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
98596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
98696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
98796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
988d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
989d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
990d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
991d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
992d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
993d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
994d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
100196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1002b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
100396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
100596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
100696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1007d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1008d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1009d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
1010d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1011d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1012d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1013d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1014d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
101796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
101896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
101996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
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 discover with the specified AP.
1030d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1031d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1032d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1033d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1034d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
103545a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
103645a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
103745a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
103845a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + macAddress, e);
103945a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
104045a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1041d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1042b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
104396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
104696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
104796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
104896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1051b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
105296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
105396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
105496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
105596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1056d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1057d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1058d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
1059d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1060d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1061d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1062d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1063d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
106445a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
106545a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
106645a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
106745a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + macAddress, e);
106845a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
106945a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1070d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1071b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
107296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
107396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
107496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
107596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
107696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
107796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
107896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
107996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1080b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
108196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
108296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
108396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
108496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1085d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1086d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1087d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
1088d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1089d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1090d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1091d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
109245a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
109345a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
109445a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
109545a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + macAddress, e);
109645a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
109745a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1098d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1099d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1100b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
110196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
110296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
110396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
110496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
110596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
110696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
110796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
110896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1109b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
111096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
111196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
111296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
111396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1114d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1115d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1116d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
1117d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1118d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1119d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
1120d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
1121d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1122d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1123d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
1124d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
112545a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
112645a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateAnqpQuery(
112745a984619e338090981499e4823e0177649e3c28Roshan Pius                    NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
112845a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
112945a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssid, e);
113045a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
113145a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1132d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1133d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1134b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
113596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
113696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
113796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
113896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
113996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
114096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
114196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
114296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
114396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
114496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1145b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
114696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
114796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
114896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
114996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1150d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1151d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1152d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
1153d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1154d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1155d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
1156d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1157d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1158d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
115945a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
116045a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
116145a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
116245a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssid, e);
116345a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
116445a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1165d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1166d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1167b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
116896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
116996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
117096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
117196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
117296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
117396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
117496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
117596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
117696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1177b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
117896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
117996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
118096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
118196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1182d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
118396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
118496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
1185d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
118696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
118796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1188d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
118996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
119096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
119196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
119296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
119396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
119496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
11963aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1197d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
119896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
119996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
120096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1201b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
120296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
12033aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
120496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
120596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1206d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1207d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1208d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1209d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1210d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1211d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1212d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
121396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
121496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
121596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
121696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
121796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
121896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
121996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1220b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
122196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
122296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
122396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
122496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1225d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1226d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1227d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1228d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1229d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1230d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1231d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
123296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
123396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
123496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
123596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
123696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
123796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
123896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1239b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
124096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
124196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
124296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
124396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1244d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1245d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1246d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1247d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1248f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST}
1249f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *        {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values.
1250d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1251d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1252f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean addRxFilter(int type) {
1253f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halType;
1254f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (type) {
1255f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V4_MULTICAST:
1256f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST;
1257f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1258f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V6_MULTICAST:
1259f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1260f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1261f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1262f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Rx Filter type: " + type);
1263f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1264f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1265f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return addRxFilter(halType);
1266f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1267f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1268f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean addRxFilter(byte type) {
126996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
127096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
127196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
127296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
127396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
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     * Remove an RX filter.
1284d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1285f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST}
1286f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *        {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values.
1287d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1288d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1289f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean removeRxFilter(int type) {
1290f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halType;
1291f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (type) {
1292f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V4_MULTICAST:
1293f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST;
1294f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1295f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V6_MULTICAST:
1296f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1297f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1298f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1299f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Rx Filter type: " + type);
1300f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1301f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1302f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return removeRxFilter(halType);
1303f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1304f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1305f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean removeRxFilter(byte type) {
130696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
130796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
130896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
130996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
131096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
131196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
131296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1313b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
131496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
131596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
131696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
131796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1318d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1319d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1320d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1321d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1322f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param mode one of the above {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_DISABLED},
1323f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *             {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_ENABLED} or
1324f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *             {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_SENSE}.
1325d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1326d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1327f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean setBtCoexistenceMode(int mode) {
1328f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halMode;
1329f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (mode) {
1330f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_ENABLED:
1331f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1332f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1333f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED:
1334f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1335f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1336f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE:
1337f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1338f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1339f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1340f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Bt Coex mode: " + mode);
1341f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1342f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1343f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return setBtCoexistenceMode(halMode);
1344f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1345f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1346f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    private boolean setBtCoexistenceMode(byte mode) {
134796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
134896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
134996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
135096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
135196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
135296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
135396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1354b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
135596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
135696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
135796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
135896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1359d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1360d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1361d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1362d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1363d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1364d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1365d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
136696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
136796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
136896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
136996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
137096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
137196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
137296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
137396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1374b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
137596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
137696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
137796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
137896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1379d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1380d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1381d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1382d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1383d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
13845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1385d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1386d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
138796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
138896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
138996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
139096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
139196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
139296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
139396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1394b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
139596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
139696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
139796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
139896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1399d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1400d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1401d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1402d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1403d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1404d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1405d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1406d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1407913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(codeStr)) return false;
1408d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1409d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1410d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1411b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
141296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
141396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
141496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
141596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
141696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
141796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
141896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
141996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1420b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
142196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
142296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
142396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
142496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
142596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
14265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
14285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
14305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
14315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
1434913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(bssidStr) || TextUtils.isEmpty(pin)) return false;
143545a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
143645a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
143745a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
143845a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
143945a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
144045a984619e338090981499e4823e0177649e3c28Roshan Pius        }
14415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
14425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
14447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
14457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
14477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
14507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1452b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
14605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1461d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
14625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
146545a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
146645a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
146745a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
146845a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
146945a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
147045a984619e338090981499e4823e0177649e3c28Roshan Pius        }
14715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
14725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
14747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
14757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
14777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
14807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1482b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
14905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
14925f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14935f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
1495913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(pin)) return false;
14967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
14987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
15017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
15027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1503b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
15057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
15115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1512d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
15135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
15145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
151645a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
151745a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
151845a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
151945a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
152045a984619e338090981499e4823e0177649e3c28Roshan Pius            return null;
152145a984619e338090981499e4823e0177649e3c28Roshan Pius        }
15225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
15235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
15247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
15257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
15267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
15277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
15287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
15297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
15307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
15327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
15337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
15347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
15357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
15367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
15377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1538b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
15417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
15465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
15475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
15485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
15507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
15517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
15527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
15537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
15557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
15567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1557b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
15597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
15655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
15665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
15675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
15685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
15707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
15717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
15727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
15737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
15757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
15767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1577b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
15797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15833e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /** See ISupplicant.hal for documentation */
15843e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    public boolean enableAutoReconnect(boolean enable) {
15853e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        synchronized (mLock) {
15863e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            final String methodStr = "enableAutoReconnect";
15873e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
15883e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            try {
15893e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                SupplicantStatus status = mISupplicantStaIface.enableAutoReconnect(enable);
15903e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
15913e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            } catch (RemoteException e) {
15923e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                handleRemoteException(e, methodStr);
15933e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return false;
15943e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            }
15953e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        }
15963e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
15973e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
1598cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1599cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1600f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *
1601f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1602cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1603cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1604f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean setLogLevel(boolean turnOnVerbose) {
1605f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        int logLevel = turnOnVerbose
1606f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                ? ISupplicant.DebugLevel.DEBUG
1607f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                : ISupplicant.DebugLevel.INFO;
1608f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return setDebugParams(logLevel, false, false);
1609cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1610cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1611cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1612cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1613cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1614cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1615cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1616cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1617cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1618cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1619cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1620cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1621b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1622cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1623cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1624cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1625cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1626cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1627cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1628cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1629cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1630cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1631cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1632cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1633cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1634cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1635cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1636cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1637cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1638cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1639cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1640cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1641cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1642cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1643cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1644cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1645cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1646cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1647cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1648cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1649cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1650cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1651b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1652cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1653cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1654cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1655cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1656cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1657cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1658cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1659cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1660cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1661cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1662cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1663cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1664cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1665cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1666cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1667cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
166896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
166996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
167096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
167196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
167296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
167396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
167496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
167596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
167696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
167796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
167896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
167996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
168096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
168196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
168296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1683511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean checkStatusAndLogFailure(SupplicantStatus status,
168496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
168596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
1686b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: "
1687b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                    + supplicantStatusCodeToString(status.code) + ", " + status.debugMessage);
168896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
1689b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        } else {
1690511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            if (mVerboseLoggingEnabled) {
1691b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded");
1692511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            }
1693b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            return true;
169496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
1695b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    }
1696b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius
1697b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    /**
1698b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     * Helper function to log callbacks.
1699b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     */
1700b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private void logCallback(final String methodStr) {
1701b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        if (mVerboseLoggingEnabled) {
1702b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
1703b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        }
1704b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    }
1705b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1706b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1707b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    private void handleRemoteException(RemoteException e, String methodStr) {
1708b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        supplicantServiceDiedHandler();
1709b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e);
171096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
171196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
171296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
171396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
171496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
171596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
171696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
171796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
171896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
171996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
172096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
172196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
172296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
172396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
172496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
172596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
172696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
172796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
172896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
172996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
173096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
173196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
173296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
173396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
173496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
173596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
173696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
173796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
173896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
173996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
174096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
174196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
174296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
17435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
17445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
17455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
17465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
17475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
17485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
17495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
17505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
17515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
17525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
17535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
17545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
17555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
17565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
17575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
17585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
17595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
17605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
17615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
17625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
17635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
17645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
17655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
17665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
17675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
17685f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
17695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
17705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
17715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
17725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
17735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
17745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
17755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
17765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
17775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
17785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
17795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
17805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
17815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
17825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
178382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
178482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
178582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
178682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
178782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
178882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
178982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
179082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
179182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
179282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
179382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
179482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
179582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
179682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
179782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
179882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
179982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
180082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
180182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
180282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
180382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
180482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
180582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
180682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
180782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
180882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
180982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
181082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
181182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
181282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1813240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1814240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1815240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1816240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1817240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1818240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1819240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1820240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1821240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1822240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1823240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
182466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1825c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
182692e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i
182792e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
182892e43feb3eb54736a28226b588bc087fdda1646eMichael Plass
18295a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
18305a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
18315a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
18325a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
18335a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
18345a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
18355a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
18365a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
18375a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
18385a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
18395a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
18405a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
18415a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
18425a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
18435a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
18445a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
18455a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
18465a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
18475a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
18485a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
18495a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
18505a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
18515a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
18525a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
18535a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
18545a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
18555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
18565a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
18575a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
18585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
18595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
18605a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
18615a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
18625a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
18635a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
18645a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
18655a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
18665a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1867c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1868c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1869b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkAdded");
1870c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1871c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1872c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1873c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1874b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkRemoved");
1875c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1876c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1877c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1878c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1879c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
1880b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onStateChanged");
1881b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1882b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
1883b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                WifiSsid wifiSsid =
1884b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
1885b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
1886911facd2a26141efe5f242e11a07a9d84a45749aRoshan Pius                mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
188735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (newSupplicantState == SupplicantState.COMPLETED) {
1888b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastNetworkConnectionEvent(
1889ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                            mIfaceName, getCurrentNetworkId(), bssidStr);
1890b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
1891911facd2a26141efe5f242e11a07a9d84a45749aRoshan Pius                mWifiMonitor.broadcastSupplicantStateChangeEvent(
1892ff27ddf1923d9d4d4cfa8cc1a1ddb8748d0f2426Ningyuan Wang                        mIfaceName, getCurrentNetworkId(), wifiSsid, bssidStr, newSupplicantState);
189382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1894c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1895c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1896c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18975a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1898c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1899c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
1900b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAnqpQueryDone");
1901b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1902b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
1903b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
1904b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
1905b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(
1906b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
1907b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
1908b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
1909b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
1910b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
1911b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
1912b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
1913b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
1914b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAnqpDoneEvent(
19152a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName, new AnqpEvent(NativeUtil.macAddressToLong(bssid), elementsMap));
1916b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1917c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1918c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1919c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1921c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
1922b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20IconQueryDone");
1923b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1924b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastIconDoneEvent(
1925b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
19262a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new IconEvent(NativeUtil.macAddressToLong(bssid), fileName, data.size(),
1927b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                NativeUtil.byteArrayFromArrayList(data)));
1928b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1929c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1930c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1931c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19325a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
1933b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20SubscriptionRemediation");
1934b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1935b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
19362a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName,
19372a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url, osuMethod));
1938b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1939c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1940c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1941c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19425a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
19435a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
1944b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20DeauthImminentNotice");
1945b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1946b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1947b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
19482a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url,
19492a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                                reasonCode == WnmData.ESS, reAuthDelayInSec));
1950b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1951c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1952c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1953c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1954c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1955b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onDisconnected");
1956b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
195792e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mVerboseLoggingEnabled) {
195892e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway
195992e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " locallyGenerated=" + locallyGenerated
196092e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " reasonCode=" + reasonCode);
196192e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
196292e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mStateIsFourway
196392e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                        && (!locallyGenerated || reasonCode != WLAN_REASON_IE_IN_4WAY_DIFFERS)) {
196492e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    mWifiMonitor.broadcastAuthenticationFailureEvent(
1965efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                            mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD);
196692e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
1967b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastNetworkDisconnectionEvent(
1968b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
1969b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1970b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1971c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1972c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1973c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19746680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
1975b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAssociationRejected");
1976b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
19776680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius                mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode, timedOut,
1978b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1979b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1980c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1981c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1982c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1983c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1984b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAuthenticationTimeout");
1985b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1986b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1987efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                        mIfaceName, WifiManager.ERROR_AUTH_FAILURE_TIMEOUT);
1988b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1989c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1990c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1991c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
199235c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
199335c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            logCallback("onBssidChanged");
199435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            synchronized (mLock) {
199535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (reason == BssidChangeReason.ASSOC_START) {
199635c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastTargetBssidEvent(
199735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
199835c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                } else if (reason == BssidChangeReason.ASSOC_COMPLETE) {
199935c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastAssociatedBssidEvent(
200035c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
200135c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                }
200235c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            }
200335c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        }
200435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius
200535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        @Override
2006c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
2007b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onEapFailure");
2008b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
2009b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
2010efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                        mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE);
2011b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
2012c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2013c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2014c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2015c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
2016b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventSuccess");
2017b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
2018b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
2019b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
2020c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2021c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2022c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2023c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
2024b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventFail");
2025b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
2026b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (configError == WpsConfigError.MSG_TIMEOUT
2027b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        && errorInd == WpsErrorIndication.NO_ERROR) {
2028b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
2029b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else {
2030b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
2031b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
2032bcf35be52f93d09a3f2ac8d4272a6d66467309b9Roshan Pius            }
2033c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2034c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2035c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2036c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
2037b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventPbcOverlap");
2038b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
2039b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
2040b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
2041c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2042c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2043c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2044c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
2045b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkStart");
2046c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2047c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2048c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2049c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
2050b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkTimeout");
2051c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2052c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
2053c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
205466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
205566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
205666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
205766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
205866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
205966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
206066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
206166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
206266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
206366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
206466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
2065240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
2066