WifiNative.java revision 077310903b601b96c20a10f874aae7cf9af81b32
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;
23f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kimimport android.net.MacAddress;
24e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Parkimport android.net.TrafficStats;
25e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensenimport android.net.apf.ApfCapabilities;
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;
37a26a8b33616c94859ba33f33403794cf636baa54Roshan Piusimport android.util.SparseArray;
38fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
3909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawalimport com.android.internal.annotations.Immutable;
400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport com.android.internal.util.HexDump;
414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport com.android.server.net.BaseNetworkObserver;
42590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tanimport com.android.server.wifi.util.FrameParser;
43ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Haroldimport com.android.server.wifi.util.NativeUtil;
44fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.PrintWriter;
460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.StringWriter;
47e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.Retention;
48e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.RetentionPolicy;
495cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.ByteBuffer;
505cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.CharBuffer;
515cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharacterCodingException;
525cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharsetDecoder;
535cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.StandardCharsets;
54eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.text.SimpleDateFormat;
55155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
56eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.Date;
57e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashMap;
58e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashSet;
59e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.Iterator;
60fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Map;
611bf983a4211f547593a60523e43112ecdb5c8997Roshan Piusimport java.util.Objects;
629ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set;
63eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.TimeZone;
6418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Native calls for bring up/shut down of the supplicant daemon and for
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sending requests to the supplicant daemon
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * {@hide}
70155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
71155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiNative {
721d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private static final String TAG = "WifiNative";
73b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
74295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private final HostapdHal mHostapdHal;
75b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WifiVendorHal mWifiVendorHal;
76b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WificondControl mWificondControl;
774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private final INetworkManagementService mNwManagementService;
781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private final PropertyService mPropertyService;
79d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private final WifiMetrics mWifiMetrics;
80a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius    private boolean mVerboseLoggingEnabled = false;
81b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // TODO(b/69426063): Remove interfaceName from constructor once WifiStateMachine switches over
834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // to the new interface management methods.
8452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiNative(WifiVendorHal vendorHal,
85295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
86295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      WificondControl condControl, INetworkManagementService nwService,
87d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                      PropertyService propertyService, WifiMetrics wifiMetrics) {
88b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal = vendorHal;
89b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal = staIfaceHal;
90295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        mHostapdHal = hostapdHal;
91b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl = condControl;
924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        mNwManagementService = nwService;
931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mPropertyService = propertyService;
94d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        mWifiMetrics = wifiMetrics;
95155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
97b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
98b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable verbose logging for all sub modules.
99b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void enableVerboseLogging(int verbose) {
101a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mVerboseLoggingEnabled = verbose > 0 ? true : false;
102a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mWificondControl.enableVerboseLogging(mVerboseLoggingEnabled);
103a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mSupplicantStaIfaceHal.enableVerboseLogging(mVerboseLoggingEnabled);
104a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mWifiVendorHal.enableVerboseLogging(mVerboseLoggingEnabled);
105ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
106ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
10798bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius    /********************************************************
10898bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     * Interface management related methods.
10998bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     ********************************************************/
110d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
111e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Meta-info about every iface that is active.
112e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
113e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class Iface {
114e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of ifaces possible */
115e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_AP = 0;
116e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_STA = 1;
117e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
118e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA})
119e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @Retention(RetentionPolicy.SOURCE)
120e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public @interface IfaceType{}
121e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
122e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Identifier allocated for the interface */
123e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final int id;
124e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of the iface: STA or AP */
125e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final @IfaceType int type;
126e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Name of the interface */
127e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public String name;
128a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        /** Is the interface up? This is used to mask up/down notifications to external clients. */
129a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        public boolean isUp;
130e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** External iface destroyed listener for the iface */
131e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public InterfaceCallback externalListener;
1324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Network observer registered for this interface */
1334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public NetworkObserverInternal networkObserver;
134e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
135e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        Iface(int id, @Iface.IfaceType int type) {
136e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.id = id;
137e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.type = type;
138e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
139a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius
140a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        @Override
141a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        public String toString() {
142a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            StringBuffer sb = new StringBuffer();
143a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            sb.append("Iface:")
144a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("{")
145a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Name=").append(name)
146a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append(",")
147a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Id=").append(id)
148a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append(",")
149a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Type=").append(type == IFACE_TYPE_STA ? "STA" : "AP")
150a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("}");
151a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            return sb.toString();
152a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        }
153e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
154e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
155e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
156e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Iface Management entity. This class maintains list of all the active ifaces.
157e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
158e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class IfaceManager {
159e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Integer to allocate for the next iface being created */
160e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private int mNextId;
161e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Map of the id to the iface structure */
162e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private HashMap<Integer, Iface> mIfaces = new HashMap<>();
163e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
164e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Allocate a new iface for the given type */
165e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface allocateIface(@Iface.IfaceType  int type) {
166e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            Iface iface = new Iface(mNextId, type);
167e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mIfaces.put(mNextId, iface);
168e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mNextId++;
169e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return iface;
170e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
171e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
172e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Remove the iface using the provided id */
173e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface removeIface(int id) {
174e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.remove(id);
175e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
176e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
177e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided id */
178e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(int id) {
179e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.get(id);
180e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
181e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
182e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided name */
183e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(@NonNull String ifaceName) {
184e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
185e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (TextUtils.equals(iface.name, ifaceName)) {
186e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return iface;
187e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
188e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
189e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return null;
190e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
191e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
192e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Iterator to use for deleting all the ifaces while performing teardown on each of them */
193e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iterator<Integer> getIfaceIdIter() {
194e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.keySet().iterator();
195e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
196e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
197e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface active. */
198e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIface() {
199e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return !mIfaces.isEmpty();
200e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
201e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
202e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface of the given type active. */
203e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIfaceOfType(@Iface.IfaceType int type) {
204e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
205e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (iface.type == type) {
206e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return true;
207e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
208e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
209e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return false;
210e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
211e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
212b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        /** Checks if there are any iface of the given type active. */
213b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private Iface findAnyIfaceOfType(@Iface.IfaceType int type) {
214b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            for (Iface iface : mIfaces.values()) {
215b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                if (iface.type == type) {
216b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                    return iface;
217b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                }
218b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
219b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return null;
220b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
221b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
222e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any STA iface active. */
223e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyStaIface() {
224e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA);
225e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
226e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
227e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any AP iface active. */
228e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyApIface() {
229e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_AP);
230e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
231b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
232b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private String findAnyStaIfaceName() {
233b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_STA);
234b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            if (iface == null) {
235b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                return null;
236b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
237b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return iface.name;
238b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
2391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
240840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        private String findAnyApIfaceName() {
241840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_AP);
242840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            if (iface == null) {
243840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                return null;
244840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
245840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            return iface.name;
246840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
247840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
2481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        /** Removes the existing iface that does not match the provided id. */
2491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        public Iface removeExistingIface(int newIfaceId) {
2501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iface removedIface = null;
2511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            // The number of ifaces in the database could be 1 existing & 1 new at the max.
2521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mIfaces.size() > 2) {
2531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.wtf(TAG, "More than 1 existing interface found");
2541d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iterator<Map.Entry<Integer, Iface>> iter = mIfaces.entrySet().iterator();
2561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            while (iter.hasNext()) {
2571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Map.Entry<Integer, Iface> entry = iter.next();
2581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (entry.getKey() != newIfaceId) {
2591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    removedIface = entry.getValue();
2601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    iter.remove();
2611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            return removedIface;
2641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
265e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
266e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
267e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private Object mLock = new Object();
268e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private final IfaceManager mIfaceMgr = new IfaceManager();
269e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private HashSet<StatusListener> mStatusListeners = new HashSet<>();
270e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
2714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no ifaces */
2724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startHal() {
2734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    if (!mWifiVendorHal.startVendorHal()) {
2771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        Log.e(TAG, "Failed to start vendor HAL");
2781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        return false;
2791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    }
2801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
2824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
2854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop HAL if there are no more ifaces */
2894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopHalAndWificondIfNecessary() {
2904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.tearDownInterfaces()) {
2931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to teardown ifaces from wificond");
2941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    mWifiVendorHal.stopVendorHal();
2971d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring stop.");
2994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS = 100;
3054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_TIMES = 50;
3064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
3074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * This method is called to wait for establishing connection to wpa_supplicant.
3084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     *
3094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * @return true if connection is established, false otherwise.
3104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
3114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean waitForSupplicantConnection() {
3124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        // Start initialization if not already started.
3134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
3144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
3154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        boolean connected = false;
3184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        int connectTries = 0;
3194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
3204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Check if the initialization is complete.
3214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            connected = mSupplicantStaIfaceHal.isInitializationComplete();
3224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (connected) {
3234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                break;
3244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            try {
3264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
3274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } catch (InterruptedException ignore) {
3284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return connected;
3314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no STA ifaces */
3344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startSupplicant() {
3354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.enableSupplicant()) {
3381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to enable supplicant");
3394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!waitForSupplicantConnection()) {
3421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to connect to supplicant");
3434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
345d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                if (!mSupplicantStaIfaceHal.registerDeathHandler(
346d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                        new SupplicantDeathHandlerInternal())) {
3471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to register supplicant death handler");
3484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
3524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop supplicant if there are no more STA ifaces */
3564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopSupplicantIfNecessary() {
3574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
3601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to deregister supplicant death handler");
3614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.disableSupplicant()) {
3631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to disable supplicant");
3644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
37011d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    private boolean registerNetworkObserver(NetworkObserverInternal observer) {
37111d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius        if (observer == null) return false;
3724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.registerObserver(observer);
3744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
38011d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    /** Helper method to unregister a network observer */
38111d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    private boolean unregisterNetworkObserver(NetworkObserverInternal observer) {
38211d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius        if (observer == null) return false;
3834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.unregisterObserver(observer);
3854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown client iface and perform necessary cleanup */
3924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
3934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
395a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to unregister network observer on " + iface);
3964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
398a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in supplicant on " + iface);
3994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownClientInterface(iface.name)) {
401a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in wificond on " + iface);
4024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopSupplicantIfNecessary();
4044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown softAp iface and perform necessary cleanup */
4094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onSoftApInterfaceDestroyed(@NonNull Iface iface) {
4104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
412a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to unregister network observer on " + iface);
4134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
414295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mHostapdHal.removeAccessPoint(iface.name)) {
415a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to remove access point on " + iface);
416295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
41727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            if (!mHostapdHal.deregisterDeathHandler()) {
41827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.e(TAG, "Failed to deregister supplicant death handler");
41927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
420295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // TODO(b/71513606): Move this to a global operation.
421295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mWificondControl.stopHostapd(iface.name)) {
422a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to stop hostapd on " + iface);
4234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownSoftApInterface(iface.name)) {
425a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in wificond on " + iface);
4264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown iface and perform necessary cleanup */
4324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onInterfaceDestroyed(@NonNull Iface iface) {
4334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
4354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onClientInterfaceDestroyed(iface);
4364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
4374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onSoftApInterfaceDestroyed(iface);
4384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Invoke the external callback.
4404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener.onDestroyed(iface.name);
4414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Callback to be invoked by HalDeviceManager when an interface is destroyed.
4464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class InterfaceDestoyedListenerInternal
4484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            implements HalDeviceManager.InterfaceDestroyedListener {
4494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        InterfaceDestoyedListenerInternal(int ifaceId) {
4534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = ifaceId;
4544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDestroyed(@NonNull String ifaceName) {
4584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.removeIface(mInterfaceId);
4604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
461a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
462a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                        Log.v(TAG, "Received iface destroyed notification on an invalid iface="
463a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + ifaceName);
464a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
4654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
4664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onInterfaceDestroyed(iface);
468a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.i(TAG, "Successfully torn down " + iface);
4694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
473f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius    /**
474f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     * Helper method invoked to trigger the status changed callback after one of the native
475f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     * daemon's death.
476f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     */
477d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private void onNativeDaemonDeath() {
478d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        synchronized (mLock) {
479d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
480d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(false);
481d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
482d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
483d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(true);
484d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
485d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
486d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
487d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
4884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
489d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the Vendor HAL daemon.
4904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
491d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class VendorHalDeathHandlerInternal implements VendorHalDeathEventHandler {
4924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDeath() {
4944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
495d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Vendor HAL died. Cleaning up internal state.");
496d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
497d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumHalCrashes();
498d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
499d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
500d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
501d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
502d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
503d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the wificond daemon.
504d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
505d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class WificondDeathHandlerInternal implements WificondDeathEventHandler {
506d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
507d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
508d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
509d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wificond died. Cleaning up internal state.");
510d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
511d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWificondCrashes();
512d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
513d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
514d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
515d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
516d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
517d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the supplicant daemon.
518d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
519d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class SupplicantDeathHandlerInternal implements SupplicantDeathEventHandler {
520d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
521d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
522d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
523d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
524d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
525d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumSupplicantCrashes();
5264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
53127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     * Death handler for the hostapd daemon.
53227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     */
53327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    private class HostapdDeathHandlerInternal implements HostapdDeathEventHandler {
53427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        @Override
53527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        public void onDeath() {
53627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            synchronized (mLock) {
53727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.i(TAG, "hostapd died. Cleaning up internal state.");
53827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                onNativeDaemonDeath();
53927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                mWifiMetrics.incrementNumHostapdCrashes();
54027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
54127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
54227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    }
54327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius
544a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    /** Helper method invoked to handle interface change. */
545a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    private void onInterfaceStateChanged(Iface iface, boolean isUp) {
546a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        synchronized (mLock) {
547a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Mask multiple notifications with the same state.
548a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            if (isUp == iface.isUp) {
549a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                if (mVerboseLoggingEnabled) {
550a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    Log.v(TAG, "Interface status unchanged on " + iface + " from " + isUp
551a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                            + ", Ignoring...");
552a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                }
553a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                return;
554a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            }
555077310903b601b96c20a10f874aae7cf9af81b32Roshan Pius            Log.i(TAG, "Interface state changed on " + iface + ", isUp=" + isUp);
556a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            if (isUp) {
557a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                iface.externalListener.onUp(iface.name);
558a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            } else {
559a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                iface.externalListener.onDown(iface.name);
560a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            }
561a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            iface.isUp = isUp;
562a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        }
563a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    }
564a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius
56527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    /**
5664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Network observer to use for all interface up/down notifications.
5674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
5684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class NetworkObserverInternal extends BaseNetworkObserver {
5694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
5704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
5714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        NetworkObserverInternal(int id) {
5734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = id;
5744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
576077310903b601b96c20a10f874aae7cf9af81b32Roshan Pius        // TODO(b/76219766): We may need to listen for link state changes in SoftAp mode.
5774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
578077310903b601b96c20a10f874aae7cf9af81b32Roshan Pius        public void interfaceStatusChanged(String ifaceName, boolean isUp) {
5794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
580a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                final Iface ifaceWithId = mIfaceMgr.getIface(mInterfaceId);
581a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                if (ifaceWithId == null) {
582a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
583a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                        Log.v(TAG, "Received iface up/down notification on an invalid iface="
584a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + mInterfaceId);
585a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
5864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
5874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
588a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                final Iface ifaceWithName = mIfaceMgr.getIface(ifaceName);
589a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                if (ifaceWithName == null || ifaceWithName != ifaceWithId) {
590a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
591a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                        Log.v(TAG, "Received iface up/down notification on an invalid iface="
592a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + ifaceName);
593a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
594a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                    return;
5954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
596a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                onInterfaceStateChanged(ifaceWithName, isUp);
5974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
6004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
6011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
6021d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
6031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // any active interface.
6041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String handleIfaceCreationWhenVendorHalNotSupported(@NonNull Iface newIface) {
6051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Iface existingIface = mIfaceMgr.removeExistingIface(newIface.id);
6061d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        if (existingIface != null) {
6071d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            onInterfaceDestroyed(existingIface);
608a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully torn down " + existingIface);
6091d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6101d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        // Return the interface name directly from the system property.
6111d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return mPropertyService.getString("wifi.interface", "wlan0");
6121d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6151d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of STA iface.
6161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6197dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    private String createStaIface(@NonNull Iface iface, boolean lowPrioritySta) {
6201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6211d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6227dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                return mWifiVendorHal.createStaIface(lowPrioritySta,
6231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
6261d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of AP iface.
6331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createApIface(@NonNull Iface iface) {
6371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createApIface(
6401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
6431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6451d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
6491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
6501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // the interface.
6511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean handleIfaceRemovalWhenVendorHalNotSupported(@NonNull Iface iface) {
6521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mIfaceMgr.removeIface(iface.id);
6531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        onInterfaceDestroyed(iface);
654a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        Log.i(TAG, "Successfully torn down " + iface);
6551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return true;
6561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeStaIface(@NonNull Iface iface) {
6641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeStaIface(iface.name);
6671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6681d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeStaIface.");
6691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6721d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeApIface(@NonNull Iface iface) {
6781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeApIface(iface.name);
6811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeApIface.");
6831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6861d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
688e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
689d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
690d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
691d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
692d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
693d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
6944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
695e59dd55ea7446c3325be8cde31fbeca1e14fb263Roshan Pius            if (!mWifiVendorHal.initialize(new VendorHalDeathHandlerInternal())) {
6961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize vendor HAL");
6974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
6984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
699ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius            if (!mWificondControl.initialize(new WificondDeathHandlerInternal())) {
7001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize wificond");
7014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
7024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
7044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
705d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
706d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
707d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
708d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
709d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
710d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
711d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
712d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
713d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
714d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
715d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
716d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
717d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
718d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
719d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
720d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
721d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
722d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
723d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
724d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
725d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
726d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
727e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
728d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
729d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
730d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
731d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
732d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
733d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
734d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
735d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
736d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
737d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
738d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
739d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
740d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
741d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
742d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
743d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
744d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
745d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
746d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
747d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
748d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
749d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
750d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
751d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
752d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
753d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
754d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
755d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
756fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
757fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
758fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
759fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
760fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
761fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
762fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
763fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
764fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
765fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
766fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
767fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
768fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
769fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
770fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
771fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
772fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
7731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + re);
774fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
7751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + ie);
776fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
777fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
778fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
779d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
780d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
781d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
782d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
783d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
784d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
7857dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
7867dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     *                       getting created, higher probability of getting destroyed).
787d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
788d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
789d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
7907dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    public String setupInterfaceForClientMode(boolean lowPrioritySta,
7917dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            @NonNull InterfaceCallback interfaceCallback) {
7924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
7941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
795d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
7991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start supplicant");
800d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
8014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
8044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new STA iface");
8064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8097dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            iface.name = createStaIface(iface, lowPrioritySta);
8104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
811a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create STA iface in vendor HAL");
8124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
813d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
817a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
8184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
819d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
823a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
8244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
825d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
8264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
830a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
8314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
834a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
835a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
836a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
837fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
838a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
8394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
841d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
842d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
843d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
844d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
845d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
846d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
847d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
848d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
849d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
850d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
851d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
852d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
8534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
8551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
856d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
8604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new AP iface");
8624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createApIface(iface);
8664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
867a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create AP iface in vendor HAL");
8684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
869d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
870d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
874a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
8754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
876d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
877d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
882a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
8834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
886a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
887a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
888a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
889a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
8904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
892d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
893d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
894d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
8959c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
8969c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
8979c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
8989c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
8999c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
9009c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
9019c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
9029c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9039c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
9041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to get iface state on invalid iface=" + ifaceName);
9059c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9069c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9079c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
9089c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
9099c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
9109c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
9119c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9129c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
9139c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9149c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9159c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
9169c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
9179c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
9189c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
9199c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
920d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
921d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
922d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
923d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
924840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
925d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
926d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
927d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
928d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
9294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
9304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
9321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to teardown an invalid iface=" + ifaceName);
9334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
9344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
9364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
9374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
9381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeStaIface(iface)) {
9391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
9404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
9414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
9424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
9431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeApIface(iface)) {
9441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
9454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
9464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
9474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully initiated teardown for iface=" + ifaceName);
9494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
950d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
951d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
952b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    /**
953840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Teardown all the active interfaces.
954840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
955840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This method tears down the associated interfaces from all the native daemons
956840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
957840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
958840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
959840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public void teardownAllInterfaces() {
960840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        synchronized (mLock) {
961840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
962840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            while (ifaceIdIter.hasNext()) {
963840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
9646a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                ifaceIdIter.remove();
9656a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                onInterfaceDestroyed(iface);
966a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.i(TAG, "Successfully torn down " + iface);
967840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
9686a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius            Log.i(TAG, "Successfully torn down all ifaces");
969840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
970840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
971840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
972840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
973b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Get name of the client interface.
974b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
975b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * This is mainly used by external modules that needs to perform some
976b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * client operations on the STA interface.
977b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
978b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting STA + STA.
979b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
980b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * @return Interface name of any active client interface, null if no active client interface
981b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * exist.
982b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Return Values for the different scenarios are listed below:
983b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * a) When there are no client interfaces, returns null.
984b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * b) when there is 1 client interface, returns the name of that interface.
985b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * c) When there are 2 or more client interface, returns the name of any client interface.
986b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     */
987b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    public String getClientInterfaceName() {
988b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        return mIfaceMgr.findAnyStaIfaceName();
989b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    }
990b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
991840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
992840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Get name of the softap interface.
993840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
994840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This is mainly used by external modules that needs to perform some
995840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * operations on the AP interface.
996840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
997840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting AP + AP.
998840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
999840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * @return Interface name of any active softap interface, null if no active softap interface
1000840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * exist.
1001840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Return Values for the different scenarios are listed below:
1002840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * a) When there are no softap interfaces, returns null.
1003840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * b) when there is 1 softap interface, returns the name of that interface.
1004840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * c) When there are 2 or more softap interface, returns the name of any softap interface.
1005840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
1006840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public String getSoftApInterfaceName() {
1007840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        return mIfaceMgr.findAnyApIfaceName();
1008840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
1009840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
1010b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1011b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
1012b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1013b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1014b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
1015b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1016b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
1017b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
1018b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
1019b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
1020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
1021b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
1022b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
1023b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1024b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1026b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
1027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
1029b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
1030b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
1031b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
1032b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
1033b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1034b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
103570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
103655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
103755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
103855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
103955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
104055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
104155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
104255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
104355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
104455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
104555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
104652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Request signal polling to wificond.
104752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
104852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
104952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an SignalPollResult object.
105052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
105152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
105252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public SignalPollResult signalPoll(@NonNull String ifaceName) {
105352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.signalPoll(ifaceName);
1054d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1055d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
1056d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
1057d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
105852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
105952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an TxPacketCounters object.
106052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
106152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
106252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
106352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getTxPacketCounters(ifaceName);
1064d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1065d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
106624250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
1067a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
1068a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
1069a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
1070a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1071a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
1072a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
1073a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
1074a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
1075a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
1076a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
1077a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
1078a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
1079a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
1080a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
1081a70c07d019065187112945c091fc2e924af18980Roshan Pius
1082a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
1083b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
108452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
10853feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * @param scanType Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
10863feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
1087b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
1088b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
1089b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
109024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
109152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean scan(
10923feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            @NonNull String ifaceName, int scanType, Set<Integer> freqs,
10933feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            Set<String> hiddenNetworkSSIDs) {
10943feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        return mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
1095155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1096155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
109718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
1098b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
109952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
1101b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
110218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
110352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getScanResults(@NonNull String ifaceName) {
110491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
110552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
110671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
110771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
110871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
110971c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
111052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
111171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
111271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
111371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
111452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getPnoScanResults(@NonNull String ifaceName) {
111552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getScanResults(ifaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
1116155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1117155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1118b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1119b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
112052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1121b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
1122b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
112318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
112452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings) {
112552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.startPnoScan(ifaceName, pnoSettings);
1126155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1127155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1128b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
113052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
1132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
113352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopPnoScan(@NonNull String ifaceName) {
113452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopPnoScan(ifaceName);
113518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
113618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1137045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1138045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
1139045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1140045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
1141045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
1142045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
1143045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
1144045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
1145045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1146045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1147295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS = 100;
1148295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_TIMES = 50;
1149295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    /**
1150295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * This method is called to wait for establishing connection to hostapd.
1151295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     *
1152295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * @return true if connection is established, false otherwise.
1153295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     */
1154295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private boolean waitForHostapdConnection() {
1155295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        // Start initialization if not already started.
1156295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.isInitializationStarted()
1157295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                && !mHostapdHal.initialize()) {
1158295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1159295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1160295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        boolean connected = false;
1161295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        int connectTries = 0;
1162295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {
1163295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // Check if the initialization is complete.
1164295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            connected = mHostapdHal.isInitializationComplete();
1165295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (connected) {
1166295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                break;
1167295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1168295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            try {
1169295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);
1170295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            } catch (InterruptedException ignore) {
1171295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1172295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1173295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return connected;
1174295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    }
1175295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius
1176045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1177045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
1178045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
117952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1180045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
1181045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
1182045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1183045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
118452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startSoftAp(
118552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {
118652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mWificondControl.startHostapd(ifaceName, listener)) {
1187295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to start hostapd");
1188295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1189295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1190295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!waitForHostapdConnection()) {
1191295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to establish connection to hostapd");
1192295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1193295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
119427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        if (!mHostapdHal.registerDeathHandler(new HostapdDeathHandlerInternal())) {
119527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            Log.e(TAG, "Failed to register hostapd death handler");
119627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            return false;
119727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
119852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.addAccessPoint(ifaceName, config)) {
1199295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to add acccess point");
1200295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1201295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1202295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return true;
1203045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1204045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1205045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1206045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
1207045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
120852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1209045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1210045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
121152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopSoftAp(@NonNull String ifaceName) {
121252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.removeAccessPoint(ifaceName)) {
1213295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to remove access point");
1214295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
121552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopHostapd(ifaceName);
1216045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1217045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1218f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    /**
1219f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * Set MAC address of the given interface
1220f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param interfaceName Name of the interface
1221f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param mac Mac address to change into
1222f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @return true on success
1223f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     */
1224f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    public boolean setMacAddress(String interfaceName, MacAddress mac) {
1225f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim        // TODO(b/72459123): Suppress interface down/up events from this call
1226f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim        return mWificondControl.setMacAddress(interfaceName, mac);
1227f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    }
1228f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim
1229b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
123002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Hostapd operations
123102367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     ********************************************************/
123202367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius
123302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    /**
123402367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Callback to notify hostapd death.
123502367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     */
123602367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    public interface HostapdDeathEventHandler {
123702367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        /**
123802367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         * Invoked when the supplicant dies.
123902367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         */
124002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        void onDeath();
1241045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1242045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
1245b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1246f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
1247f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
1248fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
1249fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
1250fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
1251fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
1252fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
1253fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
1254fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
1255fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
1256fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
1257fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
1258b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
1259782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
1260b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1261782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
1262b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
1263f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
1264e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
1265e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
126638a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
1267b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
1268b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
126952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1270b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
127138a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
127252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reconnect(@NonNull String ifaceName) {
127352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reconnect(ifaceName);
1274f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
12759d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
12769d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1277b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1278b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
127952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1280b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
12819d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
128252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reassociate(@NonNull String ifaceName) {
128352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reassociate(ifaceName);
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1287b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1288b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
128952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1290b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1291b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
129252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean disconnect(@NonNull String ifaceName) {
129352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.disconnect(ifaceName);
129477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
129577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1297b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1298b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
129952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
130252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getMacAddress(@NonNull String ifaceName) {
130352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(ifaceName);
1304446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1305446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1306f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1307f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
131052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1311155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1312155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1313155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1314155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1315155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1316155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1317155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1318155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1319155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1320155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
133352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV4Packets(@NonNull String ifaceName) {
133452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1335b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
133652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
133752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
134252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
134552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV4Packets(@NonNull String ifaceName) {
134652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1347b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
134852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
134952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
135452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
135752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV6Packets(@NonNull String ifaceName) {
135852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1359b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
136052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
136152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1362155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
136652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1367155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
136952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV6Packets(@NonNull String ifaceName) {
137052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1371b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
137252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
137352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1374155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1376f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1377f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1378f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
13797ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
138052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Sets the bluetooth coexistence mode.
138152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
138252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
138352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
138452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
138552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
138652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return Whether the mode was successfully set.
138752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
138852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceMode(@NonNull String ifaceName, int mode) {
138952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(ifaceName, mode);
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
139752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1398cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
140152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceScanMode(
140252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, boolean setCoexScanMode) {
1403b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
140452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, setCoexScanMode);
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1407b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1408b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1409b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
141052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1411b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1412b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1413b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
141452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSuspendOptimizations(@NonNull String ifaceName, boolean enabled) {
141552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(ifaceName, enabled);
1416155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1417155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
14189153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1419b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1420b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
142152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1422b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1423b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
14249153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
142552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCode(@NonNull String ifaceName, String countryCode) {
142652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(ifaceName, countryCode);
142704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
142804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
142904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1430b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1431b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
143252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1433b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1434b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
143504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
143652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void startTdls(@NonNull String ifaceName, String macAddr, boolean enable) {
1437b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
143852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(ifaceName, macAddr);
143952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(ifaceName, macAddr);
1440155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
144152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(ifaceName, macAddr);
1442155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1443155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1445b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1446b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1447b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
144852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1449b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1450b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1451b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
145252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPbc(@NonNull String ifaceName, String bssid) {
145352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(ifaceName, bssid);
1454155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1456b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1457b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1458b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
145952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1460b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1461b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1462b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
146352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPinKeypad(@NonNull String ifaceName, String pin) {
146452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(ifaceName, pin);
1465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1467b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1468b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1469b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
147052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1471b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1472b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1473b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
147452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String startWpsPinDisplay(@NonNull String ifaceName, String bssid) {
147552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(ifaceName, bssid);
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1477155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1478b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1479b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1480b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
148152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1482b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1483b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1484b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
148552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setExternalSim(@NonNull String ifaceName, boolean external) {
148652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(ifaceName, external);
148733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
148833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1489b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1490b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1491b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1492b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1493b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1494b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1495b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1496b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1497b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1498b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
149952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1500b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1502b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1503b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
150452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthResponse(
150552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, int id, String type, String response) {
1506b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1507b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
150852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1509b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1510b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
151152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1512b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1513b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
151452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
15155cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1516b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
15175cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
151833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
151933b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1520b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1522b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
152352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1524b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1525b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
152652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthFailedResponse(@NonNull String ifaceName, int id) {
152752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(ifaceName);
152826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
152926eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1530b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1531b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1532b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
153352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1534b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1535b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
153652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean umtsAuthFailedResponse(@NonNull String ifaceName, int id) {
153752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(ifaceName);
153826eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
153926eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1540b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
154352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
15444e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param unencryptedResponse String to send.
15454e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param encryptedResponse String to send.
1546b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1547b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
15484e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar    public boolean simIdentityResponse(@NonNull String ifaceName, int id,
15494e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                                       String unencryptedResponse, String encryptedResponse) {
15504e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(ifaceName,
15514e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                unencryptedResponse, encryptedResponse);
1552ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1553ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1554b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1555a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1556a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
155752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1558a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1559a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
156052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getEapAnonymousIdentity(@NonNull String ifaceName) {
156152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(ifaceName);
1562a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1563a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1564a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1566b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
156752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1568b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1569b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1570b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1571b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
157252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsRegistrar(@NonNull String ifaceName, String bssid, String pin) {
157352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(ifaceName, bssid, pin);
1574155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1575155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1578b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
157952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1580b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1581b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
158252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean cancelWps(@NonNull String ifaceName) {
158352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(ifaceName);
1584155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1585155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1586b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1587b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1588b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
158952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1590b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1591b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1592b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
159352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceName(@NonNull String ifaceName, String name) {
159452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(ifaceName, name);
1595155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1596155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1597b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1598b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1599b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
160052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1601b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1602b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1603b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
160452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceType(@NonNull String ifaceName, String type) {
160552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(ifaceName, type);
1606155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1607155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1608b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1610b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1611b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1612b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1613b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
161452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfigMethods(@NonNull String ifaceName, String cfg) {
161552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(ifaceName, cfg);
1616155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1617155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1618b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1619b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1620b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
162152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1622b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1623b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1624b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
162552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setManufacturer(@NonNull String ifaceName, String value) {
162652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(ifaceName, value);
1627155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1628155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
163252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1633b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1634b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1635b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
163652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelName(@NonNull String ifaceName, String value) {
163752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(ifaceName, value);
1638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1641b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1642b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
164352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1644b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1646b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
164752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelNumber(@NonNull String ifaceName, String value) {
164852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(ifaceName, value);
1649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1651b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1652b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1653b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
165452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1655b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1656b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1657b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
165852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSerialNumber(@NonNull String ifaceName, String value) {
165952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(ifaceName, value);
1660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1661155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1662b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1663b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1664b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
166552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1666b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1667b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
166852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void setPowerSave(@NonNull String ifaceName, boolean enabled) {
166952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(ifaceName, enabled);
1670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1672b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1673b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1674b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1675b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1676b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1677b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1678b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1679b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1680b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1683155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
16843e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
16853e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
168652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
16873e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
16883e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
16893e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
169052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean enableStaAutoReconnect(@NonNull String ifaceName, boolean enable) {
169152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(ifaceName, enable);
16923e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
16933e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
16943e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1695b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1696b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
169752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1698b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1699b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1700b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1701b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
170352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean migrateNetworksFromSupplicant(
170452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, Map<String, WifiConfiguration> configs,
170552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            SparseArray<Map<String, String>> networkExtras) {
170652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(ifaceName, configs, networkExtras);
1707155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1708155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1709b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1710b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1711b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1712c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1713c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1714c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1715c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1716c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1717c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
171952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1720b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1721b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1722b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
172352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1724c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
172552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
172652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
1727155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1728155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1729b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1730b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1731b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1732b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1733c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1734c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1735b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1736c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1737c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
173952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1740b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1741b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
174352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean roamToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1744c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
174552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
174652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(ifaceName, configuration);
1747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1748155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1749b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1751b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
175252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1753b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1754b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
175552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean removeAllNetworks(@NonNull String ifaceName) {
175652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(ifaceName);
1757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1759b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1760b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1761b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
176252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1763b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1764b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
176552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfiguredNetworkBSSID(@NonNull String ifaceName, String bssid) {
176652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(ifaceName, bssid);
1767155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1768155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1769b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1770b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1771b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
177252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1773b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1774b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1775b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1776b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1777b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
177852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestAnqp(
177952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, String bssid, Set<Integer> anqpIds,
178052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            Set<Integer> hs20Subtypes) {
1781b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1782b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
17831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for ANQP request.");
1784155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1786b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1787b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1788b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
178961233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1790b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1791b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1792b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
179352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, bssid, anqpIdList, hs20SubtypeList);
1794155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1795155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1796b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1797b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
179852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
179952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1800b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1801b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1802b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1803b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
180452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestIcon(@NonNull String ifaceName, String  bssid, String fileName) {
1805b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
18061d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for Icon request.");
180761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1808155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
180952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(ifaceName, bssid, fileName);
1810155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1811155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1812b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1813b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1814b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
181552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1816b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1817b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
181852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken(@NonNull String ifaceName) {
181952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(ifaceName);
1820155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1821403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1822403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1823403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1824403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
182552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1826403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1827403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
182852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
182952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(ifaceName, networkId);
1830403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1831403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1832b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1833b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1834b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1835af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1836af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1837af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1838af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1839af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1840af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1841af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1842af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1843af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1844b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1845d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1846b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1847b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
184818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1849b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
18507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1852062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1853e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1854297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1855e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1856e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1857e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1858297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1859e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1860e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1861b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1862b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1863b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
186452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1867b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
186852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getBgScanCapabilities(
186952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanCapabilities capabilities) {
187052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanCapabilities(ifaceName, capabilities);
1871e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1872e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1873e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1874712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1875712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1876712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
18777f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18787f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1879e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1880712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1881712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1882712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1883712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1884712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1885712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1886712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1887712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1888e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
18897f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
18906259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
18916259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
18926259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
18936259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
18946259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
18956259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
18966259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
18976259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
18986259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
18996259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
19006259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19016259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
19026259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
19036259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
19046259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
19056259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1906ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1907ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1908ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1909ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1910ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19116259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
19126259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
19133feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_LATENCY = 0;
19143feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_POWER = 1;
19153feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
19163feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius
1917e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
19183feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        /**
19193feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
19203feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
19213feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         */
19223feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        public int scanType;
1923712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1924712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1925712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1926712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1927712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
19286259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
19296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1930712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1931e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19327f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
193368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
19349bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
19359bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19369bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
19379bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
19389bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1939ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
19401bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
19411bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
19421bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
19431bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
19441bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
19451bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19461bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
19471bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
19481bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
19496259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
19501bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
19511bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1952ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1953ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1954ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1955ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1956ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1957ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1958ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19599bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19609bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
19619bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
19629bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
19639bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
19649bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19659bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
19669bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
19679bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
19689bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
19699bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
19709bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
19719bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
19729bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
197304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
1974dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
19759bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
19769bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
1978b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
197963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
198063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
198163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
198263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1983c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
198463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
198563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
198663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
198763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
198863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
198963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
199063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
199163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
199283a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
199363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
199463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
199563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1996b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
1997e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1998e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
19999bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
20009bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
20019bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20029bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
20039bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
20049bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
20059bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
20069bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
20079bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
2008063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
2009063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
2010063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
2011063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
2012063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
20139bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20149bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
201571af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
201671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
201771af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
201871af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
2019b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
2020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2021b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
2022b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
2023b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
202452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
2026b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
2027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
202952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startBgScan(
203052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanSettings settings, ScanEventHandler eventHandler) {
203152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startBgScan(ifaceName, settings, eventHandler);
20327f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
20337f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2034b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2035b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
203652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2037b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
203852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void stopBgScan(@NonNull String ifaceName) {
203952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.stopBgScan(ifaceName);
2040b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2041b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2042b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2043b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
204452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2045b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
204652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void pauseBgScan(@NonNull String ifaceName) {
204752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.pauseBgScan(ifaceName);
2048b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2049b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2050b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2051b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
205252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2053b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
205452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void restartBgScan(@NonNull String ifaceName) {
205552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.restartBgScan(ifaceName);
2056e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2057e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2058b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2059b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
206052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2061b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
206252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiScanner.ScanData[] getBgScanResults(@NonNull String ifaceName) {
206352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanResults(ifaceName);
2064e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2065e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
206652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
206752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Gets the latest link layer stats
206852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
206952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
207052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats(@NonNull String ifaceName) {
207152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(ifaceName);
20725c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
20735c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
2074b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2075b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
2076b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
207752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2078b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
2079b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
208052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int getSupportedFeatureSet(@NonNull String ifaceName) {
208152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getSupportedFeatureSet(ifaceName);
2082a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2083143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2084143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2085143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2086143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2087143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2088b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2089b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
2090b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2091b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
2092b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
2093b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
2094b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
209518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2096143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2097b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
2098143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2099143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2101b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
2102b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2103b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
2104b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
2105b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
210618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2107b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
2108143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2109042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
211068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
211168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
211268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
2113b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2114b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
211568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
211668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
2117b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
2118b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
211912cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2120939177ff615062ec826601d536466875d8457375xinhe
2121b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2122b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
2123b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
2124b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2125b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
2126b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
21276609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
21286609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2130b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
2131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
2132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
2133b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
213452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2135b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
2136b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2137b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
213852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setScanningMacOui(@NonNull String ifaceName, byte[] oui) {
213952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setScanningMacOui(ifaceName, oui);
21406609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
21416609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2142b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2143b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
2144b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2145b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
2146b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
2147d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2148d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2149b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
215152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2152b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
215352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ApfCapabilities getApfCapabilities(@NonNull String ifaceName) {
215452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getApfCapabilities(ifaceName);
2155d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2156d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2157b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2158b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
2159b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
216052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2161b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
2162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2163b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
216452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean installPacketFilter(@NonNull String ifaceName, byte[] filter) {
216552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.installPacketFilter(ifaceName, filter);
2166d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2167d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2168b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2169b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
217052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2171b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
2172b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2173b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
217452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
217552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setCountryCodeHal(ifaceName, countryCode);
2176d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2177d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2178a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2179a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
2180a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
21810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
21820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2183a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2184a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2185b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2186b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
2187b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
2188b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2189b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
2190b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2191b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
219218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2193b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
219403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
219503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2196b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2197b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
2198b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2199b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
2200b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
2201b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
2202b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
2203b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
2204b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2205b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
220618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
220703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2208b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
2209b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
221003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
221103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2212b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2213b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
2214b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
2215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2216b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2217b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
221818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2219b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
222003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
222103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2222b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2223b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
2224b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
2225b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2226b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
222718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2228b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
2229b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2230b797893fc1966803d0c013faac42e6396a37a384xinhe
2231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2232b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
2233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2234b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2235b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
223618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2237b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
223803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
223903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2240b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2241b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
2242b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
224518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2246b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
224703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
224803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
22490bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
22500bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
22510bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
22520bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
22530bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
22540bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
22550bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
22560bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
22570bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
22580bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
225953f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
226053f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
226153f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
226253f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
226353f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
22640bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
22650bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
22660bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
22670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
22680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
22690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
22700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
22710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
22720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2273b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2274b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
2275b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
227618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2277b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
227803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
227903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2280b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2281b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
2282b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2283b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
2284b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2285b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
228618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2287b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
228803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2289127f7244183786e6ccae09e81eeccdac31973e69xinhe
2290b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2291b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
2292b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2293b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2294b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
229518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2296b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2297a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2298dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2302b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2304d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2305b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2306d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2307d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2308dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
230909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
231009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
231109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
231209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2313eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2314eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2315eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2316eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2317eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2318eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
231909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
232009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
232109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
232209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2323eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
232409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
232509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
232609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
232709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2328eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2329eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
233009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
233109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
233209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
23330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2334590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2335590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2336590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2337590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2338eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2339eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2340eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2341eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2342eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2343eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2344590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2345590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2346590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2347590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
23480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
23490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2350590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
23510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
23520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
23530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
23540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2355590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2356590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
23570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
23580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2359590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
23600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
23610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
23620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
23630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2364590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2365590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2366590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2367590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2368eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2369eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2370eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2371eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2372590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2373590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2374590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
23750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
23760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
23780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
23800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
23810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
23820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
23830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
23840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
23850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
23860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
23870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
23880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
23890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
23900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2391eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2392eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2393eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2394eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2395eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2396eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2397eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2398eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2399eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2400eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2401eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2402eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2403eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2404eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2405eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2406eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2407eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2408eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2409eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2410eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2411eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2412eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2413eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2414eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2415eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2416eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2417eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2418eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
241909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
242009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
242109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
242209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
242309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
242409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
242509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
242609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
242709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
242809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
24320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
24330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
24370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
24380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
24390fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
24400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
24410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
24420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
24430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
24440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
24450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
24460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
24470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
24480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
24490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
24500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
24510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
24520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
24530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
24540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
24550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
24560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
24570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
24580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
24590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
24600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
24610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
246209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
246309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
246409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
246509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
246609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
246709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
246809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
246909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
247009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
247109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
24750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
24760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
24800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
24810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
24820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
24830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
24840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
24850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
24860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
24870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
24880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
24890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
24900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
24910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
24920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
24930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
24940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
24950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
24960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
24970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
24980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
24990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
25000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
25010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
25020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
25030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
25040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
25050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
25060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
250709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
250809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
25090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2511b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
251252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2513b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
25140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
251552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPktFateMonitoring(@NonNull String ifaceName) {
251652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startPktFateMonitoring(ifaceName);
25170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
25180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
252252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2523b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
25240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
252552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getTxPktFates(@NonNull String ifaceName, TxFateReport[] reportBufs) {
252652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getTxPktFates(ifaceName, reportBufs);
25270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
25280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
253152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
25320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
253352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRxPktFates(@NonNull String ifaceName, RxFateReport[] reportBufs) {
253452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRxPktFates(ifaceName, reportBufs);
25350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
253609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
25375c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2538e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the tx packet counts for the interface.
2539e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2540e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface.
2541e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return tx packet counts
2542e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2543e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getTxPackets(@NonNull String ifaceName) {
2544e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getTxPackets(ifaceName);
2545e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2546e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2547e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2548e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the rx packet counts for the interface.
2549e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2550e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface
2551e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return rx packet counts
2552e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2553e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getRxPackets(@NonNull String ifaceName) {
2554e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getRxPackets(ifaceName);
2555e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2556e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2557e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2558b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2559b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
256052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2561b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2562ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param dstMac Destination MAC Address
2563ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param packet Raw packet contents to send.
2564ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param protocol The ethernet protocol type
2565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2566b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2567b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2568ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold    public int startSendingOffloadedPacket(@NonNull String ifaceName, int slot,
2569ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold            byte[] dstMac, byte[] packet, int protocol, int period) {
2570ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        byte[] srcMac = NativeUtil.macAddressToByteArray(getMacAddress(ifaceName));
2571ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        return mWifiVendorHal.startSendingOffloadedPacket(
2572ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold                ifaceName, slot, srcMac, dstMac, packet, protocol, period);
2573c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2574c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
257852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2579b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2580b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2581b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
258252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopSendingOffloadedPacket(@NonNull String ifaceName, int slot) {
258352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(ifaceName, slot);
2584c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2585aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2586aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2587aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2588aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2589aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2590b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2591b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2592b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
259352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName        Name of the interface.
2594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2596b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2597b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2598b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
259952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int startRssiMonitoring(
260052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, byte maxRssi, byte minRssi,
260152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            WifiRssiEventHandler rssiEventHandler) {
2602d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
260352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, maxRssi, minRssi, rssiEventHandler);
2604aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2605aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
260652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
260752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Stop RSSI monitoring on the currently connected access point.
260852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
260952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
261052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return 0 for success, -1 for failure
261152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
261252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopRssiMonitoring(@NonNull String ifaceName) {
261352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopRssiMonitoring(ifaceName);
2614aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
26155ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
26166bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
26176bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2618b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
26196bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
26206bf6986d359556010638dfae332b585162f06520Roshan Pius     */
26216bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2622b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
26236bf6986d359556010638dfae332b585162f06520Roshan Pius    }
26243dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2625b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2626b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2627b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
262852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
263252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureNeighborDiscoveryOffload(@NonNull String ifaceName, boolean enabled) {
263352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(ifaceName, enabled);
26343dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2635da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2636da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2637da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2638da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2639da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2640da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2641da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2642da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2643da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2644da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2645da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2646da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2647da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
264852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2650da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
265152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRoamingCapabilities(
265252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, RoamingCapabilities capabilities) {
265352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRoamingCapabilities(ifaceName, capabilities);
2654da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2655da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2656da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2657da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2658da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2659da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2660da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2661da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2662da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2663da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2664b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
266552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2666b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2667da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
266852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int enableFirmwareRoaming(@NonNull String ifaceName, int state) {
266952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.enableFirmwareRoaming(ifaceName, state);
2670da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2671da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2672da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2673da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2674da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2675da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2676da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2677da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2678da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2679da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2680da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2681da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
268252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2683da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
268452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureRoaming(@NonNull String ifaceName, RoamingConfig config) {
268552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, config);
2686da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2687da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2688374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2689374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
269052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2691374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
269252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean resetRoamingConfiguration(@NonNull String ifaceName) {
2693b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2694b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
269552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, new RoamingConfig());
2696b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2697b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2698ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2699b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2700ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2701b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2702b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2703ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2704ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2705b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2706ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2707ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2708b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2709b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2710ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2711ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2712b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2713b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2714ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2715ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2716b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2717b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2720b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2721b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2722b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2723b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2724b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2725b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2726b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2727b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2728b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2729b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2730b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2731b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2732b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2733b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2734b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2735b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2736b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2737b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2739b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2740b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2741b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2743520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2744b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2745374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2746da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2747155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2748