SupplicantStaIfaceHal.java revision b70d1e046a5eb7e87c6b96beec30bcb985ee9c3c
1240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/*
298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Copyright (C) 2017 The Android Open Source Project
3240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
4240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
5240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * you may not use this file except in compliance with the License.
6240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * You may obtain a copy of the License at
7240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
8240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
9240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne *
10240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Unless required by applicable law or agreed to in writing, software
11240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
12240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * See the License for the specific language governing permissions and
14240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * limitations under the License.
15240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
16240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhnepackage com.android.server.wifi;
17240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQP3GPPNetwork;
195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPDomName;
205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPIPAddrAvailability;
215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPNAIRealm;
225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPRoamingConsortium;
235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.ANQPVenueName;
245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSConnCapability;
255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSFriendlyName;
265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSOSUProviders;
275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport static com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType.HSWANMetrics;
285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
29c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Piusimport android.content.Context;
30240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant;
31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface;
3296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork;
33240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface;
34c224fb554deca894818490c9416ff35d18a79d76Roshan Piusimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
3596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
36240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType;
37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
40240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager;
41240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification;
42f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration;
4382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.SupplicantState;
4466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration;
4582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Piusimport android.net.wifi.WifiSsid;
46240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException;
47240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log;
48f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray;
4996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
505a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.AnqpEvent;
515a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.IconEvent;
525a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.WnmData;
535a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPElement;
545a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.ANQPParser;
555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport com.android.server.wifi.hotspot2.anqp.Constants;
56d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil;
57240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.io.IOException;
595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Piusimport java.nio.BufferUnderflowException;
605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteBuffer;
615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.nio.ByteOrder;
62240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList;
63f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap;
64f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List;
65f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map;
665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Matcher;
675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Piusimport java.util.regex.Pattern;
68d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
69240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/**
70240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for
71240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon
72240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */
73b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal {
74b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
7598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private static final String SERVICE_MANAGER_NAME = "manager";
765f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
83511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean mVerboseLoggingEnabled = false;
8498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private IServiceManager mIServiceManager = null;
8598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
8698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
8798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
88b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private ISupplicantStaIfaceCallback mISupplicantStaIfaceCallback;
8903fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
907c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
917c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
927c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
935a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius    private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
94240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private final Object mLock = new Object();
95c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
96c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
977c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
98c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
99c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
100c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
101b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        mISupplicantStaIfaceCallback = new SupplicantStaIfaceHalCallback();
1028c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
103240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
104240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
105511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * Enable/Disable verbose logging.
106511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     *
107511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     * @param enable true to enable, false to disable.
108511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius     */
109511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    void enableVerboseLogging(boolean enable) {
110511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        mVerboseLoggingEnabled = enable;
111511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    }
112511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius
113511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    /**
11498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
11598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
116240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
117240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
118240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
119511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (mVerboseLoggingEnabled) Log.i(TAG, "Registering ISupplicant service ready callback.");
120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
12198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
12298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
12398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
12498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
12598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
12698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
12798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
128240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
12998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
13098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
131240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
132240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
133240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
13498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.linkToDeath(cookie -> {
135240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
136240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    synchronized (mLock) {
137240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        supplicantServiceDiedHandler();
13898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mIServiceManager = null; // Will need to register a new ServiceNotification
139240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }, 0)) {
141240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
142240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantServiceDiedHandler();
14398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
144240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
145240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
146240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                IServiceNotification serviceNotificationCb = new IServiceNotification.Stub() {
147240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    public void onRegistration(String fqName, String name, boolean preexisting) {
14898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        synchronized (mLock) {
149511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                            if (mVerboseLoggingEnabled) {
15098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
15198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                        + ", " + name + " preexisting=" + preexisting);
15298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
15398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (!initSupplicantService() || !initSupplicantStaIface()) {
15498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.e(TAG, "initalizing ISupplicantIfaces failed.");
15598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                supplicantServiceDiedHandler();
15698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            } else {
15798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
15898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        }
160240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
161240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                };
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
163240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
16498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.registerForNotifications(ISupplicant.kInterfaceName,
165240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        "", serviceNotificationCb)) {
166240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
16898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
169240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
17498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
176240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
177240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
178240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
179240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
18098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
181240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
182240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
18398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
186240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
18898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
190240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
192240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
195240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
19698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
197240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
198240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
200240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
20198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
202240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
203240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
204240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
205240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
206240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
207240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
208240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
209240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
210240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
21198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
212240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
213240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
214240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
21598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
216240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
217240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
21803fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
219240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
22098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
221240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
22298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
223240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
224240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
225240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
226240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
227240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
228240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
229240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
230240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
231240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
23298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
233240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
23403fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
235240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
236240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
237240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
23898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
23998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
240240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
241240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
24298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
24303fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
244b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            if (!registerCallback(mISupplicantStaIfaceCallback)) {
245c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
246c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
247240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
248240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
249240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
250240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
25198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
252240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
25398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
25498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
2555317e7c11c99d5cc8417c65cc73cf548f8f52b87Roshan Pius            mWifiMonitor.broadcastSupplicantDisconnectionEvent(mIfaceName);
256240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
257240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
258240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
25998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
26098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Signals whether Initialization completed successfully. Only necessary for testing, is not
26198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * needed to guard calls etc.
26298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
26398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
26498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
2658c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2668c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
2678c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
26898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
2698c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
27098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
27198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return IServiceManager.getService(SERVICE_MANAGER_NAME);
27298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
27398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
27498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
27598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
27698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
27798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
27898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
27998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
2808c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2818c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
28296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
2837c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
284d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
28566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
28666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
28766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
288d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
28966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
29066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
29166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
29266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
29366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
29466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
29566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
29666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
29766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
29866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
299f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        if (!network.saveWifiConfiguration(config)) {
30066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
301f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            if (!removeAllNetworks()) {
302f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius                loge("Failed to remove all networks on failure.");
303f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius            }
30466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
30566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
306f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius        return network;
30766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
30866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
30966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
3107c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
3117c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
3127c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
3137c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
3147c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
3157c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
3167c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
317d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
3187c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3197c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
3207c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
32166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
322d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
3237c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
3247c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
325d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
32666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
32766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
32866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
32966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
33066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
33166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
33266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
33366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
33466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = addNetwork(config);
3367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
337d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
33866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
33966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
341d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
34266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
34366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3447c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
3457c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
3467c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
3477c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
3487c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
3497c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
3507c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
3517c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
3527c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
3537c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
3547c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
3557c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
3567c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
3577c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3587c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
3597c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
3607c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
3617c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
3627c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
3637c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
3647c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return connectToNetwork(config, false);
3657c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3667c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
3677c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
3687c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
3697c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
3707c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3717c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3727c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
3737c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
3747c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3757c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
37666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
37766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
37866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
37966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
380f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
381f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
382f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
383f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
384f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
385f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
386f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
387f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
388f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
389f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
390f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
391f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
392f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
393f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
394f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
395f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
396f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
397f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
398f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
399f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
400f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
401f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
402f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (!network.loadWifiConfiguration(config, networkExtra)) {
403f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId);
404f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
405f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
406f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
407f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
408f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
409f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
410f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
411f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
412f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
413f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
414f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
415f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
416f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
417f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
418f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
419f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
420f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
421f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
422f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
423f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
42466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
42566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
42666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
42766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
42866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
42966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
43066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
43166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
43266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
43366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
43466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
43566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
43666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
43766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
43866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
43966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
44066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
44166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
44266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
44366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
4440a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
4450a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
4460a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
4470a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
4480a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
4490a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
4500a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return false;
4510a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.setBssid(bssidStr);
4520a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
4530a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
4540a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
4550a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
4560a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
4570a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
4580a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
4590a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
4600a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return null;
4610a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.getWpsNfcConfigurationToken();
4620a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
4630a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
4640a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
4658aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap identity response for the currently configured network.
4668aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
4678aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param identityStr String to send.
4688aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
4698aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
4708aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapIdentityResponse(String identityStr) {
4718aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
4728aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapIdentityResponse(identityStr);
4738aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
4748aad61408adef866a177857b79a979cf77a0a662Roshan Pius
4758aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
4768aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth response for the currently configured network.
4778aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
4788aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
4798aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
4808aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
4818aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthResponse(String paramsStr) {
4828aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
4838aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthResponse(paramsStr);
4848aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
4858aad61408adef866a177857b79a979cf77a0a662Roshan Pius
4868aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
4878aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
4888aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
4898aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
4908aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
4918aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimGsmAuthFailure() {
4928aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
4938aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimGsmAuthFailure();
4948aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
4958aad61408adef866a177857b79a979cf77a0a662Roshan Pius
4968aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
4978aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth response for the currently configured network.
4988aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
4998aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5008aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5018aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5028aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthResponse(String paramsStr) {
5038aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5048aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthResponse(paramsStr);
5058aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5068aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5078aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5088aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auts response for the currently configured network.
5098aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5108aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @param paramsStr String to send.
5118aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5128aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5138aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAutsResponse(String paramsStr) {
5148aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5158aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAutsResponse(paramsStr);
5168aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5178aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5188aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
5198aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * Send the eap sim umts auth failure for the currently configured network.
5208aad61408adef866a177857b79a979cf77a0a662Roshan Pius     *
5218aad61408adef866a177857b79a979cf77a0a662Roshan Pius     * @return true if succeeds, false otherwise.
5228aad61408adef866a177857b79a979cf77a0a662Roshan Pius     */
5238aad61408adef866a177857b79a979cf77a0a662Roshan Pius    public boolean sendCurrentNetworkEapSimUmtsAuthFailure() {
5248aad61408adef866a177857b79a979cf77a0a662Roshan Pius        if (mCurrentNetwork == null) return false;
5258aad61408adef866a177857b79a979cf77a0a662Roshan Pius        return mCurrentNetwork.sendNetworkEapSimUmtsAuthFailure();
5268aad61408adef866a177857b79a979cf77a0a662Roshan Pius    }
5278aad61408adef866a177857b79a979cf77a0a662Roshan Pius
5288aad61408adef866a177857b79a979cf77a0a662Roshan Pius    /**
529d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
530d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
53196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
53296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
53396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
53496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
53596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
53696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
5373aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
53896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
53996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
54096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
5413aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
54296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
54396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
54496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
54596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
546b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
54796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
5483aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
549c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
550c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
55196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
55296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
55396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
55496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
55596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
556d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
55796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
55896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
559d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
560d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
56196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
56296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
56396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
56496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
56596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
56696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
56796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
56896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
56996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
570b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
57196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
57296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
57396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
57496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
575d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
57696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
577f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
578f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
579f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
580f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
581f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
582f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
583f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
584c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
585511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        SupplicantStaNetworkHal network =
586511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                new SupplicantStaNetworkHal(iSupplicantStaNetwork, mIfaceName, mContext,
587511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius                        mWifiMonitor);
588511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        if (network != null) {
589511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            network.enableVerboseLogging(mVerboseLoggingEnabled);
590511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        }
591511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius        return network;
592f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
593f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
594f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
59596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
59696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
59796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
59896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
59996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
60096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
6013aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
60296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
60396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
60496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
60596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
6063aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
60796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
611b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
61296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6133aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
614c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
615c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
61696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
61796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
61896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
61996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
62096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
62196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
622c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
623c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
624c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
625c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
626c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
627c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
628c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
629c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
630c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
631b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
632c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
633c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
634c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
635c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
636c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
64196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
64396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
6443aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
64596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
64696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
64796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
64896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
6493aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
65096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
65196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
65296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
65396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
654b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
65596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
6563aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
65796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
65896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
659d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
6605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
6625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
6645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
6677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
6687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
6697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
6707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
6717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
6727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
6737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
674b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
6757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
6767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
6777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
6787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
6797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
6805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
6825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
6845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
6875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
6885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        if (!match.find() || match.groupCount() != 3) {
6895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Log.e(TAG, "Malformed WPS device type " + typeStr);
6905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
6915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
6925f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short categ = Short.parseShort(match.group(1));
6935f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
6945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short subCateg = Short.parseShort(match.group(3));
6955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
6965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] bytes = new byte[8];
6975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
6985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(categ);
6995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.put(oui);
7005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(subCateg);
7015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsDeviceType(bytes);
7025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
7035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
7057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
7077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
7107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
712b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
7205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
7225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
7257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
7277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
7307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
732b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
7405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
7425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
7457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
7477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
7507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
752b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
7605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
7625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
7657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
7677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
7707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
772b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
7805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
7825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
7857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
7877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7887651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
7907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
792b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
7937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
8005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
8015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
8025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
8035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
8045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
8055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
8065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
8075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
8085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
8095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
8105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
8115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
8125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
8147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
8157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
8167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
8177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
8187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
8197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
8207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
821b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
8227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
8237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
8247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
8257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
8267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
827d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
828d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
829d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
830d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
831d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
832d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
83396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
83496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
83596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
83696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
83796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
83896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
83996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
840b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
84196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
84296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
84396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
84496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
845d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
846d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
847d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
848d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
849d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
850d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
851d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
85296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
85396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
85496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
85596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
85696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
85796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
85896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
859b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
86096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
86196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
86296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
86396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
864d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
865d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
866d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
867d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
868d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
869d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
870d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
87196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
87296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
87396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
87496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
87596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
87696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
87796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
878b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
87996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
88096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
88196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
88296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
883d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
884d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
885d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
886d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
887d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
888d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
889d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
890d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
89196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
89296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
89396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
89496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
89596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
89696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
89796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
898b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
90296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
903d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
904d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
905d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
906d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
907d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
908d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
909d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
910d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
911d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
912d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
913b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
91496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
91596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
91696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
91796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
922b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
92596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
927d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
928d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
929d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
930d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
931d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
932d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
933d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
934d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
935d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
936d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
937b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
93896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
93996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
94096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
94196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
94296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
94396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
94496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
946b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
951d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
952d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
953d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
954d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
955d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
956d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
957d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
958d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
959d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
960d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
961b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
96296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
96396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
96496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
96596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
96696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
96996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
970b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
97196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
97296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
97396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
97496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
975d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
976d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
977d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
978d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
979d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
980d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
981d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
982d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
983d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
984d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
985d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
986d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
987d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
988d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
989d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
990b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
99396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
99496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1001b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
100296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
100396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
100596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1006d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1007d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1008d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
1009d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1010d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
1011d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
1012d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1013d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1014d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
1015d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
1016d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1017d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1018b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
101996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
102096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
102196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
102296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
102396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
102496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
102596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
102696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
102796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1028b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
102996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
103096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
103196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
103296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1033d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
103496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
103596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
1036d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
103796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
103896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1039d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
104096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
104196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
104296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
104396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
104696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
10473aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1048d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
105196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1052b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
105396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
10543aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
105596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
105696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1057d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1058d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1059d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1060d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1061d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1062d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1063d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
106496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
106596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
106696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
106796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
106896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
106996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
107096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1071b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
107296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
107396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
107496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
107596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1076d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1077d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1078d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1079d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1080d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1081d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1082d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
108396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
108496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
108596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
108696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
108796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
108896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
108996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1090b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
109196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
109296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
109396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
109496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1095d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1096d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
1097d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1098d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
1099d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1100d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1101d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1102d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1103d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1104d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1105d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1106d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1107f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean addRxFilter(byte type) {
110896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
110996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
111096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
111196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
111296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
111396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
111496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1115b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
111696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
111796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
111896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
111996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1120d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1121d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1122d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
1123d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1124d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1125d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1126d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1127d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1128f0c2cbd00fe77a8f2b94f3f0d7c28e3e5fdc1fc4Roshan Pius    public boolean removeRxFilter(byte type) {
112996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
113096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
113196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
113296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
113396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
113496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
113596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1136b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
113796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
113896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
113996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
114096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1141d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1142d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1143d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1144d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1145d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1146d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1147d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1148d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
1149d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
1150d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1151d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1152d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
115396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
115496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
115596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
115696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
115796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
115896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
115996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1160b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
116196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
116296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
116396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
116496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1165d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1166d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1167d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1168d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1169d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1170d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1171d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
117296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
117396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
117496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
117596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
117696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
117796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
117896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
117996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1180b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
118196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
118296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
118396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
118496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1185d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1186d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1187d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1188d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1189d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
11905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1191d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1192d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
119396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
119496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
119696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
119796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
119896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
119996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1200b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
120196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
120296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
120396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
120496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1205d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1206d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1207d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1208d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1209d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1210d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1211d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1212d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1213d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1214d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1215d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1216b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
121796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
121896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
121996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
122096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
122196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
122296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
122396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
122496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
1225b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
122696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
122796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
122896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
122996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
123096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
12315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
12335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
12355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
12365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
12395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
12405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
12415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
12427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
12437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
12447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
12467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
12497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1251b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
12527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
12557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
12567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
12575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12585f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
12595f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12605f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
12615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
12645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
12655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
12665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
12677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
12687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
12697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
12717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
12747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1276b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
12777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
12807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
12817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
12825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
12845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
12865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
12897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
12917651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
12947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1296b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
12977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
13045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
13065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
13075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
13095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
13105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
13115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
13127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
13137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
13147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13157651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
13167651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
13177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
13187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
13207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
13217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
13227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
13237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
13247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
13257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1326b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
13297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
13345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
13387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
13407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
13437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1345b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
13535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
13555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
13587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
13607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
13637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
1365b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
13667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
1371cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_EXCESSIVE = ISupplicant.DebugLevel.EXCESSIVE;
1372cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_MSGDUMP = ISupplicant.DebugLevel.MSGDUMP;
1373cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_DEBUG = ISupplicant.DebugLevel.DEBUG;
1374cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_INFO = ISupplicant.DebugLevel.INFO;
1375cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_WARNING = ISupplicant.DebugLevel.WARNING;
1376cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_ERROR = ISupplicant.DebugLevel.ERROR;
1377cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1378cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1379cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param level One of the above {@link #LOG_LEVEL_EXCESSIVE} - {@link #LOG_LEVEL_ERROR} value.
1380cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1381cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1382cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setLogLevel(int level) {
1383cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return setDebugParams(level, false, false);
1384cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1385cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1386cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1387cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1388cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1389cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1390cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1391cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1392cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1393cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1394cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1395cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1396b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1397cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1398cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1399cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1400cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1401cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1402cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1403cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1404cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1405cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1406cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1407cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1408cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1409cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1410cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1411cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1412cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1413cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1414cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1415cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1416cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1417cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1418cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1419cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1420cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1421cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1422cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1423cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1424cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1425cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1426b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                handleRemoteException(e, methodStr);
1427cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1428cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1429cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1430cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1431cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1432cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1433cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1434cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1435cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1436cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1437cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1438cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1439cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1440cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1441cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1442cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
144396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
144496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
144596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
144696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
144796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
144896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
144996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
145096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
145196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
145296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
145396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
145496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
145596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
145696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
145796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
1458511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius    private boolean checkStatusAndLogFailure(SupplicantStatus status,
145996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
146096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
1461b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: "
1462b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius                    + supplicantStatusCodeToString(status.code) + ", " + status.debugMessage);
146396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
1464b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        } else {
1465511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            if (mVerboseLoggingEnabled) {
1466b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded");
1467511c6a204fefd7d295cb3728e6d4665106a29ae7Roshan Pius            }
1468b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius            return true;
146996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
1470b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    }
1471b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius
1472b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    /**
1473b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     * Helper function to log callbacks.
1474b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius     */
1475b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    private void logCallback(final String methodStr) {
1476b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        if (mVerboseLoggingEnabled) {
1477b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received");
1478b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius        }
1479b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius    }
1480b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1481b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius
1482b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius    private void handleRemoteException(RemoteException e, String methodStr) {
1483b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        supplicantServiceDiedHandler();
1484b850a6ae6fe8470fd9338bbc9978caadc7ca2c4bRoshan Pius        Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e);
148596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
148696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
148796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
148896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
148996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
149096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
149196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
149296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
149396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
149496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
149596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
149696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
149796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
149896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
149996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
150096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
150196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
150296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
150396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
150496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
150596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
150696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
150796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
150896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
150996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
151096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
151196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
151296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
151396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
151496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
151596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
151696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
151796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
15185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
15195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
15205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
15215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
15225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
15235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
15245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
15255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
15265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
15275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
15285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
15295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
15305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
15315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
15325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
15335f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
15345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
15355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
15365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
15375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
15385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
15395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
15405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
15415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
15425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
15435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
15445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
15455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
15465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
15475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
15485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
15495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
15505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
15515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
15525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
15535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
15545f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
15555f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
15565f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
15575f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
155882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
155982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
156082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
156182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
156282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
156382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
156482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
156582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
156682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
156782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
156882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
156982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
157082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
157182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
157282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
157382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
157482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
157582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
157682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
157782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
157882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
157982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
158082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
158182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
158282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
158382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
158482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
158582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
158682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
158782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1588240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1589240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1590240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1591240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1592240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1593240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1594240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1595240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1596240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1597240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1598240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
159966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1600c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
16015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16025a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
16035a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
16045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
16055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
16065a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
16075a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16085a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
16095a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
16105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
16115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
16125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
16135a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
16145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
16155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
16165a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
16175a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
16185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
16195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
16225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
16245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
16255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
16265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
16275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
16285a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16295a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
16305a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
16315a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
16325a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
16335a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
16345a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
16355a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
16365a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16375a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16385a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
16395a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16405a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Helper utility to convert the bssid bytes to long.
16415a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16425a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private Long toLongBssid(byte[] bssidBytes) {
16435a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
16445a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return ByteBufferReader.readInteger(
16455a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ByteBuffer.wrap(bssidBytes), ByteOrder.BIG_ENDIAN, bssidBytes.length);
16465a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (BufferUnderflowException | IllegalArgumentException e) {
16475a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return 0L;
16485a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16495a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16505a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1651c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1652c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1653b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkAdded");
1654c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1655c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1656c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1657c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1658b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onNetworkRemoved");
1659c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1660c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1661c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1662c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1663c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
1664b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onStateChanged");
1665b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1666b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
1667b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                WifiSsid wifiSsid =
1668b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
1669b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
1670b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastSupplicantStateChangeEvent(
1671b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
1672b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (newSupplicantState == SupplicantState.ASSOCIATED) {
1673b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastAssociationSuccesfulEvent(mIfaceName, bssidStr);
1674b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else if (newSupplicantState == SupplicantState.COMPLETED) {
1675b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastNetworkConnectionEvent(
1676b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                            mIfaceName, mFrameworkNetworkId, bssidStr);
1677b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
167882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1679c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1680c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1681c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
16825a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1683c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1684c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
1685b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAnqpQueryDone");
1686b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1687b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
1688b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
1689b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
1690b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(
1691b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
1692b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
1693b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
1694b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
1695b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
1696b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
1697b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
1698b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
1699b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAnqpDoneEvent(
1700b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, new AnqpEvent(toLongBssid(bssid), elementsMap));
1701b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1702c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1703c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1704c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1706c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
1707b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20IconQueryDone");
1708b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1709b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastIconDoneEvent(
1710b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
1711b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        new IconEvent(toLongBssid(bssid), fileName, data.size(),
1712b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                NativeUtil.byteArrayFromArrayList(data)));
1713b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1714c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1715c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1716c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17175a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
1718b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20SubscriptionRemediation");
1719b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1720b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1721b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, new WnmData(toLongBssid(bssid), url, osuMethod));
1722b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1723c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1724c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1725c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
17265a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
17275a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
1728b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onHs20DeauthImminentNotice");
1729b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1730b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWnmEvent(
1731b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName,
1732b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        new WnmData(toLongBssid(bssid), url, reasonCode == WnmData.ESS,
1733b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                                reAuthDelayInSec));
1734b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1735c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1736c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1737c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1738c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1739b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onDisconnected");
1740b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1741b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastNetworkDisconnectionEvent(
1742b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, locallyGenerated ? 1 : 0, reasonCode,
1743b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1744b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1745c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1746c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1747c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1748c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode) {
1749b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAssociationRejected");
1750b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1751b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                // TODO(b/35464954): Need to figure out when to trigger
1752b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                // |WifiMonitor.AUTHENTICATION_FAILURE_REASON_WRONG_PSWD|
1753b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAssociationRejectionEvent(mIfaceName, statusCode,
1754b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        NativeUtil.macAddressFromByteArray(bssid));
1755b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1756c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1757c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1758c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1759c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1760b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onAuthenticationTimeout");
1761b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1762b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1763b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_TIMEOUT);
1764b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1765c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1766c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1767c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1768c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
1769b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onEapFailure");
1770b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1771b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastAuthenticationFailureEvent(
1772b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        mIfaceName, WifiMonitor.AUTHENTICATION_FAILURE_REASON_EAP_FAILURE);
1773b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1774c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1775c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1776c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1777c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
1778b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventSuccess");
1779b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1780b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsSuccessEvent(mIfaceName);
1781b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1782c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1783c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1784c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1785c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
1786b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventFail");
1787b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1788b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                if (configError == WpsConfigError.MSG_TIMEOUT
1789b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                        && errorInd == WpsErrorIndication.NO_ERROR) {
1790b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsTimeoutEvent(mIfaceName);
1791b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                } else {
1792b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                    mWifiMonitor.broadcastWpsFailEvent(mIfaceName, configError, errorInd);
1793b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                }
1794bcf35be52f93d09a3f2ac8d4272a6d66467309b9Roshan Pius            }
1795c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1796c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1797c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1798c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
1799b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onWpsEventPbcOverlap");
1800b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            synchronized (mLock) {
1801b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius                mWifiMonitor.broadcastWpsOverlapEvent(mIfaceName);
1802b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            }
1803c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1804c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1805c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1806c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
1807b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkStart");
1808c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1809c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1810c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1811c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
1812b70d1e046a5eb7e87c6b96beec30bcb985ee9c3cRoshan Pius            logCallback("onExtRadioWorkTimeout");
1813c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1814c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
1815c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
181666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
181766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
181866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
181966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
182066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
182166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
182266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
182366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
182466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
182566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
182666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
1827240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
1828