WifiNative.java revision fc8efe44f2f2231678b0f07b5662a8d8c9e71005
1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2008 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
19e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport android.annotation.IntDef;
20c7685b40d77b12820c5b04013592834025086cefRoshan Piusimport android.annotation.NonNull;
2168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.annotation.Nullable;
229c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Piusimport android.net.InterfaceConfiguration;
23e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensenimport android.net.apf.ApfCapabilities;
2470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IApInterface;
2570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IClientInterface;
26143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
2768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.RttManager.ResponderConfig;
28e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.ScanResult;
29dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalleimport android.net.wifi.WifiConfiguration;
30e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiScanner;
312a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Willsimport android.net.wifi.WifiWakeReasonAndCounts;
324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport android.os.INetworkManagementService;
334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport android.os.RemoteException;
34f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.SystemClock;
35e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport android.text.TextUtils;
36155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Log;
37ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Piusimport android.util.Pair;
38a26a8b33616c94859ba33f33403794cf636baa54Roshan Piusimport android.util.SparseArray;
39fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
4009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawalimport com.android.internal.annotations.Immutable;
410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport com.android.internal.util.HexDump;
42c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadhamimport com.android.server.connectivity.KeepalivePacketData;
434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport com.android.server.net.BaseNetworkObserver;
44590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tanimport com.android.server.wifi.util.FrameParser;
45fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.PrintWriter;
470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.StringWriter;
48e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.Retention;
49e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.RetentionPolicy;
505cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.ByteBuffer;
515cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.CharBuffer;
525cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharacterCodingException;
535cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharsetDecoder;
545cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.StandardCharsets;
55eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.text.SimpleDateFormat;
56155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
57eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.Date;
58e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashMap;
59e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashSet;
60e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.Iterator;
61fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Map;
621bf983a4211f547593a60523e43112ecdb5c8997Roshan Piusimport java.util.Objects;
639ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set;
64eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.TimeZone;
6518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Native calls for bring up/shut down of the supplicant daemon and for
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sending requests to the supplicant daemon
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * {@hide}
71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
72155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiNative {
7318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mTAG;
7418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    private final String mInterfaceName;
75b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
76b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WifiVendorHal mWifiVendorHal;
77b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WificondControl mWificondControl;
784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private final INetworkManagementService mNwManagementService;
79b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // TODO(b/69426063): Remove interfaceName from constructor once WifiStateMachine switches over
814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // to the new interface management methods.
82b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public WifiNative(String interfaceName, WifiVendorHal vendorHal,
834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                      SupplicantStaIfaceHal staIfaceHal, WificondControl condControl,
844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                      INetworkManagementService nwService) {
85155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        mTAG = "WifiNative-" + interfaceName;
86b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mInterfaceName = interfaceName;
87b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal = vendorHal;
88b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal = staIfaceHal;
89b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl = condControl;
904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        mNwManagementService = nwService;
91155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
9318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getInterfaceName() {
9418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills        return mInterfaceName;
95e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe    }
96e26ad459b63271548abbdeba4f8d77fcca9f88bdxinhe
97b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
98b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable verbose logging for all sub modules.
99b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void enableVerboseLogging(int verbose) {
101b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
102b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
103b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal.enableVerboseLogging(verbose > 0);
104ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
105ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
106b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius   /********************************************************
107b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    * Native Initialization/Deinitialization
108b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    ********************************************************/
109ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius    public static final int SETUP_SUCCESS = 0;
110ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius    public static final int SETUP_FAILURE_HAL = 1;
111ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius    public static final int SETUP_FAILURE_WIFICOND = 2;
112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
11370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang   /**
1143a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    * Setup wifi native for Client mode operations.
1153a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    *
1163a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    * 1. Starts the Wifi HAL and configures it in client/STA mode.
1173a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    * 2. Setup Wificond to operate in client mode and retrieve the handle to use for client
1183a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    * operations.
1193a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius    *
120ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius    * @return Pair of <Integer, IClientInterface> to indicate the status and the associated wificond
121ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius    * client interface binder handler (will be null on failure).
12270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
123c7685b40d77b12820c5b04013592834025086cefRoshan Pius    public Pair<Integer, IClientInterface> setupForClientMode(@NonNull String ifaceName) {
1248131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        if (!startHalIfNecessary(true)) {
125b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            Log.e(mTAG, "Failed to start HAL for client mode");
126ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius            return Pair.create(SETUP_FAILURE_HAL, null);
12770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
1287065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius        IClientInterface iClientInterface = mWificondControl.setupInterfaceForClientMode(ifaceName);
129ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        if (iClientInterface == null) {
130ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius            return Pair.create(SETUP_FAILURE_WIFICOND, null);
131ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        }
132ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        return Pair.create(SETUP_SUCCESS, iClientInterface);
13370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
13570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
1363a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     * Setup wifi native for AP mode operations.
1373a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     *
1383a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     * 1. Starts the Wifi HAL and configures it in AP mode.
1393a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     * 2. Setup Wificond to operate in AP mode and retrieve the handle to use for ap operations.
1403a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     *
141ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius     * @return Pair of <Integer, IApInterface> to indicate the status and the associated wificond
142ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius     * AP interface binder handler (will be null on failure).
1433a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     */
144c7685b40d77b12820c5b04013592834025086cefRoshan Pius    public Pair<Integer, IApInterface> setupForSoftApMode(@NonNull String ifaceName) {
1458131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        if (!startHalIfNecessary(false)) {
146b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            Log.e(mTAG, "Failed to start HAL for AP mode");
147ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius            return Pair.create(SETUP_FAILURE_HAL, null);
148ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        }
1497065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius        IApInterface iApInterface = mWificondControl.setupInterfaceForSoftApMode(ifaceName);
150ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        if (iApInterface == null) {
151ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius            return Pair.create(SETUP_FAILURE_WIFICOND, null);
15270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        }
153ce1de180e7652e2b2313b401451ca3d9d027b372Roshan Pius        return Pair.create(SETUP_SUCCESS, iApInterface);
15470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
15570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
15670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
1573a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     * Teardown all mode configurations in wifi native.
1583a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     *
1598e03a147b1d9ca721e1fe4f95b6b67491cfd7084Etan Cohen     * 1. Stops the Wifi HAL.
1608e03a147b1d9ca721e1fe4f95b6b67491cfd7084Etan Cohen     * 2. Tears down all the interfaces from Wificond.
1613a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius     */
1627130816d6c62e07d6d41150805515d7fd56f1f0dRoshan Pius    public void tearDown() {
1638e03a147b1d9ca721e1fe4f95b6b67491cfd7084Etan Cohen        stopHalIfNecessary();
1643a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius        if (!mWificondControl.tearDownInterfaces()) {
1653a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius            // TODO(b/34859006): Handle failures.
166b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            Log.e(mTAG, "Failed to teardown interfaces from Wificond");
1673a0679d411c5eb889d38ed32181446c82d5bd825Roshan Pius        }
16870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
16970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
170d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
171d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * TODO(b/69426063): NEW API Surface for interface management. This will eventually
172d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * deprecate the other interface management API's above. But, for now there will be
173d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * some duplication to ease transition.
174d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
175d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
176e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Meta-info about every iface that is active.
177e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
178e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class Iface {
179e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of ifaces possible */
180e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_AP = 0;
181e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_STA = 1;
182e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
183e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA})
184e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @Retention(RetentionPolicy.SOURCE)
185e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public @interface IfaceType{}
186e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
187e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Identifier allocated for the interface */
188e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final int id;
189e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of the iface: STA or AP */
190e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final @IfaceType int type;
191e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Name of the interface */
192e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public String name;
193e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** External iface destroyed listener for the iface */
194e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public InterfaceCallback externalListener;
1954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Network observer registered for this interface */
1964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public NetworkObserverInternal networkObserver;
197e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
198e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        Iface(int id, @Iface.IfaceType int type) {
199e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.id = id;
200e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.type = type;
201e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
202e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
203e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
204e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
205e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Iface Management entity. This class maintains list of all the active ifaces.
206e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
207e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class IfaceManager {
208e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Integer to allocate for the next iface being created */
209e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private int mNextId;
210e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Map of the id to the iface structure */
211e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private HashMap<Integer, Iface> mIfaces = new HashMap<>();
212e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
213e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Allocate a new iface for the given type */
214e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface allocateIface(@Iface.IfaceType  int type) {
215e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            Iface iface = new Iface(mNextId, type);
216e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mIfaces.put(mNextId, iface);
217e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mNextId++;
218e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return iface;
219e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
220e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
221e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Remove the iface using the provided id */
222e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface removeIface(int id) {
223e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.remove(id);
224e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
225e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
226e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided id */
227e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(int id) {
228e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.get(id);
229e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
230e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
231e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided name */
232e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(@NonNull String ifaceName) {
233e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
234e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (TextUtils.equals(iface.name, ifaceName)) {
235e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return iface;
236e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
237e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
238e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return null;
239e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
240e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
241e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Iterator to use for deleting all the ifaces while performing teardown on each of them */
242e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iterator<Integer> getIfaceIdIter() {
243e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.keySet().iterator();
244e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
245e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
246e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface active. */
247e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIface() {
248e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return !mIfaces.isEmpty();
249e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
250e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
251e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface of the given type active. */
252e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIfaceOfType(@Iface.IfaceType int type) {
253e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
254e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (iface.type == type) {
255e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return true;
256e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
257e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
258e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return false;
259e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
260e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
261e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any STA iface active. */
262e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyStaIface() {
263e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA);
264e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
265e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
266e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any AP iface active. */
267e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyApIface() {
268e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_AP);
269e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
270e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
271e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
272e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private Object mLock = new Object();
273e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private final IfaceManager mIfaceMgr = new IfaceManager();
274e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private HashSet<StatusListener> mStatusListeners = new HashSet<>();
275e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
2764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no ifaces */
2774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startHal() {
2784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWifiVendorHal.startVendorHal()) {
2814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to start vendor HAL");
2824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
2834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
2864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop HAL if there are no more ifaces */
2904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopHalAndWificondIfNecessary() {
2914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.tearDownInterfaces()) {
2944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to teardown ifaces from wificond");
2954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mWifiVendorHal.stopVendorHal();
2974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS = 100;
3024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_TIMES = 50;
3034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
3044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * This method is called to wait for establishing connection to wpa_supplicant.
3054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     *
3064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * @return true if connection is established, false otherwise.
3074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
3084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean waitForSupplicantConnection() {
3094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        // Start initialization if not already started.
3104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
3114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
3124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        boolean connected = false;
3154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        int connectTries = 0;
3164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
3174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Check if the initialization is complete.
3184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            connected = mSupplicantStaIfaceHal.isInitializationComplete();
3194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (connected) {
3204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                break;
3214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            try {
3234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
3244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } catch (InterruptedException ignore) {
3254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return connected;
3284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no STA ifaces */
3314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startSupplicant() {
3324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.enableSupplicant()) {
3354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to enable supplicant");
3364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!waitForSupplicantConnection()) {
3394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to connect to supplicant");
3404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.registerDeathHandler(new DeathHandlerInternal())) {
3434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to register supplicant death handler");
3444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
3484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop supplicant if there are no more STA ifaces */
3524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopSupplicantIfNecessary() {
3534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
3564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to deregister supplicant death handler");
3574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.disableSupplicant()) {
3594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to disable supplicant");
3604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean registerNetworkObserver(@NonNull NetworkObserverInternal observer) {
3674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.registerObserver(observer);
3694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean unregisterNetworkObserver(@NonNull NetworkObserverInternal observer) {
3774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.unregisterObserver(observer);
3794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown client iface and perform necessary cleanup */
3864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
3874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
3894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to unregister network observer for iface=" + iface.name);
3904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
3924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to teardown iface in supplicant=" + iface.name);
3934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownClientInterface(iface.name)) {
3954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to teardown iface in wificond=" + iface.name);
3964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopSupplicantIfNecessary();
3984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
3994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown softAp iface and perform necessary cleanup */
4034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onSoftApInterfaceDestroyed(@NonNull Iface iface) {
4044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
4064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to unregister network observer for iface=" + iface.name);
4074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.stopSoftAp(iface.name)) {
4094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to stop softap on iface=" + iface.name);
4104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownSoftApInterface(iface.name)) {
4124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to teardown iface in wificond=" + iface.name);
4134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown iface and perform necessary cleanup */
4194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onInterfaceDestroyed(@NonNull Iface iface) {
4204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
4224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onClientInterfaceDestroyed(iface);
4234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
4244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onSoftApInterfaceDestroyed(iface);
4254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Invoke the external callback.
4274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener.onDestroyed(iface.name);
4284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Callback to be invoked by HalDeviceManager when an interface is destroyed.
4334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class InterfaceDestoyedListenerInternal
4354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            implements HalDeviceManager.InterfaceDestroyedListener {
4364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        InterfaceDestoyedListenerInternal(int ifaceId) {
4404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = ifaceId;
4414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDestroyed(@NonNull String ifaceName) {
4454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.removeIface(mInterfaceId);
4474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
4484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Received iface destroyed notification on an invalid iface="
4494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
4504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
4514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onInterfaceDestroyed(iface);
4534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.i(mTAG, "Successfully torn down iface=" + ifaceName);
4544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Common death handler for any of the lower layer daemons.
4604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class DeathHandlerInternal implements VendorHalDeathEventHandler,
4624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            SupplicantDeathEventHandler, WificondDeathEventHandler {
4634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDeath() {
4654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.i(mTAG, "One of the daemons died. Tearing down everything");
4674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
4684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                while (ifaceIdIter.hasNext()) {
4694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
4704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    ifaceIdIter.remove();
4714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    onInterfaceDestroyed(iface);
4724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.i(mTAG, "Successfully torn down iface=" + iface.name);
4734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                for (StatusListener listener : mStatusListeners) {
4754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    listener.onStatusChanged(false);
4764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                // TODO(70572148): Do we need to wait to mark the system ready again?
4784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                for (StatusListener listener : mStatusListeners) {
4794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    listener.onStatusChanged(true);
4804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Network observer to use for all interface up/down notifications.
4874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class NetworkObserverInternal extends BaseNetworkObserver {
4894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        NetworkObserverInternal(int id) {
4934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = id;
4944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void interfaceLinkStateChanged(String ifaceName, boolean isUp) {
4984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.i(mTAG, "Interface link state changed=" + ifaceName + ", isUp=" + isUp);
5004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.getIface(mInterfaceId);
5014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
5024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Received iface up/down notification on an invalid iface="
5034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
5044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
5054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (isUp) {
5074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onUp(ifaceName);
5084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                } else {
5094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onDown(ifaceName);
5104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
515e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
516d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
517d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
518d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
519d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
520d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
5214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
5224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWifiVendorHal.initialize(new DeathHandlerInternal())) {
5234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to initialize vendor HAL");
5244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
5254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.registerDeathHandler(new DeathHandlerInternal())) {
5274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to initialize wificond");
5284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
5294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
5314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
532d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
533d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
534d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
535d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
536d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
537d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
538d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
539d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
540d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
541d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
542d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
543d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
544d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
545d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
546d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
547d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
548d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
549d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
550d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
551d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
552d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
553d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
554e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
555d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
556d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
557d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
558d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
559d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
560d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
561d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
562d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
563d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
564d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
565d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
566d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
567d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
568d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
569d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
570d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
571d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
572d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
573d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
574d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
575d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
576d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
577d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
578d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
579d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
580d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
581d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
582d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
583fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
584fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
585fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
586fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
587fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
588fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
589fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
590fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
591fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
592fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
593fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
594fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
595fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
596fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
597fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
598fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
599fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
600fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            Log.e(mTAG, "Unable to change interface settings: " + re);
601fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
602fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            Log.e(mTAG, "Unable to change interface settings: " + ie);
603fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
604fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
605fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
606d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
607d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
608d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
609d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
610d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
611d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
612d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
613d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
614d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
615d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForClientMode(@NonNull InterfaceCallback interfaceCallback) {
6164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
6174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
6184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to start Hal");
6194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
6224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to start supplicant");
6234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
6264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
6274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to allocate new STA iface");
6284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
6314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.name =
6324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    mWifiVendorHal.createStaIface(new InterfaceDestoyedListenerInternal(iface.id));
6334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
6344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to create iface in vendor HAL");
6354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
6364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
6394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to setup iface in wificond=" + iface.name);
6404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
6414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
6444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to setup iface in supplicant=" + iface.name);
6454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
6464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
6494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
6504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to register network observer for iface=" + iface.name);
6514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
6524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
654fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
6554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Log.i(mTAG, "Successfully setup iface=" + iface.name);
6564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
6574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
658d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
659d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
660d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
661d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
662d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
663d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
664d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
665d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
666d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
667d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
668d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
669d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
6704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
6714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
6724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to start Hal");
6734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
6764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
6774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to allocate new AP iface");
6784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
6814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.name =
6824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    mWifiVendorHal.createApIface(new InterfaceDestoyedListenerInternal(iface.id));
6834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
6844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to create iface in vendor HAL");
6854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
6864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
6894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to setup iface in wificond=" + iface.name);
6904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
6914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
6944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
6954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Failed to register network observer for iface=" + iface.name);
6964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
6974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
6984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Log.i(mTAG, "Successfully setup iface=" + iface.name);
7004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
7014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
702d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
703d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
704d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
7059c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
7069c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
7079c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
7089c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
7099c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
7109c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
7119c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
7129c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
7139c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
7149c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                Log.e(mTAG, "Trying to get iface state on invalid iface=" + ifaceName);
7159c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
7169c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
7179c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
7189c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
7199c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
7209c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
7219c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
7229c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
7239c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
7249c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
7259c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
7269c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
7279c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
7289c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
7299c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
730d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
731d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
732d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
733d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
734d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
735d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
736d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
737d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
7384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
7404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
7414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Log.e(mTAG, "Trying to teardown an invalid iface=" + ifaceName);
7424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
7434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
7454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
7464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // TODO(b/70521011): Figure out what to do for devices with no HAL.
7474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
7484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWifiVendorHal.removeStaIface(ifaceName)) {
7494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to remove iface in vendor HAL=" + ifaceName);
7504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
7514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
7524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
7534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWifiVendorHal.removeApIface(ifaceName)) {
7544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    Log.e(mTAG, "Failed to remove iface in vendor HAL=" + ifaceName);
7554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
7564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
7574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Log.i(mTAG, "Successfully initiated teardown for iface=" + ifaceName);
7594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
760d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
761d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
762b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
763b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
764b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
765b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
766b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
767b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
768b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
769b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
770b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
771b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
772b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
773b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
774b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
775b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
776b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
777b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
778b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
779b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
780b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
781b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
782b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
783b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
784b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
785b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
786b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
78770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
78855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
78955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
79055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
79155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
79255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
79355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
79455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
79555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
79655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
79755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
79855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Registers a death notification for wificond.
79955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * @return Returns true on success.
80055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
80155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public boolean registerWificondDeathHandler(@NonNull WificondDeathEventHandler handler) {
80255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        return mWificondControl.registerDeathHandler(handler);
80355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
80455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
80555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
80655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Deregisters a death notification for wificond.
80755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * @return Returns true on success.
80855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
80955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public boolean deregisterWificondDeathHandler() {
81055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        return mWificondControl.deregisterDeathHandler();
81155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
81255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
81355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
81470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Disable wpa_supplicant via wificond.
81570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
81670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
81770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean disableSupplicant() {
81870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.disableSupplicant();
81970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
82070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang
82170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
82270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * Enable wpa_supplicant via wificond.
82370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    * @return Returns true on success.
82470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    */
82570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public boolean enableSupplicant() {
82670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang        return mWificondControl.enableSupplicant();
82770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    }
82818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
829d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
830d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Request signal polling to wificond.
831d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an SignalPollResult object.
832d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
833d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
834d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public SignalPollResult signalPoll() {
83591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.signalPoll(mInterfaceName);
836d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
837d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
838d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
839d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
840d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns an TxPacketCounters object.
841d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    * Returns null on failure.
842d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    */
843d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    public TxPacketCounters getTxPacketCounters() {
84491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getTxPacketCounters(mInterfaceName);
845d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
846d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
84724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
848a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
849a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
850a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
851a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
852a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
853a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
854a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
855a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
856a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
857a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
858a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
859a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
860a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
861a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
862a70c07d019065187112945c091fc2e924af18980Roshan Pius
863a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
864b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
867b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
86824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
869b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
87091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.scan(mInterfaceName, freqs, hiddenNetworkSSIDs);
871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
872155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
87318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
874b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
875b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
876b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
87718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
878b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ArrayList<ScanDetail> getScanResults() {
87991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
88091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius                mInterfaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
88171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
88271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
88371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
88471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
88571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
88671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
88771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
88871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    public ArrayList<ScanDetail> getPnoScanResults() {
88991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(mInterfaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
890155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
891155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
892b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
893b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
894b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
895b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
89618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
897b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean startPnoScan(PnoSettings pnoSettings) {
89891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.startPnoScan(mInterfaceName, pnoSettings);
899155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
900155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
901b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
902b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
903b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
904b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
905b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean stopPnoScan() {
90691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.stopPnoScan(mInterfaceName);
90718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
90818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
909045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
910045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
911045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
912045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
913045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
914045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
915045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
916045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
917045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
918045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
919045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
920045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
921045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
922045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
923045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
924045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
925045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
926045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public boolean startSoftAp(WifiConfiguration config, SoftApListener listener) {
92791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.startSoftAp(mInterfaceName, config, listener);
928045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
929045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
930045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
931045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
932045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
933045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
934045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
935045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public boolean stopSoftAp() {
93691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.stopSoftAp(mInterfaceName);
937045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
938045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
939b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
940b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
941b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
942f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
943f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
944fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
945fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
946fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
947fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
948fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
949fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
950fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
951fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
952fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
953fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
954fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Registers a death notification for supplicant.
955fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * @return Returns true on success.
956fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
957fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public boolean registerSupplicantDeathHandler(@NonNull SupplicantDeathEventHandler handler) {
958fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        return mSupplicantStaIfaceHal.registerDeathHandler(handler);
959fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
960fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
961fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
962b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius     * This method is called repeatedly until the connection to wpa_supplicant is
963b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius     * established and a STA iface is setup.
964f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     *
965b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if connection is established, false otherwise.
966b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * TODO: Add unit tests for these once we remove the legacy code.
967f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius     */
968163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    public boolean connectToSupplicant() {
969b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Start initialization if not already started.
970b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
971b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
972b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
9735cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
974b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Check if the initialization is complete.
975b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationComplete()) {
976b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return false;
977b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        }
978b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        // Setup the STA iface once connection is established.
979b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setupIface(mInterfaceName);
980ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle    }
981ad7319939c424d42fa6a3791c47f613db8ef3cd8vandwalle
982b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
983b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Close supplicant connection.
984ed6a985c7b63e295248fa7e8292c99b48b7a4283Mitchell Wills     */
985b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void closeSupplicantConnection() {
986155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
987155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
988782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski    /**
989b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
990782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
991b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
992782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
993b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
994f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
995e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
996e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
99738a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
998b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
999b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1000b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
100138a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
1002b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean reconnect() {
1003b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.reconnect(mInterfaceName);
1004f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
10059d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
10069d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1007b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1008b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1009b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
10109d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
1011155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean reassociate() {
1012b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.reassociate(mInterfaceName);
1013155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1014155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1015155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1016b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1017b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1018b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1019b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disconnect() {
1021b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.disconnect(mInterfaceName);
102277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
102377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1024155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1026b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1029b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public String getMacAddress() {
1030b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(mInterfaceName);
1031446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1032446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1033f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1034f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1035155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1036155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
1037155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1038155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1041155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1042155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1043155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1044155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1045155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1046155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1047155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1048155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1049155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1050155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1051155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1052155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1053155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1054155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1055155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1056155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1057155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1058155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1059155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV4Packets() {
1060b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1061b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
1062b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V4_MULTICAST)
1063b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1064155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1065155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1066155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1067155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
1068155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1069155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV4Packets() {
1071b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1072b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
1073b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V4_MULTICAST)
1074b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1075155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1076155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1077155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1078155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
1079155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1080155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1081155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startFilteringMulticastV6Packets() {
1082b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1083b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
1084b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V6_MULTICAST)
1085b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1086155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1087155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1088155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1089155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
1090155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1091155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1092155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean stopFilteringMulticastV6Packets() {
1093b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(mInterfaceName)
1094b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
1095b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                        mInterfaceName, RX_FILTER_TYPE_V6_MULTICAST)
1096b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(mInterfaceName);
1097155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1098155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1099f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1100f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1101f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
11027ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
11037ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * Sets the bluetooth coexistence mode.
11047ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *
11057ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
11067ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
11077ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
11087ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      * @return Whether the mode was successfully set.
11097ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde      */
1110155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceMode(int mode) {
1111b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(mInterfaceName, mode);
1112155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1113155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1114155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1115155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1118155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1119cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1120155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1121155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1122155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
1123b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
1124b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, setCoexScanMode);
1125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1127b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1128b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1130b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1133155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSuspendOptimizations(boolean enabled) {
1134b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(mInterfaceName, enabled);
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1136155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
11379153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1138b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1139b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1140b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1141b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
11429153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
1143b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setCountryCode(String countryCode) {
1144b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(mInterfaceName, countryCode);
114504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
114604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
114704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1149b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1151b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
115204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
1153155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void startTdls(String macAddr, boolean enable) {
1154b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
1155b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(mInterfaceName, macAddr);
1156b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(mInterfaceName, macAddr);
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
1158b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(mInterfaceName, macAddr);
1159155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1160155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1161155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1163b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1164b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1165b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1166b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1167b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1168155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPbc(String bssid) {
1169b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(mInterfaceName, bssid);
1170155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1171155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1172b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1173b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1174b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1175b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1176b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1177b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsPinKeypad(String pin) {
1179b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(mInterfaceName, pin);
1180155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1181155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1182b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1183b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1184b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1185b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1186b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1187b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public String startWpsPinDisplay(String bssid) {
1189b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(mInterfaceName, bssid);
1190155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1191155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1192b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1193b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1194b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1195b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1196b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1197b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
119833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    public boolean setExternalSim(boolean external) {
1199b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(mInterfaceName, external);
120033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
120133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1202b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1203b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1204b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1205b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1206b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1207b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1208b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1209b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1210b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1211b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1212b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1213b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1214b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1216f97140d51d14ce0659d381f443c08dbd94dfea28Honore Tricot    public boolean simAuthResponse(int id, String type, String response) {
1217b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1218b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
1219b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
1220b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1221b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
1222b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
1223b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1224b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
1225b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                    mInterfaceName, response);
12265cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1227b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
12285cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
122933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
123033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1232b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1234b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1235b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
123626eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean simAuthFailedResponse(int id) {
1237b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(mInterfaceName);
123826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
123926eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1240b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1241b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1242b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
124526eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    public boolean umtsAuthFailedResponse(int id) {
1246b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(mInterfaceName);
124726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
124826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1249b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1250b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1251b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1252b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response String to send.
1253b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1254b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1255ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    public boolean simIdentityResponse(int id, String response) {
1256b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(
1257b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, response);
1258ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1259ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1260b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1261a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1262a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
1263a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1264a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
1265a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    public String getEapAnonymousIdentity() {
1266b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(mInterfaceName);
1267a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1268a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1269a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1270b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1271b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1272b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1273b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1274b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1275b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean startWpsRegistrar(String bssid, String pin) {
1277b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(mInterfaceName, bssid, pin);
1278155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1279155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1280b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1281b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1282b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1283b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1284b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean cancelWps() {
1286b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(mInterfaceName);
1287155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1289b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1290b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1291b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1292b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1293b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1294b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceName(String name) {
1296b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(mInterfaceName, name);
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1302b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1304b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1305155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setDeviceType(String type) {
1306b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(mInterfaceName, type);
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1309b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1310b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1311b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1312b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1313b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1314b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setConfigMethods(String cfg) {
1316b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(mInterfaceName, cfg);
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1319b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1320b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1321b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1322b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1323b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1324b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setManufacturer(String value) {
1326b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(mInterfaceName, value);
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1329b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1330b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1331b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1332b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1333b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1334b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelName(String value) {
1336b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(mInterfaceName, value);
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1339b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1340b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1341b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1342b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1343b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1344b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setModelNumber(String value) {
1346b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(mInterfaceName, value);
1347155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1348155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1349b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1350b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1351b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1352b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1353b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1354b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public boolean setSerialNumber(String value) {
1356b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(mInterfaceName, value);
1357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1358155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1359b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1360b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1361b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1362b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1363b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    public void setPowerSave(boolean enabled) {
1365b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(mInterfaceName, enabled);
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1368b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1369b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1370b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1371b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1372b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1373b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1374b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1375b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1376b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
13803e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
13813e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
13823e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
13833e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
13843e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
13853e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    public boolean enableStaAutoReconnect(boolean enable) {
1386b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(mInterfaceName, enable);
13873e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
13883e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
13893e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1390b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1391b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1392b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1393b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1394b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1395b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
1397b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs,
1398b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                                 SparseArray<Map<String, String>> networkExtras) {
1399b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(mInterfaceName, configs, networkExtras);
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1402b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1403b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1405c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1406c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1407c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1408c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1409c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1410c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1411b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1412b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1413b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1414b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1415a5936a61582404692c6046e3b496d3b1d22a94cbNingyuan Wang    public boolean connectToNetwork(WifiConfiguration configuration) {
1416c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
141791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        mWificondControl.abortScan(mInterfaceName);
1418b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(mInterfaceName, configuration);
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1421b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1422b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1423b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1425c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1426c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1427b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1428c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1429c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1430b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1431b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1432b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1433b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1434b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean roamToNetwork(WifiConfiguration configuration) {
1435c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
143691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        mWificondControl.abortScan(mInterfaceName);
1437b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(mInterfaceName, configuration);
1438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1439155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1440b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1441b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the framework network ID corresponding to the provided supplicant network ID for the
1442b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * network configured in wpa_supplicant.
1443b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1444b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param supplicantNetworkId network ID in wpa_supplicant for the network.
1445b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Corresponding framework network ID if found, -1 if network not found.
1446b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1447b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public int getFrameworkNetworkId(int supplicantNetworkId) {
1448b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return supplicantNetworkId;
1449155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1450155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1451b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1452b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1453b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1454b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1455b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1456b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean removeAllNetworks() {
1457b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(mInterfaceName);
1458155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1459155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1460b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1461b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1462b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1463b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1464b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1465b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConfiguredNetworkBSSID(String bssid) {
1466b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(mInterfaceName, bssid);
1467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1469b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1470b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1471b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1472b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1473b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1474b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1475b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1476b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1477b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) {
1478b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1479b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
1480b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            Log.e(mTAG, "Invalid arguments for ANQP request.");
1481155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1482155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1483b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1484b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1485b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
148661233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1487b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1488b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1489b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
1490b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius                mInterfaceName, bssid, anqpIdList, hs20SubtypeList);
1491155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1492155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1493b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1494b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
1495b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1496b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1497b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1498b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1499b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean requestIcon(String  bssid, String fileName) {
1500b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
1501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            Log.e(mTAG, "Invalid arguments for Icon request.");
150261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1503155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1504b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(mInterfaceName, bssid, fileName);
1505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1507b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1508b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1509b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1510b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1511b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1512ba3f5bc64ef27f2ec0d3eae3f53c633ea9e66268Amin Shaikh    public String getCurrentNetworkWpsNfcConfigurationToken() {
1513b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(mInterfaceName);
1514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1515403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1516403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1517403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1518403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
1519403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1520403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
1521403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    public void removeNetworkIfCurrent(int networkId) {
1522b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(mInterfaceName, networkId);
1523403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1524403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1525b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1526b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1527b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1528af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1529af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1530af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1531af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1532af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1533af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1534af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1535af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1536af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1537b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1538d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1539520fbe7db055661af039303c1081236c73b04abdRoshan Pius     * Initializes the vendor HAL. This is just used to initialize the {@link HalDeviceManager}.
1540520fbe7db055661af039303c1081236c73b04abdRoshan Pius     */
1541af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public boolean initializeVendorHal(VendorHalDeathEventHandler handler) {
1542af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        return mWifiVendorHal.initialize(handler);
1543520fbe7db055661af039303c1081236c73b04abdRoshan Pius    }
1544520fbe7db055661af039303c1081236c73b04abdRoshan Pius
1545520fbe7db055661af039303c1081236c73b04abdRoshan Pius    /**
15468131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius     * Bring up the Vendor HAL and configure for STA mode or AP mode, if vendor HAL is supported.
1547d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     *
1548d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.
15498131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius     * @return false if the HAL start fails, true if successful or if vendor HAL not supported.
1550d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius     */
15518131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius    private boolean startHalIfNecessary(boolean isStaMode) {
15528131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        if (!mWifiVendorHal.isVendorHalSupported()) {
15538131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius            Log.i(mTAG, "Vendor HAL not supported, Ignore start...");
15548131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius            return true;
15558131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        }
15563153926f9b95f42a8d3175b4f0e4d2e448ea8fc1Roshan Pius        if (isStaMode) {
15573153926f9b95f42a8d3175b4f0e4d2e448ea8fc1Roshan Pius            return mWifiVendorHal.startVendorHalSta();
15583153926f9b95f42a8d3175b4f0e4d2e448ea8fc1Roshan Pius        } else {
15593153926f9b95f42a8d3175b4f0e4d2e448ea8fc1Roshan Pius            return mWifiVendorHal.startVendorHalAp();
15603153926f9b95f42a8d3175b4f0e4d2e448ea8fc1Roshan Pius        }
15617ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
15627ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde
1563b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
15648131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius     * Stops the HAL, if vendor HAL is supported.
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
15668131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius    private void stopHalIfNecessary() {
15678131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        if (!mWifiVendorHal.isVendorHalSupported()) {
15688131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius            Log.i(mTAG, "Vendor HAL not supported, Ignore stop...");
15698131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius            return;
15708131b04dc799cb0c75240c7b9eb0517ba1f00be8Roshan Pius        }
1571b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal.stopVendorHal();
15727ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    }
15737f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1574b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
157718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1578b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
15797f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
15807f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1581062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1582e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1583297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1584e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1585e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1586e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1587297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1588e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1589e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1590b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1591b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1592b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1593b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
15966ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public boolean getBgScanCapabilities(ScanCapabilities capabilities) {
1597d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getBgScanCapabilities(mInterfaceName, capabilities);
1598e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1599e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1600e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1601712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1602712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1603712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
16047f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
16057f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1606e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1607712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1608712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1609712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1610712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1611712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1612712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1613712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1614712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1615e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
16167f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
16176259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
16186259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
16196259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
16206259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
16216259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
16226259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
16236259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
16246259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
16256259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
16266259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
16276259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
16286259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
16296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
16306259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
16316259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
16326259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1633ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1634ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1635ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1636ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1637ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
16386259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
16396259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
1640e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
1641712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1642712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1643712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1644712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1645712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
16466259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
16476259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1648712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1649e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
16507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
165168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
16529bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
16539bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
16549bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
16559bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
16569bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1657ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
16581bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
16591bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
16601bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
16611bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
16621bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
16631bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
16641bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
16651bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
16661bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
16676259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
16681bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
16691bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1670ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1671ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1672ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1673ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1674ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1675ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1676ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
16779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
16789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
16799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
16809bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
16819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
16829bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
16839bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
16849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
16859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
16869bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
16879bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
16889bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
16899bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
16909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
169104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
1692dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
16939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
16949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
16959bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
1696b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
169763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
169863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
169963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
170063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1701c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
170263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
170363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
170463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
170563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
170663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
170763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
170863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
170963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
171083a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
171163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
171263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
171363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1714b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
1715e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1716e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
17179bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
17189bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
17199bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
17209bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
17219bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
17229bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
17239bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
17249bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
17259bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
1726063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
1727063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
1728063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
1729063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
1730063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
17319bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
17329bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
173371af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
173471af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
173571af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
173671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
1737b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
1738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1739b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
1740b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
1741b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
1743b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
1744b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1745b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17466ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public boolean startBgScan(ScanSettings settings, ScanEventHandler eventHandler) {
1747d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startBgScan(mInterfaceName, settings, eventHandler);
17487f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
17497f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1751b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
1752b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17536ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void stopBgScan() {
1754d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.stopBgScan(mInterfaceName);
1755b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1756b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1757b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1758b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
1759b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17606ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void pauseBgScan() {
1761d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.pauseBgScan(mInterfaceName);
1762b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1763b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1764b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1765b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
1766b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17676ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public void restartBgScan() {
1768d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        mWifiVendorHal.restartBgScan(mInterfaceName);
1769e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1770e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1771b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1772b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
1773b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
17746ba8a37de432d957e10dd9cc74798758870d02e6Michael Plass    public WifiScanner.ScanData[] getBgScanResults() {
1775d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getBgScanResults(mInterfaceName);
1776e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1777e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1778d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats() {
1779d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(mInterfaceName);
17805c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
17815c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
1782b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1783b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
1784b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1785b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1786b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
178718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedFeatureSet() {
1788d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getSupportedFeatureSet(mInterfaceName);
1789a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
1790143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1791143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
1792143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
1793143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1794143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1795b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1796b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
1797b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1798b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
1799b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
1800b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
1801b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
180218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
1803143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
1804b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
1805143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1806143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
1807b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1808b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
1809b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1810b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
1811b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
1812b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
181318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
1814b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
1815143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
1816042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
181768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
181868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
181968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
1820b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1821b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
182268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
182368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
1824b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
1825b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
182612cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
1827939177ff615062ec826601d536466875d8457375xinhe
1828b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1829b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
1830b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
1831b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1832b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
1833b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
18346609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
18356609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
1836b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1837b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
1838b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
1839b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
1840b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1841b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
1842b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1843b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1844b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setScanningMacOui(byte[] oui) {
1845d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.setScanningMacOui(mInterfaceName, oui);
18466609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
18476609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
1848b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1849b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
1850b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1851b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
1852b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
1853d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1854d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1855b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1856b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
1857b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1858b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ApfCapabilities getApfCapabilities() {
1859d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getApfCapabilities(mInterfaceName);
1860d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1861d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1862b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1863b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
1864b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
1866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1867b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1868b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean installPacketFilter(byte[] filter) {
1869d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.installPacketFilter(mInterfaceName, filter);
1870d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1871d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1872b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1873b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
1874b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1875b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
1876b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1877b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1878b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setCountryCodeHal(String countryCode) {
1879d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.setCountryCodeHal(mInterfaceName, countryCode);
1880d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
1881d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
1882a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
1883a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
1884a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
18850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
18860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
1887a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
1888a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
1889b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1890b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
1891b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
1892b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1893b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
1894b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1895b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
189618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
1897b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
189803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
189903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
1900b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1901b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
1902b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1903b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
1904b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
1905b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
1906b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
1907b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
1908b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
1909b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
191018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
191103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
1912b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
1913b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
191403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
191503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
1916b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1917b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
1918b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
1919b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1920b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1921b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
192218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
1923b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
192403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
192503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
1926b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1927b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
1928b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
1929b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1930b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
193118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
1932b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
1933b797893fc1966803d0c013faac42e6396a37a384xinhe    }
1934b797893fc1966803d0c013faac42e6396a37a384xinhe
1935b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1936b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
1937b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1938b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
1939b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
194018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
1941b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
194203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
194303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
1944b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1945b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
1946b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1947b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
1948b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
194918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
1950b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
195103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
195203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
19530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
19540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
19550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
19560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
19570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
19580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
19590bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
19600bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
19610bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
19620bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
196353f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
196453f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
196553f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
196653f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
196753f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
19680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
19690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
19700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
19710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
19720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
19730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
19740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
19750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
19760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
1977b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1978b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
1979b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
198018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
1981b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
198203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
198303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
1984b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1985b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
1986b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1987b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
1988b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1989b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
199018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
1991b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
199203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
1993127f7244183786e6ccae09e81eeccdac31973e69xinhe
1994b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1995b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
1996b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1997b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
1998b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
199918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2000b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2001a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2002dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2003b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2004b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2005b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2006b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2007b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2008d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2009b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2010d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2011d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2012dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
201309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
201409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
201509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
201609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2017eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2018eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2019eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2020eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2021eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2022eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
202309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
202409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
202509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
202609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2027eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
202809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
202909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
203009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
203109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2032eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2033eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
203409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
203509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
203609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
20370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2038590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2039590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2040590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2041590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2042eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2043eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2044eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2045eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2046eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2047eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2048590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2049590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2050590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2051590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
20520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
20530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2054590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
20550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
20560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
20570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
20580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2059590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2060590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
20610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
20620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2063590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
20640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
20650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
20660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
20670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2068590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2069590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2070590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2071590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2072eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2073eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2074eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2075eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2076590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2077590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2078590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
20790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
20800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
20810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
20820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
20830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
20840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
20850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
20860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
20870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
20880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
20890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
20900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
20910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
20920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
20930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
20940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2095eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2096eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2097eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2098eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2099eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2100eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2101eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2102eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2103eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2104eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2105eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2106eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2107eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2108eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2109eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2110eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2111eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2112eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2113eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2114eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2115eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2116eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2117eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2118eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2119eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2120eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2121eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2122eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
212309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
212409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
212509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
212609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
212709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
212809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
212909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
213009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
213109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
213209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
21330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
21340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
21350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
21360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
21370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
21380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
21390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
21400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
21410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
21420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
21430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
21440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
21450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
21460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
21470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
21480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
21490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
21500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
21510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
21520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
21530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
21540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
21550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
21560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
21570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
21580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
21590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
21600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
21610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
21620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
21630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
21640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
21650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
216609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
216709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
216809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
216909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
217009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
217109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
217209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
217309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
217409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
217509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
21760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
21770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
21780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
21790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
21800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
21810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
21820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
21830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
21840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
21850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
21860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
21870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
21880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
21890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
21900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
21910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
21920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
21930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
21940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
21950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
21960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
21970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
21980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
21990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
22000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
22010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
22020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
22030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
22040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
22050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
22060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
22070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
22080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
22090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
22100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
221109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
221209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
22130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
22140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2216b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
22170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
22180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean startPktFateMonitoring() {
2219d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startPktFateMonitoring(mInterfaceName);
22200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
22210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
22230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2224b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2225b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
22260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
22270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getTxPktFates(TxFateReport[] reportBufs) {
2228d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getTxPktFates(mInterfaceName, reportBufs);
22290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
22300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
22310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
22320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
22330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
22340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    public boolean getRxPktFates(RxFateReport[] reportBufs) {
2235d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getRxPktFates(mInterfaceName, reportBufs);
22360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
223709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
22385c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2239b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2240b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2241b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2242b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param keepAlivePacket Raw packet contents to send.
2243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2245b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2246b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public int startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket,
2247b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                           int period) {
22483bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        String[] macAddrStr = getMacAddress().split(":");
22493bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        byte[] srcMac = new byte[6];
2250520fbe7db055661af039303c1081236c73b04abdRoshan Pius        for (int i = 0; i < 6; i++) {
22513bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
22523bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham            srcMac[i] = hexVal.byteValue();
22533bd22cebc41ed0786d0e7bd2970a634a8bb0093ePrerepa Viswanadham        }
2254d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startSendingOffloadedPacket(mInterfaceName,
2255b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                slot, srcMac, keepAlivePacket, period);
2256c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2257c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2258b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2259b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2260b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2261b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2262b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2263b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2264b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public int stopSendingOffloadedPacket(int slot) {
2265d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(mInterfaceName, slot);
2266c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2267aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2268aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2269aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2270aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2271aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2272b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2273b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2274b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2275b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2276b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2277b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2278b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2279b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
228018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int startRssiMonitoring(byte maxRssi, byte minRssi,
2281b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                                   WifiRssiEventHandler rssiEventHandler) {
2282d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
2283d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius                mInterfaceName, maxRssi, minRssi, rssiEventHandler);
2284aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2285aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
228618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int stopRssiMonitoring() {
2287d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.stopRssiMonitoring(mInterfaceName);
2288aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
22895ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
22906bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
22916bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2292b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
22936bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
22946bf6986d359556010638dfae332b585162f06520Roshan Pius     */
22956bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2296b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
22976bf6986d359556010638dfae332b585162f06520Roshan Pius    }
22983dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2302b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2304b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
23053dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    public boolean configureNeighborDiscoveryOffload(boolean enabled) {
2306d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(mInterfaceName, enabled);
23073dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2308da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2309da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2310da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2311da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2312da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2313da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2314da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2315da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2316da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2317da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2318da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2319da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2320da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
2321b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2322da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2323da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean getRoamingCapabilities(RoamingCapabilities capabilities) {
2324d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.getRoamingCapabilities(mInterfaceName, capabilities);
2325da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2326da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2327da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2328da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2329da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2330da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2331da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2332da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2333da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2334da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2335b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2336b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2337da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2338da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public int enableFirmwareRoaming(int state) {
2339d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.enableFirmwareRoaming(mInterfaceName, state);
2340da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2341da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2342da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2343da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2344da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2345da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2346da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2347da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2348da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2349da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2350da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2351da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
2352da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2353da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public boolean configureRoaming(RoamingConfig config) {
2354b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        Log.d(mTAG, "configureRoaming ");
2355d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureRoaming(mInterfaceName, config);
2356da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2357da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2358374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2359374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
2360374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
2361374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    public boolean resetRoamingConfiguration() {
2362b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2363b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
2364d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.configureRoaming(mInterfaceName, new RoamingConfig());
2365b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2366b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2367ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2368b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2369ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2370b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2371b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2372ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2373ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2374b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2375ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2376ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2377b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2378b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2379ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2380ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2381b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2382b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2383ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2384ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2385b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2386b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2387b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2388b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2389b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2390b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2391b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2392b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2393b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2394b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2395b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2396b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2397b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2398b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2399b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2400b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2401b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2402b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2403b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2405b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2406b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2407b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2408b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2409b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2410b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2411b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2412520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2413b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2414374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2415da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2417