WifiNative.java revision ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4
1155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/*
2155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Copyright (C) 2008 The Android Open Source Project
3155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
4155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Licensed under the Apache License, Version 2.0 (the "License");
5155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * you may not use this file except in compliance with the License.
6155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * You may obtain a copy of the License at
7155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
8155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *      http://www.apache.org/licenses/LICENSE-2.0
9155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
10155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Unless required by applicable law or agreed to in writing, software
11155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * distributed under the License is distributed on an "AS IS" BASIS,
12155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * See the License for the specific language governing permissions and
14155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * limitations under the License.
15155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
16155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
17155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepackage com.android.server.wifi;
18155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
19e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport android.annotation.IntDef;
20c7685b40d77b12820c5b04013592834025086cefRoshan Piusimport android.annotation.NonNull;
2168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.annotation.Nullable;
229c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Piusimport android.net.InterfaceConfiguration;
23e1dab7a2e3ab5911f812a302b4beed1f6eb5aba7Paul Jensenimport android.net.apf.ApfCapabilities;
24143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpandeimport android.net.wifi.RttManager;
2568cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wangimport android.net.wifi.RttManager.ResponderConfig;
26e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.ScanResult;
27dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalleimport android.net.wifi.WifiConfiguration;
28e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapndeimport android.net.wifi.WifiScanner;
292a6d76f0899289cd3b96e3428f02076fdbc0363eMitchell Willsimport android.net.wifi.WifiWakeReasonAndCounts;
304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport android.os.INetworkManagementService;
314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport android.os.RemoteException;
32f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalleimport android.os.SystemClock;
33e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport android.text.TextUtils;
34155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport android.util.Log;
35a26a8b33616c94859ba33f33403794cf636baa54Roshan Piusimport android.util.SparseArray;
36fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
3709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawalimport com.android.internal.annotations.Immutable;
380fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport com.android.internal.util.HexDump;
394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Piusimport com.android.server.net.BaseNetworkObserver;
40590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tanimport com.android.server.wifi.util.FrameParser;
41ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Haroldimport com.android.server.wifi.util.NativeUtil;
42fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowski
430fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.PrintWriter;
440fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawalimport java.io.StringWriter;
45e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.Retention;
46e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.lang.annotation.RetentionPolicy;
475cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.ByteBuffer;
485cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.CharBuffer;
495cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharacterCodingException;
505cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.CharsetDecoder;
515cfd8d8b9f241dcad874125a1b5538ee0d6860fexinheimport java.nio.charset.StandardCharsets;
52eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.text.SimpleDateFormat;
53155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandeimport java.util.ArrayList;
54eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.Date;
55e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashMap;
56e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.HashSet;
57e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Piusimport java.util.Iterator;
58fbb081b7c28c18f0644701061a1ab38a4627db27Bartosz Fabianowskiimport java.util.Map;
591bf983a4211f547593a60523e43112ecdb5c8997Roshan Piusimport java.util.Objects;
609ec71f6499e0e3d6f52310a41ff4a59d2fa4f8b2Mitchell Willsimport java.util.Set;
61eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawalimport java.util.TimeZone;
6218786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
63155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande/**
64155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * Native calls for bring up/shut down of the supplicant daemon and for
65155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * sending requests to the supplicant daemon
66155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande *
67155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande * {@hide}
68155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande */
69155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpandepublic class WifiNative {
701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private static final String TAG = "WifiNative";
71b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
72295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private final HostapdHal mHostapdHal;
73b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WifiVendorHal mWifiVendorHal;
74b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private final WificondControl mWificondControl;
754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private final INetworkManagementService mNwManagementService;
761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private final PropertyService mPropertyService;
77d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private final WifiMetrics mWifiMetrics;
78b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // TODO(b/69426063): Remove interfaceName from constructor once WifiStateMachine switches over
804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    // to the new interface management methods.
8152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiNative(WifiVendorHal vendorHal,
82295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      SupplicantStaIfaceHal staIfaceHal, HostapdHal hostapdHal,
83295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                      WificondControl condControl, INetworkManagementService nwService,
84d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                      PropertyService propertyService, WifiMetrics wifiMetrics) {
85b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal = vendorHal;
86b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal = staIfaceHal;
87295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        mHostapdHal = hostapdHal;
88b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl = condControl;
894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        mNwManagementService = nwService;
901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mPropertyService = propertyService;
91d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        mWifiMetrics = wifiMetrics;
92155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
93155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
94b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
95b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable verbose logging for all sub modules.
96b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
97b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void enableVerboseLogging(int verbose) {
98b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
99b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        mWifiVendorHal.enableVerboseLogging(verbose > 0);
101ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle    }
102ed9938883ae2dade81c8be6cd6ceaef3febd5239vandwalle
10398bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius    /********************************************************
10498bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     * Interface management related methods.
10598bdf92ffcda361a6e1465cd0e606c6746d0e506Roshan Pius     ********************************************************/
106d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
107e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Meta-info about every iface that is active.
108e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
109e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class Iface {
110e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of ifaces possible */
111e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_AP = 0;
112e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public static final int IFACE_TYPE_STA = 1;
113e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
114e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @IntDef({IFACE_TYPE_AP, IFACE_TYPE_STA})
115e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        @Retention(RetentionPolicy.SOURCE)
116e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public @interface IfaceType{}
117e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
118e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Identifier allocated for the interface */
119e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final int id;
120e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Type of the iface: STA or AP */
121e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public final @IfaceType int type;
122e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Name of the interface */
123e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public String name;
124e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** External iface destroyed listener for the iface */
125e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        public InterfaceCallback externalListener;
1264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Network observer registered for this interface */
1274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public NetworkObserverInternal networkObserver;
128e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
129e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        Iface(int id, @Iface.IfaceType int type) {
130e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.id = id;
131e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            this.type = type;
132e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
133e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
134e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
135e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
136e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     * Iface Management entity. This class maintains list of all the active ifaces.
137e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius     */
138e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private static class IfaceManager {
139e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Integer to allocate for the next iface being created */
140e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private int mNextId;
141e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Map of the id to the iface structure */
142e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private HashMap<Integer, Iface> mIfaces = new HashMap<>();
143e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
144e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Allocate a new iface for the given type */
145e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface allocateIface(@Iface.IfaceType  int type) {
146e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            Iface iface = new Iface(mNextId, type);
147e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mIfaces.put(mNextId, iface);
148e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            mNextId++;
149e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return iface;
150e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
151e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
152e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Remove the iface using the provided id */
153e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface removeIface(int id) {
154e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.remove(id);
155e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
156e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
157e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided id */
158e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(int id) {
159e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.get(id);
160e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
161e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
162e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Lookup the iface using the provided name */
163e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iface getIface(@NonNull String ifaceName) {
164e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
165e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (TextUtils.equals(iface.name, ifaceName)) {
166e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return iface;
167e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
168e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
169e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return null;
170e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
171e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
172e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Iterator to use for deleting all the ifaces while performing teardown on each of them */
173e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private Iterator<Integer> getIfaceIdIter() {
174e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return mIfaces.keySet().iterator();
175e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
176e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
177e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface active. */
178e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIface() {
179e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return !mIfaces.isEmpty();
180e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
181e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
182e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any iface of the given type active. */
183e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyIfaceOfType(@Iface.IfaceType int type) {
184e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            for (Iface iface : mIfaces.values()) {
185e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                if (iface.type == type) {
186e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                    return true;
187e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius                }
188e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            }
189e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return false;
190e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
191e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
192b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        /** Checks if there are any iface of the given type active. */
193b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private Iface findAnyIfaceOfType(@Iface.IfaceType int type) {
194b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            for (Iface iface : mIfaces.values()) {
195b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                if (iface.type == type) {
196b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                    return iface;
197b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                }
198b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
199b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return null;
200b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
201b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
202e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any STA iface active. */
203e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyStaIface() {
204e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_STA);
205e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
206e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
207e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        /** Checks if there are any AP iface active. */
208e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        private boolean hasAnyApIface() {
209e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius            return hasAnyIfaceOfType(Iface.IFACE_TYPE_AP);
210e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        }
211b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
212b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        private String findAnyStaIfaceName() {
213b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_STA);
214b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            if (iface == null) {
215b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius                return null;
216b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            }
217b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius            return iface.name;
218b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        }
2191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
220840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        private String findAnyApIfaceName() {
221840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iface iface = findAnyIfaceOfType(Iface.IFACE_TYPE_AP);
222840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            if (iface == null) {
223840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                return null;
224840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
225840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            return iface.name;
226840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
227840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
2281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        /** Removes the existing iface that does not match the provided id. */
2291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        public Iface removeExistingIface(int newIfaceId) {
2301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iface removedIface = null;
2311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            // The number of ifaces in the database could be 1 existing & 1 new at the max.
2321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mIfaces.size() > 2) {
2331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.wtf(TAG, "More than 1 existing interface found");
2341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Iterator<Map.Entry<Integer, Iface>> iter = mIfaces.entrySet().iterator();
2361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            while (iter.hasNext()) {
2371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Map.Entry<Integer, Iface> entry = iter.next();
2381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (entry.getKey() != newIfaceId) {
2391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    removedIface = entry.getValue();
2401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    iter.remove();
2411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
2431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            return removedIface;
2441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
245e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    }
246e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
247e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private Object mLock = new Object();
248e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private final IfaceManager mIfaceMgr = new IfaceManager();
249e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    private HashSet<StatusListener> mStatusListeners = new HashSet<>();
250e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius
2514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no ifaces */
2524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startHal() {
2534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    if (!mWifiVendorHal.startVendorHal()) {
2571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        Log.e(TAG, "Failed to start vendor HAL");
2581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        return false;
2591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    }
2601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
2624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
2654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop HAL if there are no more ifaces */
2694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopHalAndWificondIfNecessary() {
2704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
2714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyIface()) {
2724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.tearDownInterfaces()) {
2731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to teardown ifaces from wificond");
2741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                }
2751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (mWifiVendorHal.isVendorHalSupported()) {
2761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    mWifiVendorHal.stopVendorHal();
2771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                } else {
2781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.i(TAG, "Vendor Hal not supported, ignoring stop.");
2794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
2804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
2814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
2834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
2844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS = 100;
2854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private static final int CONNECT_TO_SUPPLICANT_RETRY_TIMES = 50;
2864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
2874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * This method is called to wait for establishing connection to wpa_supplicant.
2884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     *
2894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * @return true if connection is established, false otherwise.
2904ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
2914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean waitForSupplicantConnection() {
2924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        // Start initialization if not already started.
2934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        if (!mSupplicantStaIfaceHal.isInitializationStarted()
2944ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                && !mSupplicantStaIfaceHal.initialize()) {
2954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
2964ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
2974ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        boolean connected = false;
2984ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        int connectTries = 0;
2994ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_SUPPLICANT_RETRY_TIMES) {
3004ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Check if the initialization is complete.
3014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            connected = mSupplicantStaIfaceHal.isInitializationComplete();
3024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (connected) {
3034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                break;
3044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            try {
3064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                Thread.sleep(CONNECT_TO_SUPPLICANT_RETRY_INTERVAL_MS);
3074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } catch (InterruptedException ignore) {
3084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return connected;
3114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to start supplicant if there were no STA ifaces */
3144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean startSupplicant() {
3154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.enableSupplicant()) {
3181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to enable supplicant");
3194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!waitForSupplicantConnection()) {
3221d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to connect to supplicant");
3234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
325d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                if (!mSupplicantStaIfaceHal.registerDeathHandler(
326d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                        new SupplicantDeathHandlerInternal())) {
3271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to register supplicant death handler");
3284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return false;
3294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
3324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to stop supplicant if there are no more STA ifaces */
3364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void stopSupplicantIfNecessary() {
3374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mIfaceMgr.hasAnyStaIface()) {
3394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mSupplicantStaIfaceHal.deregisterDeathHandler()) {
3401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to deregister supplicant death handler");
3414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (!mWificondControl.disableSupplicant()) {
3431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to disable supplicant");
3444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
3454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean registerNetworkObserver(@NonNull NetworkObserverInternal observer) {
3514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.registerObserver(observer);
3534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method to register a network observer and return it */
3604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private boolean unregisterNetworkObserver(@NonNull NetworkObserverInternal observer) {
3614ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        try {
3624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mNwManagementService.unregisterObserver(observer);
3634ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        } catch (RemoteException e) {
3644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return false;
3654ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        return true;
3674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3694ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown client iface and perform necessary cleanup */
3704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onClientInterfaceDestroyed(@NonNull Iface iface) {
3714ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
3731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to unregister network observer for iface=" + iface.name);
3744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.teardownIface(iface.name)) {
3761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in supplicant=" + iface.name);
3774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownClientInterface(iface.name)) {
3791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in wificond=" + iface.name);
3804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
3814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopSupplicantIfNecessary();
3824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
3834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
3844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
3854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
3864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown softAp iface and perform necessary cleanup */
3874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onSoftApInterfaceDestroyed(@NonNull Iface iface) {
3884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
3894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!unregisterNetworkObserver(iface.networkObserver)) {
3901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to unregister network observer for iface=" + iface.name);
3914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
392295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mHostapdHal.removeAccessPoint(iface.name)) {
393295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Log.e(TAG, "Failed to remove access point on iface=" + iface.name);
394295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
39527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            if (!mHostapdHal.deregisterDeathHandler()) {
39627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.e(TAG, "Failed to deregister supplicant death handler");
39727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
398295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // TODO(b/71513606): Move this to a global operation.
399295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (!mWificondControl.stopHostapd(iface.name)) {
400295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Log.e(TAG, "Failed to stop hostapd on iface=" + iface.name);
4014ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mWificondControl.tearDownSoftApInterface(iface.name)) {
4031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to teardown iface in wificond=" + iface.name);
4044ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4054ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            stopHalAndWificondIfNecessary();
4064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /** Helper method invoked to teardown iface and perform necessary cleanup */
4104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private void onInterfaceDestroyed(@NonNull Iface iface) {
4114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
4124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
4134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onClientInterfaceDestroyed(iface);
4144ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
4154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onSoftApInterfaceDestroyed(iface);
4164ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Invoke the external callback.
4184ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener.onDestroyed(iface.name);
4194ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
4234ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Callback to be invoked by HalDeviceManager when an interface is destroyed.
4244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
4254ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class InterfaceDestoyedListenerInternal
4264ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            implements HalDeviceManager.InterfaceDestroyedListener {
4274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
4284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
4294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        InterfaceDestoyedListenerInternal(int ifaceId) {
4314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = ifaceId;
4324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
4344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDestroyed(@NonNull String ifaceName) {
4364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
4374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.removeIface(mInterfaceId);
4384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
4391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Received iface destroyed notification on an invalid iface="
4404ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
4414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
4424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
4434ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                onInterfaceDestroyed(iface);
4441d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Successfully torn down iface=" + ifaceName);
4454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
4464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
4474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
4484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
449d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /** Helper method invoked to cleanup state after one of the native daemon's death. */
450d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private void onNativeDaemonDeath() {
451d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        synchronized (mLock) {
452d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            Log.i(TAG, "One of the daemons died. Tearing down everything");
453d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
454d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            while (ifaceIdIter.hasNext()) {
455d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
456d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                ifaceIdIter.remove();
457d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onInterfaceDestroyed(iface);
458d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Successfully torn down iface=" + iface.name);
459d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
460d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
461d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(false);
462d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
463d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            // TODO(70572148): Do we need to wait to mark the system ready again?
464d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            for (StatusListener listener : mStatusListeners) {
465d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                listener.onStatusChanged(true);
466d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
467d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
468d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
469d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
4704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
471d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the Vendor HAL daemon.
4724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
473d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class VendorHalDeathHandlerInternal implements VendorHalDeathEventHandler {
4744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
4754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void onDeath() {
4764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
477d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "Vendor HAL died. Cleaning up internal state.");
478d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
479d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumHalCrashes();
480d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
481d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
482d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
483d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
484d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
485d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the wificond daemon.
486d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
487d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class WificondDeathHandlerInternal implements WificondDeathEventHandler {
488d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
489d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
490d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
491d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wificond died. Cleaning up internal state.");
492d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
493d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWificondCrashes();
494d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            }
495d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        }
496d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    }
497d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius
498d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    /**
499d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     * Death handler for the supplicant daemon.
500d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius     */
501d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius    private class SupplicantDeathHandlerInternal implements SupplicantDeathEventHandler {
502d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        @Override
503d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius        public void onDeath() {
504d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            synchronized (mLock) {
505d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                Log.i(TAG, "wpa_supplicant died. Cleaning up internal state.");
506d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                onNativeDaemonDeath();
507d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumSupplicantCrashes();
5084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5104ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    /**
51327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     * Death handler for the hostapd daemon.
51427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius     */
51527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    private class HostapdDeathHandlerInternal implements HostapdDeathEventHandler {
51627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        @Override
51727c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        public void onDeath() {
51827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            synchronized (mLock) {
51927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                Log.i(TAG, "hostapd died. Cleaning up internal state.");
52027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                onNativeDaemonDeath();
52127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius                mWifiMetrics.incrementNumHostapdCrashes();
52227c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            }
52327c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
52427c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    }
52527c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius
52627c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius    /**
5274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     * Network observer to use for all interface up/down notifications.
5284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius     */
5294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    private class NetworkObserverInternal extends BaseNetworkObserver {
5304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        /** Identifier allocated for the interface */
5314ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        private final int mInterfaceId;
5324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        NetworkObserverInternal(int id) {
5344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            mInterfaceId = id;
5354ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        @Override
5384ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        public void interfaceLinkStateChanged(String ifaceName, boolean isUp) {
5394ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            synchronized (mLock) {
5401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Interface link state changed=" + ifaceName + ", isUp=" + isUp);
5414ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                final Iface iface = mIfaceMgr.getIface(mInterfaceId);
5424ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (iface == null) {
5431d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Received iface up/down notification on an invalid iface="
5444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                            + ifaceName);
5454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
5464ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5474ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                if (isUp) {
5484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onUp(ifaceName);
5494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                } else {
5504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    iface.externalListener.onDown(ifaceName);
5514ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
5524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
5534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
5544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius    }
5554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius
5561d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
5571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
5581d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // any active interface.
5591d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String handleIfaceCreationWhenVendorHalNotSupported(@NonNull Iface newIface) {
5601d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Iface existingIface = mIfaceMgr.removeExistingIface(newIface.id);
5611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        if (existingIface != null) {
5621d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            onInterfaceDestroyed(existingIface);
5631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully torn down iface=" + existingIface.name);
5641d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
5651d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        // Return the interface name directly from the system property.
5661d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return mPropertyService.getString("wifi.interface", "wlan0");
5671d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
5681d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
5691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
5701d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of STA iface.
5711d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
5721d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
5731d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
5741d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createStaIface(@NonNull Iface iface) {
5751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
5761d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
5771d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createStaIface(
5781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
5791d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
5801d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createStaIface.");
5811d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
5821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
5831d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
5841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
5851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
5861d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
5871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle creation of AP iface.
5881d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
5891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
5901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
5911d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private String createApIface(@NonNull Iface iface) {
5921d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
5931d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
5941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.createApIface(
5951d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                        new InterfaceDestoyedListenerInternal(iface.id));
5961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
5971d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
5981d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceCreationWhenVendorHalNotSupported(iface);
5991d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6001d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6011d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6021d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6031d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // For devices that don't support the vendor HAL, we will not support any concurrency.
6041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // So simulate the HalDeviceManager behavior by triggering the destroy listener for
6051d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    // the interface.
6061d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean handleIfaceRemovalWhenVendorHalNotSupported(@NonNull Iface iface) {
6071d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        mIfaceMgr.removeIface(iface.id);
6081d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        onInterfaceDestroyed(iface);
6091d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Log.i(TAG, "Successfully torn down iface=" + iface.name);
6101d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        return true;
6111d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6121d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6131d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6151d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
6161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * teardown any existing iface.
6171d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6181d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeStaIface(@NonNull Iface iface) {
6191d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6201d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6211d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeStaIface(iface.name);
6221d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeStaIface.");
6241d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6251d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6261d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6271d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
6291d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    /**
6301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     * Helper function to handle removal of STA iface.
6311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius     */
6321d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    private boolean removeApIface(@NonNull Iface iface) {
6331d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        synchronized (mLock) {
6341d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            if (mWifiVendorHal.isVendorHalSupported()) {
6351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return mWifiVendorHal.removeApIface(iface.name);
6361d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            } else {
6371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.i(TAG, "Vendor Hal not supported, ignoring removeApIface.");
6381d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                return handleIfaceRemovalWhenVendorHalNotSupported(iface);
6391d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            }
6401d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        }
6411d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius    }
6421d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius
643e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius    /**
644d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Initialize the native modules.
645d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
646d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return true on success, false otherwise.
647d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
648d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public boolean initialize() {
6494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
650e59dd55ea7446c3325be8cde31fbeca1e14fb263Roshan Pius            if (!mWifiVendorHal.initialize(new VendorHalDeathHandlerInternal())) {
6511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize vendor HAL");
6524ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
6534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
654d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius            if (!mWificondControl.registerDeathHandler(new WificondDeathHandlerInternal())) {
6551d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to initialize wificond");
6564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return false;
6574ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
6584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return true;
6594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
660d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
661d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
662d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
663d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the status of one of the native daemons
664d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL) changes.
665d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
666d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface StatusListener {
667d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
668d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param allReady Indicates if all the native daemons are ready for operation or not.
669d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
670d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onStatusChanged(boolean allReady);
671d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
672d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
673d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
674d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Register a StatusListener to get notified about any status changes from the native daemons.
675d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
676d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * It is safe to re-register the same callback object - duplicates are detected and only a
677d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * single copy kept.
678d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
679d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param listener StatusListener listener object.
680d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
681d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void registerStatusListener(@NonNull StatusListener listener) {
682e96a22b75e69fc49139a2acc7b0740aba10fa2c4Roshan Pius        mStatusListeners.add(listener);
683d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
684d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
685d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
686d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Callback to notify when the associated interface is destroyed, up or down.
687d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
688d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public interface InterfaceCallback {
689d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
690d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface destroyed by HalDeviceManager.
691d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
692d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
693d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
694d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDestroyed(String ifaceName);
695d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
696d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
697d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is up.
698d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
699d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
700d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
701d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onUp(String ifaceName);
702d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
703d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        /**
704d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * Interface is down.
705d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         *
706d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         * @param ifaceName Name of the iface.
707d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius         */
708d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius        void onDown(String ifaceName);
709d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
710d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
711fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    private void initializeNwParamsForClientInterface(@NonNull String ifaceName) {
712fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        try {
713fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // A runtime crash or shutting down AP mode can leave
714fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IP addresses configured, and this affects
715fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // connectivity when supplicant starts up.
716fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Ensure we have no IP addresses before a supplicant start.
717fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.clearInterfaceAddresses(ifaceName);
718fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
719fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // Set privacy extensions
720fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.setInterfaceIpv6PrivacyExtensions(ifaceName, true);
721fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
722fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // IPv6 is enabled only as long as access point is connected since:
723fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - IPv6 addresses and routes stick around after disconnection
724fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel is unaware when connected and fails to start IPv6 negotiation
725fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            // - kernel can start autoconfiguration when 802.1x is not complete
726fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            mNwManagementService.disableIpv6(ifaceName);
727fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (RemoteException re) {
7281d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + re);
729fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        } catch (IllegalStateException ie) {
7301d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Unable to change interface settings: " + ie);
731fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius        }
732fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius    }
733fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius
734d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
735d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Client mode operations.
736d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
737d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in STA mode in all the native daemons
738d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
739d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
740d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
741d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
742d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
743d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForClientMode(@NonNull InterfaceCallback interfaceCallback) {
7444ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
7454ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
7461d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
747d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7484ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7494ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7504ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startSupplicant()) {
7511d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start supplicant");
752d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
7534ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7544ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7554ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_STA);
7564ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
7571d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new STA iface");
7584ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7594ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7604ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
7611d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createStaIface(iface);
7624ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
7631d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to create iface in vendor HAL");
7644ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
765d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
7664ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7674ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7684ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForClientMode(iface.name) == null) {
7691d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
7704ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
771d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
7724ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7734ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7744ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!mSupplicantStaIfaceHal.setupIface(iface.name)) {
7751d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in supplicant=" + iface.name);
7764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
777d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToSupplicant();
7784ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
7804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
7814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
7821d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
7834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
7844ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
7854ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
786fc8efe44f2f2231678b0f07b5662a8d8c9e71005Roshan Pius            initializeNwParamsForClientInterface(iface.name);
7871d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully setup iface=" + iface.name);
7884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
7894ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
790d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
791d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
792d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
793d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Setup an interface for Soft AP mode operations.
794d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
795d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method configures an interface in AP mode in all the native daemons
796d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
797d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
798d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param interfaceCallback Associated callback for notifying status changes for the iface.
799d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @return Returns the name of the allocated interface, will be null on failure.
800d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
801d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
8024ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8034ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!startHal()) {
8041d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to start Hal");
805d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8064ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8074ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8084ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
8094ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8101d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to allocate new AP iface");
8114ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8124ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8134ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.externalListener = interfaceCallback;
8141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            iface.name = createApIface(iface);
8154ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (TextUtils.isEmpty(iface.name)) {
8161d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to create iface in vendor HAL");
8174ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                mIfaceMgr.removeIface(iface.id);
818d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
819d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToHal();
8204ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8214ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8224ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
8231d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to setup iface in wificond=" + iface.name);
8244ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
825d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                // TODO(b/68716726): Separate SoftAp metrics
826d2f09d1534b94adbfaf8f3e4b36abc5558fee37eRoshan Pius                mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
8274ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8284ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8294ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            iface.networkObserver = new NetworkObserverInternal(iface.id);
8304ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (!registerNetworkObserver(iface.networkObserver)) {
8311d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Failed to register network observer for iface=" + iface.name);
8324ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                teardownInterface(iface.name);
8334ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return null;
8344ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8351d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully setup iface=" + iface.name);
8364ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            return iface.name;
8374ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
838d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
839d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
840d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    /**
8419c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * Check if the interface is up or down.
8429c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     *
8439c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @param ifaceName Name of the interface.
8449c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     * @return true if iface is up, false if it's down or on error.
8459c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius     */
8469c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    public boolean isInterfaceUp(@NonNull String ifaceName) {
8479c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        synchronized (mLock) {
8489c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
8499c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (iface == null) {
8501d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to get iface state on invalid iface=" + ifaceName);
8519c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
8529c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8539c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            InterfaceConfiguration config = null;
8549c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            try {
8559c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                config = mNwManagementService.getInterfaceConfig(ifaceName);
8569c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            } catch (RemoteException e) {
8579c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8589c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            if (config == null) {
8599c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius                return false;
8609c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            }
8619c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius            return config.isUp();
8629c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius        }
8639c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    }
8649c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius
8659c0e999631eea5a83bd0caabbf5243ed36e24004Roshan Pius    /**
866d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * Teardown an interface in Client/AP mode.
867d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
868d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * This method tears down the associated interface from all the native daemons
869d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
870840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
871d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     *
872d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     * @param ifaceName Name of the interface.
873d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius     */
874d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    public void teardownInterface(@NonNull String ifaceName) {
8754ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        synchronized (mLock) {
8764ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            final Iface iface = mIfaceMgr.getIface(ifaceName);
8774ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface == null) {
8781d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                Log.e(TAG, "Trying to teardown an invalid iface=" + ifaceName);
8794ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                return;
8804ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8814ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // Trigger the iface removal from HAL. The rest of the cleanup will be triggered
8824ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            // from the interface destroyed callback.
8834ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            if (iface.type == Iface.IFACE_TYPE_STA) {
8841d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeStaIface(iface)) {
8851d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
8864ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
8874ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
8884ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            } else if (iface.type == Iface.IFACE_TYPE_AP) {
8891d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                if (!removeApIface(iface)) {
8901d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius                    Log.e(TAG, "Failed to remove iface in vendor HAL=" + ifaceName);
8914ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                    return;
8924ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius                }
8934ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius            }
8941d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.i(TAG, "Successfully initiated teardown for iface=" + ifaceName);
8954ae0d964e0be84bc843488736a8c6a3afc436121Roshan Pius        }
896d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius    }
897d39ac242d0a0af8f43657327ece788c97a0644d3Roshan Pius
898b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    /**
899840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Teardown all the active interfaces.
900840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
901840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This method tears down the associated interfaces from all the native daemons
902840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * (wificond, wpa_supplicant & vendor HAL).
903840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Also, brings down the HAL, supplicant or hostapd as necessary.
904840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
905840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public void teardownAllInterfaces() {
906840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        synchronized (mLock) {
907840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Iterator<Integer> ifaceIdIter = mIfaceMgr.getIfaceIdIter();
908840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            while (ifaceIdIter.hasNext()) {
909840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                Iface iface = mIfaceMgr.getIface(ifaceIdIter.next());
910840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius                teardownInterface(iface.name);
911840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            }
912840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius            Log.i(TAG, "Successfully initiated teardown for all ifaces");
913840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        }
914840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
915840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
916840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
917b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Get name of the client interface.
918b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
919b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * This is mainly used by external modules that needs to perform some
920b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * client operations on the STA interface.
921b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
922b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting STA + STA.
923b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     *
924b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * @return Interface name of any active client interface, null if no active client interface
925b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * exist.
926b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * Return Values for the different scenarios are listed below:
927b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * a) When there are no client interfaces, returns null.
928b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * b) when there is 1 client interface, returns the name of that interface.
929b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     * c) When there are 2 or more client interface, returns the name of any client interface.
930b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius     */
931b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    public String getClientInterfaceName() {
932b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius        return mIfaceMgr.findAnyStaIfaceName();
933b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius    }
934b49bf2570ec24a05f974fe17bb72be7320cd77f6Roshan Pius
935840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    /**
936840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Get name of the softap interface.
937840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
938840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * This is mainly used by external modules that needs to perform some
939840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * operations on the AP interface.
940840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
941840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * TODO(b/70932231): This may need to be reworked once we start supporting AP + AP.
942840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     *
943840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * @return Interface name of any active softap interface, null if no active softap interface
944840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * exist.
945840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * Return Values for the different scenarios are listed below:
946840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * a) When there are no softap interfaces, returns null.
947840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * b) when there is 1 softap interface, returns the name of that interface.
948840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     * c) When there are 2 or more softap interface, returns the name of any softap interface.
949840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius     */
950840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    public String getSoftApInterfaceName() {
951840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius        return mIfaceMgr.findAnyApIfaceName();
952840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius    }
953840d73a4914b82963475dbd228b0e3669ac0d543Roshan Pius
954b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
955b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Wificond operations
956b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
957b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
958b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Result of a signal poll.
959b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
960b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class SignalPollResult {
961b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // RSSI value in dBM.
962b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int currentRssi;
963b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        //Transmission bit rate in Mbps.
964b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txBitrate;
965b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Association frequency in MHz.
966b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int associationFrequency;
967b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
968b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
969b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
970b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * WiFi interface transimission counters.
971b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
972b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static class TxPacketCounters {
973b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of successfully transmitted packets.
974b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txSucceeded;
975b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Number of tramsmission failures.
976b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        public int txFailed;
977b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
978b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
97970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    /**
98055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     * Callback to notify wificond death.
98155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius     */
98255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    public interface WificondDeathEventHandler {
98355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        /**
98455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         * Invoked when the wificond dies.
98555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius         */
98655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius        void onDeath();
98755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    }
98855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius
98955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius    /**
99052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Request signal polling to wificond.
99152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
99252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
99352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an SignalPollResult object.
99452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
99552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
99652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public SignalPollResult signalPoll(@NonNull String ifaceName) {
99752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.signalPoll(ifaceName);
998d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
999d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
1000d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    /**
1001d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang     * Fetch TX packet counters on current connection from wificond.
100252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
100352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns an TxPacketCounters object.
100452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Returns null on failure.
100552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
100652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
100752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getTxPacketCounters(ifaceName);
1008d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang    }
1009d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang
101024250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius    /**
1011a70c07d019065187112945c091fc2e924af18980Roshan Pius     * Query the list of valid frequencies for the provided band.
1012a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The result depends on the on the country code that has been set.
1013a70c07d019065187112945c091fc2e924af18980Roshan Pius     *
1014a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1015a70c07d019065187112945c091fc2e924af18980Roshan Pius     * The following bands are supported:
1016a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_24_GHZ
1017a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ
1018a70c07d019065187112945c091fc2e924af18980Roshan Pius     * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY
1019a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @return frequencies vector of valid frequencies (MHz), or null for error.
1020a70c07d019065187112945c091fc2e924af18980Roshan Pius     * @throws IllegalArgumentException if band is not recognized.
1021a70c07d019065187112945c091fc2e924af18980Roshan Pius     */
1022a70c07d019065187112945c091fc2e924af18980Roshan Pius    public int [] getChannelsForBand(int band) {
1023a70c07d019065187112945c091fc2e924af18980Roshan Pius        return mWificondControl.getChannelsForBand(band);
1024a70c07d019065187112945c091fc2e924af18980Roshan Pius    }
1025a70c07d019065187112945c091fc2e924af18980Roshan Pius
1026a70c07d019065187112945c091fc2e924af18980Roshan Pius    /**
1027b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start a scan using wificond for the given parameters.
102852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
10293feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * @param scanType Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
10303feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius     * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
1031b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param freqs list of frequencies to scan for, if null scan all supported channels.
1032b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
1033b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns true on success.
103424250365afbd9a20b2e03364eddf2025c8f1138aRoshan Pius     */
103552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean scan(
10363feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            @NonNull String ifaceName, int scanType, Set<Integer> freqs,
10373feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius            Set<String> hiddenNetworkSSIDs) {
10383feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        return mWificondControl.scan(ifaceName, scanType, freqs, hiddenNetworkSSIDs);
1039155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1040155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
104118786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    /**
1042b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetch the latest scan result from kernel via wificond.
104352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1044b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Returns an ArrayList of ScanDetail.
1045b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Returns an empty ArrayList on failure.
104618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
104752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getScanResults(@NonNull String ifaceName) {
104891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius        return mWificondControl.getScanResults(
104952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, WificondControl.SCAN_TYPE_SINGLE_SCAN);
105071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    }
105171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao
105271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao    /**
105371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Fetch the latest scan result from kernel via wificond.
105452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
105571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * @return Returns an ArrayList of ScanDetail.
105671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     * Returns an empty ArrayList on failure.
105771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao     */
105852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ArrayList<ScanDetail> getPnoScanResults(@NonNull String ifaceName) {
105952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.getScanResults(ifaceName, WificondControl.SCAN_TYPE_PNO_SCAN);
1060155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1061155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1062b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1063b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start PNO scan.
106452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1065b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pnoSettings Pno scan configuration.
1066b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
106718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills     */
106852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPnoScan(@NonNull String ifaceName, PnoSettings pnoSettings) {
106952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.startPnoScan(ifaceName, pnoSettings);
1070155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1071155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1072b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1073b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop PNO scan.
107452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1075b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success.
1076b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
107752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopPnoScan(@NonNull String ifaceName) {
107852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopPnoScan(ifaceName);
107918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    }
108018786eca942042388748b0d98979f21c9dff4a89Mitchell Wills
1081045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1082045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Callbacks for SoftAp interface.
1083045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
1084045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    public interface SoftApListener {
1085045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        /**
1086045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         * Invoked when the number of associated stations changes.
1087045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius         */
1088045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius        void onNumAssociatedStationsChanged(int numStations);
1089045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1090045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1091295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS = 100;
1092295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private static final int CONNECT_TO_HOSTAPD_RETRY_TIMES = 50;
1093295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    /**
1094295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * This method is called to wait for establishing connection to hostapd.
1095295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     *
1096295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     * @return true if connection is established, false otherwise.
1097295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius     */
1098295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    private boolean waitForHostapdConnection() {
1099295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        // Start initialization if not already started.
1100295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!mHostapdHal.isInitializationStarted()
1101295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                && !mHostapdHal.initialize()) {
1102295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1103295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1104295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        boolean connected = false;
1105295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        int connectTries = 0;
1106295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {
1107295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            // Check if the initialization is complete.
1108295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            connected = mHostapdHal.isInitializationComplete();
1109295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            if (connected) {
1110295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                break;
1111295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1112295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            try {
1113295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius                Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);
1114295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            } catch (InterruptedException ignore) {
1115295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            }
1116295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1117295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return connected;
1118295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius    }
1119295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius
1120045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1121045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Start Soft AP operation using the provided configuration.
1122045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
112352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1124045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param config Configuration to use for the soft ap created.
1125045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @param listener Callback for AP events.
1126045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1127045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
112852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startSoftAp(
112952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {
113052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mWificondControl.startHostapd(ifaceName, listener)) {
1131295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to start hostapd");
1132295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1133295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1134295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        if (!waitForHostapdConnection()) {
1135295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to establish connection to hostapd");
1136295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1137295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
113827c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        if (!mHostapdHal.registerDeathHandler(new HostapdDeathHandlerInternal())) {
113927c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            Log.e(TAG, "Failed to register hostapd death handler");
114027c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius            return false;
114127c6f0c111f97e95e3388e9702218cf9e481abb1Roshan Pius        }
114252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.addAccessPoint(ifaceName, config)) {
1143295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to add acccess point");
1144295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            return false;
1145295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
1146295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        return true;
1147045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1148045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1149045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    /**
1150045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * Stop the ongoing Soft AP operation.
1151045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     *
115252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1153045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     * @return true on success, false otherwise.
1154045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius     */
115552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopSoftAp(@NonNull String ifaceName) {
115652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        if (!mHostapdHal.removeAccessPoint(ifaceName)) {
1157295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius            Log.e(TAG, "Failed to remove access point");
1158295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius        }
115952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWificondControl.stopHostapd(ifaceName);
1160045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1161045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
116302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Hostapd operations
116402367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     ********************************************************/
116502367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius
116602367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    /**
116702367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     * Callback to notify hostapd death.
116802367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius     */
116902367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius    public interface HostapdDeathEventHandler {
117002367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        /**
117102367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         * Invoked when the supplicant dies.
117202367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius         */
117302367176dbfc4b7ef84c6f8d37770973ef416994Roshan Pius        void onDeath();
1174045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius    }
1175045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius
1176b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1177b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Supplicant operations
1178b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1179f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius
1180f3aae0be78cd02f5fedd7d99b73536d2c799b030Roshan Pius    /**
1181fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     * Callback to notify supplicant death.
1182fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius     */
1183fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    public interface SupplicantDeathEventHandler {
1184fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        /**
1185fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         * Invoked when the supplicant dies.
1186fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius         */
1187fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius        void onDeath();
1188fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    }
1189fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius
1190fd95a68590a4dcc82734e42b85898c953d21dbf7Roshan Pius    /**
1191b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set supplicant log level
1192782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     *
1193b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param turnOnVerbose Whether to turn on verbose logging or not.
1194782eac0bacec797262eb4d721ad58cfcf2fbf885Tomasz Wiszkowski     */
1195b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public void setSupplicantLogLevel(boolean turnOnVerbose) {
1196f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius        mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
1197e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius    }
1198e3831b70d4a8a967fe8df5496d542a432692c434Roshan Pius
119938a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius    /**
1200b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reconnection if the iface is disconnected.
1201b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
120252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1203b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
120438a6c1ba5d461b8c7b11685c5dd2e98d9e106b55Roshan Pius     */
120552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reconnect(@NonNull String ifaceName) {
120652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reconnect(ifaceName);
1207f22d23092ab37286a5ef9d257d5bb32c421d2669vandwalle    }
12089d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius
12099d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius    /**
1210b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a reassociation even if the iface is currently connected.
1211b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
121252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1213b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
12149d7489491984e86915b2cf4fac38a882de1c8cdbRoshan Pius     */
121552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean reassociate(@NonNull String ifaceName) {
121652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.reassociate(ifaceName);
1217155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1218155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1219155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1220b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Trigger a disconnection from the currently connected network.
1221b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
122252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1223b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1224b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
122552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean disconnect(@NonNull String ifaceName) {
122652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.disconnect(ifaceName);
122777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist    }
122877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist
1229155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1230b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Makes a callback to HIDL to getMacAddress from supplicant
1231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
123252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return string containing the MAC address, or null on a failed call
1234b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
123552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getMacAddress(@NonNull String ifaceName) {
123652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getMacAddress(ifaceName);
1237446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng    }
1238446db2d5457456743e4476029e14d7c3bb9f5bccYuhao Zheng
1239f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
1240f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
1241155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1242155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V4 packets
124352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1244155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1245155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1246155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Multicast filtering rules work as follows:
1247155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1248155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
1249155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * a power optimized mode (typically when screen goes off).
1250155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1251155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
1252155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
1253155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1254155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-ADD Num
1255155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
1256155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1257155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * and DRIVER RXFILTER-START
1258155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * In order to stop the usage of these rules, we do
1259155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1260155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-STOP
1261155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * DRIVER RXFILTER-REMOVE Num
1262155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *   where Num is as described for RXFILTER-ADD
1263155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
1264155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * The  SETSUSPENDOPT driver command overrides the filtering rules
1265155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
126652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV4Packets(@NonNull String ifaceName) {
126752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1268b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
126952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
127052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1271155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1272155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1273155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1274155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V4 packets.
127552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1276155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1277155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
127852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV4Packets(@NonNull String ifaceName) {
127952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1280b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
128152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V4_MULTICAST)
128252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1283155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1284155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1285155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1286155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Start filtering out Multicast V6 packets
128752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1288155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1289155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
129052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startFilteringMulticastV6Packets(@NonNull String ifaceName) {
129152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1292b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.removeRxFilter(
129352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
129452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1295155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1296155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1297155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1298155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Stop filtering out Multicast V6 packets.
129952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1300155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the operation succeeded, {@code false} otherwise
1301155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
130252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean stopFilteringMulticastV6Packets(@NonNull String ifaceName) {
130352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.stopRxFilter(ifaceName)
1304b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && mSupplicantStaIfaceHal.addRxFilter(
130552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                        ifaceName, RX_FILTER_TYPE_V6_MULTICAST)
130652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                && mSupplicantStaIfaceHal.startRxFilter(ifaceName);
1307155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1308155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1309f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
1310f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
1311f2e03411f137f55940a8f3592e96a272585bd7ddRoshan Pius    public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
13127ef73dd1b6e43c72b3841723504cd86dc402a134Vinit Deshapnde    /**
131352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Sets the bluetooth coexistence mode.
131452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
131552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
131652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
131752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
131852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
131952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return Whether the mode was successfully set.
132052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
132152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceMode(@NonNull String ifaceName, int mode) {
132252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceMode(ifaceName, mode);
1323155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1324155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1325155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
1326155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
1327155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * some of the low-level scan parameters used by the driver are changed to
1328155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * reduce interference with A2DP streaming.
1329155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     *
133052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1331cc180872c51908b15ce5cbf834634ff323e036bcChristopher Wiley     * @param setCoexScanMode whether to enable or disable this mode
1332155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     * @return {@code true} if the command succeeded, {@code false} otherwise.
1333155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
133452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setBluetoothCoexistenceScanMode(
133552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, boolean setCoexScanMode) {
1336b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(
133752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, setCoexScanMode);
1338155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1339155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1340b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1341b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable suspend mode optimizations.
1342b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
134352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1344b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false otherwise.
1345b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1346b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
134752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSuspendOptimizations(@NonNull String ifaceName, boolean enabled) {
134852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setSuspendModeEnabled(ifaceName, enabled);
1349155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1350155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
13519153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius    /**
1352b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code.
1353b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
135452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1355b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode 2 byte ASCII string. For ex: US, CA.
1356b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
13579153bd67d51b305ffdd61355e0748e3c332c2cafRoshan Pius     */
135852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCode(@NonNull String ifaceName, String countryCode) {
135952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCountryCode(ifaceName, countryCode);
136004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    }
136104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang
136204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang    /**
1363b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate TDLS discover and setup or teardown with the specified peer.
1364b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
136552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1366b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param macAddr MAC Address of the peer.
1367b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enable true to start discovery and setup, false to teardown.
136804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang     */
136952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void startTdls(@NonNull String ifaceName, String macAddr, boolean enable) {
1370b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (enable) {
137152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsDiscover(ifaceName, macAddr);
137252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsSetup(ifaceName, macAddr);
1373155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        } else {
137452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            mSupplicantStaIfaceHal.initiateTdlsTeardown(ifaceName, macAddr);
1375155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1376155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1377155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1378b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1379b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1380b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
138152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1382b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1383b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1384b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
138552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPbc(@NonNull String ifaceName, String bssid) {
138652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPbc(ifaceName, bssid);
1387155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1388155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1389b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1390b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin keypad operation with the specified pin.
1391b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
139252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1393b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1394b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1395b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
139652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsPinKeypad(@NonNull String ifaceName, String pin) {
139752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinKeypad(ifaceName, pin);
1398155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1399155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1400b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1401b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin display operation with the specified peer.
1402b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
140352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1404b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1405b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return new pin generated on success, null otherwise.
1406b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
140752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String startWpsPinDisplay(@NonNull String ifaceName, String bssid) {
140852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsPinDisplay(ifaceName, bssid);
1409155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1410155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1411b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1412b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sets whether to use external sim for SIM/USIM processing.
1413b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
141452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1415b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param external true to enable, false otherwise.
1416b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1417b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
141852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setExternalSim(@NonNull String ifaceName, boolean external) {
141952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setExternalSim(ifaceName, external);
142033b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
142133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1422b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1423b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Sim auth response types.
1424b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1425b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
1426b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
1427b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
1428b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1429b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1430b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the sim auth response for the currently configured network.
1431b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
143252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1433b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
1434b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response Response params.
1435b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1436b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
143752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthResponse(
143852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, int id, String type, String response) {
1439b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
1440b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(
144152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1442b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
1443b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(
144452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
1445b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
1446b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius            return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(
144752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                    ifaceName, response);
14485cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        } else {
1449b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return false;
14505cf97c9b13cc06554c8901e63d55ba051b7e7881Roshan Pius        }
145133b575ca6bee66183929f9474b5a161432918604Vinit Deshpande    }
145233b575ca6bee66183929f9474b5a161432918604Vinit Deshpande
1453b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1454b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim gsm auth failure for the currently configured network.
1455b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
145652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1457b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1458b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
145952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simAuthFailedResponse(@NonNull String ifaceName, int id) {
146052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(ifaceName);
146126eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
146226eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1463b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1464b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap sim umts auth failure for the currently configured network.
1465b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
146652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1467b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1468b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
146952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean umtsAuthFailedResponse(@NonNull String ifaceName, int id) {
147052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(ifaceName);
147126eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande    }
147226eebecc04b55129a902d1e7b670fe05668c14faVinit Deshpande
1473b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1474b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Send the eap identity response for the currently configured network.
1475b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
147652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1477b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param response String to send.
1478b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if succeeds, false otherwise.
1479b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
148052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean simIdentityResponse(@NonNull String ifaceName, int id, String response) {
1481b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(
148252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, response);
1483ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot    }
1484ad607d99c372160c7d4b38e755e1b47d6419856eHonore Tricot
1485b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1486a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * This get anonymous identity from supplicant and returns it as a string.
1487a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     *
148852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1489a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     * @return anonymous identity string if succeeds, null otherwise.
1490a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang     */
149152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getEapAnonymousIdentity(@NonNull String ifaceName) {
149252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(ifaceName);
1493a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    }
1494a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang
1495a1da73ea4926ce8a5689594ff3685b0fe033d99fNingyuan Wang    /**
1496b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start WPS pin registrar operation with the specified peer and pin.
1497b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
149852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1499b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the peer.
1500b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param pin Pin to be used.
1501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1502b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
150352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startWpsRegistrar(@NonNull String ifaceName, String bssid, String pin) {
150452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.startWpsRegistrar(ifaceName, bssid, pin);
1505155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1506155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1507b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1508b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels any ongoing WPS requests.
1509b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
151052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1511b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1512b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
151352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean cancelWps(@NonNull String ifaceName) {
151452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.cancelWps(ifaceName);
1515155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1516155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1517b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1518b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device name.
1519b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
152052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1521b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param name String to be set.
1522b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1523b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
152452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceName(@NonNull String ifaceName, String name) {
152552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceName(ifaceName, name);
1526155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1527155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1528b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1529b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS device type.
1530b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
153152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1532b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
1533b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1534b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
153552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setDeviceType(@NonNull String ifaceName, String type) {
153652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsDeviceType(ifaceName, type);
1537155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1538155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1539b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1540b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS config methods
1541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param cfg List of config methods.
1543b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1544b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
154552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfigMethods(@NonNull String ifaceName, String cfg) {
154652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsConfigMethods(ifaceName, cfg);
1547155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1548155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1549b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1550b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS manufacturer.
1551b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
155252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1553b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1554b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1555b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
155652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setManufacturer(@NonNull String ifaceName, String value) {
155752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsManufacturer(ifaceName, value);
1558155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1559155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1560b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1561b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model name.
1562b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
156352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1564b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1565b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1566b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
156752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelName(@NonNull String ifaceName, String value) {
156852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelName(ifaceName, value);
1569155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1570155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1571b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1572b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS model number.
1573b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
157452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1576b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
157852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setModelNumber(@NonNull String ifaceName, String value) {
157952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsModelNumber(ifaceName, value);
1580155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1581155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1582b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1583b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set WPS serial number.
1584b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
158552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1586b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param value String to be set.
1587b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1588b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
158952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setSerialNumber(@NonNull String ifaceName, String value) {
159052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setWpsSerialNumber(ifaceName, value);
1591155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1592155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1593b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1594b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable or disable power save mode.
1595b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
159652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1597b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
1598b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
159952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void setPowerSave(@NonNull String ifaceName, boolean enabled) {
160052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.setPowerSave(ifaceName, enabled);
1601155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1602155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1603b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1604b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set concurrency priority between P2P & STA operations.
1605b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
1606b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
1607b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                            false otherwise.
1608b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise.
1609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
1610b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
1611b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
1612155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1613155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1614155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    /**
16153e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * Enable/Disable auto reconnect functionality in wpa_supplicant.
16163e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     *
161752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
16183e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @param enable true to enable auto reconnecting, false to disable.
16193e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     * @return true if request is sent successfully, false otherwise.
16203e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius     */
162152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean enableStaAutoReconnect(@NonNull String ifaceName, boolean enable) {
162252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.enableAutoReconnect(ifaceName, enable);
16233e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    }
16243e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius
16253e240b2bfb6fefe8b91ad68e8a12b652b4136c69Roshan Pius    /**
1626b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Migrate all the configured networks from wpa_supplicant.
1627b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
162852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configs       Map of configuration key to configuration objects corresponding to all
1630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *                      the networks.
1631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
1632b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Max priority of all the configs.
1633155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande     */
163452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean migrateNetworksFromSupplicant(
163552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, Map<String, WifiConfiguration> configs,
163652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            SparseArray<Map<String, String>> networkExtras) {
163752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.loadNetworks(ifaceName, configs, networkExtras);
1638155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1639155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1641b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Add the provided network configuration to wpa_supplicant and initiate connection to it.
1642b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This method does the following:
1643c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the connection request.
1644c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
1645c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Add a new network to wpa_supplicant.
1646c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Save the provided configuration to wpa_supplicant.
1647c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 5. Select the new network in wpa_supplicant.
1648c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 6. Triggers reconnect command to wpa_supplicant.
1649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
165052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1651b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1652b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1653b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
165452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean connectToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1655c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock connection request.
165652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
165752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.connectToNetwork(ifaceName, configuration);
1658155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1660b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1661b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiates roaming to the already configured network in wpa_supplicant. If the network
1662b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configuration provided does not match the already configured network, then this triggers
1663b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * a new connection attempt (instead of roam).
1664c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 1. Abort any ongoing scan to unblock the roam request.
1665c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 2. First check if we're attempting to connect to the same network as we currently have
1666b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * configured.
1667c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 3. Set the new bssid for the network in wpa_supplicant.
1668c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang     * 4. Triggers reassociate command to wpa_supplicant.
1669b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
167052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1671b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param configuration WifiConfiguration parameters for the provided network.
1672b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1673b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
167452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean roamToNetwork(@NonNull String ifaceName, WifiConfiguration configuration) {
1675c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang        // Abort ongoing scan before connect() to unblock roaming request.
167652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWificondControl.abortScan(ifaceName);
167752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.roamToNetwork(ifaceName, configuration);
1678155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1679155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1680b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1681b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Remove all the networks.
1682b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
168352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1684b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return {@code true} if it succeeds, {@code false} otherwise
1685b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
168652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean removeAllNetworks(@NonNull String ifaceName) {
168752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.removeAllNetworks(ifaceName);
1688155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1689155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1690b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1691b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the BSSID for the currently configured network in wpa_supplicant.
1692b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
169352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1694b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if successful, false otherwise.
1695b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
169652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setConfiguredNetworkBSSID(@NonNull String ifaceName, String bssid) {
169752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.setCurrentNetworkBssid(ifaceName, bssid);
1698155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1699155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1700b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1701b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Initiate ANQP query.
1702b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
170352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1704b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP to be queried
1705b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param anqpIds Set of anqp IDs.
1706b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param hs20Subtypes Set of HS20 subtypes.
1707b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
1708b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
170952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestAnqp(
171052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, String bssid, Set<Integer> anqpIds,
171152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            Set<Integer> hs20Subtypes) {
1712b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
1713b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
17141d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for ANQP request.");
1715155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande            return false;
1716155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
1717b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Short> anqpIdList = new ArrayList<>();
1718b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        for (Integer anqpId : anqpIds) {
1719b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            anqpIdList.add(anqpId.shortValue());
172061233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski        }
1721b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
1722b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        hs20SubtypeList.addAll(hs20Subtypes);
1723b8dc0d2fb3b03c84922136452f1aacb43649ae85Roshan Pius        return mSupplicantStaIfaceHal.initiateAnqpQuery(
172452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, bssid, anqpIdList, hs20SubtypeList);
1725155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1726155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1727b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1728b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request a passpoint icon file |filename| from the specified AP |bssid|.
172952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
173052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1731b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param bssid BSSID of the AP
1732b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param fileName name of the icon file
1733b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if request is sent successfully, false otherwise
1734b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
173552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean requestIcon(@NonNull String ifaceName, String  bssid, String fileName) {
1736b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bssid == null || fileName == null) {
17371d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius            Log.e(TAG, "Invalid arguments for Icon request.");
173861233efc46707ace6cb3a45dd84766f06df946afTomasz Wiszkowski            return false;
1739155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande        }
174052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.initiateHs20IconQuery(ifaceName, bssid, fileName);
1741155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1742155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande
1743b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1744b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the currently configured network's WPS NFC token.
1745b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
174652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1747b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Hex string corresponding to the WPS NFC token.
1748b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
174952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public String getCurrentNetworkWpsNfcConfigurationToken(@NonNull String ifaceName) {
175052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(ifaceName);
1751155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande    }
1752403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1753403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    /** Remove the request |networkId| from supplicant if it's the current network,
1754403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * if the current configured network matches |networkId|.
1755403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     *
175652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1757403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     * @param networkId network id of the network to be removed from supplicant.
1758403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang     */
175952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void removeNetworkIfCurrent(@NonNull String ifaceName, int networkId) {
176052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mSupplicantStaIfaceHal.removeNetworkIfCurrent(ifaceName, networkId);
1761403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang    }
1762403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang
1763b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
1764b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor HAL operations
1765b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
1766af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    /**
1767af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     * Callback to notify vendor HAL death.
1768af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius     */
1769af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    public interface VendorHalDeathEventHandler {
1770af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        /**
1771af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         * Invoked when the vendor HAL dies.
1772af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius         */
1773af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius        void onDeath();
1774af0e32cfa2f7402c60b9df88a0d9bd19f421026cRoshan Pius    }
1775b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
1776d84fd37259c6e956d0f00c261f573dfa319acb91Roshan Pius    /**
1777b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Tests whether the HAL is running or not
1778b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
177918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean isHalStarted() {
1780b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.isHalStarted();
17817f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
17827f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1783062e3f39e37874fedc01f267de5f4cf7dbebe2b4Randy Pan    // TODO: Change variable names to camel style.
1784e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanCapabilities {
1785297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_cache_size;
1786e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_scan_buckets;
1787e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_ap_cache_per_scan;
1788e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde        public int  max_rssi_sample_size;
1789297c3acabe7a85eb87240fe3ccf772e57ce6aef7Mitchell Wills        public int  max_scan_reporting_threshold;
1790e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1791e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1792b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1793b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the scan capabilities
1794b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
179552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1796b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param capabilities object to be filled in
1797b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success. false for failure
1798b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
179952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getBgScanCapabilities(
180052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanCapabilities capabilities) {
180152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanCapabilities(ifaceName, capabilities);
1802e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1803e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1804e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ChannelSettings {
1805712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int frequency;
1806712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int dwell_time_ms;
1807712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public boolean passive;
18087f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
18097f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1810e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class BucketSettings {
1811712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int bucket;
1812712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int band;
1813712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int period_ms;
1814712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_period_ms;
1815712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int step_count;
1816712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_events;
1817712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_channels;
1818712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public ChannelSettings[] channels;
1819e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
18207f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
18216259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    /**
18226259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     * Network parameters for hidden networks to be scanned for.
18236259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius     */
18246259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    public static class HiddenNetwork {
18256259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public String ssid;
18266259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
18276259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        @Override
18286259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public boolean equals(Object otherObj) {
18296259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            if (this == otherObj) {
18306259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return true;
18316259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
18326259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius                return false;
18336259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            }
18346259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            HiddenNetwork other = (HiddenNetwork) otherObj;
18356259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return Objects.equals(ssid, other.ssid);
18366259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        }
1837ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1838ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1839ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1840ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return (ssid == null ? 0 : ssid.hashCode());
1841ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
18426259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius    }
18436259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius
18443feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_LATENCY = 0;
18453feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_LOW_POWER = 1;
18463feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius    public static final int SCAN_TYPE_HIGH_ACCURACY = 2;
18473feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius
1848e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    public static class ScanSettings {
18493feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        /**
18503feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * Type of scan to perform. One of {@link ScanSettings#SCAN_TYPE_LOW_LATENCY},
18513feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         * {@link ScanSettings#SCAN_TYPE_LOW_POWER} or {@link ScanSettings#SCAN_TYPE_HIGH_ACCURACY}.
18523feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius         */
18533feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius        public int scanType;
1854712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int base_period_ms;
1855712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int max_ap_per_scan;
1856712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_percent;
1857712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int report_threshold_num_scans;
1858712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public int num_buckets;
18596259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        /* Not used for bg scans. Only works for single scans. */
18606259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius        public HiddenNetwork[] hiddenNetworks;
1861712ef6246834caeac3d5b06bea08e85d6b29cd7aMitchell Wills        public BucketSettings[] buckets;
1862e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
18637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
186468cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
18659bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Network parameters to start PNO scan.
18669bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
18679bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoNetwork {
18689bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public String ssid;
18699bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public byte flags;
1870ef3ea1092bc17673c0a85a845b053151b7c10e07Roshan Pius        public byte auth_bit_field;
18711bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius
18721bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        @Override
18731bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        public boolean equals(Object otherObj) {
18741bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            if (this == otherObj) {
18751bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return true;
18761bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            } else if (otherObj == null || getClass() != otherObj.getClass()) {
18771bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                return false;
18781bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            }
18791bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius            PnoNetwork other = (PnoNetwork) otherObj;
18806259b630ddb59b642729a2d2113d81ed8e33a0e3Roshan Pius            return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
18811bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius                    && (auth_bit_field == other.auth_bit_field));
18821bf983a4211f547593a60523e43112ecdb5c8997Roshan Pius        }
1883ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh
1884ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        @Override
1885ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        public int hashCode() {
1886ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            int result = (ssid == null ? 0 : ssid.hashCode());
1887ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
1888ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh            return result;
1889ef1606e936204c56ffdae305f2f423ee3503fecdMehdi Alizadeh        }
18909bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
18919bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
18929bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
18939bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Parameters to start PNO scan. This holds the list of networks which are going to used for
18949bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * PNO scan.
18959bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
18969bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public static class PnoSettings {
18979bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min5GHzRssi;
18989bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int min24GHzRssi;
18999bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int initialScoreMax;
19009bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int currentConnectionBonus;
19019bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int sameNetworkBonus;
19029bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int secureBonus;
19039bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public int band5GHzBonus;
190404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang        public int periodInMs;
1905dcd877d6c143db557884993ea437e2a432cb0ba3Roshan Pius        public boolean isConnected;
19069bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        public PnoNetwork[] networkList;
19079bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19089bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
1909b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    public static interface ScanEventHandler {
191063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
191163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called for each AP as it is found with the entire contents of the beacon/probe response.
191263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
191363539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1914c9e6069eb941d282af213dc20b171877db6b567bMitchell Wills        void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
191563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
191663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Callback on an event during a gscan scan.
191763539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * See WifiNative.WIFI_SCAN_* for possible values.
191863539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
191963539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        void onScanStatus(int event);
192063539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
192163539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is paused.
192263539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
192383a674a18c84ff4f01377bbfd8988699dec93bc2Vinit Deshpande        void onScanPaused(WifiScanner.ScanData[] data);
192463539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills        /**
192563539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         * Called with the current cached scan results when gscan is resumed.
192663539f1283899fbbf83ab90757961b4be51d5034Mitchell Wills         */
1927b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande        void onScanRestarted();
1928e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1929e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
19309bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    /**
19319bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     * Handler to notify the occurrence of various events during PNO scan.
19329bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius     */
19339bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    public interface PnoEventHandler {
19349bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        /**
19359bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * Callback to notify when one of the shortlisted networks is found during PNO scan.
19369bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         * @param results List of Scan results received.
19379bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius         */
19389bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius        void onPnoNetworkFound(ScanResult[] results);
1939063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius
1940063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        /**
1941063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         * Callback to notify when the PNO scan schedule fails.
1942063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius         */
1943063cfc7e3eef78fcbda24a66f0c473828b39c854Roshan Pius        void onPnoScanFailed();
19449bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius    }
19459bd01d6cb65ea96d6729d35a1fc43bb2bb40e3bdRoshan Pius
194671af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
194771af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
194871af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
194971af8bb37fee5852ae458edabdef3b487d62a5b8Mitchell Wills    public static final int WIFI_SCAN_FAILED = 3;
1950b7cc309f06da8a18224057c21ba086f8550367d6Vinit Deshpande
1951b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1952b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a background scan.
1953b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Any ongoing scan will be stopped first
1954b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
195552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1956b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param settings     to control the scan
1957b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param eventHandler to call with the results
1958b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
1959b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
196052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startBgScan(
196152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, ScanSettings settings, ScanEventHandler eventHandler) {
196252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startBgScan(ifaceName, settings, eventHandler);
19637f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde    }
19647f9a15d554f69311a0db43347d6473a7c4c46e2eVinit Deshapnde
1965b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1966b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops any ongoing backgound scan
196752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1968b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
196952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void stopBgScan(@NonNull String ifaceName) {
197052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.stopBgScan(ifaceName);
1971b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1972b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1973b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1974b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Pauses an ongoing backgound scan
197552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1976b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
197752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void pauseBgScan(@NonNull String ifaceName) {
197852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.pauseBgScan(ifaceName);
1979b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande    }
1980b0b1d59786de7ff1fc98e31a16a7d710458bf549Vinit Deshpande
1981b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1982b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Restarts a paused scan
198352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1984b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
198552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public void restartBgScan(@NonNull String ifaceName) {
198652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        mWifiVendorHal.restartBgScan(ifaceName);
1987e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1988e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
1989b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
1990b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Gets the latest scan results received.
199152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
1992b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
199352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiScanner.ScanData[] getBgScanResults(@NonNull String ifaceName) {
199452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getBgScanResults(ifaceName);
1995e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde    }
1996e4e3750390bec0a849a9153348b7c21b2cc8b843Vinit Deshapnde
199752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
199852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Gets the latest link layer stats
199952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
200052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
200152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public WifiLinkLayerStats getWifiLinkLayerStats(@NonNull String ifaceName) {
200252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getWifiLinkLayerStats(ifaceName);
20035c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales    }
20045c08cc119b92af69997af194cc8b6d0111e37d31Andres Morales
2005b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2006b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the supported features
2007b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
200852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2009b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
2010b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
201152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int getSupportedFeatureSet(@NonNull String ifaceName) {
201252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getSupportedFeatureSet(ifaceName);
2013a632d8a6edd350c7644b593b18eceaa5b368505bVinit Deshpande    }
2014143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2015143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    public static interface RttEventHandler {
2016143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande        void onRttResults(RttManager.RttResult[] result);
2017143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2018143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2019b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2020b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Starts a new rtt request
2021b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2022b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}.
2023b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked to notify any results.
2024b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if the request was successful, false otherwise.
2025b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
202618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean requestRtt(
2027143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande            RttManager.RttParams[] params, RttEventHandler handler) {
2028b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.requestRtt(params, handler);
2029143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2030143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande
2031b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2032b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Cancels an outstanding rtt request
2033b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2034b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param params RTT request params. Refer to {@link RttManager#RttParams}
2035b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true if there was an outstanding request and it was successfully cancelled
2036b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
203718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean cancelRtt(RttManager.RttParams[] params) {
2038b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.cancelRtt(params);
2039143657392bf0702a155fe688171a5abbf4c86570Vinit Deshpande    }
2040042c54bfd5144ce8e720585b2093796e7e28de5eVinit Deshpande
204168cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    /**
204268cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
204368cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     * role is successfully enabled, {@code null} otherwise.
2044b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2045b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param timeoutSeconds timeout to use for the responder.
204668cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang     */
204768cb8c02b4ad079c54a2ffd4407da921d18c7af9Wei Wang    @Nullable
2048b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public ResponderConfig enableRttResponder(int timeoutSeconds) {
2049b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.enableRttResponder(timeoutSeconds);
205012cf388ecf3b2aa5ba66ed680b931fa356ab75b5xinhe    }
2051939177ff615062ec826601d536466875d8457375xinhe
2052b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2053b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
2054b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * {@code false} otherwise.
2055b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2056b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public boolean disableRttResponder() {
2057b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.disableRttResponder();
20586609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
20596609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2060b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2061b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set the MAC OUI during scanning.
2062b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * An OUI {Organizationally Unique Identifier} is a 24-bit number that
2063b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * uniquely identifies a vendor or manufacturer.
2064b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
206552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2066b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param oui OUI to set.
2067b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2068b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
206952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setScanningMacOui(@NonNull String ifaceName, byte[] oui) {
207052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setScanningMacOui(ifaceName, oui);
20716609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen    }
20726609df5a9c14e4440c085567a27437a8cfc50f88Paul Jensen
2073b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2074b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * RTT (Round Trip Time) measurement capabilities of the device.
2075b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2076b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public RttManager.RttCapabilities getRttCapabilities() {
2077b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRttCapabilities();
2078d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2079d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2080b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2081b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Get the APF (Android Packet Filter) capabilities of the device
208252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2083b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
208452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public ApfCapabilities getApfCapabilities(@NonNull String ifaceName) {
208552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getApfCapabilities(ifaceName);
2086d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2087d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2088b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2089b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Installs an APF program on this iface, replacing any existing program.
2090b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
209152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2092b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param filter is the android packet filter program
2093b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2094b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
209552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean installPacketFilter(@NonNull String ifaceName, byte[] filter) {
209652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.installPacketFilter(ifaceName, filter);
2097d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2098d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2099b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2100b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Set country code for this AP iface.
210152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2102b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param countryCode - two-letter country code (as ISO 3166)
2103b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success
2104b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
210552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean setCountryCodeHal(@NonNull String ifaceName, String countryCode) {
210652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.setCountryCodeHal(ifaceName, countryCode);
2107d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe    }
2108d57f630f6a7a5fca872d2b96fc4cce1905daee5dxinhe
2109a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    //---------------------------------------------------------------------------------
2110a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    /* Wifi Logger commands/events */
2111a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    public static interface WifiLoggerEventHandler {
21120bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onRingBufferData(RingBufferStatus status, byte[] buffer);
21130bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        void onWifiAlert(int errorCode, byte[] buffer);
2114a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2115a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle
2116b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2117b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Registers the logger callback and enables alerts.
2118b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
2119b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2120b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param handler Callback to be invoked.
2121b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2122b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
212318786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
2124b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.setLoggingEventHandler(handler);
212503ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
212603ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2127b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2128b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Control debug data collection
2129b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2130b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
2131b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param flags        Ignored.
2132b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxInterval  Maximum interval between reports; ignore if 0.
2133b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
2134b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName     Name of the ring for which data collection is to start.
2135b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2136b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
213718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
213803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe            int minDataSize, String ringName){
2139b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.startLoggingRingBuffer(
2140b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                verboseLevel, flags, maxInterval, minDataSize, ringName);
214103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
214203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2143b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2144b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Logger features exposed.
2145b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This is a no-op now, will always return -1.
2146b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2147b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2148b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
214918786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public int getSupportedLoggerFeatureSet() {
2150b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getSupportedLoggerFeatureSet();
215103ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
215203ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2153b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2154b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stops all logging and resets the logger callback.
2155b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * This stops both the alerts and ring buffer data collection.
2156b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2157b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
215818786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean resetLogHandler() {
2159b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.resetLogHandler();
2160b797893fc1966803d0c013faac42e6396a37a384xinhe    }
2161b797893fc1966803d0c013faac42e6396a37a384xinhe
2162b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2163b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi driver version string
2164b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2165b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2166b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
216718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getDriverVersion() {
2168b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverVersion();
216903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
217003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2171b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2172b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Vendor-provided wifi firmware version string
2173b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2174b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return String returned from the HAL.
2175b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
217618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public String getFirmwareVersion() {
2177b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFirmwareVersion();
217803ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
217903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
21800bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    public static class RingBufferStatus{
21810bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        String name;
21820bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int flag;
21830bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferId;
21840bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int ringBufferByteSize;
21850bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int verboseLevel;
21860bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenBytes;
21870bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int readBytes;
21880bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        int writtenRecords;
21890bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
219053f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        // Bit masks for interpreting |flag|
219153f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_BINARY_ENTRIES = (1 << 0);
219253f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_ASCII_ENTRIES = (1 << 1);
219353f278b6fed422a18d763b07216a21e96d9445f9Michael Plass        public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
219453f278b6fed422a18d763b07216a21e96d9445f9Michael Plass
21950bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        @Override
21960bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        public String toString() {
21970bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande            return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
21980bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
21990bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
22000bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande                    " writtenRecords: " + writtenRecords;
22010bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande        }
22020bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande    }
22030bf150b2d69ec62df905bc6f8603437dc4caee1fVinit Deshpande
2204b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2205b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * API to get the status of all ring buffers supported by driver
2206b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
220718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public RingBufferStatus[] getRingBufferStatus() {
2208b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferStatus();
220903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
221003ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe
2211b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2212b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Indicates to driver that all the data has to be uploaded urgently
2213b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2214b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param ringName Name of the ring buffer requested.
2215b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true on success, false otherwise.
2216b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
221718786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public boolean getRingBufferData(String ringName) {
2218b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getRingBufferData(ringName);
221903ba4a5b108ab2bbdb5d0e7be46ac45c00a6d9ffxinhe    }
2220127f7244183786e6ccae09e81eeccdac31973e69xinhe
2221b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2222b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the firmware
2223b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2224b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2225b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
222618786eca942042388748b0d98979f21c9dff4a89Mitchell Wills    public byte[] getFwMemoryDump() {
2227b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getFwMemoryDump();
2228a0d34d3626bd9631039a485d2d428b1b7de390e2Pierre Vandwalle    }
2229dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle
2230b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2231b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Request vendor debug info from the driver
2232b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
2233b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return Raw data obtained from the HAL.
2234b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2235d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    public byte[] getDriverStateDump() {
2236b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getDriverStateDump();
2237d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal    }
2238d0cb2fae195ebb9f658095667f3c7b7b8d69a204mukesh agrawal
2239dd490cf1df37b70a8625dc4ec8e712f740dd1e4aPierre Vandwalle    //---------------------------------------------------------------------------------
224009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /* Packet fate API */
224109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
224209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
224309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    abstract static class FateReport {
2244eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int USEC_PER_MSEC = 1000;
2245eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
2246eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        // maximal value of a driver timestamp in milliseconds.
2247eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
2248eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
2249eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
225009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFate;
225109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final long mDriverTimestampUSec;
225209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte mFrameType;
225309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        final byte[] mFrameBytes;
2254eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        final long mEstimatedWallclockMSec;
225509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
225609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
225709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFate = fate;
225809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mDriverTimestampUSec = driverTimestampUSec;
2259eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            mEstimatedWallclockMSec =
2260eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
226109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameType = frameType;
226209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            mFrameBytes = frameBytes;
226309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
22640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2265590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toTableRowString() {
2266590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2267590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2268590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
2269eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            dateFormatter.setTimeZone(TimeZone.getDefault());
2270eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2271eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    mDriverTimestampUSec,
2272eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    dateFormatter.format(new Date(mEstimatedWallclockMSec)),
2273eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    directionToString(), fateToString(), parser.mMostSpecificProtocolString,
2274eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    parser.mTypeString, parser.mResultString);
2275590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2276590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2277590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
2278590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public String toVerboseStringWithPiiAllowed() {
22790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            StringWriter sw = new StringWriter();
22800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            PrintWriter pw = new PrintWriter(sw);
2281590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
22820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame direction: %s\n", directionToString());
22830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
22840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame fate: %s\n", fateToString());
22850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
2286590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
2287590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.format("Frame protocol type: %s\n", parser.mTypeString);
22880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.format("Frame length: %d\n", mFrameBytes.length);
22890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("Frame bytes");
2290590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
22910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            pw.append("\n");
22920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return sw.toString();
22930fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
22940fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
2295590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        /* Returns a header to match the output of toTableRowString(). */
2296590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        public static String getTableHeader() {
2297590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            StringWriter sw = new StringWriter();
2298590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            PrintWriter pw = new PrintWriter(sw);
2299eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2300eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
2301eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
2302eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                    "---------", "--------", "---------", "----", "--------", "----", "------");
2303590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan            return sw.toString();
2304590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan        }
2305590f3fc2045389d5ef274c4b3bd6162d93b1a0acSamuel Tan
23060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String directionToString();
23070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected abstract String fateToString();
23090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        private static String frameTypeToString(byte frameType) {
23110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (frameType) {
23120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
23130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "unknown";
23140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
23150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "data";
23160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
23170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "802.11 management";
23180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
23190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(frameType);
23200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
23210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
2322eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2323eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        /**
2324eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * Converts a driver timestamp to a wallclock time, based on the current
2325eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
2326eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         * microseconds, with the same base as BOOTTIME.
2327eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal         */
2328eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
2329eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long wallclockMillisNow = System.currentTimeMillis();
2330eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long boottimeMillisNow = SystemClock.elapsedRealtime();
2331eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
2332eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2333eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
2334eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            if (boottimeTimestampMillis < driverTimestampMillis) {
2335eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // The 32-bit microsecond count has wrapped between the time that the driver
2336eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // recorded the packet, and the call to this function. Adjust the BOOTTIME
2337eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // timestamp, to compensate.
2338eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                //
2339eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // Note that overflow is not a concern here, since the result is less than
2340eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
2341eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
2342eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
2343eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                // within a long.
2344eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal                boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
2345eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            }
2346eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal
2347eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
2348eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal            return wallclockMillisNow - millisSincePacketTimestamp;
2349eaf6303a081b4a7f2231b5053099da7a1c16b7bdmukesh agrawal        }
235009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
235109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
235209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
235309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one outbound packet.
235409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
235509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
235609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class TxFateReport extends FateReport {
235709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
235809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
235909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
23600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
23620fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
23630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "TX";
23640fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
23650fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
23660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
23670fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
23680fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
23690fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_ACKED:
23700fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "acked";
23710fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_SENT:
23720fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "sent";
23730fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
23740fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
23750fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
23760fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
23770fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
23780fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
23790fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
23800fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
23810fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
23820fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
23830fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
23840fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
23850fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
23860fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
23870fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
23880fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
23890fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
23900fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
23910fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
23920fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
239309b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
239409b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
239509b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    /**
239609b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     * Represents the fate information for one inbound packet.
239709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal     */
239809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    @Immutable
239909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    public static final class RxFateReport extends FateReport {
240009b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
240109b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal            super(fate, driverTimestampUSec, frameType, frameBytes);
240209b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal        }
24030fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24040fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24050fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String directionToString() {
24060fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            return "RX";
24070fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
24080fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24090fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        @Override
24100fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        protected String fateToString() {
24110fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            switch (mFate) {
24120fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
24130fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "success";
24140fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
24150fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware queued";
24160fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
24170fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (filter)";
24180fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
24190fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (invalid frame)";
24200fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
24210fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (no bufs)";
24220fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
24230fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "firmware dropped (other)";
24240fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
24250fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver queued";
24260fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
24270fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (filter)";
24280fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
24290fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (invalid frame)";
24300fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
24310fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (no bufs)";
24320fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
24330fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return "driver dropped (other)";
24340fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                default:
24350fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal                    return Byte.toString(mFate);
24360fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal            }
24370fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal        }
243809b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal    }
243909b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
24400fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
24410fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
2442b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
244352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2444b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
24450fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
244652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean startPktFateMonitoring(@NonNull String ifaceName) {
244752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.startPktFateMonitoring(ifaceName);
24480fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
24490fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24500fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
24510fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
2452b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
245352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2454b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
24550fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
245652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getTxPktFates(@NonNull String ifaceName, TxFateReport[] reportBufs) {
245752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getTxPktFates(ifaceName, reportBufs);
24580fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
24590fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal
24600fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    /**
24610fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
246252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
24630fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal     */
246452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRxPktFates(@NonNull String ifaceName, RxFateReport[] reportBufs) {
246552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRxPktFates(ifaceName, reportBufs);
24660fcb06473cbe2824e401a80c0520bb1c14ed8f41mukesh agrawal    }
246709b1d0786d05436d524d7556c269e665a0962ee6mukesh agrawal
24685c3c06082b24f9ff0d479e82a63b52220c86598bRoshan Pius    /**
2469b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start sending the specified keep alive packets periodically.
2470b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
247152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2472b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot Integer used to identify each request.
2473ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param dstMac Destination MAC Address
2474ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param packet Raw packet contents to send.
2475ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold     * @param protocol The ethernet protocol type
2476b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param period Period to use for sending these packets.
2477b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2478b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2479ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold    public int startSendingOffloadedPacket(@NonNull String ifaceName, int slot,
2480ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold            byte[] dstMac, byte[] packet, int protocol, int period) {
2481ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        byte[] srcMac = NativeUtil.macAddressToByteArray(getMacAddress(ifaceName));
2482ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold        return mWifiVendorHal.startSendingOffloadedPacket(
2483ed0b7cfa5bb7be5731e42c2aaac7c9fdaa68baa4Nathan Harold                ifaceName, slot, srcMac, dstMac, packet, protocol, period);
2484c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2485c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham
2486b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2487b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Stop sending the specified keep alive packets.
2488b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
248952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2490b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param slot id - same as startSendingOffloadedPacket call.
2491b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for error
2492b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
249352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopSendingOffloadedPacket(@NonNull String ifaceName, int slot) {
249452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopSendingOffloadedPacket(ifaceName, slot);
2495c55e88163b223db0ca6a99ed6ffe91845c30a576Prerepa Viswanadham    }
2496aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2497aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    public static interface WifiRssiEventHandler {
2498aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham        void onRssiThresholdBreached(byte curRssi);
2499aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2500aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
2501b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2502b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Start RSSI monitoring on the currently connected access point.
2503b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
250452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName        Name of the interface.
2505b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param maxRssi          Maximum RSSI threshold.
2506b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param minRssi          Minimum RSSI threshold.
2507b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
2508b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return 0 for success, -1 for failure
2509b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
251052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int startRssiMonitoring(
251152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, byte maxRssi, byte minRssi,
251252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            WifiRssiEventHandler rssiEventHandler) {
2513d77212c2b255b5e6331222fde66bdc735295fbbeRoshan Pius        return mWifiVendorHal.startRssiMonitoring(
251452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius                ifaceName, maxRssi, minRssi, rssiEventHandler);
2515aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
2516aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham
251752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    /**
251852ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * Stop RSSI monitoring on the currently connected access point.
251952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     *
252052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
252152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @return 0 for success, -1 for failure
252252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     */
252352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int stopRssiMonitoring(@NonNull String ifaceName) {
252452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.stopRssiMonitoring(ifaceName);
2525aed5cb65d8eefb2eee56a29e33ac3cd8b03312e7Prerepa Viswanadham    }
25265ea42964ba17901a8d724736b450ace6ed48880fPrerepa Viswanadham
25276bf6986d359556010638dfae332b585162f06520Roshan Pius    /**
25286bf6986d359556010638dfae332b585162f06520Roshan Pius     * Fetch the host wakeup reasons stats from wlan driver.
2529b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
25306bf6986d359556010638dfae332b585162f06520Roshan Pius     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
25316bf6986d359556010638dfae332b585162f06520Roshan Pius     */
25326bf6986d359556010638dfae332b585162f06520Roshan Pius    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
2533b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        return mWifiVendorHal.getWlanWakeReasonCount();
25346bf6986d359556010638dfae332b585162f06520Roshan Pius    }
25353dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline
2536b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2537b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Enable/Disable Neighbour discovery offload functionality in the firmware.
2538b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
253952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2540b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @param enabled true to enable, false to disable.
2541b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2542b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
254352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureNeighborDiscoveryOffload(@NonNull String ifaceName, boolean enabled) {
254452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureNeighborDiscoveryOffload(ifaceName, enabled);
25453dd6f75ff2ab823bd0c14581f2e047c74916f16fErik Kline    }
2546da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2547da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    // Firmware roaming control.
2548da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2549da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2550da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class to retrieve firmware roaming capability parameters.
2551da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2552da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingCapabilities {
2553da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxBlacklistSize;
2554da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public int  maxWhitelistSize;
2555da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2556da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2557da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2558da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Query the firmware roaming capabilities.
255952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2560b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return true for success, false otherwise.
2561da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
256252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean getRoamingCapabilities(
256352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius            @NonNull String ifaceName, RoamingCapabilities capabilities) {
256452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.getRoamingCapabilities(ifaceName, capabilities);
2565da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2566da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2567da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2568da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Macros for controlling firmware roaming.
2569da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2570da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int DISABLE_FIRMWARE_ROAMING = 0;
2571da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static final int ENABLE_FIRMWARE_ROAMING = 1;
2572da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2573da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2574da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Enable/disable firmware roaming.
2575b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     *
257652ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2577b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * @return error code returned from HAL.
2578da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
257952ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public int enableFirmwareRoaming(@NonNull String ifaceName, int state) {
258052ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.enableFirmwareRoaming(ifaceName, state);
2581da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2582da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2583da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2584da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Class for specifying the roaming configurations.
2585da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
2586da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    public static class RoamingConfig {
2587da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> blacklistBssids;
2588da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan        public ArrayList<String> whitelistSsids;
2589da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2590da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2591da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    /**
2592da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     * Set firmware roaming configurations.
259352ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2594da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan     */
259552ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean configureRoaming(@NonNull String ifaceName, RoamingConfig config) {
25961d4d6b7b1fe4d95ad04c8f0c501e233be4160f90Roshan Pius        Log.d(TAG, "configureRoaming ");
259752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, config);
2598da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2599da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan
2600374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan    /**
2601374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     * Reset firmware roaming configuration.
260252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius     * @param ifaceName Name of the interface.
2603374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan     */
260452ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius    public boolean resetRoamingConfiguration(@NonNull String ifaceName) {
2605b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // Pass in an empty RoamingConfig object which translates to zero size
2606b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        // blacklist and whitelist to reset the firmware roaming configuration.
260752ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius        return mWifiVendorHal.configureRoaming(ifaceName, new RoamingConfig());
2608b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2609b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2610ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2611b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Tx power level scenarios that can be selected.
2612ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2613b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_NORMAL = 0;
2614b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public static final int TX_POWER_SCENARIO_VOICE_CALL = 1;
2615ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2616ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    /**
2617b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * Select one of the pre-configured TX power level scenarios or reset it back to normal.
2618ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * Primarily used for meeting SAR requirements during voice calls.
2619ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     *
2620b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or
2621b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius     *        {@link #TX_POWER_SCENARIO_VOICE_CALL}.
2622ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     * @return true for success; false for failure or if the HAL version does not support this API.
2623ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius     */
2624b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius    public boolean selectTxPowerScenario(int scenario) {
2625b7f35c58029fe5dce64813271ad4e8b1b6ea8893Roshan Pius        return mWifiVendorHal.selectTxPowerScenario(scenario);
2626ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius    }
2627ba89009ba7554d5073c0b93c04f167c3a11667faRoshan Pius
2628b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /********************************************************
2629b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * JNI operations
2630b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     ********************************************************/
2631b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* Register native functions */
2632b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    static {
2633b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        /* Native functions are defined in libwifi-service.so */
2634b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        System.loadLibrary("wifi-service");
2635b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        registerNatives();
2636b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
2637b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2638b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native int registerNatives();
2639b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /* kernel logging support */
2640b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    private static native byte[] readKernelLogNative();
2641b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius
2642b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    /**
2643b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     * Fetches the latest kernel logs.
2644b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius     */
2645b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    public synchronized String readKernelLog() {
2646b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        byte[] bytes = readKernelLogNative();
2647b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius        if (bytes != null) {
2648b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
2649b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            try {
2650b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
2651b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return decoded.toString();
2652b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            } catch (CharacterCodingException cce) {
2653b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius                return new String(bytes, StandardCharsets.ISO_8859_1);
2654b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            }
2655520fbe7db055661af039303c1081236c73b04abdRoshan Pius        } else {
2656b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius            return "*** failed to read kernel log ***";
2657374f78d3841f7bf74543dc4d21db66d1d3472c3aRandy Pan        }
2658da4958bd7409aaf26ead2b221754d4a5035f7bdfRandy Pan    }
2659155b9d09ef9b8ead3ca617afdd91e74070d3f0cbVinit Deshpande}
2660