WifiNative.java revision b6a730ce63a9a864adaea6ba1bee827444be52a5
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) {
605e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
606e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            Iface existingIface = mIfaceMgr.removeExistingIface(newIface.id);
607e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            if (existingIface != null) {
608e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius                onInterfaceDestroyed(existingIface);
609e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius                Log.i(TAG, "Successfully torn down " + existingIface);
610e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            }
611e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            // Return the interface name directly from the system property.
612e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mPropertyService.getString("wifi.interface", "wlan0");
6131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6151d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of STA iface.
6181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6217dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    private String createStaIface(@NonNull Iface iface, boolean lowPrioritySta) {
6221d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6247dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                return mWifiVendorHal.createStaIface(lowPrioritySta,
6251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6261d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
6281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of AP iface.
6351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createApIface(@NonNull Iface iface) {
6391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createApIface(
6421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
6451d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
6511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
6521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // the interface.
6531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean handleIfaceRemovalWhenVendorHalNotSupported(@NonNull Iface iface) {
654e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
655e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            mIfaceMgr.removeIface(iface.id);
656e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            onInterfaceDestroyed(iface);
657e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            Log.i(TAG, "Successfully torn down " + iface);
658e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return true;
659e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
6601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeStaIface(@NonNull Iface iface) {
6681d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeStaIface(iface.name);
6711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6721d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeStaIface.");
6731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeApIface(@NonNull Iface iface) {
6821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeApIface(iface.name);
6851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6861d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeApIface.");
6871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6881d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6911d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
692e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
693d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
694d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
695d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
696d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
697d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
6984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
699e59dd55ea7446c3325be8cde31fbeca1e14fb263Roshan Pius            if (!mWifiVendorHal.initialize(new VendorHalDeathHandlerInternal())) {
7001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize vendor HAL");
7014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
7024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
703ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius            if (!mWificondControl.initialize(new WificondDeathHandlerInternal())) {
7041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize wificond");
7054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
7064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
7084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
709d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
710d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
711d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
712d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
713d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
714d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
715d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
716d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
717d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
718d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
719d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
720d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
721d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
722d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
723d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
724d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
725d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
726d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
727d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
728d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
729d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
730d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
731e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
732d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
733d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
734d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
735d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
736d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
737d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
738d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
739d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
740d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
741d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
742d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
743d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
744d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
745d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
746d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
747d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
748d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
749d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
750d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
751d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
752d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
753d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
754d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
755d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
756d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
757d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
758d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
759d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
760fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
761fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
762fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
763fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
764fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
765fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
766fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
767fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
768fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
769fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
770fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
771fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
772fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
773fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
774fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
775fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
776fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
7771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + re);
778fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
7791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + ie);
780fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
781fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
782fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
783d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
784d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
785d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
786d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
787d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
788d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
7897dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
7907dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     *                       getting created, higher probability of getting destroyed).
791d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
792d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
793d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
7947dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    public String setupInterfaceForClientMode(boolean lowPrioritySta,
7957dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            @NonNull InterfaceCallback interfaceCallback) {
7964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
7981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
799d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
8031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start supplicant");
804d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
8054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
8084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8091d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new STA iface");
8104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8137dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            iface.name = createStaIface(iface, lowPrioritySta);
8144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
815a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create STA iface in vendor HAL");
8164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
817d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
821a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
8224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
823d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
827a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
8284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
829d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
8304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
834a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
8354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
838a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
839a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
840a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
841fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
842a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
8434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
845d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
846d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
847d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
848d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
849d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
850d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
851d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
852d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
853d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
854d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
855d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
856d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
8574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
8591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
860d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
8644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new AP iface");
8664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createApIface(iface);
8704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
871a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create AP iface in vendor HAL");
8724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
873d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
874d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
878a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
8794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
880d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
881d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
886a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
8874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
890a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
891a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
892a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
893a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
8944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
896d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
897d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
898d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
8999c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
9009c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
9019c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
9029c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
9039c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
9049c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
9059c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
9069c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9079c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
9081d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to get iface state on invalid iface=" + ifaceName);
9099c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9109c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9119c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
9129c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
9139c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
9149c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
9159c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9169c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
9179c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9189c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9199c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
9209c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
9219c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
9229c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
9239c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
924d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
925d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
926d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
927d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
928840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
929d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
930d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
931d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
932d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
9334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
9344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
9361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to teardown an invalid iface=" + ifaceName);
9374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
9384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
9404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
9414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
9421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeStaIface(iface)) {
9431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
9444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
9454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
9464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
9471d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeApIface(iface)) {
9481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
9494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
9504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
9514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully initiated teardown for iface=" + ifaceName);
9534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
954d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
955d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
956b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    /**
957840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Teardown all the active interfaces.
958840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
959840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This method tears down the associated interfaces from all the native daemons
960840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
961840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
962840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
963840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public void teardownAllInterfaces() {
964840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        synchronized (mLock) {
965840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
966840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            while (ifaceIdIter.hasNext()) {
967840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
9686a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                ifaceIdIter.remove();
9696a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                onInterfaceDestroyed(iface);
970a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.i(TAG, "Successfully torn down " + iface);
971840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
9726a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius            Log.i(TAG, "Successfully torn down all ifaces");
973840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
974840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
975840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
976840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
977b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Get name of the client interface.
978b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
979b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * This is mainly used by external modules that needs to perform some
980b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * client operations on the STA interface.
981b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
982b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting STA + STA.
983b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
984b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * @return Interface name of any active client interface, null if no active client interface
985b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * exist.
986b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Return Values for the different scenarios are listed below:
987b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * a) When there are no client interfaces, returns null.
988b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * b) when there is 1 client interface, returns the name of that interface.
989b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * c) When there are 2 or more client interface, returns the name of any client interface.
990b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     */
991b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    public String getClientInterfaceName() {
992e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
993e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mIfaceMgr.findAnyStaIfaceName();
994e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
995b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    }
996b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
997840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
998840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Get name of the softap interface.
999840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1000840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This is mainly used by external modules that needs to perform some
1001840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * operations on the AP interface.
1002840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1003840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting AP + AP.
1004840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1005840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * @return Interface name of any active softap interface, null if no active softap interface
1006840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * exist.
1007840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Return Values for the different scenarios are listed below:
1008840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * a) When there are no softap interfaces, returns null.
1009840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * b) when there is 1 softap interface, returns the name of that interface.
1010840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * c) When there are 2 or more softap interface, returns the name of any softap interface.
1011840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
1012840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public String getSoftApInterfaceName() {
1013e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
1014e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mIfaceMgr.findAnyApIfaceName();
1015e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
1016840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
1017840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
1018b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1019b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
1020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1021b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1022b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
1023b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1024b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
1025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
1026b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
1027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
1028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
1029b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
1030b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
1031b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1032b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1033b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1034b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
1035b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1036b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
1037b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
1038b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
1039b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
1040b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
1041b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1042b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
104370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
104455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
104555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
104655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
104755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
104855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
104955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
105055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
105155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
105255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
105355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
105452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Request signal polling to wificond.
105552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
105652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
105752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an SignalPollResult object.
105852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
105952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
106052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public SignalPollResult signalPoll(@NonNull String ifaceName) {
106152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.signalPoll(ifaceName);
1062d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1063d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
1064d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
1065d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
106652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
106752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an TxPacketCounters object.
106852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
106952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
107052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
107152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getTxPacketCounters(ifaceName);
1072d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1073d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
107424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
1075a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
1076a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
1077a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
1078a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1079a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
1080a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
1081a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
1082a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
1083a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
1084a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
1085a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
1086a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
1087a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
1088a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
1089a70c07d019065187112945c091fc2e924af18980Roshan Pius
1090a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
1091b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
109252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
10933feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * @param scanType Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
10943feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
1095b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
1096b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
1097b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
109824250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
109952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean scan(
11003feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            @NonNull String ifaceName, int scanType, Set<Integer> freqs,
11013feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            Set<String> hiddenNetworkSSIDs) {
11023feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        return mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
1103155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1104155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
110518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
1106b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
110752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1108b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
1109b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
111018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
111152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getScanResults(@NonNull String ifaceName) {
111291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
111352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
111471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
111571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
111671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
111771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
111852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
111971c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
112071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
112171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
112252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getPnoScanResults(@NonNull String ifaceName) {
112352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getScanResults(ifaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
1124155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1125155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1126b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1127b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
112852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
1130b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
113118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
113252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings) {
113352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.startPnoScan(ifaceName, pnoSettings);
1134155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1135155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1136b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1137b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
113852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1139b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
1140b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
114152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopPnoScan(@NonNull String ifaceName) {
114252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopPnoScan(ifaceName);
114318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
114418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1145045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1146045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
1147045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1148045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
1149045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
1150045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
1151045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
1152045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
11534de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh
11544de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh        /**
11554de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh         * Invoked when the channel switch event happens.
11564de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh         */
11574de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh        void onSoftApChannelSwitched(int frequency, int bandwidth);
1158045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1159045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1160295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS = 100;
1161295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_TIMES = 50;
1162295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    /**
1163295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * This method is called to wait for establishing connection to hostapd.
1164295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     *
1165295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * @return true if connection is established, false otherwise.
1166295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     */
1167295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private boolean waitForHostapdConnection() {
1168295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        // Start initialization if not already started.
1169295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.isInitializationStarted()
1170295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                && !mHostapdHal.initialize()) {
1171295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1172295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1173295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        boolean connected = false;
1174295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        int connectTries = 0;
1175295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {
1176295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // Check if the initialization is complete.
1177295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            connected = mHostapdHal.isInitializationComplete();
1178295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (connected) {
1179295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                break;
1180295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1181295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            try {
1182295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);
1183295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            } catch (InterruptedException ignore) {
1184295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1185295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1186295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return connected;
1187295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    }
1188295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius
1189045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1190045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
1191045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
119252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1193045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
1194045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
1195045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1196045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
119752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startSoftAp(
119852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {
119952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mWificondControl.startHostapd(ifaceName, listener)) {
1200295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to start hostapd");
1201295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1202295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1203295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!waitForHostapdConnection()) {
1204295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to establish connection to hostapd");
1205295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1206295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
120727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        if (!mHostapdHal.registerDeathHandler(new HostapdDeathHandlerInternal())) {
120827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            Log.e(TAG, "Failed to register hostapd death handler");
120927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            return false;
121027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
121152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.addAccessPoint(ifaceName, config)) {
1212295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to add acccess point");
1213295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1214295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1215295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return true;
1216045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1217045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1218045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1219045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
1220045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
122152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1222045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1223045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
122452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopSoftAp(@NonNull String ifaceName) {
122552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.removeAccessPoint(ifaceName)) {
1226295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to remove access point");
1227295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
122852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopHostapd(ifaceName);
1229045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1230045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1231f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    /**
1232f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * Set MAC address of the given interface
1233f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param interfaceName Name of the interface
1234f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param mac Mac address to change into
1235f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @return true on success
1236f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     */
1237f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    public boolean setMacAddress(String interfaceName, MacAddress mac) {
1238f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim        // TODO(b/72459123): Suppress interface down/up events from this call
1239f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim        return mWificondControl.setMacAddress(interfaceName, mac);
1240f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    }
1241f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim
1242b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
124302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Hostapd operations
124402367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     ********************************************************/
124502367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius
124602367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    /**
124702367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Callback to notify hostapd death.
124802367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     */
124902367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    public interface HostapdDeathEventHandler {
125002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        /**
125102367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         * Invoked when the supplicant dies.
125202367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         */
125302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        void onDeath();
1254045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1255045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1256b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1257b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
1258b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1259f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
1260f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
1261fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
1262fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
1263fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
1264fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
1265fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
1266fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
1267fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
1268fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
1269fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
1270fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
1271b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
1272782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
1273b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1274782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
1275b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
1276f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
1277e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
1278e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
127938a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
1280b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
1281b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
128252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1283b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
128438a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
128552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reconnect(@NonNull String ifaceName) {
128652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reconnect(ifaceName);
1287f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
12889d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
12899d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1290b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1291b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
129252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1293b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
12949d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
129552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reassociate(@NonNull String ifaceName) {
129652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reassociate(ifaceName);
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1299155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
130252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1304b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
130552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean disconnect(@NonNull String ifaceName) {
130652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.disconnect(ifaceName);
130777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
130877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1309155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1310b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1311b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
131252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1313b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1314b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
131552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getMacAddress(@NonNull String ifaceName) {
131652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(ifaceName);
1317446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1318446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1319f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1320f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1321155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1322155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
132352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1330155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1331155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1334155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1335155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1336155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1337155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1340155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1341155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1342155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1343155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1344155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1345155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
134652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV4Packets(@NonNull String ifaceName) {
134752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1348b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
134952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
135052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1351155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1352155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1353155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
135552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1357155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
135852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV4Packets(@NonNull String ifaceName) {
135952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1360b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
136152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
136252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1363155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1364155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1365155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
136752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1368155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1369155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
137052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV6Packets(@NonNull String ifaceName) {
137152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1372b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
137352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
137452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
137952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1380155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
138252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV6Packets(@NonNull String ifaceName) {
138352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1384b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
138552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
138652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1389f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1390f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1391f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
13927ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
139352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Sets the bluetooth coexistence mode.
139452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
139552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
139652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
139752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
139852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
139952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return Whether the mode was successfully set.
140052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
140152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceMode(@NonNull String ifaceName, int mode) {
140252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(ifaceName, mode);
1403155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1404155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1405155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1406155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1407155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
141052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1411cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1412155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
141452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceScanMode(
141552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, boolean setCoexScanMode) {
1416b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
141752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, setCoexScanMode);
1418155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1419155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1420b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1421b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1422b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
142352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1425b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1426b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
142752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSuspendOptimizations(@NonNull String ifaceName, boolean enabled) {
142852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(ifaceName, enabled);
1429155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1430155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
14319153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1432b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1433b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
143452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1435b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1436b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
14379153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
143852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCode(@NonNull String ifaceName, String countryCode) {
143952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(ifaceName, countryCode);
144004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
144104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
144204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1443b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1444b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
144552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1446b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1447b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
144804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
144952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void startTdls(@NonNull String ifaceName, String macAddr, boolean enable) {
1450b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
145152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(ifaceName, macAddr);
145252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(ifaceName, macAddr);
1453155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
145452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(ifaceName, macAddr);
1455155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1456155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1457155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1458b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1459b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1460b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
146152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1462b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1463b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1464b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
146552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPbc(@NonNull String ifaceName, String bssid) {
146652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(ifaceName, bssid);
1467155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1468155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1469b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1470b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1471b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
147252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1473b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1474b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1475b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
147652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPinKeypad(@NonNull String ifaceName, String pin) {
147752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(ifaceName, pin);
1478155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1479155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1480b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1481b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1482b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
148352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1484b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1485b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1486b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
148752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String startWpsPinDisplay(@NonNull String ifaceName, String bssid) {
148852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(ifaceName, bssid);
1489155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1490155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1491b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1492b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1493b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
149452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1495b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1496b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1497b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
149852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setExternalSim(@NonNull String ifaceName, boolean external) {
149952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(ifaceName, external);
150033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
150133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1502b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1503b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1504b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1505b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1506b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1507b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1508b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1509b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1510b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy     * EAP-SIM Error Codes
1511b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy     */
1512b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy    public static final int EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED = 16385;
1513b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy
1514b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy    /**
1515b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1516b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
151752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1518b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1519b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1520b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
152252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthResponse(
152352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, int id, String type, String response) {
1524b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1525b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
152652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1527b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1528b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
152952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1530b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1531b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
153252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
15335cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1534b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
15355cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
153633b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
153733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1538b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1539b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1540b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
154152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1543b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
154452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthFailedResponse(@NonNull String ifaceName, int id) {
154552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(ifaceName);
154626eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
154726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1548b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1549b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1550b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
155152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1552b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1553b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
155452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean umtsAuthFailedResponse(@NonNull String ifaceName, int id) {
155552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(ifaceName);
155626eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
155726eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1558b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1559b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1560b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
156152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
15624e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param unencryptedResponse String to send.
15634e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param encryptedResponse String to send.
1564b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
15664e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar    public boolean simIdentityResponse(@NonNull String ifaceName, int id,
15674e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                                       String unencryptedResponse, String encryptedResponse) {
15684e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(ifaceName,
15694e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                unencryptedResponse, encryptedResponse);
1570ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1571ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1572b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1573a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1574a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
157552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1576a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1577a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
157852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getEapAnonymousIdentity(@NonNull String ifaceName) {
157952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(ifaceName);
1580a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1581a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1582a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1583b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1584b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
158552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1586b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1587b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1588b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1589b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
159052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsRegistrar(@NonNull String ifaceName, String bssid, String pin) {
159152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(ifaceName, bssid, pin);
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1593155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1596b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
159752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1598b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1599b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
160052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean cancelWps(@NonNull String ifaceName) {
160152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(ifaceName);
1602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1603155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1604b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1605b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1606b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
160752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1608b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1610b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
161152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceName(@NonNull String ifaceName, String name) {
161252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(ifaceName, name);
1613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1615b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1616b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1617b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
161852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1619b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1620b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1621b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
162252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceType(@NonNull String ifaceName, String type) {
162352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(ifaceName, type);
1624155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1625155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1626b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1627b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1628b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
163252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfigMethods(@NonNull String ifaceName, String cfg) {
163352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(ifaceName, cfg);
1634155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1635155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1636b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1637b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1638b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
163952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1641b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1642b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
164352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setManufacturer(@NonNull String ifaceName, String value) {
164452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(ifaceName, value);
1645155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1646155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1647b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1648b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
165052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1651b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1652b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1653b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
165452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelName(@NonNull String ifaceName, String value) {
165552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(ifaceName, value);
1656155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1657155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1658b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1659b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1660b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
166152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1662b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1663b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1664b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
166552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelNumber(@NonNull String ifaceName, String value) {
166652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(ifaceName, value);
1667155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1668155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1669b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1670b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1671b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
167252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1673b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1674b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1675b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
167652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSerialNumber(@NonNull String ifaceName, String value) {
167752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(ifaceName, value);
1678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1680b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1681b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1682b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
168352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1684b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1685b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
168652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void setPowerSave(@NonNull String ifaceName, boolean enabled) {
168752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(ifaceName, enabled);
1688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1690b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1691b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1692b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1693b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1694b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1695b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1696b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1697b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1698b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1700155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1701155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
17023e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
17033e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
170452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
17053e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
17063e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
17073e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
170852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean enableStaAutoReconnect(@NonNull String ifaceName, boolean enable) {
170952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(ifaceName, enable);
17103e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
17113e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
17123e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1713b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1714b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
171552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1716b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1717b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1720155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
172152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean migrateNetworksFromSupplicant(
172252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, Map<String, WifiConfiguration> configs,
172352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            SparseArray<Map<String, String>> networkExtras) {
172452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(ifaceName, configs, networkExtras);
1725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1727b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1728b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1729b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1730c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1731c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1732c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1733c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1734c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1735c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1736b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
173752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1739b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1740b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
174152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1742c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
174352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
174452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
1745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1747b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1748b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1749b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1751c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1752c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1753b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1754c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1755c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1756b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
175752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1758b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1759b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1760b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
176152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean roamToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1762c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
176352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
176452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(ifaceName, configuration);
1765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1766155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1767b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1768b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1769b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
177052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1771b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1772b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
177352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean removeAllNetworks(@NonNull String ifaceName) {
177452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(ifaceName);
1775155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1776155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1777b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1778b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1779b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
178052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1781b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1782b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
178352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfiguredNetworkBSSID(@NonNull String ifaceName, String bssid) {
178452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(ifaceName, bssid);
1785155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1786155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1787b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1788b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1789b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
179052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1791b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1792b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1793b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1794b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1795b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
179652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestAnqp(
179752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, String bssid, Set<Integer> anqpIds,
179852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            Set<Integer> hs20Subtypes) {
1799b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1800b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
18011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for ANQP request.");
1802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1804b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1805b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1806b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
180761233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1808b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1809b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1810b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
181152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, bssid, anqpIdList, hs20SubtypeList);
1812155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1813155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1814b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1815b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
181652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
181752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1818b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1819b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1820b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1821b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
182252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestIcon(@NonNull String ifaceName, String  bssid, String fileName) {
1823b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
18241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for Icon request.");
182561233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1826155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
182752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(ifaceName, bssid, fileName);
1828155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1829155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1830b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1831b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1832b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
183352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1834b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1835b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
183652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken(@NonNull String ifaceName) {
183752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(ifaceName);
1838155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1839403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1840403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1841403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1842403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
184352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1844403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1845403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
184652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
184752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(ifaceName, networkId);
1848403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1849403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1850b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1851b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1852b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1853af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1854af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1855af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1856af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1857af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1858af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1859af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1860af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1861af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1862b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1863d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1864b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
186618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1867b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
18687f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18697f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1870062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1871e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1872297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1873e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1874e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1875e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1876297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1877e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1878e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1879b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1880b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1881b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
188252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1883b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1884b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1885b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
188652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getBgScanCapabilities(
188752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanCapabilities capabilities) {
188852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanCapabilities(ifaceName, capabilities);
1889e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1890e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1891e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1892712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1893712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1894712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
18957f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18967f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1897e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1898712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1899712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1900712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1901712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1902712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1903712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1904712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1905712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1906e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19077f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
19086259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
19096259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
19106259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
19116259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
19126259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
19136259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
19146259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
19156259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
19166259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
19176259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
19186259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19196259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
19206259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
19216259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
19226259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
19236259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1924ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1925ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1926ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1927ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1928ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
19306259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
19313feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_LATENCY = 0;
19323feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_POWER = 1;
19333feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
19343feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius
1935e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
19363feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        /**
19373feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
19383feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
19393feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         */
19403feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        public int scanType;
1941712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1942712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1943712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1944712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1945712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
19466259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
19476259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1948712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1949e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
19507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
195168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
19529bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
19539bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19549bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
19559bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
19569bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1957ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
19581bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
19591bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
19601bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
19611bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
19621bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
19631bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
19641bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
19651bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
19661bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
19676259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
19681bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
19691bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1970ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1971ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1972ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1973ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1974ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1975ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1976ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
19779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
19799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
19809bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
19819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
19829bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19839bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
19849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
19859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
19869bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
19879bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
19889bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
19899bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
19909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
199104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
1992dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
19939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
19949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19959bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
1996b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
199763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
199863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
199963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
200063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2001c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
200263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
200363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
200463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
200563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
200663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
200763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
200863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
200963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
201083a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
201163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
201263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
201363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2014b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
2015e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2016e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
20179bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
20189bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
20199bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20209bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
20219bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
20229bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
20239bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
20249bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
20259bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
2026063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
2027063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
2028063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
2029063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
2030063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
20319bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20329bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
203371af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
203471af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
203571af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
203671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
2037b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
2038b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2039b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
2040b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
2041b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
204252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2043b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
2044b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
2045b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2046b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
204752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startBgScan(
204852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanSettings settings, ScanEventHandler eventHandler) {
204952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startBgScan(ifaceName, settings, eventHandler);
20507f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
20517f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2052b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2053b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
205452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2055b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
205652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void stopBgScan(@NonNull String ifaceName) {
205752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.stopBgScan(ifaceName);
2058b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2059b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2060b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2061b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
206252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2063b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
206452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void pauseBgScan(@NonNull String ifaceName) {
206552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.pauseBgScan(ifaceName);
2066b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2067b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2068b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2069b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
207052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2071b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
207252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void restartBgScan(@NonNull String ifaceName) {
207352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.restartBgScan(ifaceName);
2074e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2075e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2076b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2077b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
207852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2079b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
208052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiScanner.ScanData[] getBgScanResults(@NonNull String ifaceName) {
208152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanResults(ifaceName);
2082e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2083e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
208452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
208552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Gets the latest link layer stats
208652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
208752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
208852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats(@NonNull String ifaceName) {
208952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(ifaceName);
20905c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
20915c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
2092b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2093b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
2094b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
209552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2096b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
2097b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
209852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int getSupportedFeatureSet(@NonNull String ifaceName) {
209952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getSupportedFeatureSet(ifaceName);
2100a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2101143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2102143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2103143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2104143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2105143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2106b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2107b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
2108b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2109b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
2110b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
2111b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
2112b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
211318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2114143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2115b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
2116143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2117143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2118b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2119b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
2120b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2121b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
2122b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
2123b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
212418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2125b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
2126143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2127042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
212868cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
212968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
213068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
2131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
213368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
213468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
2135b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
2136b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
213712cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2138939177ff615062ec826601d536466875d8457375xinhe
2139b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2140b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
2141b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
2142b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2143b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
2144b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
21456609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
21466609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2147b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
2149b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
2150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
2151b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
215252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2153b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
2154b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2155b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
215652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setScanningMacOui(@NonNull String ifaceName, byte[] oui) {
215752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setScanningMacOui(ifaceName, oui);
21586609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
21596609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2160b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2161b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
2162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2163b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
2164b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
2165d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2166d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2167b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2168b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
216952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2170b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
217152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ApfCapabilities getApfCapabilities(@NonNull String ifaceName) {
217252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getApfCapabilities(ifaceName);
2173d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2174d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2175b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2176b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
2177b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
217852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2179b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
2180b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2181b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
218252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean installPacketFilter(@NonNull String ifaceName, byte[] filter) {
218352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.installPacketFilter(ifaceName, filter);
2184d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2185d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2186b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2187b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
218852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2189b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
2190b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2191b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
219252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
219352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setCountryCodeHal(ifaceName, countryCode);
2194d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2195d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2196a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2197a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
2198a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
21990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
22000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2201a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2202a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2203b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2204b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
2205b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
2206b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2207b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
2208b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2209b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
221018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2211b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
221203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
221303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2214b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
2216b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2217b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
2218b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
2219b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
2220b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
2221b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
2222b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2223b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
222418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
222503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2226b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
2227b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
222803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
222903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2230b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
2232b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
2233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2234b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2235b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
223618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2237b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
223803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
223903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2240b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2241b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
2242b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
2243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
224518786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2246b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
2247b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2248b797893fc1966803d0c013faac42e6396a37a384xinhe
2249b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2250b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
2251b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2252b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2253b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
225418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2255b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
225603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
225703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2258b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2259b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
2260b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2261b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2262b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
226318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2264b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
226503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
226603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
22670bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
22680bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
22690bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
22700bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
22710bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
22720bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
22730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
22740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
22750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
22760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
227753f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
227853f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
227953f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
228053f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
228153f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
22820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
22830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
22840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
22850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
22860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
22870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
22880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
22890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
22900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2291b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2292b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
2293b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
229418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2295b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
229603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
229703ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2298b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
2300b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2301b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
2302b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2303b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
230418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2305b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
230603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2307127f7244183786e6ccae09e81eeccdac31973e69xinhe
2308b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2309b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
2310b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2311b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2312b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
231318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2314b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2315a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2316dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2317b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2318b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2319b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2320b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2321b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2322d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2323b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2324d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2325d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2326dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
232709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
232809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
232909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
233009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2331eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2332eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2333eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2334eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2335eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2336eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
233709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
233809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
233909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
234009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2341eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
234209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
234309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
234409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
234509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2346eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2347eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
234809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
234909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
235009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
23510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2352590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2353590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2354590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2355590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2356eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2357eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2358eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2359eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2360eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2361eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2362590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2363590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2364590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2365590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
23660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
23670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2368590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
23690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
23700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
23710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
23720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2373590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2374590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
23750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
23760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2377590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
23780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
23790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
23800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
23810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2382590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2383590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2384590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2385590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2386eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2387eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2388eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2389eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2390590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2391590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2392590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
23930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
23940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
23960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
23980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
23990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
24000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
24010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
24020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
24030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
24040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
24050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
24060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
24070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
24080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2409eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2410eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2411eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2412eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2413eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2414eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2415eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2416eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2417eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2418eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2419eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2420eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2421eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2422eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2423eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2424eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2425eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2426eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2427eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2428eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2429eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2430eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2431eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2432eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2433eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2434eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2435eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2436eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
243709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
243809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
243909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
244009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
244109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
244209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
244309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
244409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
244509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
244609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
24500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
24510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
24550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
24560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
24570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
24580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
24590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
24600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
24610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
24620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
24630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
24640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
24650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
24660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
24670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
24680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
24690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
24700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
24710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
24720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
24730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
24740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
24750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
24760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
24770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
24780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
24790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
248009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
248109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
248209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
248309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
248409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
248509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
248609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
248709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
248809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
248909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
24930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
24940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24950fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
24980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
24990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
25000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
25010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
25020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
25030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
25040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
25050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
25060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
25070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
25080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
25090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
25100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
25110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
25120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
25130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
25140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
25150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
25160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
25170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
25180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
25190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
25200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
25210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
25220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
25230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
25240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
252509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
252609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
25270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2529b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
253052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2531b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
25320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
253352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPktFateMonitoring(@NonNull String ifaceName) {
253452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startPktFateMonitoring(ifaceName);
25350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
25360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2539b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
254052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
25420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
254352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getTxPktFates(@NonNull String ifaceName, TxFateReport[] reportBufs) {
254452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getTxPktFates(ifaceName, reportBufs);
25450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
25460fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25470fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
25480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
254952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
25500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
255152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRxPktFates(@NonNull String ifaceName, RxFateReport[] reportBufs) {
255252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRxPktFates(ifaceName, reportBufs);
25530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
255409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
25555c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2556e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the tx packet counts for the interface.
2557e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2558e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface.
2559e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return tx packet counts
2560e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2561e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getTxPackets(@NonNull String ifaceName) {
2562e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getTxPackets(ifaceName);
2563e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2564e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2565e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2566e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the rx packet counts for the interface.
2567e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2568e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface
2569e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return rx packet counts
2570e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2571e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getRxPackets(@NonNull String ifaceName) {
2572e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getRxPackets(ifaceName);
2573e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2574e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2575e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
257852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2579b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2580ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param dstMac Destination MAC Address
2581ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param packet Raw packet contents to send.
2582ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param protocol The ethernet protocol type
2583b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2584b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2585b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2586ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold    public int startSendingOffloadedPacket(@NonNull String ifaceName, int slot,
2587ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold            byte[] dstMac, byte[] packet, int protocol, int period) {
2588ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        byte[] srcMac = NativeUtil.macAddressToByteArray(getMacAddress(ifaceName));
2589ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        return mWifiVendorHal.startSendingOffloadedPacket(
2590ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold                ifaceName, slot, srcMac, dstMac, packet, protocol, period);
2591c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2592c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2593b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
259652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2597b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2598b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2599b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
260052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopSendingOffloadedPacket(@NonNull String ifaceName, int slot) {
260152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(ifaceName, slot);
2602c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2603aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2604aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2605aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2606aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2607aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2608b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2610b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
261152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName        Name of the interface.
2612b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2613b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2614b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2615b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2616b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
261752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int startRssiMonitoring(
261852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, byte maxRssi, byte minRssi,
261952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            WifiRssiEventHandler rssiEventHandler) {
2620d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
262152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, maxRssi, minRssi, rssiEventHandler);
2622aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2623aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
262452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
262552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Stop RSSI monitoring on the currently connected access point.
262652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
262752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
262852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return 0 for success, -1 for failure
262952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
263052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopRssiMonitoring(@NonNull String ifaceName) {
263152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopRssiMonitoring(ifaceName);
2632aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
26335ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
26346bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
26356bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2636b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
26376bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
26386bf6986d359556010638dfae332b585162f06520Roshan Pius     */
26396bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
26416bf6986d359556010638dfae332b585162f06520Roshan Pius    }
26423dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2643b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2644b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
264652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2647b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2648b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
265052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureNeighborDiscoveryOffload(@NonNull String ifaceName, boolean enabled) {
265152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(ifaceName, enabled);
26523dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2653da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2654da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2655da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2656da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2657da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2658da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2659da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2660da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2661da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2662da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2663da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2664da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2665da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
266652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2667b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2668da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
266952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRoamingCapabilities(
267052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, RoamingCapabilities capabilities) {
267152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRoamingCapabilities(ifaceName, capabilities);
2672da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2673da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2674da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2675da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2676da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2677da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2678da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2679da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2680da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2681da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2682b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
268352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2684b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2685da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
268652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int enableFirmwareRoaming(@NonNull String ifaceName, int state) {
268752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.enableFirmwareRoaming(ifaceName, state);
2688da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2689da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2690da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2691da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2692da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2693da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2694da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2695da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2696da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2697da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2698da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2699da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
270052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2701da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
270252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureRoaming(@NonNull String ifaceName, RoamingConfig config) {
270352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, config);
2704da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2705da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2706374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2707374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
270852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2709374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
271052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean resetRoamingConfiguration(@NonNull String ifaceName) {
2711b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2712b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
271352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, new RoamingConfig());
2714b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2715b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2716ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2717b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2718ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2719b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2720b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2721ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2722ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2723b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2724ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2725ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2726b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2727b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2728ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2729ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2730b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2731b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2732ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2733ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2734b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2735b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2736b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2737b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2739b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2740b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2741b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2743b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2744b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2745b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2746b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2747b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2748b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2749b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2751b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2752b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2753b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2754b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2755b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2756b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2757b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2758b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2759b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2760b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2761520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2762b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2763374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2764da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2765155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2766