SupplicantStaIfaceHal.java revision 82c5c5f2ee520a1066cf5d6421885bb53bbfe269
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 {
74240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static final boolean DBG = false;
75b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    private static final String TAG = "SupplicantStaIfaceHal";
7698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private static final String SERVICE_MANAGER_NAME = "manager";
775f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
785f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Regex pattern for extracting the wps device type bytes.
795f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
805f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
815f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static final Pattern WPS_DEVICE_TYPE_PATTERN =
825f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$");
835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
8498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private IServiceManager mIServiceManager = null;
8598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    // Supplicant HAL interface objects
8698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicant mISupplicant;
8798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private ISupplicantStaIface mISupplicantStaIface;
8803fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius    private String mIfaceName;
897c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network in wpa_supplicant
907c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    private SupplicantStaNetworkHal mCurrentNetwork;
917c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    // Currently configured network's framework network Id.
925a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius    private int mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
93240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private final Object mLock = new Object();
94c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final Context mContext;
95c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    private final WifiMonitor mWifiMonitor;
967c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
97c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius    public SupplicantStaIfaceHal(Context context, WifiMonitor monitor) {
98c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mContext = context;
99c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius        mWifiMonitor = monitor;
1008c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
101240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
102240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    /**
10398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Registers a service notification for the ISupplicant service, which triggers intialization of
10498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * the ISupplicantStaIface
105240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     * @return true if the service notification was successfully registered
106240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne     */
107240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    public boolean initialize() {
10898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback.");
109240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
11098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
11198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
11298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mIServiceManager != null) {
11398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // Already have an IServiceManager and serviceNotification registered, don't
11498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                // don't register another.
11598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return true;
11698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            }
117240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
11898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mIServiceManager = getServiceManagerMockable();
11998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (mIServiceManager == null) {
120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to get HIDL Service Manager");
121240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
122240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
12398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.linkToDeath(cookie -> {
124240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "IServiceManager died: cookie=" + cookie);
125240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    synchronized (mLock) {
126240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        supplicantServiceDiedHandler();
12798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mIServiceManager = null; // Will need to register a new ServiceNotification
128240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
129240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }, 0)) {
130240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.wtf(TAG, "Error on linkToDeath on IServiceManager");
131240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantServiceDiedHandler();
13298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
133240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
134240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
135240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                IServiceNotification serviceNotificationCb = new IServiceNotification.Stub() {
136240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    public void onRegistration(String fqName, String name, boolean preexisting) {
13798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        synchronized (mLock) {
13898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (DBG) {
13998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName
14098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                        + ", " + name + " preexisting=" + preexisting);
14198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
14298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            if (!initSupplicantService() || !initSupplicantStaIface()) {
14398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.e(TAG, "initalizing ISupplicantIfaces failed.");
14498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                supplicantServiceDiedHandler();
14598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            } else {
14698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                                Log.i(TAG, "Completed initialization of ISupplicant interfaces.");
14798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                            }
148240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        }
149240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
150240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                };
151240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it
152240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                   exists */
15398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (!mIServiceManager.registerForNotifications(ISupplicant.kInterfaceName,
154240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        "", serviceNotificationCb)) {
155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    Log.e(TAG, "Failed to register for notifications to "
156240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            + ISupplicant.kInterfaceName);
15798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                    mIServiceManager = null; // Will need to register a new ServiceNotification
158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    return false;
159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
160240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
161240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: "
162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        + e);
16398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                supplicantServiceDiedHandler();
164240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
165240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
166240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
168240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
16998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantService() {
170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
171240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
17298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant = getSupplicantMockable();
173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
174240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.getService exception: " + e);
175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
176240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
17798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (mISupplicant == null) {
178240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
179240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
181240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
182240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        return true;
183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
18598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private boolean initSupplicantStaIface() {
186240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
187240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            /** List all supplicant Ifaces */
188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>();
189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            try {
19098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                mISupplicant.listInterfaces((SupplicantStatus status,
191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        ArrayList<ISupplicant.IfaceInfo> ifaces) -> {
192240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    if (status.code != SupplicantStatusCode.SUCCESS) {
193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code);
194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        return;
195240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
196240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    supplicantIfaces.addAll(ifaces);
197240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                });
198240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            } catch (RemoteException e) {
199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "ISupplicant.listInterfaces exception: " + e);
20098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
201240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
202240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            if (supplicantIfaces.size() == 0) {
203240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup.");
20498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                return false;
205240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
206240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            Mutable<ISupplicantIface> supplicantIface = new Mutable<>();
20703fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            Mutable<String> ifaceName = new Mutable<>();
208240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) {
20998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                if (ifaceInfo.type == IfaceType.STA) {
210240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    try {
21198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        mISupplicant.getInterface(ifaceInfo,
212240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                (SupplicantStatus status, ISupplicantIface iface) -> {
213240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                if (status.code != SupplicantStatusCode.SUCCESS) {
214240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    Log.e(TAG, "Failed to get ISupplicantIface " + status.code);
215240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                    return;
216240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                }
217240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                                supplicantIface.value = iface;
218240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                            });
219240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    } catch (RemoteException e) {
220240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                        Log.e(TAG, "ISupplicant.getInterface exception: " + e);
22198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                        return false;
222240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    }
22303fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                    ifaceName.value = ifaceInfo.name;
224240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                    break;
225240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                }
226240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
22798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            if (supplicantIface.value == null) {
22898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne                Log.e(TAG, "initSupplicantStaIface got null iface");
229240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne                return false;
230240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            }
23198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value);
23203fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius            mIfaceName = ifaceName.value;
233c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!registerCallback(new SupplicantStaIfaceHalCallback())) {
234c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
235c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
236240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            return true;
237240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
238240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
239240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
24098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    private void supplicantServiceDiedHandler() {
241240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        synchronized (mLock) {
24298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicant = null;
24398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne            mISupplicantStaIface = null;
244240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
245240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
246240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
24798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    /**
24898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Signals whether Initialization completed successfully. Only necessary for testing, is not
24998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * needed to guard calls etc.
25098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     */
25198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    public boolean isInitializationComplete() {
25298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return mISupplicantStaIface != null;
2538c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2548c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
2558c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    /**
25698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne     * Wrapper functions to access static HAL methods, created to be mockable in unit tests
2578c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius     */
25898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected IServiceManager getServiceManagerMockable() throws RemoteException {
25998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return IServiceManager.getService(SERVICE_MANAGER_NAME);
26098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
26198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
26298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicant getSupplicantMockable() throws RemoteException {
26398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicant.getService();
26498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    }
26598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne
26698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne    protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) {
26798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne        return ISupplicantStaIface.asInterface(iface.asBinder());
2688c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius    }
2698c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius
27096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
2717c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add a network configuration to wpa_supplicant.
272d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
27366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @param config Config corresponding to the network.
27466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * @return SupplicantStaNetwork of the added network in wpa_supplicant.
27566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
276d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
27766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        logi("addSupplicantStaNetwork via HIDL");
27866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (config == null) {
27966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Cannot add NULL network!");
28066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
28166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
28266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        SupplicantStaNetworkHal network = addNetwork();
28366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network == null) {
28466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to add a network!");
28566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
28666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
28766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (network.saveWifiConfiguration(config)) {
28866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return network;
28966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        } else {
29066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to save variables for: " + config.configKey());
29166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return null;
29266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
29366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
29466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
29566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
2967c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
2977c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * This method does the following:
2987c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. Triggers disconnect command to wpa_supplicant (if |shouldDisconnect| is true).
2997c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Remove any existing network in wpa_supplicant.
3007c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Add a new network to wpa_supplicant.
3017c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 4. Save the provided configuration to wpa_supplicant.
3027c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 5. Select the new network in wpa_supplicant.
303d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
3047c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3057c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param shouldDisconnect whether to trigger a disconnection or not.
3067c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
30766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
308d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) {
3097c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
3107c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = null;
311d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        logd("connectToNetwork " + config.configKey()
31266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                + " (shouldDisconnect " + shouldDisconnect + ")");
31366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (shouldDisconnect && !disconnect()) {
31466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to trigger disconnect");
31566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
31666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
31766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        if (!removeAllNetworks()) {
31866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            loge("Failed to remove existing networks");
31966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
32066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3217c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mCurrentNetwork = addNetwork(config);
3227c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mCurrentNetwork == null) {
323d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to add/save network configuration: " + config.configKey());
32466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
32566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3267c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.select()) {
327d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            loge("Failed to select network configuration: " + config.configKey());
32866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            return false;
32966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
3307c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        mFrameworkNetworkId = config.networkId;
3317c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        return true;
3327c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    }
3337c0ec884188660f72977c8a80366049705c48ffaRoshan Pius
3347c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    /**
3357c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
3367c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configuration provided does not match the already configured network, then this triggers
3377c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * a new connection attempt (instead of roam).
3387c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 1. First check if we're attempting to connect to the same network as we currently have
3397c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * configured.
3407c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 2. Set the new bssid for the network in wpa_supplicant.
3417c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * 3. Trigger reassociate command to wpa_supplicant.
3427c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     *
3437c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @param config WifiConfiguration parameters for the provided network.
3447c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
3457c0ec884188660f72977c8a80366049705c48ffaRoshan Pius     */
3467c0ec884188660f72977c8a80366049705c48ffaRoshan Pius    public boolean roamToNetwork(WifiConfiguration config) {
3477c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (mFrameworkNetworkId != config.networkId || mCurrentNetwork == null) {
3487c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            Log.w(TAG, "Cannot roam to a different network, initiate new connection. "
3497c0ec884188660f72977c8a80366049705c48ffaRoshan Pius                    + "Current network ID: " + mFrameworkNetworkId);
3507c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return connectToNetwork(config, false);
3517c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3527c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
3537c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        logd("roamToNetwork" + config.configKey() + " (bssid " + bssid + ")");
3547c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!mCurrentNetwork.setBssid(bssid)) {
3557c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to set new bssid on network: " + config.configKey());
3567c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3577c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
3587c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        if (!reassociate()) {
3597c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            loge("Failed to trigger reassociate");
3607c0ec884188660f72977c8a80366049705c48ffaRoshan Pius            return false;
3617c0ec884188660f72977c8a80366049705c48ffaRoshan Pius        }
36266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
36366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
36466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
36566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
366f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Load all the configured networks from wpa_supplicant.
367f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
368f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
369f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *                      the networks.
370f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
371f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return true if succeeds, false otherwise.
372f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
373f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    public boolean loadNetworks(Map<String, WifiConfiguration> configs,
374f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                                SparseArray<Map<String, String>> networkExtras) {
375f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        List<Integer> networkIds = listNetworks();
376f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        if (networkIds == null) {
377f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Log.e(TAG, "Failed to list networks");
378f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            return false;
379f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
380f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        for (Integer networkId : networkIds) {
381f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            SupplicantStaNetworkHal network = getNetwork(networkId);
382f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (network == null) {
383f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to get network with ID: " + networkId);
384f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
385f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
386f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            WifiConfiguration config = new WifiConfiguration();
387f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            Map<String, String> networkExtra = new HashMap<>();
388f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (!network.loadWifiConfiguration(config, networkExtra)) {
389f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId);
390f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                return false;
391f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
392f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            // Set the default IP assignments.
393f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
394f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            config.setProxySettings(IpConfiguration.ProxySettings.NONE);
395f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
396f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            networkExtras.put(networkId, networkExtra);
397f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY);
398f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            final WifiConfiguration duplicateConfig = configs.put(configKey, config);
399f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            if (duplicateConfig != null) {
400f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                // The network is already known. Overwrite the duplicate entry.
401f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId);
402f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                removeNetwork(duplicateConfig.networkId);
403f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius                networkExtras.remove(duplicateConfig.networkId);
404f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius            }
405f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        }
406f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius        return true;
407f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
408f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
409f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
41066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     * Remove all networks from supplicant
41166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne     */
41266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    public boolean removeAllNetworks() {
41366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        synchronized (mLock) {
41466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            ArrayList<Integer> networks = listNetworks();
41566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            if (networks == null) {
41666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                Log.e(TAG, "removeAllNetworks failed, got null networks");
41766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                return false;
41866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
41966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            for (int id : networks) {
42066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                if (!removeNetwork(id)) {
42166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
42266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                    return false;
42366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne                }
42466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne            }
42566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        }
42666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        return true;
42766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
42866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
42966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    /**
4300a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Set the currently configured network's bssid.
4310a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
4320a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX"
4330a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return true if succeeds, false otherwise.
4340a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
4350a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public boolean setCurrentNetworkBssid(String bssidStr) {
4360a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return false;
4370a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.setBssid(bssidStr);
4380a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
4390a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
4400a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
4410a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * Get the currently configured network's WPS NFC token.
4420a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     *
4430a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     * @return Hex string corresponding to the WPS NFC token.
4440a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius     */
4450a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken() {
4460a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        if (mCurrentNetwork == null) return null;
4470a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius        return mCurrentNetwork.getWpsNfcConfigurationToken();
4480a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    }
4490a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius
4500a3dcd72290481cb1fcbaaec268cccf343e4ff48Roshan Pius    /**
451d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Adds a new network.
452d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
45396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the new network, or null if the call fails
45496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
45596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal addNetwork() {
45696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
45796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addNetwork";
45896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
45996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
4603aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> newNetwork = new Mutable<>();
46196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
46296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.addNetwork((SupplicantStatus status,
46396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
4643aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
46596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        newNetwork.value = network;
46696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
46796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
46896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
46996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
47096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
47196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
4723aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (newNetwork.value != null) {
473c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
474c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder()));
47596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
47696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
47796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
47896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
47996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
480d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
48196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
48296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Remove network from supplicant with network Id
483d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
484d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
48596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
48696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeNetwork(int id) {
48796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
48896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeNetwork";
48996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
49096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
49196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
49296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeNetwork(id);
49396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
49496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
49596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
49696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
49796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
49896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
49996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
50096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
501d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
50296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
503f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * Use this to mock the creation of SupplicantStaNetworkHal instance.
504f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     *
505f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL.
506f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
507f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     * the call fails
508f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius     */
509f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    protected SupplicantStaNetworkHal getStaNetworkMockable(
510c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius            ISupplicantStaNetwork iSupplicantStaNetwork) {
51103fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius        return new SupplicantStaNetworkHal(
51203fea88ccab149c07391d38f3c406bb04ab0a3a9Roshan Pius                iSupplicantStaNetwork, mIfaceName, mContext, mWifiMonitor);
513f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    }
514f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius
515f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius    /**
51696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if
51796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * the call fails
51896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
51996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private SupplicantStaNetworkHal getNetwork(int id) {
52096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
52196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getNetwork";
52296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
5233aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>();
52496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
52596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
52696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getNetwork(id, (SupplicantStatus status,
52796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        ISupplicantNetwork network) -> {
5283aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
52996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        gotNetwork.value = network;
53096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
53196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
53296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
53396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
53496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
53596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
5363aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            if (gotNetwork.value != null) {
537c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                return getStaNetworkMockable(
538c7a4b6706fa09042bb36a64036d86d88eb6e4126Roshan Pius                        ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder()));
53996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } else {
54096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return null;
54196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
54296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
54396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
54496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
545c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    /** See ISupplicantStaNetwork.hal for documentation */
546c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private boolean registerCallback(ISupplicantStaIfaceCallback callback) {
547c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        synchronized (mLock) {
548c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            final String methodStr = "registerCallback";
549c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
550c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            try {
551c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                SupplicantStatus status =  mISupplicantStaIface.registerCallback(callback);
552c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
553c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            } catch (RemoteException e) {
554c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                supplicantServiceDiedHandler();
555c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                return false;
556c224fb554deca894818490c9416ff35d18a79d76Roshan Pius            }
557c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
558c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
559c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
56096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
56196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns
56296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * null if the call fails
56396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
56496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private java.util.ArrayList<Integer> listNetworks() {
56596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
56696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "listNetworks";
56796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
5683aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            Mutable<ArrayList<Integer>> networkIdList = new Mutable<>();
56996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
57096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
57196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.listNetworks((SupplicantStatus status,
57296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        java.util.ArrayList<Integer> networkIds) -> {
5733aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
57496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        networkIdList.value = networkIds;
57596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
57696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
57796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
57896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
57996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
58096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
5813aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return networkIdList.value;
58296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
58396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
584d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
5855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
5865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device name.
5875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
5885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param name String to be set.
5895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
5905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
5915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceName(String name) {
5927651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
5937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceName";
5947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
5957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
5967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
5977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceName(name);
5987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
5997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
6007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
6017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
6027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
6037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
6047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
6057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
6067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
6075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS device type.
6095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
6115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsDeviceType(String typeStr) {
6145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr);
6155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        if (!match.find() || match.groupCount() != 3) {
6165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            Log.e(TAG, "Malformed WPS device type " + typeStr);
6175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            return false;
6185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
6195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short categ = Short.parseShort(match.group(1));
6205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] oui = NativeUtil.hexStringToByteArray(match.group(2));
6215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short subCateg = Short.parseShort(match.group(3));
6225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
6235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byte[] bytes = new byte[8];
6245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
6255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(categ);
6265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.put(oui);
6275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        byteBuffer.putShort(subCateg);
6285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsDeviceType(bytes);
6295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
6305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
6317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsDeviceType(byte[/* 8 */] type) {
6327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
6337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsDeviceType";
6347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
6357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
6367651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
6377651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsDeviceType(type);
6387651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
6397651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
6407651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
6417651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
6427651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
6437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
6447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
6457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
6467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
6475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS manufacturer.
6495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6505f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param manufacturer String to be set.
6515f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6525f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6535f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsManufacturer(String manufacturer) {
6547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
6557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsManufacturer";
6567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
6577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
6587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
6597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsManufacturer(manufacturer);
6607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
6617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
6627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
6637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
6647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
6657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
6667651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
6677651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
6687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
6695f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6705f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model name.
6715f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6725f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelName String to be set.
6735f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6745f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6755f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelName(String modelName) {
6767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
6777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelName";
6787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
6797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
6807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
6817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelName(modelName);
6827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
6837651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
6847651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
6857651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
6867651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
6877651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
6887651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
6897651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
6907651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
6915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
6925f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS model number.
6935f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
6945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param modelNumber String to be set.
6955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
6965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
6975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsModelNumber(String modelNumber) {
6987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
6997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsModelNumber";
7007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
7017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsModelNumber(modelNumber);
7047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
7067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
7077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
7087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS serial number.
7155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param serialNumber String to be set.
7175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsSerialNumber(String serialNumber) {
7207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsSerialNumber";
7227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
7237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsSerialNumber(serialNumber);
7267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
7287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
7297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
7307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
7355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
7365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Set WPS config methods
7375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
7385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param configMethodsStr List of config methods.
7395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
7405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
7415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setWpsConfigMethods(String configMethodsStr) {
7425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        short configMethodsMask = 0;
7435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        String[] configMethodsStrArr = configMethodsStr.split("\\s+");
7445f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        for (int i = 0; i < configMethodsStrArr.length; i++) {
7455f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]);
7465f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
7475f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return setWpsConfigMethods(configMethodsMask);
7485f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
7495f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
7507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean setWpsConfigMethods(short configMethods) {
7517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
7527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setWpsConfigMethods";
7537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
7547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
7557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
7567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setWpsConfigMethods(configMethods);
7577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
7587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
7597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
7607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
7617651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
7627651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
7637651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
7647651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
7657651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
766d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
767d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reassociation even if the iface is currently connected.
768d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
769d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
770d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
771d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reassociate() {
77296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
77396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reassociate";
77496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
77596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
77696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
77796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reassociate();
77896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
77996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
78096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
78196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
78296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
78396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
78496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
78596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
786d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
787d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
788d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a reconnection if the iface is disconnected.
789d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
790d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
791d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
792d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean reconnect() {
79396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
79496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "reconnect";
79596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
79696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
79796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
79896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.reconnect();
79996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
80096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
80196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
80296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
80396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
80496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
80596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
80696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
807d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
808d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
809d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Trigger a disconnection from the currently connected network.
810d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
811d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
812d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
813d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean disconnect() {
81496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
81596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "disconnect";
81696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
81796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
81896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
81996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.disconnect();
82096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
82196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
82296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
82396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
82496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
82596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
82696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
82796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
828d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
829d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
830d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable power save mode.
831d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
832d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
833d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
834d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
835d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setPowerSave(boolean enable) {
83696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
83796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setPowerSave";
83896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
83996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
84096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
84196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable);
84296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
84396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
84496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
84596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
84696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
84796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
84896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
84996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
850d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
851d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
852d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS discover with the specified AP.
853d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
854d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
855d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
856d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
857d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsDiscover(String macAddress) {
858d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress));
859d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
860b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
86196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) {
86296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
86396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsDiscover";
86496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
86596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
86696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
86796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress);
86896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
86996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
87096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
87196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
87296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
87396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
87496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
87596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
876d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
877d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
878d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS setup with the specified AP.
879d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
880d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
881d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
882d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
883d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsSetup(String macAddress) {
884d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress));
885d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
886b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
88796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) {
88896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
88996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsSetup";
89096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
89196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
89296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
89396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress);
89496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
89596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
89696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
89796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
89896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
902d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
903d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
904d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Initiate TDLS teardown with the specified AP.
905d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param macAddress MAC Address of the AP.
906d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
907d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
908d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateTdlsTeardown(String macAddress) {
909d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress));
910d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
911d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
912b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
91396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) {
91496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
91596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateTdlsTeardown";
91696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
91796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress);
92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
92296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
92596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
92796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
928d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
929d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
930d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP elements |elements| from the specified AP |bssid|.
931d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
932d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
933d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId.
934d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes.
935d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
936d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
937d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements,
938d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                                     ArrayList<Integer> hs20SubTypes) {
939d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateAnqpQuery(
940d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes);
941d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
942d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
943b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
94496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateAnqpQuery(byte[/* 6 */] macAddress,
94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) {
94696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateAnqpQuery";
94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress,
95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        infoElements, subTypes);
95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
95496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
95596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
95696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
96096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
961d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
962d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
963d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Request the specified ANQP ICON from the specified AP |bssid|.
964d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
965d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param bssid BSSID of the AP
966d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param fileName Name of the file to request.
967d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
968d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
969d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean initiateHs20IconQuery(String bssid, String fileName) {
970d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName);
971d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
972d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
973b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
97496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) {
97596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
97696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "initiateHs20IconQuery";
97796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
97896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
97996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
98096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress,
98196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        fileName);
98296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
98396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
98496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
98596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
98696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
98796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
98896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
98996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
990d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Makes a callback to HIDL to getMacAddress from supplicant
993d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
99496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * @return string containing the MAC address, or null on a failed call
99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
996d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public String getMacAddress() {
99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "getMacAddress";
99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
100196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Mutable<String> gotMac = new Mutable<>();
100296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
100396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                mISupplicantStaIface.getMacAddress((SupplicantStatus status,
100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        byte[/* 6 */] macAddr) -> {
10053aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius                    if (checkStatusAndLogFailure(status, methodStr)) {
1006d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius                        gotMac.value = NativeUtil.macAddressFromByteArray(macAddr);
100796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    }
100896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                });
100996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
101096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e);
101196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
101296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
10133aa9b7e616f685ded8fade523317e96cedcdcc2dRoshan Pius            return gotMac.value;
101496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1016d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1017d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1018d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Start using the added RX filters.
1019d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1020d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1021d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1022d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean startRxFilter() {
102396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
102496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "startRxFilter";
102596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
102696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
102796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
102896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.startRxFilter();
102996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
103096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
103196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
103296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
103396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
103496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
103596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
103696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1037d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1038d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1039d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Stop using the added RX filters.
1040d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1041d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1042d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1043d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean stopRxFilter() {
104496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
104596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "stopRxFilter";
104696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
104796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
104896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
104996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.stopRxFilter();
105096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
105196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
105296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
105396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
105496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
105596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
105696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
105796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1058d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1059d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V4_MULTICAST =
1060d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1061d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte RX_FILTER_TYPE_V6_MULTICAST =
1062d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius            ISupplicantStaIface.RxFilterType.V6_MULTICAST;
1063d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1064d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Add an RX filter.
1065d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1066d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1067d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1068d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1069d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
107096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean addRxFilter(byte type) {
107196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
107296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "addRxFilter";
107396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
107496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
107596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
107696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.addRxFilter(type);
107796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
107896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
107996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
108096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
108196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
108296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
108396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
108496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1085d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1086d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1087d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Remove an RX filter.
1088d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1089d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or
1090d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *        {@link #RX_FILTER_TYPE_V6_MULTICAST} values.
1091d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1092d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
109396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean removeRxFilter(byte type) {
109496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
109596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "removeRxFilter";
109696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
109796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
109896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
109996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type);
110096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
110196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
110296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
110396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
110496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
110596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
110696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
110796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1108d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1109d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED;
1110d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED;
1111d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE;
1112d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1113d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set Bt co existense mode.
1114d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1115d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED}
1116d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *             or {@link #BT_COEX_MODE_SENSE} values.
1117d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1118d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1119d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceMode(byte mode) {
112096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
112196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceMode";
112296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
112396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
112496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
112596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode);
112696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
112796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
112896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
112996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
113096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
113196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
113296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
113396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1134d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1135d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /** Enable or disable BT coexistence mode.
1136d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1137d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false to disable.
1138d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1139d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1140d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setBtCoexistenceScanModeEnabled(boolean enable) {
114196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
114296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setBtCoexistenceScanModeEnabled";
114396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
114496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
114596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
114696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status =
114796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                        mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable);
114896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
114996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
115096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
115196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
115296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
115396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
115496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
115596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1156d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1157d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1158d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Enable or disable suspend mode optimizations.
1159d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1160d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param enable true to enable, false otherwise.
11615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
1162d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1163d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setSuspendModeEnabled(boolean enable) {
116496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
116596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setSuspendModeEnabled";
116696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
116796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
116896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
116996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable);
117096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
117196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
117296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
117396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
117496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
117596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
117696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
117796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
1178d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1179d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    /**
1180d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * Set country code.
1181d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     *
1182d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @param codeStr 2 byte ASCII string. For ex: US, CA.
1183d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     * @return true if request is sent successfully, false otherwise.
1184d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius     */
1185d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    public boolean setCountryCode(String codeStr) {
1186d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius        return setCountryCode(NativeUtil.stringToByteArray(codeStr));
1187d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius    }
1188d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius
1189b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
119096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean setCountryCode(byte[/* 2 */] code) {
119196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        synchronized (mLock) {
119296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr = "setCountryCode";
119396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (DBG) Log.i(TAG, methodStr);
119496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
119596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            try {
119696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                SupplicantStatus status = mISupplicantStaIface.setCountryCode(code);
119796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return checkStatusAndLogFailure(status, methodStr);
119896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            } catch (RemoteException e) {
119996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
120096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                supplicantServiceDiedHandler();
120196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return false;
120296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            }
120396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
120496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
120596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
12065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
12085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
12105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
12115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsRegistrar(String bssidStr, String pin) {
12145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsRegistrar(NativeUtil.macAddressToByteArray(bssidStr), pin);
12155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
12165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
12177651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
12187651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsRegistrar(byte[/* 6 */] bssid, String pin) {
12197651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12207651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsRegistrar";
12217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
12227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsRegistrar(bssid, pin);
12257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
12277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
12287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
12297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
12327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
12337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
12345f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12355f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
12365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
12385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPbc(String bssidStr) {
12415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPbc(NativeUtil.macAddressToByteArray(bssidStr));
12425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
12435f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
12447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
12457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private boolean startWpsPbc(byte[/* 6 */] bssid) {
12467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPbc";
12487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
12497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPbc(bssid);
12527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
12547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
12557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
12567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12587651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
12597651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
12607651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
12615f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12625f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin keypad operation with the specified pin.
12635f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12645f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param pin Pin to be used.
12655f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
12665f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12675f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean startWpsPinKeypad(String pin) {
12687651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12697651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinKeypad";
12707651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
12717651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
12727651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
12737651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.startWpsPinKeypad(pin);
12747651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
12757651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
12767651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
12777651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
12787651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
12797651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
12807651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
12817651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
12827651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
12835f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
12845f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Start WPS pin display operation with the specified peer.
12855f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
12865f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param bssidStr BSSID of the peer.
12875f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return new pin generated on success, null otherwise.
12885f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
12895f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public String startWpsPinDisplay(String bssidStr) {
12905f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        return startWpsPinDisplay(NativeUtil.macAddressToByteArray(bssidStr));
12915f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
12925f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
12937651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    /** See ISupplicantStaIface.hal for documentation */
12947651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    private String startWpsPinDisplay(byte[/* 6 */] bssid) {
12957651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
12967651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "startWpsPinDisplay";
12977651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
12987651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null;
12997651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final Mutable<String> gotPin = new Mutable<>();
13007651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13017651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                mISupplicantStaIface.startWpsPinDisplay(bssid,
13027651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        (SupplicantStatus status, String pin) -> {
13037651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            if (checkStatusAndLogFailure(status, methodStr)) {
13047651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                                gotPin.value = pin;
13057651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                            }
13067651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                        });
13077651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
13087651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
13097651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
13107651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13117651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            return gotPin.value;
13127651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13137651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13147651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Cancels any ongoing WPS requests.
13175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean cancelWps() {
13217651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13227651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "cancelWps";
13237651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
13247651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13257651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13267651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.cancelWps();
13277651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13287651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
13297651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
13307651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
13317651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13327651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13337651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13347651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13357651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
13365f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
13375f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Sets whether to use external sim for SIM/USIM processing.
13385f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     *
13395f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @param useExternalSim true to enable, false otherwise.
13405f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * @return true if request is sent successfully, false otherwise.
13415f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
13425f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    public boolean setExternalSim(boolean useExternalSim) {
13437651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        synchronized (mLock) {
13447651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            final String methodStr = "setExternalSim";
13457651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (DBG) Log.i(TAG, methodStr);
13467651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false;
13477651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            try {
13487651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                SupplicantStatus status = mISupplicantStaIface.setExternalSim(useExternalSim);
13497651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return checkStatusAndLogFailure(status, methodStr);
13507651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            } catch (RemoteException e) {
13517651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e);
13527651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                supplicantServiceDiedHandler();
13537651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius                return false;
13547651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius            }
13557651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius        }
13567651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius    }
13577651e69b6f5e2b28a4fee7284ac2522faa002c9fRoshan Pius
1358cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_EXCESSIVE = ISupplicant.DebugLevel.EXCESSIVE;
1359cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_MSGDUMP = ISupplicant.DebugLevel.MSGDUMP;
1360cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_DEBUG = ISupplicant.DebugLevel.DEBUG;
1361cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_INFO = ISupplicant.DebugLevel.INFO;
1362cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_WARNING = ISupplicant.DebugLevel.WARNING;
1363cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public static final int LOG_LEVEL_ERROR = ISupplicant.DebugLevel.ERROR;
1364cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1365cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set the debug log level for wpa_supplicant
1366cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param level One of the above {@link #LOG_LEVEL_EXCESSIVE} - {@link #LOG_LEVEL_ERROR} value.
1367cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1368cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1369cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setLogLevel(int level) {
1370cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return setDebugParams(level, false, false);
1371cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1372cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1373cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1374cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) {
1375cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1376cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setDebugParams";
1377cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (DBG) Log.i(TAG, methodStr);
1378cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1379cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1380cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status =
1381cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                        mISupplicant.setDebugParams(level, showTimestamp, showKeys);
1382cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1383cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1384cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                Log.e(TAG, "ISupplicant." + methodStr + ": exception:" + e);
1385cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                supplicantServiceDiedHandler();
1386cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1387cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1388cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1389cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1390cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1391cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1392cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Set concurrency priority between P2P & STA operations.
1393cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *
1394cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1395cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     *                            false otherwise.
1396cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * @return true if request is sent successfully, false otherwise.
1397cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1398cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1399cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (isStaHigherPriority) {
1400cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.STA);
1401cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        } else {
1402cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return setConcurrencyPriority(IfaceType.P2P);
1403cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1404cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1405cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1406cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /** See ISupplicant.hal for documentation */
1407cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean setConcurrencyPriority(int type) {
1408cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        synchronized (mLock) {
1409cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            final String methodStr = "setConcurrencyPriority";
1410cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (DBG) Log.i(TAG, methodStr);
1411cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            if (!checkSupplicantAndLogFailure(methodStr)) return false;
1412cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            try {
1413cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                SupplicantStatus status = mISupplicant.setConcurrencyPriority(type);
1414cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return checkStatusAndLogFailure(status, methodStr);
1415cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            } catch (RemoteException e) {
1416cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                Log.e(TAG, "ISupplicant." + methodStr + ": exception:" + e);
1417cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                supplicantServiceDiedHandler();
1418cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius                return false;
1419cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            }
1420cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1421cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1422cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
1423cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    /**
1424cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     * Returns false if Supplicant is null, and logs failure to call methodStr
1425cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius     */
1426cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    private boolean checkSupplicantAndLogFailure(final String methodStr) {
1427cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (DBG) Log.i(TAG, methodStr);
1428cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        if (mISupplicant == null) {
1429cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null");
1430cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius            return false;
1431cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        }
1432cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius        return true;
1433cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius    }
1434cb9565f0cb8fa92346549bcacdfbf91cdf8e6bd3Roshan Pius
143596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
143696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns false if SupplicantStaIface is null, and logs failure to call methodStr
143796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
143896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) {
143996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
144096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (mISupplicantStaIface == null) {
144196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null");
144296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
144396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
144496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
144596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
144696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
144796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
144896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Returns true if provided status code is SUCCESS, logs debug message and returns false
144996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * otherwise
145096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
145196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    private static boolean checkStatusAndLogFailure(SupplicantStatus status,
145296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            final String methodStr) {
145396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (DBG) Log.i(TAG, methodStr);
145496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        if (status.code != SupplicantStatusCode.SUCCESS) {
145596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            Log.e(TAG, methodStr + " failed: " + supplicantStatusCodeToString(status.code) + ", "
145696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                    + status.debugMessage);
145796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            return false;
145896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
145996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        return true;
146096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
146196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
146296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    /**
146396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * Converts SupplicantStatus code values to strings for debug logging
146496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     * TODO(b/34811152) Remove this, or make it more break resistance
146596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne     */
146696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    public static String supplicantStatusCodeToString(int code) {
146796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        switch (code) {
146896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 0:
146996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "SUCCESS";
147096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 1:
147196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_UNKNOWN";
147296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 2:
147396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_ARGS_INVALID";
147496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 3:
147596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_INVALID";
147696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 4:
147796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_UNKNOWN";
147896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 5:
147996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_EXISTS";
148096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 6:
148196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_DISABLED";
148296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 7:
148396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_IFACE_NOT_DISCONNECTED";
148496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 8:
148596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_INVALID";
148696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            case 9:
148796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "FAILURE_NETWORK_UNKNOWN";
148896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne            default:
148996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne                return "??? UNKNOWN_CODE";
149096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne        }
149196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne    }
149296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne
14935f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
14945f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    /**
14955f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     * Converts the Wps config method string to the equivalent enum value.
14965f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius     */
14975f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    private static short stringToWpsConfigMethod(String configMethod) {
14985f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        switch (configMethod) {
14995f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "usba":
15005f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.USBA;
15015f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ethernet":
15025f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.ETHERNET;
15035f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "label":
15045f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.LABEL;
15055f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "display":
15065f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.DISPLAY;
15075f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "int_nfc_token":
15085f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.INT_NFC_TOKEN;
15095f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "ext_nfc_token":
15105f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.EXT_NFC_TOKEN;
15115f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "nfc_interface":
15125f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.NFC_INTERFACE;
15135f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "push_button":
15145f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PUSHBUTTON;
15155f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "keypad":
15165f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.KEYPAD;
15175f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_push_button":
15185f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_PUSHBUTTON;
15195f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_push_button":
15205f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_PUSHBUTTON;
15215f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "p2ps":
15225f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.P2PS;
15235f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "virtual_display":
15245f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.VIRT_DISPLAY;
15255f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            case "physical_display":
15265f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                return WpsConfigMethods.PHY_DISPLAY;
15275f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius            default:
15285f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                throw new IllegalArgumentException(
15295f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius                        "Invalid WPS config method: " + configMethod);
15305f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius        }
15315f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius    }
15325f39baacf16b55c5551574bd1d973cdb14f70c45Roshan Pius
153382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    /**
153482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     * Converts the supplicant state received from HIDL to the equivalent framework state.
153582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius     */
153682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    private static SupplicantState supplicantHidlStateToFrameworkState(int state) {
153782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        switch (state) {
153882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.DISCONNECTED:
153982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.DISCONNECTED;
154082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.IFACE_DISABLED:
154182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INTERFACE_DISABLED;
154282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.INACTIVE:
154382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.INACTIVE;
154482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.SCANNING:
154582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.SCANNING;
154682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.AUTHENTICATING:
154782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.AUTHENTICATING;
154882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATING:
154982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATING;
155082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.ASSOCIATED:
155182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.ASSOCIATED;
155282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE:
155382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.FOUR_WAY_HANDSHAKE;
155482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.GROUP_HANDSHAKE:
155582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.GROUP_HANDSHAKE;
155682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            case ISupplicantStaIfaceCallback.State.COMPLETED:
155782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                return SupplicantState.COMPLETED;
155882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            default:
155982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                throw new IllegalArgumentException("Invalid state: " + state);
156082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius        }
156182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius    }
156282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius
1563240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    private static class Mutable<E> {
1564240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        public E value;
1565240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1566240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable() {
1567240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            value = null;
1568240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1569240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne
1570240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        Mutable(E value) {
1571240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne            this.value = value;
1572240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne        }
1573240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne    }
157466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
1575c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    private class SupplicantStaIfaceHalCallback extends ISupplicantStaIfaceCallback.Stub {
15765a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
15775a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parses the provided payload into an ANQP element.
15785a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
15795a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
15805a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
15815a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @return AnqpElement instance on success, null on failure.
15825a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
15835a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private ANQPElement parseAnqpElement(Constants.ANQPElementType infoID,
15845a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                             ArrayList<Byte> payload) {
15855a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
15865a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return Constants.getANQPElementID(infoID) != null
15875a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ? ANQPParser.parseElement(
15885a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)))
15895a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        : ANQPParser.parseHS20Element(
15905a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        infoID, ByteBuffer.wrap(NativeUtil.byteArrayFromArrayList(payload)));
15915a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (IOException | BufferUnderflowException e) {
15925a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                Log.e(TAG, "Failed parsing ANQP element payload: " + infoID, e);
15935a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return null;
15945a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
15955a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
15965a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
15975a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
15985a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Parse the ANQP element data and add to the provided elements map if successful.
15995a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         *
16005a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param elementsMap Map to add the parsed out element to.
16015a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param infoID  Element type.
16025a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * @param payload Raw payload bytes.
16035a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16045a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private void addAnqpElementToMap(Map<Constants.ANQPElementType, ANQPElement> elementsMap,
16055a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         Constants.ANQPElementType infoID,
16065a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                         ArrayList<Byte> payload) {
16075a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (payload == null || payload.isEmpty()) return;
16085a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            ANQPElement element = parseAnqpElement(infoID, payload);
16095a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            if (element != null) {
16105a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                elementsMap.put(infoID, element);
16115a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16125a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16135a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
16145a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        /**
16155a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         * Helper utility to convert the bssid bytes to long.
16165a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius         */
16175a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        private Long toLongBssid(byte[] bssidBytes) {
16185a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            try {
16195a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return ByteBufferReader.readInteger(
16205a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                        ByteBuffer.wrap(bssidBytes), ByteOrder.BIG_ENDIAN, bssidBytes.length);
16215a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            } catch (BufferUnderflowException | IllegalArgumentException e) {
16225a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                return 0L;
16235a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            }
16245a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        }
16255a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius
1626c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1627c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkAdded(int id) {
1628c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1629c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1630c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1631c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onNetworkRemoved(int id) {
1632c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1633c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1634c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1635c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
1636c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                   ArrayList<Byte> ssid) {
163782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            SupplicantState newSupplicantState = supplicantHidlStateToFrameworkState(newState);
163882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            WifiSsid wifiSsid =
163982c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                    WifiSsid.createFromByteArray(NativeUtil.byteArrayFromArrayList(ssid));
164082c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            String bssidStr = NativeUtil.macAddressFromByteArray(bssid);
164182c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            mWifiMonitor.broadcastSupplicantStateChangeEvent(
164282c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                    mIfaceName, mFrameworkNetworkId, wifiSsid, bssidStr, newSupplicantState);
164382c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            if (newSupplicantState == SupplicantState.ASSOCIATED) {
164482c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                mWifiMonitor.broadcastAssociationSuccesfulEvent(mIfaceName, bssidStr);
164582c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            } else if (newSupplicantState == SupplicantState.COMPLETED) {
164682c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                mWifiMonitor.broadcastNetworkConnectionEvent(
164782c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius                        mIfaceName, mFrameworkNetworkId, bssidStr);
164882c5c5f2ee520a1066cf5d6421885bb53bbfe269Roshan Pius            }
1649c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1650c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1651c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
16525a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onAnqpQueryDone(byte[/* 6 */] bssid,
1653c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.AnqpData data,
1654c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                    ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
16555a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            Map<Constants.ANQPElementType, ANQPElement> elementsMap = new HashMap<>();
16565a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQPVenueName, data.venueName);
16575a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQPRoamingConsortium, data.roamingConsortium);
16585a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQPIPAddrAvailability, data.ipAddrTypeAvailability);
16595a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQPNAIRealm, data.naiRealm);
16605a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQP3GPPNetwork, data.anqp3gppCellularNetwork);
16615a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, ANQPDomName, data.domainName);
16625a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, HSFriendlyName, hs20Data.operatorFriendlyName);
16635a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, HSWANMetrics, hs20Data.wanMetrics);
16645a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, HSConnCapability, hs20Data.connectionCapability);
16655a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            addAnqpElementToMap(elementsMap, HSOSUProviders, hs20Data.osuProvidersList);
16665a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            mWifiMonitor.broadcastAnqpDoneEvent(
16675a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    mIfaceName, new AnqpEvent(toLongBssid(bssid), elementsMap));
1668c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1669c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1670c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
16715a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
1672c224fb554deca894818490c9416ff35d18a79d76Roshan Pius                                        ArrayList<Byte> data) {
16735a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            mWifiMonitor.broadcastIconDoneEvent(
16745a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    mIfaceName,
16755a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    new IconEvent(toLongBssid(bssid), fileName, data.size(),
16765a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                            NativeUtil.byteArrayFromArrayList(data)));
1677c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1678c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1679c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
16805a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid, byte osuMethod, String url) {
16815a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            mWifiMonitor.broadcastWnmEvent(
16825a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    mIfaceName, new WnmData(toLongBssid(bssid), url, osuMethod));
1683c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1684c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1685c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
16865a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius        public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
16875a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                                               int reAuthDelayInSec, String url) {
16885a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius            mWifiMonitor.broadcastWnmEvent(
16895a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    mIfaceName,
16905a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                    new WnmData(toLongBssid(bssid), url, reasonCode == WnmData.ESS,
16915a1adfdef3025a595544b3d17e1d5d9afca7673bRoshan Pius                            reAuthDelayInSec));
1692c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1693c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1694c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1695c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated, int reasonCode) {
1696c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1697c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1698c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1699c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode) {
1700c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1701c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1702c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1703c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
1704c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1705c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1706c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1707c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onEapFailure() {
1708c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1709c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1710c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1711c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventSuccess() {
1712c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1713c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1714c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1715c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
1716c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1717c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1718c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1719c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onWpsEventPbcOverlap() {
1720c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1721c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1722c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1723c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkStart(int id) {
1724c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1725c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
1726c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        @Override
1727c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        public void onExtRadioWorkTimeout(int id) {
1728c224fb554deca894818490c9416ff35d18a79d76Roshan Pius        }
1729c224fb554deca894818490c9416ff35d18a79d76Roshan Pius    }
1730c224fb554deca894818490c9416ff35d18a79d76Roshan Pius
173166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logd(String s) {
173266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.d(TAG, s);
173366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
173466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
173566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void logi(String s) {
173666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.i(TAG, s);
173766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
173866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne
173966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    private void loge(String s) {
174066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne        Log.e(TAG, s);
174166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne    }
1742240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne}
1743