SupplicantStaIfaceHal.java revision 7b5e49330904ad3db564b57ef3cff1fc63b911b7
1240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/*
298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Copyright (C) 2017 The Android Open Source Project
3240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
4240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
5240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * you may not use this file except in compliance with the License.
6240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * You may obtain a copy of the License at
7240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
8240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
9240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
10240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Unless required by applicable law or agreed to in writing, software
11240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
12240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * See the License for the specific language governing permissions and
14240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * limitations under the License.
15240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
16240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhnepackage com.android.server.wifi;
17240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork;
195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName;
205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability;
215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm;
225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium;
235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName;
245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSConnCapability;
255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSFriendlyName;
265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
29c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Piusimport android.content.Context;
30240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
3296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
33240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
34c224fb554deca894818490c9416ff35d18a79d76Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
3535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback.BssidChangeReason;
3696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
39240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
41240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
42240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
43f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
4482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.SupplicantState;
4566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
46efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Raoimport android.net.wifi.WifiManager;
4782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.WifiSsid;
48f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Piusimport android.os.HwRemoteBinder;
49240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
50913bcdf2c0c37a04735e7401037e729496aae021Roshan Piusimport android.text.TextUtils;
51240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
52f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
5396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
545a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.AnqpEvent;
555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.IconEvent;
565a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.WnmData;
575a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPElement;
585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPParser;
595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.Constants;
60d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
61240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
625a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.io.IOException;
635a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.nio.BufferUnderflowException;
645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteBuffer;
655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteOrder;
66240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
67f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
68f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
69f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Matcher;
715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Pattern;
72d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
73240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
74240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
75240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
76240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
77b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
78b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
86f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final Object mLock = new Object();
87511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean mVerboseLoggingEnabled = false;
88f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
8998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
90f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private IServiceManager mIServiceManager = null;
9198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
9298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
93b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
941c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    private final IServiceNotification mServiceNotificationCallback =
951c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            new IServiceNotification.Stub() {
961c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        public void onRegistration(String fqName, String name, boolean preexisting) {
971c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            synchronized (mLock) {
981c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (mVerboseLoggingEnabled) {
991c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
1001c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                            + ", " + name + " preexisting=" + preexisting);
1011c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1021c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                if (!initSupplicantService() || !initSupplicantStaIface()) {
1031c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.e(TAG, "initalizing ISupplicantIfaces failed.");
1041c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    supplicantServiceDiedHandler();
1051c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                } else {
1061c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                    Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
1071c353f3fca322aab2fff5369a55876a91a112775Roshan Pius                }
1081c353f3fca322aab2fff5369a55876a91a112775Roshan Pius            }
1091c353f3fca322aab2fff5369a55876a91a112775Roshan Pius        }
1101c353f3fca322aab2fff5369a55876a91a112775Roshan Pius    };
111f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mServiceManagerDeathRecipient =
112f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
113f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "IServiceManager died: cookie=" + cookie);
114f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
115f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
116f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    mIServiceManager = null; // Will need to register a new ServiceNotification
117f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
118f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
119f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius    private final HwRemoteBinder.DeathRecipient mSupplicantDeathRecipient =
120f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            cookie -> {
121f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                Log.w(TAG, "ISupplicant/ISupplicantStaIface died: cookie=" + cookie);
122f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                synchronized (mLock) {
123f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                    supplicantServiceDiedHandler();
124f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius                }
125f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius            };
126f42911bc9a921c28ce1614c3513e088e755a55f0Roshan Pius
12703fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
1287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
1297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
1307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
1315a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius    private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
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
25798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
258240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
259240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
260240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
261240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
26298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
263240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
264240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
265240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
266240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
267240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
268240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
269240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
270240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
271240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
27298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
273240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
274240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
275240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
27698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
277240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
278240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
27903fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
280240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
28198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
282240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
28398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
284240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
285240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
286240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
287240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
288240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
289240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
290240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
291240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
292240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
29398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
294240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
29503fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
296240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
297240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
298240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
29998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
30098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
301240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
302240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
30398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
30403fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
305ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            if (!linkToSupplicantStaIfaceDeath()) {
306ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius                return false;
307ca919e89a95472f2785b3ee951f9779544d19f7fRoshan Pius            }
308b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            if (!registerCallback(mISupplicantStaIfaceCallback)) {
309c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
310c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
311240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
312240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
313240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
314240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
31598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
316240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
31798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
31898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
3195317e7c11c99d5cc8417c65cc73cf548f8f52b87Roshan Pius            mWifiMonitor.broadcastSupplicantDisconnectionEvent(mIfaceName);
320240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
321240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
322240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
32398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
32424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
32524250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
32624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    public boolean isInitializationStarted() {
32724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius        return mIServiceManager != null;
32824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    }
32924250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius
33024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
33124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     * Signals whether Initialization completed successfully.
33298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
33398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
33498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
3358c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3368c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
3378c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
33898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
3398c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
34098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
341006eb17e06a7843e3da3bf939833b94e58a5a034Yifan Hong        return IServiceManager.getService();
34298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
34398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
34598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
34698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
34798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
34898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
34998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
3508c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
3518c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
35296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
3537c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
354d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
35566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
35666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
35766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
35845a984619e338090981499e4823e0177649e3c28Roshan Pius    private SupplicantStaNetworkHal addNetworkAndSaveConfig(WifiConfiguration config) {
35966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
36066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
36166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
36266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
36366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
36466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
36566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
36666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
36766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
36866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
36945a984619e338090981499e4823e0177649e3c28Roshan Pius        boolean saveSuccess = false;
37045a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
37145a984619e338090981499e4823e0177649e3c28Roshan Pius            saveSuccess = network.saveWifiConfiguration(config);
37245a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
37345a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Exception while saving config params: " + config, e);
37445a984619e338090981499e4823e0177649e3c28Roshan Pius        }
37545a984619e338090981499e4823e0177649e3c28Roshan Pius        if (!saveSuccess) {
37666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
377f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            if (!removeAllNetworks()) {
378f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius                loge("Failed to remove all networks on failure.");
379f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            }
38066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
38166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
382f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        return network;
38366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
38466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
38566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
3867c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
3877c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
3887c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
3897c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
3907c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
3917c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
3927c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
393d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
3947c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3957c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
39666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
397a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang    public boolean connectToNetwork(WifiConfiguration config) {
3987c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
3997c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
400a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang        logd("connectToNetwork " + config.configKey());
40166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
40266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
40366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
40545a984619e338090981499e4823e0177649e3c28Roshan Pius        mCurrentNetwork = addNetworkAndSaveConfig(config);
4067c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
407d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
40866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
40966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4107c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
411d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
41266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
41366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
4147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
4157c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
4167c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
4177c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
4187c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
4197c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
4207c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
4217c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
4227c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
4237c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
4247c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
4257c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
4267c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
4277c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
4287c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
4297c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
4307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
4317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
4327c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
4337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
434a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang            return connectToNetwork(config);
4357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
4377c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
4387c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
4397c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
4407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4417c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
4427c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
4437c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
4447c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
4457c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
44666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
44766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
44866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
44966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
450f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
451f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
452f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
453f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
454f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
455f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
456f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
457f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
458f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
459f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
460f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
461f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
462f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
463f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
464f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
465f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
466f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
467f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
468f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
469f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
470f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
471f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
472a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            boolean loadSuccess = false;
473a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            try {
474a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                loadSuccess = network.loadWifiConfiguration(config, networkExtra);
475a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            } catch (IllegalArgumentException e) {
476a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.wtf(TAG, "Exception while loading config params: " + config, e);
477a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            }
478a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius            if (!loadSuccess) {
479a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId
480a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                        + ". Skipping...");
481a859d834edbba90793c2ff36ce2d579cac617786Roshan Pius                continue;
482f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
483f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
484f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
485f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
486f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
487f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
488f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
489f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
490f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
491f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
492f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
493f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
494f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
495f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
496f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
497f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
498f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
499f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
500f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
50166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
50266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
50366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
50466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
50566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
50666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
50766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
50866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
50966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
51066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
51166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
51266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
51366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
51466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
51566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
51666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
5177b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        // Reset current network info.  Probably not needed once we add support to remove/reset
5187b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        // current network on receiving disconnection event from supplicant (b/32898136).
5197b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
5207b5e49330904ad3db564b57ef3cff1fc63b911b7Peter Qiu        mCurrentNetwork = null;
52166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
52266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
52366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
52466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
5250a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
5260a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5270a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
5280a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
5290a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5300a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
5310a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return false;
5320a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.setBssid(bssidStr);
5330a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5340a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5350a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
5360a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
5370a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
5380a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
5390a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
5400a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
5410a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return null;
5420a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.getWpsNfcConfigurationToken();
5430a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
5440a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
5450a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
546a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * Get the eap anonymous identity for the currently configured network.
547a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
548a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
549a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
550a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    public String getCurrentNetworkEapAnonymousIdentity() {
551a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang        if (mCurrentNetwork == null) return null;
552a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang        return mCurrentNetwork.fetchEapAnonymousIdentity();
553a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
554a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
555a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
5568aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap identity response for the currently configured network.
5578aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5588aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param identityStr String to send.
5598aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5608aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5618aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
5628aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5638aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapIdentityResponse(identityStr);
5648aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5658aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5668aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5678aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth response for the currently configured network.
5688aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5698aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5708aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5718aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5728aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
5738aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5748aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr);
5758aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5768aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5778aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5788aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
5798aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5808aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5818aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5828aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
5838aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5848aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthFailure();
5858aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5868aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5878aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5888aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth response for the currently configured network.
5898aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5908aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5918aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5928aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5938aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
5948aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5958aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr);
5968aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5978aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5988aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5998aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auts response for the currently configured network.
6008aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6018aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
6028aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6038aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6048aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
6058aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
6068aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr);
6078aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6088aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6098aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
6108aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth failure for the currently configured network.
6118aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
6128aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
6138aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
6148aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
6158aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
6168aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthFailure();
6178aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
6188aad61408adef866a177857b79a979cf77a0a662Roshan Pius
6198aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
620d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
621d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
62296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
62396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
62496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
62596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
62696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
62796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
6283aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
62996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
63096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
63196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6323aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
63396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
63596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
63696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
637b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6393aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
640c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
641c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
64396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
64496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
64596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
64696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
647d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
64896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
64996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
650d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
651d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
65296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
65396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
65496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
65596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
65696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
65796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
65896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
65996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
66096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
661b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
66296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
66396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
66596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
666d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
66796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
668f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
669f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
670f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
671f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
672f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
673f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
674f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
675c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
676511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        SupplicantStaNetworkHal network =
677511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                new SupplicantStaNetworkHal(iSupplicantStaNetwork, mIfaceName, mContext,
678511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                        mWifiMonitor);
679511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (network != null) {
680511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            network.enableVerboseLogging(mVerboseLoggingEnabled);
681511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        }
682511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        return network;
683f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
684f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
685f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
68696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
68796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
68896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
68996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
69096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
69196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
6923aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
69396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
69496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
69596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
69696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6973aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
69896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
69996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
70096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
70196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
702b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
70396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7043aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
705c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
706c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
70796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
70896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
70996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
71096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
71196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
71296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
713c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
714c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
715c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
716c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
717c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
718c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
719c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
720c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
721c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
722b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
723c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
724c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
725c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
726c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
727c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
72896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
72996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
73096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
73196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
73296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
73396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
73496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
7353aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
73696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
73796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
73896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
73996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
7403aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
74196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
74296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
74396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
74496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
745b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
74696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
7473aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
74896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
74996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
750d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
7515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
7535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
7555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
7587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
7607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
7637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
765b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
7735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
7755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
77845a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
77945a984619e338090981499e4823e0177649e3c28Roshan Pius            Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
78045a984619e338090981499e4823e0177649e3c28Roshan Pius            if (!match.find() || match.groupCount() != 3) {
78145a984619e338090981499e4823e0177649e3c28Roshan Pius                Log.e(TAG, "Malformed WPS device type " + typeStr);
78245a984619e338090981499e4823e0177649e3c28Roshan Pius                return false;
78345a984619e338090981499e4823e0177649e3c28Roshan Pius            }
78445a984619e338090981499e4823e0177649e3c28Roshan Pius            short categ = Short.parseShort(match.group(1));
78545a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
78645a984619e338090981499e4823e0177649e3c28Roshan Pius            short subCateg = Short.parseShort(match.group(3));
78745a984619e338090981499e4823e0177649e3c28Roshan Pius
78845a984619e338090981499e4823e0177649e3c28Roshan Pius            byte[] bytes = new byte[8];
78945a984619e338090981499e4823e0177649e3c28Roshan Pius            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
79045a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(categ);
79145a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.put(oui);
79245a984619e338090981499e4823e0177649e3c28Roshan Pius            byteBuffer.putShort(subCateg);
79345a984619e338090981499e4823e0177649e3c28Roshan Pius            return setWpsDeviceType(bytes);
79445a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
79545a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + typeStr, e);
7965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
7975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
7985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
7995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
8017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
8037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
8067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
808b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
8165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
8185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
8217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
8237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
8267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
828b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
8365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
8385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
8417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
8437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
8467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
848b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
8565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
8585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
8617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
8637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
8667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
868b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
8765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
8785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
8817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
8837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
8867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
888b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
8945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
8955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
8965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
8985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
9005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
9015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
9025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
9035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
9045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
9055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
9065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
9075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
9085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
9097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
9107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
9117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
9127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
9137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
9147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
9157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
9167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
917b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
9187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
9197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
9207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
9217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
9227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
923d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
924d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
925d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
926d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
927d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
928d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
93096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
93196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
93296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
93396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
93496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
93596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
936b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
93796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
93896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
93996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
94096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
941d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
942d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
943d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
944d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
945d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
946d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
947d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
95496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
955b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
95696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
960d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
961d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
962d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
963d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
964d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
965d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
966d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
96996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
97096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
97196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
97296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
97396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
974b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
97596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
97696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
97796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
97896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
979d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
980d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
981d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
982d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
983d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
984d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
985d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
986d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
98796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
98896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
98996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
99096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
99396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
994b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
999d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1000d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1001d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
1002d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1003d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1004d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1005d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1006d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
100745a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
100845a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
100945a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
101045a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + macAddress, e);
101145a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
101245a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1013d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1014b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
101796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
101896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
101996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
102096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
102196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
102296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1023b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
102496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
102596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
102696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
102796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1028d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1029d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1030d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
1031d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1032d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
1033d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1034d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1035d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
103645a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
103745a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
103845a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
103945a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + macAddress, e);
104045a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
104145a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1042d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1043b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
104696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
104796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
104896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
105196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1052b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
105396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
105496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
105596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
105696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1057d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1058d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1059d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
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 initiateTdlsTeardown(String macAddress) {
106445a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
106545a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateTdlsTeardown(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    }
1071d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1072b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
107396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
107496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
107596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
107696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
107796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
107896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
107996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
108096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1081b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
108296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
108396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
108496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
108596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1086d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1087d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1088d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
1089d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1090d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1091d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
1092d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
1093d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1094d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1095d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
1096d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
109745a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
109845a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateAnqpQuery(
109945a984619e338090981499e4823e0177649e3c28Roshan Pius                    NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
110045a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
110145a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssid, e);
110245a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
110345a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1104d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1105d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1106b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
110796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
110896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
110996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
111096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
111196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
111296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
111396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
111496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
111596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
111696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1117b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
111896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
111996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
112096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
112196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1122d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1123d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1124d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
1125d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1126d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1127d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
1128d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1129d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1130d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
113145a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
113245a984619e338090981499e4823e0177649e3c28Roshan Pius            return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
113345a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
113445a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssid, e);
113545a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
113645a984619e338090981499e4823e0177649e3c28Roshan Pius        }
1137d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1138d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1139b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
114096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
114196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
114296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
114396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
114496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
114596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
114696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
114796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
114896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1149b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
115096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
115196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
115296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
115396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1154d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
115596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
115696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
1157d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
115896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
115996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1160d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
116196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
116296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
116396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
116496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
116596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
116696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
116796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
11683aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1169d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
117096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
117196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
117296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1173b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
117496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
11753aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
117696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
117796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1178d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1179d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1180d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1181d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1182d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1183d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1184d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
118596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
118696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
118796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
118896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
118996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
119096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
119196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1192b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
119396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
119496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
119696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1197d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1198d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1199d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1200d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1201d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1202d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1203d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
120496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
120596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
120696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
120796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
120896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
120996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
121096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1211b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
121296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
121396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
121496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
121596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1216d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1217d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1218d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1219d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1220f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST}
1221f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *        {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values.
1222d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1223d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1224f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean addRxFilter(int type) {
1225f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halType;
1226f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (type) {
1227f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V4_MULTICAST:
1228f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST;
1229f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1230f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V6_MULTICAST:
1231f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1232f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1233f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1234f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Rx Filter type: " + type);
1235f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1236f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1237f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return addRxFilter(halType);
1238f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1239f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1240f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean addRxFilter(byte type) {
124196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
124296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
124396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
124496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
124596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
124696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
124796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1248b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
124996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
125096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
125196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
125296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1253d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1254d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1255d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
1256d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1257f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST}
1258f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *        {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values.
1259d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1260d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1261f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean removeRxFilter(int type) {
1262f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halType;
1263f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (type) {
1264f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V4_MULTICAST:
1265f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST;
1266f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1267f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.RX_FILTER_TYPE_V6_MULTICAST:
1268f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1269f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1270f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1271f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Rx Filter type: " + type);
1272f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1273f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1274f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return removeRxFilter(halType);
1275f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1276f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1277f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean removeRxFilter(byte type) {
127896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
127996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
128096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
128196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
128296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
128396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
128496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1285b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
128696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
128796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
128896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
128996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1290d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1291d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1292d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1293d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1294f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param mode one of the above {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_DISABLED},
1295f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *             {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_ENABLED} or
1296f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *             {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_SENSE}.
1297d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1298d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1299f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean setBtCoexistenceMode(int mode) {
1300f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        byte halMode;
1301f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        switch (mode) {
1302f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_ENABLED:
1303f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1304f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1305f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED:
1306f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1307f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1308f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            case WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE:
1309f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                halMode = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1310f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                break;
1311f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius            default:
1312f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                Log.e(TAG, "Invalid Bt Coex mode: " + mode);
1313f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                return false;
1314f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        }
1315f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return setBtCoexistenceMode(halMode);
1316f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    }
1317f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius
1318f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    private boolean setBtCoexistenceMode(byte mode) {
131996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
132096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
132196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
132296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
132396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
132496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
132596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1326b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
132796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
132896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
132996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
133096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1331d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1332d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1333d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1334d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1335d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1336d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1337d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
133896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
133996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
134096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
134196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
134296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
134396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
134496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
134596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1346b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
134796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
134896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
134996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
135096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1351d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1352d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1353d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1354d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1355d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
13565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1357d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1358d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
135996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
136096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
136196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
136296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
136396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
136496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
136596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1366b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
136796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
136896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
136996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
137096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1371d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1372d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1373d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1374d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1375d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1376d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1377d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1378d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1379913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(codeStr)) return false;
1380d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1381d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1382d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1383b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
138496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
138596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
138696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
138796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
138896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
138996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
139096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
139196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1392b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
139396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
139496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
139596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
139696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
139796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
13985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
14005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
14025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
14035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
1406913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(bssidStr) || TextUtils.isEmpty(pin)) return false;
140745a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
140845a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
140945a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
141045a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
141145a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
141245a984619e338090981499e4823e0177649e3c28Roshan Pius        }
14135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
14145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
14167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
14177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
14197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
14227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1424b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
14325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1433d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
14345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
143745a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
143845a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
143945a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
144045a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
144145a984619e338090981499e4823e0177649e3c28Roshan Pius            return false;
144245a984619e338090981499e4823e0177649e3c28Roshan Pius        }
14435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
14445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
14467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
14477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
14497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
14527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1454b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
14625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
14635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
14645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
14655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
1467913bcdf2c0c37a04735e7401037e729496aae021Roshan Pius        if (TextUtils.isEmpty(pin)) return false;
14687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
14707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
14717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
14727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
14737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
14747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1475b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
14767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
14777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
14787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
14797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
14807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
14815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
14835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
1484d19743b66ba214a8c4a5166d1fe7d938f97a3f03Roshan Pius     * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard.
14855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
14865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
148845a984619e338090981499e4823e0177649e3c28Roshan Pius        try {
148945a984619e338090981499e4823e0177649e3c28Roshan Pius            return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
149045a984619e338090981499e4823e0177649e3c28Roshan Pius        } catch (IllegalArgumentException e) {
149145a984619e338090981499e4823e0177649e3c28Roshan Pius            Log.e(TAG, "Illegal argument " + bssidStr, e);
149245a984619e338090981499e4823e0177649e3c28Roshan Pius            return null;
149345a984619e338090981499e4823e0177649e3c28Roshan Pius        }
14945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
14955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
14977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
14987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
14997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
15007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
15017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
15027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
15047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
15057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
15067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
15077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
15087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
15097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1510b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
15137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
15185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
15195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
15205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
15227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
15237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
15247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
15257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
15277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
15287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1529b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
15317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
15375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
15385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
15395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
15405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
15427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
15437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
15447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
15457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
15467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
15477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
15487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1549b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
15507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
15517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
15527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
15537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
15547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
15553e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /** See ISupplicant.hal for documentation */
15563e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    public boolean enableAutoReconnect(boolean enable) {
15573e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        synchronized (mLock) {
15583e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            final String methodStr = "enableAutoReconnect";
15593e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
15603e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            try {
15613e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                SupplicantStatus status = mISupplicantStaIface.enableAutoReconnect(enable);
15623e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
15633e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            } catch (RemoteException e) {
15643e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                handleRemoteException(e, methodStr);
15653e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius                return false;
15663e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius            }
15673e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius        }
15683e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
15693e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
1570cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1571cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1572f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     *
1573f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1574cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1575cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1576f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public boolean setLogLevel(boolean turnOnVerbose) {
1577f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        int logLevel = turnOnVerbose
1578f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                ? ISupplicant.DebugLevel.DEBUG
1579f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius                : ISupplicant.DebugLevel.INFO;
1580f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        return setDebugParams(logLevel, false, false);
1581cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1582cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1583cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1584cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1585cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1586cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1587cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1588cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1589cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1590cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1591cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1592cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1593b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1594cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1595cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1596cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1597cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1598cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1599cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1600cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1601cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1602cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1603cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1604cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1605cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1606cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1607cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1608cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1609cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1610cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1611cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1612cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1613cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1614cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1615cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1616cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1617cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1618cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1619cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1620cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1621cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1622cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1623b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1624cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1625cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1626cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1627cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1628cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1629cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1630cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1631cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1632cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1633cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1634cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1635cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1636cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1637cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1638cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1639cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
164096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
164196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
164296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
164396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
164496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
164596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
164696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
164796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
164896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
164996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
165096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
165196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
165296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
165396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
165496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1655511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean checkStatusAndLogFailure(SupplicantStatus status,
165696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
165796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
1658b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: "
1659b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                    + supplicantStatusCodeToString(status.code) + ", " + status.debugMessage);
166096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
1661b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        } else {
1662511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            if (mVerboseLoggingEnabled) {
1663b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded");
1664511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            }
1665b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            return true;
166696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
1667b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    }
1668b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius
1669b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    /**
1670b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     * Helper function to log callbacks.
1671b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     */
1672b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private void logCallback(final String methodStr) {
1673b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        if (mVerboseLoggingEnabled) {
1674b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
1675b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        }
1676b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    }
1677b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1678b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1679b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    private void handleRemoteException(RemoteException e, String methodStr) {
1680b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        supplicantServiceDiedHandler();
1681b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e);
168296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
168396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
168496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
168596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
168696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
168796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
168896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
168996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
169096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
169196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
169296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
169396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
169496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
169596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
169696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
169796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
169896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
169996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
170096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
170196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
170296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
170396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
170496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
170596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
170696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
170796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
170896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
170996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
171096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
171196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
171296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
171396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
171496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
17155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
17165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
17175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
17185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
17195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
17205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
17215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
17225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
17235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
17245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
17255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
17265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
17275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
17285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
17295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
17305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
17315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
17325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
17335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
17345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
17355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
17365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
17375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
17385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
17395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
17405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
17415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
17425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
17435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
17445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
17455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
17465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
17475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
17485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
17495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
17505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
17515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
17525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
17535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
17545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
175582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
175682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
175782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
175882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
175982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
176082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
176182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
176282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
176382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
176482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
176582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
176682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
176782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
176882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
176982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
177082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
177182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
177282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
177382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
177482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
177582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
177682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
177782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
177882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
177982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
178082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
178182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
178282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
178382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
178482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1785240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1786240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1787240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1788240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1789240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1790240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1791240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1792240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1793240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1794240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1795240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
179666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1797c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
179892e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private static final int WLAN_REASON_IE_IN_4WAY_DIFFERS = 17; // IEEE 802.11i
179992e43feb3eb54736a28226b588bc087fdda1646eMichael Plass        private boolean mStateIsFourway = false; // Used to help check for PSK password mismatch
180092e43feb3eb54736a28226b588bc087fdda1646eMichael Plass
18015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
18025a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
18035a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
18045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
18055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
18065a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
18075a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
18085a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
18095a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
18105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
18115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
18125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
18135a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
18145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
18155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
18165a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
18175a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
18185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
18195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
18205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
18215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
18225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
18235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
18245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
18255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
18265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
18275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
18285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
18295a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
18305a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
18315a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
18325a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
18335a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
18345a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
18355a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
18365a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
18375a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
18385a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1839c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1840c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1841b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkAdded");
1842c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1843c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1844c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1845c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1846b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkRemoved");
1847c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1848c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1849c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1850c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1851c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
1852b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onStateChanged");
1853b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1854b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
1855b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                WifiSsid wifiSsid =
1856b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
1857b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
1858911facd2a26141efe5f242e11a07a9d84a45749aRoshan Pius                mStateIsFourway = (newState == ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE);
185935c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (newSupplicantState == SupplicantState.COMPLETED) {
1860b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastNetworkConnectionEvent(
1861b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                            mIfaceName, mFrameworkNetworkId, bssidStr);
1862b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
1863911facd2a26141efe5f242e11a07a9d84a45749aRoshan Pius                mWifiMonitor.broadcastSupplicantStateChangeEvent(
1864911facd2a26141efe5f242e11a07a9d84a45749aRoshan Pius                        mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
186582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1866c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1867c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1868c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18695a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1870c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1871c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
1872b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAnqpQueryDone");
1873b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1874b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
1875b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
1876b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
1877b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(
1878b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
1879b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
1880b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
1881b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
1882b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
1883b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
1884b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
1885b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
1886b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAnqpDoneEvent(
18872a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName, new AnqpEvent(NativeUtil.macAddressToLong(bssid), elementsMap));
1888b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1889c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1890c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1891c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
18925a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1893c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
1894b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20IconQueryDone");
1895b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1896b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastIconDoneEvent(
1897b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
18982a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new IconEvent(NativeUtil.macAddressToLong(bssid), fileName, data.size(),
1899b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                NativeUtil.byteArrayFromArrayList(data)));
1900b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1901c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1902c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1903c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
1905b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20SubscriptionRemediation");
1906b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1907b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
19082a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        mIfaceName,
19092a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url, osuMethod));
1910b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1911c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1912c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1913c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
19155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
1916b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20DeauthImminentNotice");
1917b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1918b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1919b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
19202a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                        new WnmData(NativeUtil.macAddressToLong(bssid), url,
19212a1078dc3729bab248bbd28c8336749481e045cfRoshan Pius                                reasonCode == WnmData.ESS, reAuthDelayInSec));
1922b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1923c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1924c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1925c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1926c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1927b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onDisconnected");
1928b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
192992e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mVerboseLoggingEnabled) {
193092e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    Log.e(TAG, "onDisconnected 4way=" + mStateIsFourway
193192e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " locallyGenerated=" + locallyGenerated
193292e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                            + " reasonCode=" + reasonCode);
193392e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
193492e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                if (mStateIsFourway
193592e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                        && (!locallyGenerated || reasonCode != WLAN_REASON_IE_IN_4WAY_DIFFERS)) {
193692e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                    mWifiMonitor.broadcastAuthenticationFailureEvent(
1937efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                            mIfaceName, WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD);
193892e43feb3eb54736a28226b588bc087fdda1646eMichael Plass                }
1939b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastNetworkDisconnectionEvent(
1940b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
1941b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1942b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1943c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1944c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1945c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
19466680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode, boolean timedOut) {
1947b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAssociationRejected");
1948b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
19496680c62f91f61660d47c34ae435113ca5846b79dRoshan Pius                mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode, timedOut,
1950b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1951b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1952c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1953c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1954c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1955c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1956b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAuthenticationTimeout");
1957b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1958b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1959efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                        mIfaceName, WifiManager.ERROR_AUTH_FAILURE_TIMEOUT);
1960b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1961c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1962c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1963c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
196435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
196535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            logCallback("onBssidChanged");
196635c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            synchronized (mLock) {
196735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                if (reason == BssidChangeReason.ASSOC_START) {
196835c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastTargetBssidEvent(
196935c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
197035c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                } else if (reason == BssidChangeReason.ASSOC_COMPLETE) {
197135c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                    mWifiMonitor.broadcastAssociatedBssidEvent(
197235c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                            mIfaceName, NativeUtil.macAddressFromByteArray(bssid));
197335c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius                }
197435c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius            }
197535c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        }
197635c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius
197735c9c7f7a2f83d81b8d61da834b3960f5b9ffe19Roshan Pius        @Override
1978c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
1979b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onEapFailure");
1980b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1981b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1982efab6719309021b890dc39b1a7434ea6b7f7bb64Sohani Rao                        mIfaceName, WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE);
1983b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1984c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1985c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1986c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1987c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
1988b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventSuccess");
1989b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1990b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
1991b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1992c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1993c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1994c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1995c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
1996b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventFail");
1997b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1998b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (configError == WpsConfigError.MSG_TIMEOUT
1999b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        && errorInd == WpsErrorIndication.NO_ERROR) {
2000b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
2001b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else {
2002b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
2003b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
2004bcf35be52f93d09a3f2ac8d4272a6d66467309b9Roshan Pius            }
2005c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2006c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2007c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2008c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
2009b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventPbcOverlap");
2010b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
2011b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
2012b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
2013c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2014c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2015c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2016c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
2017b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkStart");
2018c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2019c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
2020c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
2021c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
2022b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkTimeout");
2023c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
2024c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
2025c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
202666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
202766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
202866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
202966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
203066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
203166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
203266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
203366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
203466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
203566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
203666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
2037240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
2038