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;
77d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius    private final WifiMonitor mWifiMonitor;
784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private final INetworkManagementService mNwManagementService;
791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private final PropertyService mPropertyService;
80d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private final WifiMetrics mWifiMetrics;
81a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius    private boolean mVerboseLoggingEnabled = false;
82b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
8352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiNative(WifiVendorHal vendorHal,
84295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
85d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius                      WificondControl condControl, WifiMonitor wifiMonitor,
86d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius                      INetworkManagementService nwService,
87d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                      PropertyService propertyService, WifiMetrics wifiMetrics) {
88b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal = vendorHal;
89b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal = staIfaceHal;
90295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        mHostapdHal = hostapdHal;
91b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl = condControl;
92d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius        mWifiMonitor = wifiMonitor;
934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        mNwManagementService = nwService;
941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mPropertyService = propertyService;
95d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        mWifiMetrics = wifiMetrics;
96155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
97155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
98b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
99b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable verbose logging for all sub modules.
100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
101b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void enableVerboseLogging(int verbose) {
102a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mVerboseLoggingEnabled = verbose > 0 ? true : false;
103a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mWificondControl.enableVerboseLogging(mVerboseLoggingEnabled);
104a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mSupplicantStaIfaceHal.enableVerboseLogging(mVerboseLoggingEnabled);
105a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        mWifiVendorHal.enableVerboseLogging(mVerboseLoggingEnabled);
106ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
107ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
10898bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius    /********************************************************
10998bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     * Interface management related methods.
11098bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     ********************************************************/
111d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
112e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Meta-info about every iface that is active.
113e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
114e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class Iface {
115e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of ifaces possible */
116e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_AP = 0;
117e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_STA = 1;
118e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
119e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA})
120e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @Retention(RetentionPolicy.SOURCE)
121e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public @interface IfaceType{}
122e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
123e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Identifier allocated for the interface */
124e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final int id;
125e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of the iface: STA or AP */
126e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final @IfaceType int type;
127e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Name of the interface */
128e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public String name;
129a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        /** Is the interface up? This is used to mask up/down notifications to external clients. */
130a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        public boolean isUp;
131e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** External iface destroyed listener for the iface */
132e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public InterfaceCallback externalListener;
1334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Network observer registered for this interface */
1344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public NetworkObserverInternal networkObserver;
135e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
136e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        Iface(int id, @Iface.IfaceType int type) {
137e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.id = id;
138e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.type = type;
139e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
140a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius
141a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        @Override
142a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        public String toString() {
143a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            StringBuffer sb = new StringBuffer();
144a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            sb.append("Iface:")
145a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("{")
146a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Name=").append(name)
147a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append(",")
148a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Id=").append(id)
149a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append(",")
150a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("Type=").append(type == IFACE_TYPE_STA ? "STA" : "AP")
151a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                .append("}");
152a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            return sb.toString();
153a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius        }
154e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
155e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
156e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
157e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Iface Management entity. This class maintains list of all the active ifaces.
158e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
159e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class IfaceManager {
160e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Integer to allocate for the next iface being created */
161e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private int mNextId;
162e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Map of the id to the iface structure */
163e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private HashMap<Integer, Iface> mIfaces = new HashMap<>();
164e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
165e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Allocate a new iface for the given type */
166e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface allocateIface(@Iface.IfaceType  int type) {
167e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            Iface iface = new Iface(mNextId, type);
168e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mIfaces.put(mNextId, iface);
169e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mNextId++;
170e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return iface;
171e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
172e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
173e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Remove the iface using the provided id */
174e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface removeIface(int id) {
175e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.remove(id);
176e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
177e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
178e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided id */
179e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(int id) {
180e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.get(id);
181e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
182e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
183e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided name */
184e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(@NonNull String ifaceName) {
185e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
186e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (TextUtils.equals(iface.name, ifaceName)) {
187e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return iface;
188e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
189e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
190e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return null;
191e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
192e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
193e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Iterator to use for deleting all the ifaces while performing teardown on each of them */
194e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iterator<Integer> getIfaceIdIter() {
195e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.keySet().iterator();
196e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
197e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
198e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface active. */
199e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIface() {
200e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return !mIfaces.isEmpty();
201e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
202e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
203e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface of the given type active. */
204e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIfaceOfType(@Iface.IfaceType int type) {
205e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
206e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (iface.type == type) {
207e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return true;
208e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
209e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
210e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return false;
211e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
212e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
213b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        /** Checks if there are any iface of the given type active. */
214b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private Iface findAnyIfaceOfType(@Iface.IfaceType int type) {
215b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            for (Iface iface : mIfaces.values()) {
216b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                if (iface.type == type) {
217b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                    return iface;
218b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                }
219b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
220b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return null;
221b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
222b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
223e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any STA iface active. */
224e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyStaIface() {
225e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA);
226e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
227e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
228e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any AP iface active. */
229e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyApIface() {
230e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_AP);
231e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
232b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
233b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private String findAnyStaIfaceName() {
234b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_STA);
235b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            if (iface == null) {
236b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                return null;
237b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
238b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return iface.name;
239b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
2401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
241840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        private String findAnyApIfaceName() {
242840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_AP);
243840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            if (iface == null) {
244840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                return null;
245840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
246840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            return iface.name;
247840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
248840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
2491d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        /** Removes the existing iface that does not match the provided id. */
2501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        public Iface removeExistingIface(int newIfaceId) {
2511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iface removedIface = null;
2521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            // The number of ifaces in the database could be 1 existing & 1 new at the max.
2531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mIfaces.size() > 2) {
2541d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.wtf(TAG, "More than 1 existing interface found");
2551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iterator<Map.Entry<Integer, Iface>> iter = mIfaces.entrySet().iterator();
2571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            while (iter.hasNext()) {
2581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Map.Entry<Integer, Iface> entry = iter.next();
2591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (entry.getKey() != newIfaceId) {
2601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    removedIface = entry.getValue();
2611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    iter.remove();
2621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            return removedIface;
2651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
266e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
267e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
268e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private Object mLock = new Object();
269e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private final IfaceManager mIfaceMgr = new IfaceManager();
270e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private HashSet<StatusListener> mStatusListeners = new HashSet<>();
271e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
2724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no ifaces */
2734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startHal() {
2744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    if (!mWifiVendorHal.startVendorHal()) {
2781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        Log.e(TAG, "Failed to start vendor HAL");
2791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        return false;
2801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    }
2811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
2834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
2864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop HAL if there are no more ifaces */
2904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopHalAndWificondIfNecessary() {
2914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.tearDownInterfaces()) {
2941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to teardown ifaces from wificond");
2951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2971d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    mWifiVendorHal.stopVendorHal();
2981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring stop.");
3004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS = 100;
3064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_TIMES = 50;
3074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
3084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * This method is called to wait for establishing connection to wpa_supplicant.
3094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     *
3104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * @return true if connection is established, false otherwise.
3114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
3124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean waitForSupplicantConnection() {
3134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        // Start initialization if not already started.
3144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
3154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
3164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        boolean connected = false;
3194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        int connectTries = 0;
3204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
3214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Check if the initialization is complete.
3224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            connected = mSupplicantStaIfaceHal.isInitializationComplete();
3234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (connected) {
3244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                break;
3254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            try {
3274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
3284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } catch (InterruptedException ignore) {
3294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return connected;
3324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no STA ifaces */
3354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startSupplicant() {
3364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.enableSupplicant()) {
3391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to enable supplicant");
3404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!waitForSupplicantConnection()) {
3431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to connect to supplicant");
3444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
346d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                if (!mSupplicantStaIfaceHal.registerDeathHandler(
347d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                        new SupplicantDeathHandlerInternal())) {
3481d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to register supplicant death handler");
3494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
3534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop supplicant if there are no more STA ifaces */
3574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopSupplicantIfNecessary() {
3584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
3611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to deregister supplicant death handler");
3624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.disableSupplicant()) {
3641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to disable supplicant");
3654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
37111d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    private boolean registerNetworkObserver(NetworkObserverInternal observer) {
37211d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius        if (observer == null) return false;
3734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.registerObserver(observer);
3754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
38111d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    /** Helper method to unregister a network observer */
38211d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius    private boolean unregisterNetworkObserver(NetworkObserverInternal observer) {
38311d08f50a9fdae5a4962aa7cf3f06e2de095ba81Roshan Pius        if (observer == null) return false;
3844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.unregisterObserver(observer);
3864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown client iface and perform necessary cleanup */
3934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
3944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
395d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius            mWifiMonitor.stopMonitoring(iface.name);
3964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
397a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to unregister network observer on " + iface);
3984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
400a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in supplicant on " + iface);
4014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownClientInterface(iface.name)) {
403a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in wificond on " + iface);
4044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopSupplicantIfNecessary();
4064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown softAp iface and perform necessary cleanup */
4114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onSoftApInterfaceDestroyed(@NonNull Iface iface) {
4124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
414a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to unregister network observer on " + iface);
4154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
416295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mHostapdHal.removeAccessPoint(iface.name)) {
417a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to remove access point on " + iface);
418295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
41927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            if (!mHostapdHal.deregisterDeathHandler()) {
42027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.e(TAG, "Failed to deregister supplicant death handler");
42127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
422295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // TODO(b/71513606): Move this to a global operation.
423295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mWificondControl.stopHostapd(iface.name)) {
424a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to stop hostapd on " + iface);
4254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownSoftApInterface(iface.name)) {
427a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to teardown iface in wificond on " + iface);
4284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown iface and perform necessary cleanup */
4344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onInterfaceDestroyed(@NonNull Iface iface) {
4354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
4374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onClientInterfaceDestroyed(iface);
4384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
4394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onSoftApInterfaceDestroyed(iface);
4404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Invoke the external callback.
4424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener.onDestroyed(iface.name);
4434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Callback to be invoked by HalDeviceManager when an interface is destroyed.
4484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class InterfaceDestoyedListenerInternal
4504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            implements HalDeviceManager.InterfaceDestroyedListener {
4514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        InterfaceDestoyedListenerInternal(int ifaceId) {
4554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = ifaceId;
4564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDestroyed(@NonNull String ifaceName) {
4604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.removeIface(mInterfaceId);
4624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
463a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
464a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                        Log.v(TAG, "Received iface destroyed notification on an invalid iface="
465a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + ifaceName);
466a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
4674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
4684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onInterfaceDestroyed(iface);
470a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.i(TAG, "Successfully torn down " + iface);
4714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
475f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius    /**
476f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     * Helper method invoked to trigger the status changed callback after one of the native
477f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     * daemon's death.
478f0b59e444f685dda92df73d5e70fd44a21d72e3dRoshan Pius     */
479d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private void onNativeDaemonDeath() {
480d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        synchronized (mLock) {
481d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
482d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(false);
483d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
484d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
485d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(true);
486d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
487d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
488d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
489d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
4904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
491d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the Vendor HAL daemon.
4924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
493d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class VendorHalDeathHandlerInternal implements VendorHalDeathEventHandler {
4944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDeath() {
4964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
497d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Vendor HAL died. Cleaning up internal state.");
498d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
499d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumHalCrashes();
500d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
501d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
502d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
503d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
504d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
505d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the wificond daemon.
506d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
507d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class WificondDeathHandlerInternal implements WificondDeathEventHandler {
508d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
509d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
510d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
511d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wificond died. Cleaning up internal state.");
512d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
513d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWificondCrashes();
514d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
515d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
516d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
517d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
518d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
519d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the supplicant daemon.
520d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
521d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class SupplicantDeathHandlerInternal implements SupplicantDeathEventHandler {
522d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
523d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
524d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
525d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
526d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
527d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumSupplicantCrashes();
5284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
53327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     * Death handler for the hostapd daemon.
53427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     */
53527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    private class HostapdDeathHandlerInternal implements HostapdDeathEventHandler {
53627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        @Override
53727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        public void onDeath() {
53827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            synchronized (mLock) {
53927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.i(TAG, "hostapd died. Cleaning up internal state.");
54027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                onNativeDaemonDeath();
54127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                mWifiMetrics.incrementNumHostapdCrashes();
54227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
54327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
54427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    }
54527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius
546a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    /** Helper method invoked to handle interface change. */
547a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    private void onInterfaceStateChanged(Iface iface, boolean isUp) {
548a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        synchronized (mLock) {
549a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Mask multiple notifications with the same state.
550a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            if (isUp == iface.isUp) {
551a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                if (mVerboseLoggingEnabled) {
552a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    Log.v(TAG, "Interface status unchanged on " + iface + " from " + isUp
553a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                            + ", Ignoring...");
554a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                }
555a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                return;
556a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            }
557077310903b601b96c20a10f874aae7cf9af81b32Roshan Pius            Log.i(TAG, "Interface state changed on " + iface + ", isUp=" + isUp);
558a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            if (isUp) {
559a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                iface.externalListener.onUp(iface.name);
560a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            } else {
561a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                iface.externalListener.onDown(iface.name);
562a79e9c8ea6461b65cef7a8542af088b8f2945ea2Roshan Pius                if (iface.type == Iface.IFACE_TYPE_STA) {
563a79e9c8ea6461b65cef7a8542af088b8f2945ea2Roshan Pius                    mWifiMetrics.incrementNumClientInterfaceDown();
564a79e9c8ea6461b65cef7a8542af088b8f2945ea2Roshan Pius                } else if (iface.type == Iface.IFACE_TYPE_AP) {
565a79e9c8ea6461b65cef7a8542af088b8f2945ea2Roshan Pius                    mWifiMetrics.incrementNumSoftApInterfaceDown();
566a79e9c8ea6461b65cef7a8542af088b8f2945ea2Roshan Pius                }
567a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            }
568a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            iface.isUp = isUp;
569a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius        }
570a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius    }
571a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius
57227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    /**
5734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Network observer to use for all interface up/down notifications.
5744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
5754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class NetworkObserverInternal extends BaseNetworkObserver {
5764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
5774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
5784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        NetworkObserverInternal(int id) {
5804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = id;
5814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
583077310903b601b96c20a10f874aae7cf9af81b32Roshan Pius        // TODO(b/76219766): We may need to listen for link state changes in SoftAp mode.
584a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius        /**
585a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * Note: We should ideally listen to
586a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * {@link BaseNetworkObserver#interfaceStatusChanged(String, boolean)} here. But, that
587a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * callback is not working currently (broken in netd). So, instead listen to link state
588a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * change callbacks as triggers to query the real interface state. We should get rid of
589a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * this workaround if we get the |interfaceStatusChanged| callback to work in netd.
590a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * Also, this workaround will not detect an interface up event, if the link state is
591a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         * still down.
592a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius         */
5934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
594a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius        public void interfaceLinkStateChanged(String ifaceName, boolean unusedIsLinkUp) {
5954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
596a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                final Iface ifaceWithId = mIfaceMgr.getIface(mInterfaceId);
597a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                if (ifaceWithId == null) {
598a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
599a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius                        Log.v(TAG, "Received iface link up/down notification on an invalid iface="
600a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + mInterfaceId);
601a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
6024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
6034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
604a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                final Iface ifaceWithName = mIfaceMgr.getIface(ifaceName);
605a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                if (ifaceWithName == null || ifaceWithName != ifaceWithId) {
606a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    if (mVerboseLoggingEnabled) {
607a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius                        Log.v(TAG, "Received iface link up/down notification on an invalid iface="
608a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                                + ifaceName);
609a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                    }
610a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius                    return;
6114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
612a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius                onInterfaceStateChanged(ifaceWithName, isInterfaceUp(ifaceName));
6134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
6154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
6164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
61780512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius    /**
61880512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius     * Radio mode change handler for the Vendor HAL daemon.
61980512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius     */
62080512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius    private class VendorHalRadioModeChangeHandlerInternal
62180512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            implements VendorHalRadioModeChangeEventHandler {
62280512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        @Override
62380512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        public void onMcc(int band) {
62480512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            synchronized (mLock) {
62580512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                Log.i(TAG, "Device is in MCC mode now");
62680512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                mWifiMetrics.incrementNumRadioModeChangeToMcc();
62780512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            }
62880512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        }
62980512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        @Override
63080512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        public void onScc(int band) {
63180512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            synchronized (mLock) {
63280512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                Log.i(TAG, "Device is in SCC mode now");
63380512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                mWifiMetrics.incrementNumRadioModeChangeToScc();
63480512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            }
63580512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        }
63680512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        @Override
63780512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        public void onSbs(int band) {
63880512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            synchronized (mLock) {
63980512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                Log.i(TAG, "Device is in SBS mode now");
64080512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                mWifiMetrics.incrementNumRadioModeChangeToSbs();
64180512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            }
64280512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        }
64380512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        @Override
64480512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        public void onDbs() {
64580512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            synchronized (mLock) {
64680512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                Log.i(TAG, "Device is in DBS mode now");
64780512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                mWifiMetrics.incrementNumRadioModeChangeToDbs();
64880512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            }
64980512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius        }
65080512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius    }
65180512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius
6521d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
6531d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
6541d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // any active interface.
6551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String handleIfaceCreationWhenVendorHalNotSupported(@NonNull Iface newIface) {
656e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
657e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            Iface existingIface = mIfaceMgr.removeExistingIface(newIface.id);
658e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            if (existingIface != null) {
659e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius                onInterfaceDestroyed(existingIface);
660e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius                Log.i(TAG, "Successfully torn down " + existingIface);
661e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            }
662e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            // Return the interface name directly from the system property.
663e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mPropertyService.getString("wifi.interface", "wlan0");
6641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6681d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of STA iface.
6691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6727dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    private String createStaIface(@NonNull Iface iface, boolean lowPrioritySta) {
6731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6757dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                return mWifiVendorHal.createStaIface(lowPrioritySta,
6761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
6791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of AP iface.
6861d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6881d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createApIface(@NonNull Iface iface) {
6901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6911d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6921d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createApIface(
6931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
6941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
6961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
6971d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
7001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
7011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
7021d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
7031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // the interface.
7041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean handleIfaceRemovalWhenVendorHalNotSupported(@NonNull Iface iface) {
705e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
706e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            mIfaceMgr.removeIface(iface.id);
707e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            onInterfaceDestroyed(iface);
708e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            Log.i(TAG, "Successfully torn down " + iface);
709e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return true;
710e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
7111d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
7121d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
7131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
7141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
7151d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
7161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
7171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
7181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeStaIface(@NonNull Iface iface) {
7191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
7201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
7211d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeStaIface(iface.name);
7221d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
7231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeStaIface.");
7241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
7251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
7261d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
7271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
7281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
7291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
7301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
7311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
7321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeApIface(@NonNull Iface iface) {
7331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
7341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
7351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeApIface(iface.name);
7361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
7371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeApIface.");
7381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
7391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
7401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
7411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
7421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
743e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
744d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
745d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
746d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
747d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
748d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
7494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
750e59dd55ea7446c3325be8cde31fbeca1e14fb263Roshan Pius            if (!mWifiVendorHal.initialize(new VendorHalDeathHandlerInternal())) {
7511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize vendor HAL");
7524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
7534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
754ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius            if (!mWificondControl.initialize(new WificondDeathHandlerInternal())) {
7551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize wificond");
7564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
7574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
75880512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius            mWifiVendorHal.registerRadioModeChangeHandler(
75980512c6070e4c2c84a2d7c58ad56d4f1ca3258edRoshan Pius                    new VendorHalRadioModeChangeHandlerInternal());
7604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
7614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
762d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
763d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
764d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
765d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
766d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
767d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
768d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
769d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
770d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
771d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
772d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
773d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
774d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
775d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
776d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
777d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
778d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
779d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
780d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
781d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
782d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
783d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
784e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
785d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
786d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
787d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
788d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
789d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
790d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
791d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
792d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
793d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
794d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
795d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
796d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
797d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
798d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
799d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
800d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
801d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
802d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
803d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
804d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
805d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
806d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
807d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
808d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
809d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
810d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
811d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
812d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
813fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
814fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
815fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
816fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
817fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
818fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
819fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
820fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
821fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
822fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
823fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
824fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
825fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
826fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
827fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
828fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
829fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
8301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + re);
831fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
8321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + ie);
833fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
834fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
835fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
836d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
837d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
838d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
839d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
840d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
841d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
8427dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     * @param lowPrioritySta The requested STA has a low request priority (lower probability of
8437dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen     *                       getting created, higher probability of getting destroyed).
844d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
845d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
846d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
8477dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen    public String setupInterfaceForClientMode(boolean lowPrioritySta,
8487dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            @NonNull InterfaceCallback interfaceCallback) {
8494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
8511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
8525ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
8534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
8561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start supplicant");
8575ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
8584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
8614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new STA iface");
8634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8667dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen            iface.name = createStaIface(iface, lowPrioritySta);
8674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
868a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create STA iface in vendor HAL");
8694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
8705ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
8714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
874a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
8754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8765ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
8774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
880a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in supplicant on " + iface);
8814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8825ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
8834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
887a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
8884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
891d5a111a5d14d95288b6fc6986ef08ce22266c3fbRoshan Pius            mWifiMonitor.startMonitoring(iface.name);
892a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
893a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
894a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
895fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
896a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
8974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
899d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
900d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
901d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
902d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
903d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
904d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
905d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
906d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
907d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
908d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
909d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
910d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
9114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
9124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
9131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
9145ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHal();
9154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
9164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
9184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
9191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new AP iface");
9204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
9214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
9231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createApIface(iface);
9244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
925a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to create AP iface in vendor HAL");
9264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
9275ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHal();
9284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
9294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
931a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
9324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
9335ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToWificond();
9344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
9354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
9374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
938a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.e(TAG, "Failed to register network observer on " + iface);
9394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
9404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
9414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
942a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // Just to avoid any race conditions with interface state change callbacks,
943a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            // update the interface state before we exit.
944a2e62c7f5bfb411ccead4eab0d435d50fcdd4909Roshan Pius            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
945a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius            Log.i(TAG, "Successfully setup " + iface);
9464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
9474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
948d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
949d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
950d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
951a0897ed68d9f3e7f8227abb0b5ecc3f6c7bb6988Roshan Pius     *
9529c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
9539c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
9549c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
9559c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
9569c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
9579c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
9589c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
9599c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9609c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
9611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to get iface state on invalid iface=" + ifaceName);
9629c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9639c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9649c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
9659c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
9669c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
9679c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
9689c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9699c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
9709c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
9719c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
9729c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
9739c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
9749c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
9759c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
9769c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
977d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
978d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
979d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
980d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
981840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
982d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
983d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
984d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
985d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
9864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
9874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
9884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
9891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to teardown an invalid iface=" + ifaceName);
9904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
9914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
9924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
9934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
9944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
9951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeStaIface(iface)) {
9961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
9974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
9984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
9994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
10001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeApIface(iface)) {
10011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
10024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
10034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
10044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
10051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully initiated teardown for iface=" + ifaceName);
10064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
1007d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
1008d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
1009b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    /**
1010840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Teardown all the active interfaces.
1011840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1012840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This method tears down the associated interfaces from all the native daemons
1013840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
1014840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
1015840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
1016840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public void teardownAllInterfaces() {
1017840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        synchronized (mLock) {
1018840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
1019840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            while (ifaceIdIter.hasNext()) {
1020840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
10216a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                ifaceIdIter.remove();
10226a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius                onInterfaceDestroyed(iface);
1023a372690f3ed1d59b1e4769dac6bfcb1bd16db37cRoshan Pius                Log.i(TAG, "Successfully torn down " + iface);
1024840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
10256a14fff538a205a0a4fc8bbedce6068134fc424eRoshan Pius            Log.i(TAG, "Successfully torn down all ifaces");
1026840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
1027840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
1028840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
1029840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
1030b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Get name of the client interface.
1031b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
1032b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * This is mainly used by external modules that needs to perform some
1033b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * client operations on the STA interface.
1034b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
1035b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting STA + STA.
1036b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
1037b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * @return Interface name of any active client interface, null if no active client interface
1038b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * exist.
1039b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Return Values for the different scenarios are listed below:
1040b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * a) When there are no client interfaces, returns null.
1041b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * b) when there is 1 client interface, returns the name of that interface.
1042b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * c) When there are 2 or more client interface, returns the name of any client interface.
1043b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     */
1044b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    public String getClientInterfaceName() {
1045e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
1046e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mIfaceMgr.findAnyStaIfaceName();
1047e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
1048b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    }
1049b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
1050840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
1051840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Get name of the softap interface.
1052840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1053840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This is mainly used by external modules that needs to perform some
1054840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * operations on the AP interface.
1055840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1056840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting AP + AP.
1057840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
1058840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * @return Interface name of any active softap interface, null if no active softap interface
1059840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * exist.
1060840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Return Values for the different scenarios are listed below:
1061840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * a) When there are no softap interfaces, returns null.
1062840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * b) when there is 1 softap interface, returns the name of that interface.
1063840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * c) When there are 2 or more softap interface, returns the name of any softap interface.
1064840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
1065840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public String getSoftApInterfaceName() {
1066e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        synchronized (mLock) {
1067e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius            return mIfaceMgr.findAnyApIfaceName();
1068e4f3828b4430b45fcf5ac72b58b40ae6956c5a3cRoshan Pius        }
1069840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
1070840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
1071b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1072b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
1073b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1074b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1075b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
1076b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1077b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
1078b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
1079b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
1080b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
1081b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
1082b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
1083b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
1084b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1085b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1086b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1087b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
1088b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1089b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
1090b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
1091b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
1092b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
1093b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
1094b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
1095b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
109670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
109755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
109855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
109955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
110055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
110155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
110255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
110355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
110455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
110555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
110655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
110752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Request signal polling to wificond.
110852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
110952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
111052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an SignalPollResult object.
111152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
111252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
111352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public SignalPollResult signalPoll(@NonNull String ifaceName) {
111452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.signalPoll(ifaceName);
1115d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1116d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
1117d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
1118d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
111952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
112052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an TxPacketCounters object.
112152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
112252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
112352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
112452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getTxPacketCounters(ifaceName);
1125d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1126d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
112724250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
1128a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
1129a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
1130a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
1131a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1132a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
1133a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
1134a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
1135a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
1136a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
1137a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
1138a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
1139a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
1140a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
1141a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
1142a70c07d019065187112945c091fc2e924af18980Roshan Pius
1143a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
1144b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
114552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
11463feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * @param scanType Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
11473feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
1148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
1149b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
1150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
115124250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
115252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean scan(
11533feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            @NonNull String ifaceName, int scanType, Set<Integer> freqs,
11543feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            Set<String> hiddenNetworkSSIDs) {
11553feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        return mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
1156155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1157155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
115818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
1159b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
116052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1161b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
1162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
116318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
116452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getScanResults(@NonNull String ifaceName) {
116591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
116652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
116771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
116871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
116971c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
117071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
117152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
117271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
117371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
117471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
117552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getPnoScanResults(@NonNull String ifaceName) {
117652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getScanResults(ifaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
1177155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1178155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1179b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1180b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
118152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1182b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
1183b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
118418786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
118552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings) {
118652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.startPnoScan(ifaceName, pnoSettings);
1187155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1188155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1189b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1190b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
119152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1192b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
1193b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
119452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopPnoScan(@NonNull String ifaceName) {
119552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopPnoScan(ifaceName);
119618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
119718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1198045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1199045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
1200045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1201045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
1202045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
1203045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
1204045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
1205045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
12064de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh
12074de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh        /**
12084de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh         * Invoked when the channel switch event happens.
12094de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh         */
12104de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh        void onSoftApChannelSwitched(int frequency, int bandwidth);
1211045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1212045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1213295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS = 100;
1214295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_TIMES = 50;
1215295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    /**
1216295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * This method is called to wait for establishing connection to hostapd.
1217295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     *
1218295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * @return true if connection is established, false otherwise.
1219295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     */
1220295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private boolean waitForHostapdConnection() {
1221295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        // Start initialization if not already started.
1222295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.isInitializationStarted()
1223295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                && !mHostapdHal.initialize()) {
1224295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1225295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1226295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        boolean connected = false;
1227295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        int connectTries = 0;
1228295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {
1229295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // Check if the initialization is complete.
1230295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            connected = mHostapdHal.isInitializationComplete();
1231295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (connected) {
1232295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                break;
1233295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1234295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            try {
1235295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);
1236295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            } catch (InterruptedException ignore) {
1237295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1238295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1239295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return connected;
1240295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    }
1241295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius
1242045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1243045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
1244045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
124552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1246045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
1247045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
1248045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1249045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
125052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startSoftAp(
125152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {
125252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mWificondControl.startHostapd(ifaceName, listener)) {
1253295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to start hostapd");
12545ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius            mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
1255295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1256295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1257295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!waitForHostapdConnection()) {
1258295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to establish connection to hostapd");
12595ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius            mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
1260295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1261295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
126227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        if (!mHostapdHal.registerDeathHandler(new HostapdDeathHandlerInternal())) {
126327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            Log.e(TAG, "Failed to register hostapd death handler");
12645ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius            mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
126527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            return false;
126627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
126752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.addAccessPoint(ifaceName, config)) {
1268295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to add acccess point");
12695ed6b02a8435874d16a4ef3decc8df1b7e07f852Roshan Pius            mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
1270295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1271295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1272295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return true;
1273045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1274045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1275045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1276045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
1277045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
127852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1279045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1280045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
128152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopSoftAp(@NonNull String ifaceName) {
128252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.removeAccessPoint(ifaceName)) {
1283295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to remove access point");
1284295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
128552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopHostapd(ifaceName);
1286045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1287045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1288f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    /**
1289f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * Set MAC address of the given interface
1290f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param interfaceName Name of the interface
1291f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @param mac Mac address to change into
1292f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     * @return true on success
1293f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim     */
1294f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    public boolean setMacAddress(String interfaceName, MacAddress mac) {
1295f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim        // TODO(b/72459123): Suppress interface down/up events from this call
12961c7f0d2c83318cdd1c127a083362e91765c0d941Jong Wook Kim        return mWifiVendorHal.setMacAddress(interfaceName, mac);
1297f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim    }
1298f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim
1299b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
130002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Hostapd operations
130102367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     ********************************************************/
130202367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius
130302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    /**
130402367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Callback to notify hostapd death.
130502367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     */
130602367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    public interface HostapdDeathEventHandler {
130702367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        /**
130802367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         * Invoked when the supplicant dies.
130902367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         */
131002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        void onDeath();
1311045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1312045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1313b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1314b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
1315b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1316f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
1317f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
1318fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
1319fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
1320fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
1321fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
1322fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
1323fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
1324fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
1325fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
1326fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
1327fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
1328b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
1329782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
1330b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1331782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
1332b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
1333f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
1334e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
1335e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
133638a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
1337b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
1338b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
133952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1340b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
134138a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
134252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reconnect(@NonNull String ifaceName) {
134352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reconnect(ifaceName);
1344f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
13459d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
13469d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1347b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1348b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
134952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1350b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
13519d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
135252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reassociate(@NonNull String ifaceName) {
135352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reassociate(ifaceName);
1354155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1355155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1356155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1357b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1358b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
135952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1360b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1361b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
136252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean disconnect(@NonNull String ifaceName) {
136352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.disconnect(ifaceName);
136477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
136577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1366155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1367b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1368b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
136952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1370b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1371b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
137252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getMacAddress(@NonNull String ifaceName) {
137352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(ifaceName);
1374446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1375446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1376f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1377f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1378155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1379155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
138052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1381155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1382155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1383155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1384155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1385155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1386155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1389155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1390155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1391155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1392155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1393155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1394155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1395155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1396155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1397155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1400155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1401155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1402155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
140352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV4Packets(@NonNull String ifaceName) {
140452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1405b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
140652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
140752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1408155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1411155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
141252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1413155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1414155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
141552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV4Packets(@NonNull String ifaceName) {
141652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1417b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
141852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
141952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1420155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1421155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1422155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1423155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
142452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1425155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1426155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
142752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV6Packets(@NonNull String ifaceName) {
142852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1429b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
143052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
143152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1432155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1433155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1434155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1435155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
143652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1437155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1438155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
143952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV6Packets(@NonNull String ifaceName) {
144052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1441b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
144252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
144352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1444155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1445155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1446f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1447f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1448f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
14497ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
145052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Sets the bluetooth coexistence mode.
145152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
145252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
145352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
145452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
145552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
145652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return Whether the mode was successfully set.
145752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
145852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceMode(@NonNull String ifaceName, int mode) {
145952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(ifaceName, mode);
1460155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1461155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1462155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1463155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1464155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1465155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1466155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
146752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1468cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1469155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1470155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
147152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceScanMode(
147252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, boolean setCoexScanMode) {
1473b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
147452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, setCoexScanMode);
1475155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1476155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1477b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1478b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1479b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
148052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1481b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1482b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1483b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
148452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSuspendOptimizations(@NonNull String ifaceName, boolean enabled) {
148552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(ifaceName, enabled);
1486155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1487155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
14889153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1489b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1490b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
149152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1492b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1493b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
14949153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
149552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCode(@NonNull String ifaceName, String countryCode) {
149652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(ifaceName, countryCode);
149704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
149804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
149904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1500b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
150252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1503b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1504b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
150504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
150652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void startTdls(@NonNull String ifaceName, String macAddr, boolean enable) {
1507b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
150852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(ifaceName, macAddr);
150952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(ifaceName, macAddr);
1510155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
151152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(ifaceName, macAddr);
1512155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1513155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1514155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1515b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1516b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1517b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
151852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1519b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1520b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
152252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPbc(@NonNull String ifaceName, String bssid) {
152352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(ifaceName, bssid);
1524155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1525155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1526b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1527b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1528b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
152952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1530b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1531b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1532b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
153352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPinKeypad(@NonNull String ifaceName, String pin) {
153452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(ifaceName, pin);
1535155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1536155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1537b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1538b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1539b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
154052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1543b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
154452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String startWpsPinDisplay(@NonNull String ifaceName, String bssid) {
154552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(ifaceName, bssid);
1546155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1548b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1549b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1550b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
155152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1552b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1553b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1554b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
155552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setExternalSim(@NonNull String ifaceName, boolean external) {
155652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(ifaceName, external);
155733b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
155833b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1559b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1560b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1561b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1562b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1563b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1564b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1566b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1567b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy     * EAP-SIM Error Codes
1568b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy     */
1569b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy    public static final int EAP_SIM_VENDOR_SPECIFIC_CERT_EXPIRED = 16385;
1570b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy
1571b6a730ce63a9a864adaea6ba1bee827444be52a5Ahmed ElArabawy    /**
1572b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1573b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
157452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1578b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
157952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthResponse(
158052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, int id, String type, String response) {
1581b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1582b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
158352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1584b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1585b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
158652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1587b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1588b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
158952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
15905cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1591b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
15925cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
159333b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
159433b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1596b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1597b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
159852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1599b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1600b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
160152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthFailedResponse(@NonNull String ifaceName, int id) {
160252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(ifaceName);
160326eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
160426eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1605b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1606b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1607b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
160852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1610b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
161152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean umtsAuthFailedResponse(@NonNull String ifaceName, int id) {
161252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(ifaceName);
161326eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
161426eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1615b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1616b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1617b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
161852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
16194e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param unencryptedResponse String to send.
16204e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar     * @param encryptedResponse String to send.
1621b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1622b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
16234e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar    public boolean simIdentityResponse(@NonNull String ifaceName, int id,
16244e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                                       String unencryptedResponse, String encryptedResponse) {
16254e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(ifaceName,
16264e45fd9302b4ed943732ad85c0a88c7d7830be1dpkanwar                unencryptedResponse, encryptedResponse);
1627ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1628ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1630a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1631a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
163252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1633a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1634a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
163552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getEapAnonymousIdentity(@NonNull String ifaceName) {
163652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(ifaceName);
1637a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1638a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1639a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1641b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
164252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1643b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1644b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1646b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
164752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsRegistrar(@NonNull String ifaceName, String bssid, String pin) {
164852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(ifaceName, bssid, pin);
1649155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1650155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1651b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1652b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1653b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
165452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1655b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1656b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
165752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean cancelWps(@NonNull String ifaceName) {
165852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(ifaceName);
1659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1660155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1661b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1662b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1663b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
166452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1665b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1666b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1667b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
166852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceName(@NonNull String ifaceName, String name) {
166952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(ifaceName, name);
1670155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1671155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1672b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1673b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1674b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
167552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1676b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1677b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1678b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
167952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceType(@NonNull String ifaceName, String type) {
168052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(ifaceName, type);
1681155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1682155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1683b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1684b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1685b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1686b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1687b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1688b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
168952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfigMethods(@NonNull String ifaceName, String cfg) {
169052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(ifaceName, cfg);
1691155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1692155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1693b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1694b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1695b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
169652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1697b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1698b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1699b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
170052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setManufacturer(@NonNull String ifaceName, String value) {
170152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(ifaceName, value);
1702155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1703155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1704b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1705b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1706b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
170752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1708b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1709b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1710b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
171152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelName(@NonNull String ifaceName, String value) {
171252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(ifaceName, value);
1713155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1714155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1715b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1716b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1717b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
171852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1720b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1721b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
172252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelNumber(@NonNull String ifaceName, String value) {
172352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(ifaceName, value);
1724155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1726b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1727b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1728b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
172952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1730b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1731b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1732b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
173352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSerialNumber(@NonNull String ifaceName, String value) {
173452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(ifaceName, value);
1735155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1736155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1737b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1738b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1739b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
174052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1741b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
174352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void setPowerSave(@NonNull String ifaceName, boolean enabled) {
174452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(ifaceName, enabled);
1745155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1746155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1747b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1748b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1749b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1751b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1752b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1753b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1754b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1755b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1756155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1757155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1758155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
17593e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
17603e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
176152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
17623e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
17633e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
17643e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
176552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean enableStaAutoReconnect(@NonNull String ifaceName, boolean enable) {
176652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(ifaceName, enable);
17673e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
17683e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
17693e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1770b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1771b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
177252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1773b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1774b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1775b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1776b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1777155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
177852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean migrateNetworksFromSupplicant(
177952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, Map<String, WifiConfiguration> configs,
178052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            SparseArray<Map<String, String>> networkExtras) {
178152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(ifaceName, configs, networkExtras);
1782155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1783155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1784b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1785b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1786b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1787c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1788c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1789c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1790c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1791c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1792c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1793b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
179452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1795b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1796b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1797b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
179852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1799c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
180052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
180152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
1802155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1803155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1804b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1805b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1806b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1807b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1808c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1809c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1810b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1811c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1812c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1813b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
181452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1815b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1816b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1817b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
181852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean roamToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1819c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
182052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
182152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(ifaceName, configuration);
1822155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1823155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1824b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1825b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1826b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
182752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1828b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1829b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
183052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean removeAllNetworks(@NonNull String ifaceName) {
183152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(ifaceName);
1832155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1833155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1834b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1835b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1836b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
183752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1838b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1839b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
184052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfiguredNetworkBSSID(@NonNull String ifaceName, String bssid) {
184152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(ifaceName, bssid);
1842155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1843155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1844b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1845b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1846b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
184752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1848b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1849b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1850b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1851b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1852b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
185352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestAnqp(
185452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, String bssid, Set<Integer> anqpIds,
185552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            Set<Integer> hs20Subtypes) {
1856b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1857b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
18581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for ANQP request.");
1859155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1860155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1861b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1862b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1863b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
186461233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1867b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
186852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, bssid, anqpIdList, hs20SubtypeList);
1869155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1870155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1871b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1872b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
187352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
187452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1875b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1876b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1877b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1878b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
187952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestIcon(@NonNull String ifaceName, String  bssid, String fileName) {
1880b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
18811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for Icon request.");
188261233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1883155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
188452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(ifaceName, bssid, fileName);
1885155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1886155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1887b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1888b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1889b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
189052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1891b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1892b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
189352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken(@NonNull String ifaceName) {
189452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(ifaceName);
1895155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1896403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1897403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1898403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1899403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
190052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1901403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1902403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
190352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
190452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(ifaceName, networkId);
1905403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1906403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1907b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1908b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1909b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1910af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1911af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1912af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1913af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1914af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1915af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1916af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1917af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1918af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1919b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1920d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1921f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius     * Callback to notify when vendor HAL detects that a change in radio mode.
1922f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius     */
1923f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius    public interface VendorHalRadioModeChangeEventHandler {
1924f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        /**
1925f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * Invoked when the vendor HAL detects a change to MCC mode.
1926f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * MCC (Multi channel concurrency) = Multiple interfaces are active on the same band,
1927f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * different channels, same radios.
1928f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *
1929f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * @param band Band on which MCC is detected (specified by one of the
1930f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *             WifiScanner.WIFI_BAND_* constants)
1931f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         */
1932f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        void onMcc(int band);
1933f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        /**
1934f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * Invoked when the vendor HAL detects a change to SCC mode.
1935f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * SCC (Single channel concurrency) = Multiple interfaces are active on the same band, same
1936f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * channels, same radios.
1937f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *
1938f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * @param band Band on which SCC is detected (specified by one of the
1939f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *             WifiScanner.WIFI_BAND_* constants)
1940f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         */
1941f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        void onScc(int band);
1942f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        /**
1943f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * Invoked when the vendor HAL detects a change to SBS mode.
1944f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * SBS (Single Band Simultaneous) = Multiple interfaces are active on the same band,
1945f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * different channels, different radios.
1946f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *
1947f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * @param band Band on which SBS is detected (specified by one of the
1948f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         *             WifiScanner.WIFI_BAND_* constants)
1949f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         */
1950f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        void onSbs(int band);
1951f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        /**
1952f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * Invoked when the vendor HAL detects a change to DBS mode.
1953f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * DBS (Dual Band Simultaneous) = Multiple interfaces are active on the different bands,
1954f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         * different channels, different radios.
1955f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius         */
1956f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius        void onDbs();
1957f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius    }
1958f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius
1959f5749a73fe63a3e01db62a9752be365fb40ec633Roshan Pius    /**
1960b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1961b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
196218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1963b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
19647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
19657f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1966062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1967e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1968297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1969e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1970e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1971e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1972297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1973e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1974e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1975b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1976b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1977b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
197852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1979b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1980b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1981b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
198252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getBgScanCapabilities(
198352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanCapabilities capabilities) {
198452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanCapabilities(ifaceName, capabilities);
1985e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1986e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1987e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1988712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1989712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1990712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
19917f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
19927f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1993e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1994712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1995712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1996712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1997712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1998712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1999712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
2000712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
2001712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
2002e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
20037f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
20046259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
20056259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
20066259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
20076259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
20086259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
20096259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
20106259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
20116259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
20126259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
20136259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
20146259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
20156259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
20166259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
20176259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
20186259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
20196259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
2020ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
2021ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
2022ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
2023ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
2024ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
20256259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
20266259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
20273feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_LATENCY = 0;
20283feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_POWER = 1;
20293feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
20303feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius
2031e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
20323feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        /**
20333feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
20343feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
20353feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         */
20363feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        public int scanType;
2037712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
2038712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
2039712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
2040712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
2041712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
20426259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
20436259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
2044712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
2045e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
20467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
204768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
20489bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
20499bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20509bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
20519bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
20529bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
2053ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
20541bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
20551bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
20561bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
20571bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
20581bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
20591bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
20601bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
20611bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
20621bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
20636259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
20641bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
20651bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
2066ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
2067ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
2068ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
2069ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
2070ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
2071ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
2072ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
20739bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20749bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
20759bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
20769bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
20779bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
20789bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
20799bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
20809bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
20819bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
20829bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
20839bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
20849bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
20859bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
20869bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
208704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
2088dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
20899bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
20909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
20919bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
2092b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
209363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
209463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
209563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
209663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2097c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
209863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
209963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
210063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
210163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
210263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
210363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
210463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
210563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
210683a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
210763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
210863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
210963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
2110b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
2111e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2112e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
21139bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
21149bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
21159bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
21169bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
21179bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
21189bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
21199bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
21209bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
21219bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
2122063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
2123063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
2124063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
2125063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
2126063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
21279bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
21289bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
212971af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
213071af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
213171af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
213271af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
2133b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
2134b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2135b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
2136b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
2137b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
213852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2139b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
2140b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
2141b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2142b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
214352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startBgScan(
214452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanSettings settings, ScanEventHandler eventHandler) {
214552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startBgScan(ifaceName, settings, eventHandler);
21467f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
21477f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
2148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2149b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
215052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2151b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
215252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void stopBgScan(@NonNull String ifaceName) {
215352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.stopBgScan(ifaceName);
2154b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2155b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2156b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2157b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
215852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2159b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
216052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void pauseBgScan(@NonNull String ifaceName) {
216152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.pauseBgScan(ifaceName);
2162b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
2163b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
2164b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2165b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
216652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2167b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
216852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void restartBgScan(@NonNull String ifaceName) {
216952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.restartBgScan(ifaceName);
2170e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2171e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
2172b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2173b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
217452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2175b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
217652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiScanner.ScanData[] getBgScanResults(@NonNull String ifaceName) {
217752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanResults(ifaceName);
2178e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
2179e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
218052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
218152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Gets the latest link layer stats
218252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
218352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
218452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats(@NonNull String ifaceName) {
218552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(ifaceName);
21865c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
21875c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
2188b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2189b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
2190b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
219152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2192b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
2193b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
219452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int getSupportedFeatureSet(@NonNull String ifaceName) {
219552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getSupportedFeatureSet(ifaceName);
2196a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2197143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2198143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2199143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2200143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2201143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2202b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2203b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
2204b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2205b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
2206b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
2207b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
2208b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
220918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2210143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2211b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
2212143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2213143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2214b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
2216b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2217b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
2218b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
2219b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
222018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2221b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
2222143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2223042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
222468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
222568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
222668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
2227b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2228b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
222968cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
223068cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
2231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
2232b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
223312cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2234939177ff615062ec826601d536466875d8457375xinhe
2235b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2236b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
2237b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
2238b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2239b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
2240b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
22416609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
22426609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2243b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2244b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
2245b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
2246b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
2247b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
224852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2249b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
2250b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2251b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
225252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setScanningMacOui(@NonNull String ifaceName, byte[] oui) {
225352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setScanningMacOui(ifaceName, oui);
22546609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
22556609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2256b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2257b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
2258b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2259b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
2260b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
2261d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2262d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2263b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2264b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
226552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2266b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
226752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ApfCapabilities getApfCapabilities(@NonNull String ifaceName) {
226852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getApfCapabilities(ifaceName);
2269d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2270d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2271b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2272b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
2273b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2274e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     * @param ifaceName Name of the interface
2275b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
2276b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2277b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
227852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean installPacketFilter(@NonNull String ifaceName, byte[] filter) {
227952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.installPacketFilter(ifaceName, filter);
2280d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2281d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2282b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2283e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     * Reads the APF program and data buffer for this iface.
2284e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     *
2285e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     * @param ifaceName Name of the interface
2286e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     * @return the buffer returned by the driver, or null in case of an error
2287e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti     */
2288e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti    public byte[] readPacketFilter(@NonNull String ifaceName) {
2289e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti        return mWifiVendorHal.readPacketFilter(ifaceName);
2290e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti    }
2291e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti
2292e25d3edec10f7b9cd60c291808f760a490b7d31dBernie Innocenti    /**
2293b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
229452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2295b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
2296b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2297b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
229852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
229952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setCountryCodeHal(ifaceName, countryCode);
2300d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2301d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2302a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2303a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
2304a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
23050bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
23060bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2307a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2308a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2309b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2310b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
2311b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
2312b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2313b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
2314b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2315b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
231618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2317b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
231803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
231903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2320b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2321b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
2322b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2323b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
2324b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
2325b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
2326b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
2327b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
2328b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2329b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
233018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
233103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2332b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
2333b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
233403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
233503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2336b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2337b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
2338b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
2339b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2340b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2341b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
234218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2343b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
234403ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
234503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2346b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2347b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
2348b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
2349b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2350b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
235118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2352b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
2353b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2354b797893fc1966803d0c013faac42e6396a37a384xinhe
2355b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2356b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
2357b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2358b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2359b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
236018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2361b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
236203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
236303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2364b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2365b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
2366b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2367b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2368b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
236918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2370b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
237103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
237203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
23730bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
23740bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
23750bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
23760bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
23770bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
23780bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
23790bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
23800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
23810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
23820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
238353f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
238453f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
238553f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
238653f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
238753f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
23880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
23890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
23900bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
23910bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
23920bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
23930bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
23940bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
23950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
23960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2397b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2398b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
2399b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
240018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2401b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
240203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
240303ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2405b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
2406b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2407b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
2408b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2409b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
241018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2411b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
241203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2413127f7244183786e6ccae09e81eeccdac31973e69xinhe
2414b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2415b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
2416b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2417b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2418b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
241918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2420b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2421a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2422dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2423b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2425b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2426b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2427b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2428d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2429b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2430d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2431d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2432dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
243309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
243409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
243509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
243609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2437eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2438eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2439eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2440eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2441eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2442eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
244309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
244409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
244509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
244609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2447eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
244809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
244909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
245009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
245109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2452eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2453eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
245409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
245509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
245609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2458590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2459590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2460590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2461590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2462eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2463eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2464eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2465eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2466eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2467eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2468590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2469590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2470590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2471590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
24720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
24730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2474590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
24750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
24760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
24770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
24780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2479590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2480590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
24810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
24820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2483590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
24840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
24850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
24860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2488590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2489590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2490590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2491590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2492eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2493eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2494eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2495eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2496590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2497590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2498590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
24990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
25000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
25020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
25040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
25050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
25060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
25070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
25080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
25090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
25100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
25110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
25120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
25130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
25140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2515eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2516eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2517eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2518eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2519eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2520eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2521eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2522eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2523eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2524eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2525eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2526eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2527eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2528eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2529eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2530eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2531eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2532eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2533eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2534eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2535eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2536eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2537eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2538eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2539eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2540eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2541eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2542eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
254309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
254409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
254509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
254609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
254709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
254809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
254909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
255009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
255109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
255209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
25530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
25550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
25560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
25570fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
25580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
25600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
25610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
25620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
25630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
25640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
25650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
25660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
25670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
25680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
25690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
25700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
25710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
25720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
25730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
25740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
25750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
25760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
25770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
25780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
25790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
25800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
25810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
25820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
25830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
25840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
25850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
258609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
258709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
258809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
258909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
259009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
259109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
259209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
259309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
259409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
259509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
25960fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
25970fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
25980fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
25990fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
26000fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
26010fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
26020fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
26030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
26040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
26050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
26060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
26070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
26080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
26090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
26100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
26110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
26120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
26130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
26140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
26150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
26160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
26170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
26180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
26190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
26200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
26210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
26220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
26230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
26240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
26250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
26260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
26270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
26280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
26290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
26300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
263109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
263209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
26330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
26340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2635b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
263652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2637b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
26380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
263952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPktFateMonitoring(@NonNull String ifaceName) {
264052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startPktFateMonitoring(ifaceName);
26410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
26420fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
26430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
26440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
264652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2647b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
26480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
264952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getTxPktFates(@NonNull String ifaceName, TxFateReport[] reportBufs) {
265052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getTxPktFates(ifaceName, reportBufs);
26510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
26520fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
26530fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
26540fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
265552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
26560fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
265752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRxPktFates(@NonNull String ifaceName, RxFateReport[] reportBufs) {
265852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRxPktFates(ifaceName, reportBufs);
26590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
266009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
26615c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2662e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the tx packet counts for the interface.
2663e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2664e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface.
2665e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return tx packet counts
2666e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2667e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getTxPackets(@NonNull String ifaceName) {
2668e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getTxPackets(ifaceName);
2669e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2670e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2671e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2672e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * Get the rx packet counts for the interface.
2673e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     *
2674e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @param ifaceName Name of the interface
2675e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     * @return rx packet counts
2676e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park     */
2677e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    public long getRxPackets(@NonNull String ifaceName) {
2678e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park        return TrafficStats.getRxPackets(ifaceName);
2679e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    }
2680e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park
2681e4334721104f3fa6df8886f5f46e43e0317a8dd2Ecco Park    /**
2682b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2683b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
268452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2685b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2686ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param dstMac Destination MAC Address
2687ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param packet Raw packet contents to send.
2688ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param protocol The ethernet protocol type
2689b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2690b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2691b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2692ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold    public int startSendingOffloadedPacket(@NonNull String ifaceName, int slot,
2693ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold            byte[] dstMac, byte[] packet, int protocol, int period) {
2694ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        byte[] srcMac = NativeUtil.macAddressToByteArray(getMacAddress(ifaceName));
2695ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        return mWifiVendorHal.startSendingOffloadedPacket(
2696ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold                ifaceName, slot, srcMac, dstMac, packet, protocol, period);
2697c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2698c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2699b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2700b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2701b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
270252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2703b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2704b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2705b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
270652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopSendingOffloadedPacket(@NonNull String ifaceName, int slot) {
270752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(ifaceName, slot);
2708c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2709aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2710aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2711aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2712aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2713aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2714b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2715b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2716b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
271752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName        Name of the interface.
2718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2720b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2721b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2722b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
272352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int startRssiMonitoring(
272452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, byte maxRssi, byte minRssi,
272552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            WifiRssiEventHandler rssiEventHandler) {
2726d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
272752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, maxRssi, minRssi, rssiEventHandler);
2728aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2729aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
273052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
273152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Stop RSSI monitoring on the currently connected access point.
273252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
273352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
273452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return 0 for success, -1 for failure
273552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
273652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopRssiMonitoring(@NonNull String ifaceName) {
273752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopRssiMonitoring(ifaceName);
2738aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
27395ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
27406bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
27416bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2742b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
27436bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
27446bf6986d359556010638dfae332b585162f06520Roshan Pius     */
27456bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2746b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
27476bf6986d359556010638dfae332b585162f06520Roshan Pius    }
27483dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2749b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2750b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2751b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
275252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2753b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2754b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2755b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
275652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureNeighborDiscoveryOffload(@NonNull String ifaceName, boolean enabled) {
275752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(ifaceName, enabled);
27583dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2759da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2760da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2761da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2762da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2763da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2764da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2765da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2766da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2767da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2768da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2769da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2770da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2771da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
277252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2773b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2774da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
277552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRoamingCapabilities(
277652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, RoamingCapabilities capabilities) {
277752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRoamingCapabilities(ifaceName, capabilities);
2778da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2779da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2780da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2781da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2782da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2783da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2784da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2785da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2786da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2787da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2788b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
278952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2790b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2791da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
279252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int enableFirmwareRoaming(@NonNull String ifaceName, int state) {
279352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.enableFirmwareRoaming(ifaceName, state);
2794da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2795da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2796da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2797da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2798da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2799da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2800da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2801da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2802da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2803da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2804da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2805da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
280652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2807da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
280852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureRoaming(@NonNull String ifaceName, RoamingConfig config) {
280952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, config);
2810da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2811da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2812374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2813374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
281452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2815374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
281652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean resetRoamingConfiguration(@NonNull String ifaceName) {
2817b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2818b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
281952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, new RoamingConfig());
2820b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2821b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2822ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2823b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2824ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2825b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2826b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2827ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2828ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2829b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2830ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2831ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2832b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2833b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2834ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2835ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2836b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2837b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2838ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2839ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2840b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2841b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2842b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2843b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2844b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2845b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2846b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2847b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2848b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2849b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2850b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2851b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2852b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2853b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2854b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2855b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2856b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2857b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2858b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2859b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2860b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2861b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2862b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2863b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2864b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2865b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2866b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2867520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2868b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2869374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2870da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2871155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2872